actions.js

来自「在线编辑器」· JavaScript 代码 · 共 771 行 · 第 1/2 页

JS
771
字号
/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights and * limitations under the License. * * The Original Code is Bespin. * * The Initial Developer of the Original Code is Mozilla. * Portions created by the Initial Developer are Copyright (C) 2009 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Bespin Team (bespin@mozilla.com) * * ***** END LICENSE BLOCK ***** */dojo.provide("bespin.editor.actions");  // = Actions =//// The editor can run various actions. They are defined here and you can add or change them dynamically. Cool huh?//// An action mutates the model or editor state in some way. The only way the editor state or model should be manipulated is via// the execution of actions.//// Actions integrate with the undo manager by including instructions for how to undo (and redo) the action. These instructions// take the form of a hash containing the necessary state for undo/redo. A key "action" corresponds to the function name of the// action that should be executed to undo or redo the operation and the remaining keys correspond to state necessary to perform// the action. See below for various examples.dojo.declare("bespin.editor.Actions", null, {     constructor: function(editor) {        this.editor = editor;        this.ignoreRepaints = false;    },    // this is a generic helper method used by various cursor-moving methods    handleCursorSelection: function(args) {        if (args.event.shiftKey) {            if (!this.editor.selection) this.editor.setSelection({ startPos: bespin.editor.utils.copyPos(args.pos) });            this.editor.setSelection({ startPos: this.editor.selection.startPos, endPos: bespin.editor.utils.copyPos(this.editor.cursorPosition)});        } else {            this.editor.setSelection(undefined);        }    },    moveCursorLeft: function(args) {        // start of the line so move up        if (_settings.isOn(_settings.get('strictlines')) && (this.editor.cursorPosition.col == 0)) {            var originalRow = args.pos.row;            this.moveCursorUp(args);            if (originalRow > 0) this.moveToLineEnd(args);            return;        }        this.editor.cursorPosition.col = Math.max(0, args.pos.col - 1);        this.handleCursorSelection(args);        this.repaint();    },    moveCursorRight: function(args) {        // end of the line, so go to the start of the next line        if (_settings.isOn(_settings.get('strictlines')) && (this.editor.cursorPosition.col >= this.editor.model.getRowLength(args.pos.row))) {            var originalRow = args.pos.row;            this.moveCursorDown(args);            if (originalRow < this.editor.model.getRowCount() - 1) this.moveToLineStart(args);            return;        }        this.editor.cursorPosition.col = args.pos.col + 1;        this.handleCursorSelection(args);        this.repaint();    },    moveCursorUp: function(args) {        this.editor.cursorPosition.row = Math.max(0, args.pos.row - 1);        if (_settings.isOn(_settings.get('strictlines')) && args.pos.col > this.editor.model.getRowLength(this.editor.cursorPosition.row)) {            this.handleCursorSelection(args);                        args.pos.row -= 1; // one above            this.moveToLineEnd(args);        } else {            this.handleCursorSelection(args);                    }        this.repaint();        args.pos.row = this.editor.cursorPosition.row;        return args;    },    moveCursorDown: function(args) {        this.editor.cursorPosition.row = Math.min(this.editor.model.getRowCount() - 1, args.pos.row + 1);        if (_settings.isOn(_settings.get('strictlines')) && args.pos.col > this.editor.model.getRowLength(this.editor.cursorPosition.row)) {            this.handleCursorSelection(args);                        args.pos.row += 1; // one below            this.moveToLineEnd(args);        } else {            this.handleCursorSelection(args);        }        this.repaint();        args.pos.row = this.editor.cursorPosition.row;        return args;    },    moveToLineStart: function(args) {        var line = this.editor.model.getRowArray(this.editor.cursorPosition.row).join('');        var match = /^(\s+).*/.exec(line)        var leadingWhitespaceLength = 0;        // Check to see if there is leading white space and move to the first text if that is the case        if (match && match.length == 2) {            leadingWhitespaceLength = match[1].length;        }        if (args.pos.col == 0) {            this.editor.cursorPosition.col = leadingWhitespaceLength;        } else if (args.pos.col == leadingWhitespaceLength) {            this.editor.cursorPosition.col = 0;        } else {            this.editor.cursorPosition.col = leadingWhitespaceLength;        }        this.handleCursorSelection(args);        this.repaint();        args.pos.col = this.editor.cursorPosition.col;        return args;    },    moveToLineEnd: function(args) {        this.editor.cursorPosition.col = this.editor.model.getRowLength(args.pos.row);        this.handleCursorSelection(args);        this.repaint();        args.pos.col = this.editor.cursorPosition.col;        return args;    },    moveToFileTop: function(args) {        this.editor.cursorPosition.col = this.editor.cursorPosition.row = 0;        this.handleCursorSelection(args);        this.repaint();        args.pos.col = args.pos.row = 0;        return args;    },    moveToFileBottom: function(args) {        this.editor.cursorPosition.row = this.editor.model.getRowCount() - 1;        this.editor.cursorPosition.col = this.editor.model.getRowLength(this.editor.cursorPosition.row);        this.handleCursorSelection(args);        this.repaint();        args.pos.row = this.editor.cursorPosition.row;        args.pos.col = this.editor.cursorPosition.col;        return args;    },    movePageUp: function(args) {        this.editor.cursorPosition.row = Math.max(this.editor.ui.firstVisibleRow - this.editor.ui.visibleRows, 0);        this.handleCursorSelection(args);        this.repaint();        return args;    },    movePageDown: function(args) {        this.editor.cursorPosition.row = Math.min(this.editor.cursorPosition.row + this.editor.ui.visibleRows, this.editor.model.getRowCount() - 1);        this.handleCursorSelection(args);        this.repaint();        return args;    },    moveWordLeft: function(args) {        var row = this.editor.model.getRowArray(args.pos.row);        if (args.pos.col == 0) { // -- at the start to move up and to the end            var newargs = this.moveCursorUp(args);            this.moveToLineEnd(newargs);            return;        }        // Short circuit if cursor is ahead of actual spaces in model        if (row.length < args.pos.col) {            args = this.moveToLineEnd(args);        }        var newcol = args.pos.col;        // This slurps up trailing spaces        var wasSpaces = false;        while (newcol > 0) {            newcol--;            var c = row[newcol];            var charCode = c.charCodeAt(0);            if (charCode == 32) {                wasSpaces = true;            } else {                newcol++;                break;            }        }        // This jumps to stop words                if (!wasSpaces) {            while (newcol > 0) {                newcol--;                var c = row[newcol];                var charCode = c.charCodeAt(0);                if ( (charCode < 65) || (charCode > 122) ) { // if you get to an alpha you are done                    if (newcol != args.pos.col - 1) newcol++; // right next to a stop char, move back one                    break;                }            }        }                this.editor.cursorPosition.col = newcol;        this.handleCursorSelection(args);        this.repaint();    },    moveWordRight: function(args) {        var row = this.editor.model.getRowArray(args.pos.row);        if (row.length <= args.pos.col) { // -- at the edge so go to the next line            this.moveCursorDown(this.moveToLineStart(args));            return;        }        var newcol = args.pos.col;        // This slurps up leading spaces        var wasSpaces = false;        while (newcol < row.length) {            var c = row[newcol];            var charCode = c.charCodeAt(0);            if (charCode == 32) {                wasSpaces = true;                newcol++;            } else {                break;            }        }        // This jumps to stop words                if (!wasSpaces) {                    while (newcol < row.length) {                newcol++;                if (row.length == newcol) { // one more to go                    this.moveToLineEnd(args);                    return;                }                var c = row[newcol];                var charCode = c.charCodeAt(0);                            if ( (charCode < 65) || (charCode > 122) ) {                    break;                }            }        }            this.editor.cursorPosition.col = newcol;        this.handleCursorSelection(args);        this.repaint();    },    undoRedo: function(args) {        if (! args.event.shiftKey) {    // holding down the shift key causes the undo keystroke to be a redo TODO: move this logic to key handler            this.undo();        } else {            this.redo();        }    },    undo: function() {        this.editor.undoManager.undo();    },    redo: function() {        this.editor.undoManager.redo();    },    selectAll: function(args) {        // do nothing with an empty doc        if (this.editor.model.getMaxCols == 0) return;        args.startPos = { col: 0, row: 0 };        args.endPos = { col: this.editor.model.getRowLength(this.editor.model.getRowCount() - 1), row: this.editor.model.getRowCount() - 1 };        this.select(args);    },    select: function(args) {        if (args.startPos) {            this.editor.setSelection({ startPos: args.startPos, endPos: args.endPos });            this.editor.moveCursor(args.endPos);        } else {            this.editor.setSelection(undefined);        }    },    insertTab: function(args) {        if (this.editor.getSelection() && !args.undoInsertTab) {            this.indent(args);            return;        }        var tabWidth = parseInt(_settings.get('tabsize') || bespin.defaultTabSize);   // TODO: global needs fixing        var tabWidthCount = tabWidth;        var tab = "";        while (tabWidthCount-- > 0) {            tab += " ";        }                this.editor.model.insertCharacters({row: args.pos.row, col: args.pos.col}, tab);                    this.editor.moveCursor({row: args.pos.row, col: args.pos.col + tabWidth});                this.repaint();                // undo/redo        args.action = "insertTab";        var redoOperation = args;        var undoArgs = { action: "removeTab", queued: args.queued, pos: bespin.editor.utils.copyPos(args.pos) };        var undoOperation = undoArgs;        this.editor.undoManager.addUndoOperation(new bespin.editor.UndoItem(undoOperation, redoOperation));    },        // this function can only be called by editor.undoManager for undo insertTab in the case of beeing nothing selected    removeTab: function(args) {        var tabWidth = parseInt(_settings.get('tabsize') || bespin.defaultTabSize);   // TODO: global needs fixing                this.editor.model.deleteCharacters({row: args.pos.row, col: args.pos.col}, tabWidth);        this.editor.moveCursor({row: args.pos.row, col: args.pos.col});                this.repaint();                args.action = "removeTab";        var redoOperation = args;        var undoArgs = { action: "insertTab", undoInsertTab: true, queued: args.queued, pos: bespin.editor.utils.copyPos(args.pos) };        var undoOperation = undoArgs;        this.editor.undoManager.addUndoOperation(new bespin.editor.UndoItem(undoOperation, redoOperation));    },    indent: function(args) {        var historyIndent = args.historyIndent || false;            if (!historyIndent) {            var newHistoryIndent = new Array();        }        var selection = args.selection || this.editor.getSelection();        var fakeSelection = args.fakeSelection || false;        var startRow = selection.startPos.row;        var endRow = selection.endPos.row;        var tabWidth = tabWidthCount = parseInt(_settings.get('tabsize') || bespin.defaultTabSize);   // TODO: global needs fixing        var tab = "";        while (tabWidthCount-- > 0) {            tab += " ";        }        for (var y = startRow; y <= endRow; y++) {            if (!historyIndent) {                var row = this.editor.model.getRowArray(y).join("");                var match = /^(\s+).*/.exec(row);                var leadingWhitespaceLength = 0;                if (match && match.length == 2) {                    leadingWhitespaceLength = match[1].length;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?