From f51433072941d6c35916c60414037d9d1582aa6a Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 2 Mar 2013 17:54:21 +0400 Subject: [PATCH 1/3] add extension for enabling spellchecking from contextmenu --- lib/ace/config.js | 4 +-- lib/ace/ext/spellcheck.js | 58 +++++++++++++++++++++++++++++++++++ lib/ace/keyboard/textinput.js | 32 +++++++++++++------ lib/ace/virtual_renderer.js | 4 +-- 4 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 lib/ace/ext/spellcheck.js diff --git a/lib/ace/config.js b/lib/ace/config.js index c617959d..4a7dc286 100644 --- a/lib/ace/config.js +++ b/lib/ace/config.js @@ -103,12 +103,12 @@ exports.loadModule = function(moduleName, onLoad) { module = require(moduleName); } catch (e) {}; if (module) - return onLoad(module); + return onLoad && onLoad(module); var afterLoad = function() { require([moduleName], function(module) { exports._emit("load.module", {name: moduleName, module: module}); - onLoad(module); + onLoad && onLoad(module); }); }; diff --git a/lib/ace/ext/spellcheck.js b/lib/ace/ext/spellcheck.js new file mode 100644 index 00000000..23ac3c31 --- /dev/null +++ b/lib/ace/ext/spellcheck.js @@ -0,0 +1,58 @@ +define(function(require, exports, module) { +"use strict"; + +exports.contextMenuHandler = function(e){ + var host = e.target; + var text = host.textInput.getElement(); + if (!host.selection.isEmpty()) + return; + var c = host.getCursorPosition(); + var r = host.session.getWordRange(c.row, c.column); + var w = host.session.getTextRange(r); + + host.session.tokenRe.lastIndex = 0; + if (!host.session.tokenRe.test(w)) + return; + var PLACEHOLDER = "\x01\x01"; + var value = w + " " + PLACEHOLDER; + text.value = value; + text.setSelectionRange(w.length + 1, w.length + 1); + text.setSelectionRange(0, 0); + + host.textInput.setInputHandler(function(newVal) { + if (newVal == value) + return ''; + if (newVal.lastIndexOf(value) == newVal.length - value.length) + return newVal.slice(0, -value.length); + if (newVal.indexOf(value) === 0) + return newVal.slice(value.length); + if (newVal.slice(-2) == PLACEHOLDER) { + var val = newVal.slice(0, -2); + if (val.slice(-1) == " ") { + val = val.slice(0, -1); + host.session.replace(r, val); + return ""; + } + } + + return newVal; + }); +}; +// todo support highlighting with typo.js +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + spellcheck: { + set: function(val) { + var text = this.textInput.getElement(); + text.spellcheck = !!val; + if (!val) + this.removeListener("nativecontextmenu", exports.contextMenuHandler); + else + this.on("nativecontextmenu", exports.contextMenuHandler); + }, + value: true + } +}); + +}); + diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 397a0917..e8f3ed29 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -96,8 +96,13 @@ var TextInput = function(parentNode, host) { function resetSelection(isEmpty) { if (inCompostion) return; - var selectionStart = isEmpty ? 2 : 1; - var selectionEnd = 2; + if (inputHandler) { + selectionStart = 0 + selectionEnd = isEmpty == false ? text.value.length - 1 : 0; + } else { + var selectionStart = isEmpty ? 2 : 1; + var selectionEnd = 2; + } // on firefox this throws if textarea is hidden try { text.setSelectionRange(selectionStart, selectionEnd); @@ -180,19 +185,25 @@ var TextInput = function(parentNode, host) { var onSelect = function(e) { if (cut) { cut = false; - return; - } - if (copied) { + } else if (copied) { copied = false; - return; - } - if (isAllSelected(text)) { + } else if (isAllSelected(text)) { host.selectAll(); resetSelection(); + } else if (inputHandler) { + resetSelection(); } }; + var inputHandler = null; + this.setInputHandler = function(onInput) {inputHandler = onInput}; + this.getInputHandler = function() {return inputHandler}; + var sendText = function(data) { + if (inputHandler) { + data = inputHandler(data); + inputHandler = null; + } if (pasted) { resetSelection(); if (data) @@ -377,10 +388,11 @@ var TextInput = function(parentNode, host) { var style = dom.computedStyle(host.container); var top = rect.top + (parseInt(style.borderTopWidth) || 0); var left = rect.left + (parseInt(rect.borderLeftWidth) || 0); + var maxTop = rect.bottom - top - text.clientHeight; var move = function(e) { text.style.left = e.clientX - left - 2 + "px"; - text.style.top = e.clientY - top - 2 + "px"; - }; + text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px"; + }; move(e); if (e.type != "mousedown") diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 719df69a..0de955cb 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -549,8 +549,8 @@ var VirtualRenderer = function(container, theme) { this.textarea.style.height = this.lineHeight + "px"; this.textarea.style.width = w + "px"; - this.textarea.style.right = this.$size.scrollerWidth - posLeft - w + "px"; - this.textarea.style.bottom = this.$size.height - posTop - this.lineHeight + "px"; + this.textarea.style.right = Math.max(0, this.$size.scrollerWidth - posLeft - w) + "px"; + this.textarea.style.bottom = Math.max(0, this.$size.height - posTop - this.lineHeight) + "px"; }; /** From 5fa2af19914149ed9b20a6fcdf4b519d88f794ef Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 9 Mar 2013 19:11:07 +0400 Subject: [PATCH 2/3] fix #1286 ibus Chinese input issue --- lib/ace/keyboard/textinput.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index e8f3ed29..0c7514ad 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -210,7 +210,8 @@ var TextInput = function(parentNode, host) { host.onPaste(data); pasted = false; } else if (data == PLACEHOLDER[0]) { - host.execCommand("del", {source: "ace"}); + if (Date.now() - lastCompositionTime > 100) + host.execCommand("del", {source: "ace"}); } else { if (data.substring(0, 2) == PLACEHOLDER) data = data.substr(2); @@ -355,10 +356,12 @@ var TextInput = function(parentNode, host) { if (!inCompostion) return; host.onCompositionUpdate(text.value); }; - + + var lastCompositionTime = -1; var onCompositionEnd = function(e) { inCompostion = false; host.onCompositionEnd(); + lastCompositionTime = Date.now(); }; var syncComposition = lang.delayedCall(onCompositionUpdate, 50); From d24c853f88f2ebbf8afb4d742a7af278a5be155e Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 10 Mar 2013 19:26:28 +0400 Subject: [PATCH 3/3] fix bug with suggestions differing only by first letter --- lib/ace/ext/spellcheck.js | 16 +++++++++++++--- lib/ace/keyboard/textinput.js | 11 +++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/ace/ext/spellcheck.js b/lib/ace/ext/spellcheck.js index 23ac3c31..b3600e5f 100644 --- a/lib/ace/ext/spellcheck.js +++ b/lib/ace/ext/spellcheck.js @@ -1,5 +1,6 @@ define(function(require, exports, module) { "use strict"; +var event = require("../lib/event"); exports.contextMenuHandler = function(e){ var host = e.target; @@ -18,17 +19,26 @@ exports.contextMenuHandler = function(e){ text.value = value; text.setSelectionRange(w.length + 1, w.length + 1); text.setSelectionRange(0, 0); + + var afterKeydown = false; + event.addListener(text, "keydown", function onKeydown() { + event.removeListener(text, "keydown", onKeydown); + afterKeydown = true; + }); host.textInput.setInputHandler(function(newVal) { + console.log(newVal , value, text.selectionStart, text.selectionEnd) if (newVal == value) return ''; - if (newVal.lastIndexOf(value) == newVal.length - value.length) - return newVal.slice(0, -value.length); - if (newVal.indexOf(value) === 0) + if (newVal.lastIndexOf(value, 0) === 0) return newVal.slice(value.length); + if (newVal.substr(text.selectionEnd) == value) + return newVal.slice(0, -value.length); if (newVal.slice(-2) == PLACEHOLDER) { var val = newVal.slice(0, -2); if (val.slice(-1) == " ") { + if (afterKeydown) + return val.substring(0, text.selectionEnd); val = val.slice(0, -1); host.session.replace(r, val); return ""; diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 0c7514ad..049ddca4 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -97,8 +97,8 @@ var TextInput = function(parentNode, host) { if (inCompostion) return; if (inputHandler) { - selectionStart = 0 - selectionEnd = isEmpty == false ? text.value.length - 1 : 0; + selectionStart = 0; + selectionEnd = isEmpty ? 0 : text.value.length - 1; } else { var selectionStart = isEmpty ? 2 : 1; var selectionEnd = 2; @@ -191,12 +191,12 @@ var TextInput = function(parentNode, host) { host.selectAll(); resetSelection(); } else if (inputHandler) { - resetSelection(); + resetSelection(host.selection.isEmpty()); } }; var inputHandler = null; - this.setInputHandler = function(onInput) {inputHandler = onInput}; + this.setInputHandler = function(cb) {inputHandler = cb}; this.getInputHandler = function() {return inputHandler}; var sendText = function(data) { @@ -231,9 +231,8 @@ var TextInput = function(parentNode, host) { if (inCompostion) return; var data = text.value; - resetValue(); - sendText(data); + resetValue(); }; var onCut = function(e) {