From 97b00ea46b730e6b321947aac69e5e62f32685fd Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 19 Nov 2011 20:29:36 +0400 Subject: [PATCH] untangle keybinding.js --- lib/ace/commands/default_commands.js | 15 ++-- lib/ace/editor.js | 25 +------ lib/ace/keyboard/keybinding.js | 105 ++++++++++++++------------- lib/ace/keyboard/textinput.js | 4 +- 4 files changed, 67 insertions(+), 82 deletions(-) diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index a0a97862..74dfe16f 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -284,6 +284,9 @@ exports.commands = [{ name: "indent", bindKey: bindKey("Tab", "Tab"), exec: function(editor) { editor.indent(); } +}, { + name: "insertstring", + exec: function(editor, str) { editor.insert(str); } }, { name: "inserttext", exec: function(editor, args) { @@ -318,21 +321,15 @@ exports.commands = [{ }, { name: "unfold", bindKey: bindKey("Alt-Shift-L", "Alt-Shift-L"), - exec: function(editor) { - editor.session.toggleFold(true); - } + exec: function(editor) { editor.session.toggleFold(true); } }, { name: "foldall", bindKey: bindKey("Alt-0", "Alt-0"), - exec: function(editor) { - editor.session.foldAll(); - } + exec: function(editor) { editor.session.foldAll(); } }, { name: "unfoldall", bindKey: bindKey("Alt-Shift-0", "Alt-Shift-0"), - exec: function(editor) { - editor.session.unfold(); - } + exec: function(editor) { editor.session.unfold(); } }]; }); diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 95881cc3..e6ffbd93 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -523,30 +523,11 @@ var Editor = function(renderer, session) { mode.autoOutdent(lineState, session, cursor.row); }; - this.onTextInput = function(text, notPasted) { - if (!notPasted) + this.onTextInput = function(text, pasted) { + if (pasted) this._emit("paste", text); - // In case the text was not pasted and we got only one character, then - // handel it as a command key stroke. - if (notPasted && text.length == 1) { - // Note: The `null` as `keyCode` is important here, as there are - // some checks in the code for `keyCode == 0` meaning the text comes - // from the keyBinding.onTextInput code path. - var handled = this.keyBinding.onCommandKey({}, 0, null, text); - - // Check if the text was handled. If not, then handled it as "normal" - // text and insert it to the editor directly. This shouldn't be done - // using the this.keyBinding.onTextInput(text) function, as it would - // make the `text` get sent to the keyboardHandler twice, which might - // turn out to be a bad thing in case there is a custome keyboard - // handler like the StateHandler. - if (!handled) { - this.insert(text); - } - } else { - this.keyBinding.onTextInput(text); - } + this.keyBinding.onTextInput(text, pasted); }; this.onCommandKey = function(e, hashId, keyCode) { diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js index 0c4860d8..d8fe9fdc 100644 --- a/lib/ace/keyboard/keybinding.js +++ b/lib/ace/keyboard/keybinding.js @@ -21,6 +21,7 @@ * Contributor(s): * Fabian Jakobs * Julian Viereck + * Harutyun Amirjanyan * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -46,71 +47,77 @@ require("../commands/default_commands"); var KeyBinding = function(editor) { this.$editor = editor; this.$data = { }; - this.$keyboardHandler = null; + this.$handlers = [this]; }; (function() { this.setKeyboardHandler = function(keyboardHandler) { - if (this.$keyboardHandler != keyboardHandler) { - this.$data = { }; - this.$keyboardHandler = keyboardHandler; - } + if (this.$handlers[this.$handlers.length - 1] == keyboardHandler) + return; + this.$data = { }; + this.$handlers = keyboardHandler ? [this, keyboardHandler] : [this]; + }; + + this.addKeyboardHandler = function(keyboardHandler) { + this.removeKeyboardHandler(keyboardHandler); + this.$handlers.push(keyboardHandler); + }; + + this.removeKeyboardHandler = function(keyboardHandler) { + var i = this.$handlers.indexOf(keyboardHandler); + if (i == -1) + return false; + this.$handlers.splice(i, 1); + return true; }; this.getKeyboardHandler = function() { - return this.$keyboardHandler; + return this.$handlers[this.$handlers - 1]; }; - this.$callKeyboardHandler = function (e, hashId, keyOrText, keyCode) { - var toExecute; - var commands = this.$editor.commands; - - if (this.$keyboardHandler) { - toExecute = - this.$keyboardHandler.handleKeyboard(this.$data, hashId, keyOrText, keyCode, e); - } - - - // If there is nothing to execute yet, then use the default keymapping. - if (!toExecute || !toExecute.command) { - if (hashId != 0 || keyCode != 0) { - toExecute = { - command: commands.findKeyCommand(hashId, keyOrText) - } - } else { - toExecute = { - command: "inserttext", - args: { - text: keyOrText - } - } - } - } - - var success = false; - if (toExecute && toExecute.command) { - success = commands.exec( - toExecute.command, - this.$editor, toExecute.args + this.$callKeyboardHandlers = function (hashId, keyString, keyCode, e) { + for (var i = this.$handlers.length; i--;) { + var toExecute = this.$handlers[i].handleKeyboard( + this.$data, hashId, keyString, keyCode, e ); - if (success) { - event.stopEvent(e); - } + if (toExecute) + break; } - return success; + + if (!toExecute || !toExecute.command) + return false; + var success = false, commands = this.$editor.commands; + + // allow keyboardHandler to consume keys + if (toExecute.command != "null") + success = commands.exec(toExecute.command, this.$editor, toExecute.args); + else + success = true; + + if (success && e) + event.stopEvent(e); + + return success }; - this.onCommandKey = function(e, hashId, keyCode, keyString) { - // In case there is no keyString, try to interprete the keyCode. - if (!keyString) { - keyString = keyUtil.keyCodeToString(keyCode); + this.handleKeyboard = function(data, hashId, keyString) { + return { + command: this.$editor.commands.findKeyCommand(hashId, keyString) } - return this.$callKeyboardHandler(e, hashId, keyString, keyCode); }; - this.onTextInput = function(text) { - return this.$callKeyboardHandler({}, 0, text, 0); - } + this.onCommandKey = function(e, hashId, keyCode) { + var keyString = keyUtil.keyCodeToString(keyCode); + this.$callKeyboardHandlers(hashId, keyString, keyCode, e); + }; + + this.onTextInput = function(text, pasted) { + var success = false; + if (!pasted && text.length == 1) + success = this.$callKeyboardHandlers(0, text); + if (!success) + this.$editor.commands.exec("insertstring", this.$editor, text); + }; }).call(KeyBinding.prototype); diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index fabb4ca3..5acdb861 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -73,10 +73,10 @@ var TextInput = function(parentNode, host) { if (value.charCodeAt(value.length-1) == PLACEHOLDER.charCodeAt(0)) { value = value.slice(0, -1); if (value) - host.onTextInput(value, !pasted); + host.onTextInput(value, pasted); } else { - host.onTextInput(value, !pasted); + host.onTextInput(value, pasted); } // If editor is no longer focused we quit immediately, since