From 361c52a16afeb201d5ab00b99b5e8837b33b1503 Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 6 Dec 2012 01:39:55 +0400 Subject: [PATCH 01/10] \x00 crashes firefox ime --- lib/ace/keyboard/textinput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 4e07d24a..d8daf70f 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -53,7 +53,7 @@ var TextInput = function(parentNode, host) { text.style.top = "-2em"; parentNode.insertBefore(text, parentNode.firstChild); - var PLACEHOLDER = useragent.isIE || useragent.isOpera ? "\x01\x01" : "\x00\x00"; + var PLACEHOLDER = "\x01\x01"; resetValue(); From 3565a061913367350608e0268b50546b3a3e67b1 Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 6 Dec 2012 01:44:53 +0400 Subject: [PATCH 02/10] cleanup --- lib/ace/keyboard/textinput.js | 96 +++++++++++++++++------------------ 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index d8daf70f..950026a8 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -55,28 +55,55 @@ var TextInput = function(parentNode, host) { var PLACEHOLDER = "\x01\x01"; - resetValue(); - - if (isFocused()) - host.onFocus(); - - // Somehow fixes problem with firing onpropertychange on first typed char - if (useragent.isOldIE) { - resetSelection(); - resetValue(); - setTimeout(resetSelection); - } - var cut = false var copied = false; var pasted = false; - var inCompostion = false; - var resetTimeout = null; - var tempStyle = ''; + resetValue(); + if (isFocused()) + host.onFocus(); + + + var isAllSelected = function(text) { + return text.selectionStart === 0 && text.selectionEnd === text.value.length; + } + // IE8 does not support setSelectionRange + if (!text.setSelectionRange && text.createTextRange) { + text.setSelectionRange = function(selectionStart, selectionEnd) { + var range = this.createTextRange(); + range.collapse(true); + range.moveStart('character', selectionStart); + range.moveEnd('character', selectionEnd); + range.select(); + }; + isAllSelected = function(text) { + try { + var range = text.ownerDocument.selection.createRange(); + }catch(e) {} + if (!range || range.parentElement() != text) return false; + return range.text == text.value; + } + } + if (useragent.isOldIE) { + event.addListener(text, "propertychange", function(e){ + if (text.value != "" && text.value != PLACEHOLDER) + onInput(e); + }); + + var keytable = { 13:1, 27:1 }; + event.addListener(text, "keyup", function (e) { + if (inCompostion && (!text.value || keytable[e.keyCode])) + setTimeout(onCompositionEnd, 0); + if ((text.value.charCodeAt(0)|0) < 129) { + return; + } + inCompostion ? onCompositionUpdate() : onCompositionStart(); + }); + } + function resetValue() { if (inCompostion) return; @@ -101,17 +128,7 @@ var TextInput = function(parentNode, host) { var selectionEnd = 2; // on firefox this throws if textarea is hidden try { - if (text.setSelectionRange) { - text.setSelectionRange(selectionStart, selectionEnd); - } - // IE8 does not support setSelectionRange - else if (text.createTextRange) { - var range = text.createTextRange(); - range.collapse(true); - range.moveEnd('character', selectionEnd); - range.moveStart('character', selectionStart); - range.select(); - } + text.setSelectionRange(selectionStart, selectionEnd); } catch(e){} }; @@ -124,7 +141,7 @@ var TextInput = function(parentNode, host) { copied = false; return; } - if (text.selectionStart === 0 && text.selectionEnd === text.value.length) { + if (isAllSelected(text)) { host.selectAll(); resetSelection(); } @@ -214,7 +231,6 @@ var TextInput = function(parentNode, host) { } var clipboardData = e.clipboardData || window.clipboardData; - if (clipboardData) { // Safari 5 has clipboardData object, but does not handle setData() var supported = clipboardData.setData("Text", data); @@ -234,8 +250,6 @@ var TextInput = function(parentNode, host) { host.onCopy(); }); } - - }; var onPaste = function(e) { @@ -286,22 +300,7 @@ var TextInput = function(parentNode, host) { }); } - if (useragent.isOldIE) { - event.addListener(text, "propertychange", function(e){ - if (text.value != "" && text.value != PLACEHOLDER) - onInput(e); - }); - var keytable = { 13:1, 27:1 }; - event.addListener(text, "keyup", function (e) { - if (inCompostion && (!text.value || keytable[e.keyCode])) - setTimeout(onCompositionEnd, 0); - if ((text.value.charCodeAt(0)|0) < 129) { - return; - } - inCompostion ? onCompositionUpdate() : onCompositionStart(); - }); - } event.addListener(text, "compositionstart", onCompositionStart); if (useragent.isGecko) { @@ -315,16 +314,13 @@ var TextInput = function(parentNode, host) { event.addListener(text, "blur", function() { host.onBlur(); }); - event.addListener(text, "focus", function() { host.onFocus(); resetSelection(); }); - this.focus = function() { text.focus(); }; - this.blur = function() { text.blur(); }; @@ -334,6 +330,7 @@ var TextInput = function(parentNode, host) { } this.isFocused = isFocused; + // CONTEXTMENU this.getElement = function() { return text; }; @@ -378,11 +375,12 @@ var TextInput = function(parentNode, host) { this.onContextMenuClose = onContextMenuClose; // firefox fires contextmenu event after opening it - if (!useragent.isGecko) + if (!useragent.isGecko) { event.addListener(text, "contextmenu", function(e) { host.textInput.onContextMenu(e); onContextMenuClose(); }); + } }; exports.TextInput = TextInput; From d11b01c3130a2ba9400afe7c548e1a16fef42efb Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 6 Dec 2012 01:48:14 +0400 Subject: [PATCH 03/10] fix typing on ie8 --- lib/ace/keyboard/textinput.js | 60 ++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 950026a8..88f2ca6d 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -88,16 +88,37 @@ var TextInput = function(parentNode, host) { } } if (useragent.isOldIE) { - event.addListener(text, "propertychange", function(e){ - if (text.value != "" && text.value != PLACEHOLDER) - onInput(e); - }); + var propchangeTimeout; + var propertyChangeCounter = 0; + var onPropertyChange = function(e){ + if (propertyChangeCounter) + return; + var data = text.value; + if (inCompostion || !data || data == PLACEHOLDER) + return; + // can happen either after delete or during insert operation + if (e && data == PLACEHOLDER[0]) { + if (!propchangeTimeout) { + propchangeTimeout = setTimeout(function() { + onPropertyChange(); + propchangeTimeout = null; + }); + } + return; + } + + sendText(data); + propertyChangeCounter++ + resetValue(); + propertyChangeCounter-- + } + event.addListener(text, "propertychange", onPropertyChange); var keytable = { 13:1, 27:1 }; event.addListener(text, "keyup", function (e) { if (inCompostion && (!text.value || keytable[e.keyCode])) setTimeout(onCompositionEnd, 0); - if ((text.value.charCodeAt(0)|0) < 129) { + if ((text.value.charCodeAt(0)||0) < 129) { return; } inCompostion ? onCompositionUpdate() : onCompositionStart(); @@ -147,12 +168,7 @@ var TextInput = function(parentNode, host) { } }; - var onInput = function(e) { - if (inCompostion) - return; - var data = text.value; - resetValue(); - + var sendText = function(data) { if (pasted) { resetSelection(); if (data) @@ -165,16 +181,24 @@ var TextInput = function(parentNode, host) { data = data.substr(2); else if (data[0] == PLACEHOLDER[0]) data = data.substr(1); + else if (data[data.length - 1] == PLACEHOLDER[0]) + data = data.slice(0, -1); + // can happen if undo in textarea isn't stopped + if (data[data.length - 1] == PLACEHOLDER[0]) + data = data.slice(0, -1); - if (data) { - // can happen if undo in textarea isn't stopped - if (data[data.length - 1] == PLACEHOLDER[0]) - data = data.slice(0, -1); - if (data) - host.onTextInput(data); - } + if (data) + host.onTextInput(data); } }; + var onInput = function(e) { + if (inCompostion) + return; + var data = text.value; + resetValue(); + + sendText(data); + }; var onCompositionStart = function(e) { inCompostion = true; From 0e87da74b22c8abc955e6124a67c34e0ab8a04dd Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 26 Oct 2012 01:45:32 +0400 Subject: [PATCH 04/10] disable autocapitalize to improve behavior on mobile browsers --- lib/ace/keyboard/textinput.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 88f2ca6d..f20740b7 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -48,6 +48,8 @@ var TextInput = function(parentNode, host) { text.setAttribute("x-palm-disable-auto-cap", true); text.wrap = "off"; + text.autocorrect = "off"; + text.autocapitalize = "off"; text.spellcheck = false; text.style.top = "-2em"; From 0cd2faecc505c90baa0a099e39ad95adf4dfcfc0 Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 6 Dec 2012 02:27:00 +0400 Subject: [PATCH 05/10] restore selection only if something is selected --- lib/ace/keyboard/textinput.js | 49 ++++++++++++++++++----------------- lib/ace/lib/lang.js | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index f20740b7..77412920 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -34,6 +34,7 @@ define(function(require, exports, module) { var event = require("../lib/event"); var useragent = require("../lib/useragent"); var dom = require("../lib/dom"); +var lang = require("../lib/lang"); var TextInput = function(parentNode, host) { var text = dom.createElement("textarea"); @@ -61,9 +62,17 @@ var TextInput = function(parentNode, host) { var copied = false; var pasted = false; var inCompostion = false; - var resetTimeout = null; var tempStyle = ''; - + var isSelectionEmpty = true; + var syncSelection = lang.delayedCall(function() { + resetSelection(isSelectionEmpty); + }); + var syncValue = lang.delayedCall(function() { + if (!inCompostion) { + text.value = PLACEHOLDER; + resetSelection(); + } + }); resetValue(); if (isFocused()) host.onFocus(); @@ -90,7 +99,7 @@ var TextInput = function(parentNode, host) { } } if (useragent.isOldIE) { - var propchangeTimeout; + var syncProperty = lang.delayedCall(onPropertyChange); var propertyChangeCounter = 0; var onPropertyChange = function(e){ if (propertyChangeCounter) @@ -99,20 +108,13 @@ var TextInput = function(parentNode, host) { if (inCompostion || !data || data == PLACEHOLDER) return; // can happen either after delete or during insert operation - if (e && data == PLACEHOLDER[0]) { - if (!propchangeTimeout) { - propchangeTimeout = setTimeout(function() { - onPropertyChange(); - propchangeTimeout = null; - }); - } - return; - } + if (e && data == PLACEHOLDER[0]) + return syncProperty.schedule(); sendText(data); - propertyChangeCounter++ + propertyChangeCounter++; resetValue(); - propertyChangeCounter-- + propertyChangeCounter--; } event.addListener(text, "propertychange", onPropertyChange); @@ -132,16 +134,8 @@ var TextInput = function(parentNode, host) { return; text.value = PLACEHOLDER; //http://code.google.com/p/chromium/issues/detail?id=76516 - if (!resetTimeout) { - resetTimeout = setTimeout(function(){ - resetTimeout = null; - if (inCompostion) - return; - if (useragent.isWebKit) - text.value = PLACEHOLDER; - resetSelection(); - }); - } + if (useragent.isWebKit) + syncValue.schedule(); }; function resetSelection(isEmpty) { @@ -407,6 +401,13 @@ var TextInput = function(parentNode, host) { onContextMenuClose(); }); } + + host.addEventListener('changeSelection', function(){ + if (host.selection.isEmpty() != isSelectionEmpty) { + isSelectionEmpty = !isSelectionEmpty; + syncSelection.schedule(); + } + }); }; exports.TextInput = TextInput; diff --git a/lib/ace/lib/lang.js b/lib/ace/lib/lang.js index 6ea59761..4f81c842 100644 --- a/lib/ace/lib/lang.js +++ b/lib/ace/lib/lang.js @@ -179,7 +179,7 @@ exports.delayedCall = function(fcn, defaultTimeout) { timer = setTimeout(callback, timeout || defaultTimeout); }; - _self.delay = delayed; + _self.delay = _self; _self.schedule = function(timeout) { if (timer == null) timer = setTimeout(callback, timeout || 0); From 38a5a522c2d17cd909346186813e2385c4c437bc Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 6 Dec 2012 02:35:43 +0400 Subject: [PATCH 06/10] allow displaying spellcheck suggestions in contextmenu --- lib/ace/keyboard/textinput.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 77412920..be5202d3 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -359,12 +359,17 @@ var TextInput = function(parentNode, host) { if (!tempStyle) tempStyle = text.style.cssText; - text.style.cssText = - "position:fixed; z-index:100000;" + - (useragent.isIE ? "background:rgba(0, 0, 0, 0.03); opacity:0.1;" : "") + //"background:rgba(250, 0, 0, 0.3); opacity:1;" + - "left:" + (e.clientX - 2) + "px; top:" + (e.clientY - 2) + "px;"; + text.style.cssText = "z-index:100000;" + + (useragent.isIE ? "opacity:0.1;" : "")// + "background:rgba(250, 0, 0, 0.3); opacity:1;" resetSelection(host.selection.isEmpty()); + host._emit("nativecontextmenu", {target: editor}); + var rect = host.container.getBoundingClientRect(); + var move = function(e) { + text.style.left = e.clientX - rect.left - 2 + "px"; + text.style.top = e.clientY - rect.top - 2 + "px"; + }; + move(e); if (e.type != "mousedown") return; @@ -374,10 +379,7 @@ var TextInput = function(parentNode, host) { // on windows context menu is opened after mouseup if (useragent.isWin) - event.capture(host.container, function(e) { - text.style.left = e.clientX - 2 + "px"; - text.style.top = e.clientY - 2 + "px"; - }, onContextMenuClose); + event.capture(host.container, move, onContextMenuClose); }; function onContextMenuClose() { From e5b307d0569b8657765b651264c98ce958afb95d Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 6 Dec 2012 13:53:03 +0400 Subject: [PATCH 07/10] do not change selection of blurred textarea --- lib/ace/keyboard/textinput.js | 117 +++++++++++++++++----------------- 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index be5202d3..db2a6468 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -64,17 +64,69 @@ var TextInput = function(parentNode, host) { var inCompostion = false; var tempStyle = ''; var isSelectionEmpty = true; + + // FOCUS + var isFocused = document.activeElement === text; + event.addListener(text, "blur", function() { + host.onBlur(); + isFocused = false; + }); + event.addListener(text, "focus", function() { + isFocused = true; + host.onFocus(); + resetSelection(); + }); + this.focus = function() { + text.focus(); + }; + this.blur = function() { + text.blur(); + }; + this.isFocused = function() { + return isFocused; + }; + + // modifying selection of blured textarea can focus it (chrome mac/linux) var syncSelection = lang.delayedCall(function() { - resetSelection(isSelectionEmpty); + isFocused && resetSelection(isSelectionEmpty); }); var syncValue = lang.delayedCall(function() { if (!inCompostion) { - text.value = PLACEHOLDER; - resetSelection(); + text.value = PLACEHOLDER; + isFocused && resetSelection(); } }); + + function resetSelection(isEmpty) { + if (inCompostion) + return; + var selectionStart = isEmpty ? 2 : 1; + var selectionEnd = 2; + // on firefox this throws if textarea is hidden + try { + text.setSelectionRange(selectionStart, selectionEnd); + } catch(e){} + }; + + function resetValue() { + if (inCompostion) + return; + text.value = PLACEHOLDER; + //http://code.google.com/p/chromium/issues/detail?id=76516 + if (useragent.isWebKit) + syncValue.schedule(); + }; + + useragent.isWebKit || host.addEventListener('changeSelection', function() { + if (host.selection.isEmpty() != isSelectionEmpty) { + isSelectionEmpty = !isSelectionEmpty; + syncSelection.schedule(); + } + }); + + resetValue(); - if (isFocused()) + if (isFocused) host.onFocus(); @@ -129,26 +181,6 @@ var TextInput = function(parentNode, host) { }); } - function resetValue() { - if (inCompostion) - return; - text.value = PLACEHOLDER; - //http://code.google.com/p/chromium/issues/detail?id=76516 - if (useragent.isWebKit) - syncValue.schedule(); - }; - - function resetSelection(isEmpty) { - if (inCompostion) - return; - var selectionStart = isEmpty ? 2 : 1; - var selectionEnd = 2; - // on firefox this throws if textarea is hidden - try { - text.setSelectionRange(selectionStart, selectionEnd); - } catch(e){} - }; - var onSelect = function(e) { if (cut) { cut = false; @@ -321,35 +353,14 @@ var TextInput = function(parentNode, host) { } - + // COMPOSITION event.addListener(text, "compositionstart", onCompositionStart); - if (useragent.isGecko) { + if (useragent.isGecko) event.addListener(text, "text", onCompositionUpdate); - } - if (useragent.isWebKit) { + if (useragent.isWebKit) event.addListener(text, "keyup", onCompositionUpdate); - } event.addListener(text, "compositionend", onCompositionEnd); - event.addListener(text, "blur", function() { - host.onBlur(); - }); - event.addListener(text, "focus", function() { - host.onFocus(); - resetSelection(); - }); - this.focus = function() { - text.focus(); - }; - this.blur = function() { - text.blur(); - }; - - function isFocused() { - return document.activeElement === text; - } - this.isFocused = isFocused; - // CONTEXTMENU this.getElement = function() { return text; @@ -382,7 +393,7 @@ var TextInput = function(parentNode, host) { event.capture(host.container, move, onContextMenuClose); }; - function onContextMenuClose() { + this.onContextMenuClose = function() { setTimeout(function () { if (tempStyle) { text.style.cssText = tempStyle; @@ -394,7 +405,6 @@ var TextInput = function(parentNode, host) { } }, 0); }; - this.onContextMenuClose = onContextMenuClose; // firefox fires contextmenu event after opening it if (!useragent.isGecko) { @@ -403,13 +413,6 @@ var TextInput = function(parentNode, host) { onContextMenuClose(); }); } - - host.addEventListener('changeSelection', function(){ - if (host.selection.isEmpty() != isSelectionEmpty) { - isSelectionEmpty = !isSelectionEmpty; - syncSelection.schedule(); - } - }); }; exports.TextInput = TextInput; From c9b8159382c75b161ed409d47a45989f227a1bbb Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 6 Dec 2012 14:12:31 +0400 Subject: [PATCH 08/10] remove unused browser_focus.js --- lib/ace/lib/browser_focus.js | 95 ------------------------------------ 1 file changed, 95 deletions(-) delete mode 100644 lib/ace/lib/browser_focus.js diff --git a/lib/ace/lib/browser_focus.js b/lib/ace/lib/browser_focus.js deleted file mode 100644 index 37597015..00000000 --- a/lib/ace/lib/browser_focus.js +++ /dev/null @@ -1,95 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Distributed under the BSD license: - * - * Copyright (c) 2010, Ajax.org B.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Ajax.org B.V. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var oop = require("./oop"); -var event = require("./event"); -var EventEmitter = require("./event_emitter").EventEmitter; - -/* - * This class keeps track of the focus state of the given window. - * Focus changes for example when the user switches a browser tab, - * goes to the location bar or switches to another application. - */ -var BrowserFocus = function(win) { - win = win || window; - - this.lastFocus = new Date().getTime(); - this._isFocused = true; - - var _self = this; - - // IE < 9 supports focusin and focusout events - if ("onfocusin" in win.document) { - event.addListener(win.document, "focusin", function(e) { - _self._setFocused(true); - }); - - event.addListener(win.document, "focusout", function(e) { - _self._setFocused(!!e.toElement); - }); - } - else { - event.addListener(win, "blur", function(e) { - _self._setFocused(false); - }); - - event.addListener(win, "focus", function(e) { - _self._setFocused(true); - }); - } -}; - -(function(){ - - oop.implement(this, EventEmitter); - - this.isFocused = function() { - return this._isFocused; - }; - - this._setFocused = function(isFocused) { - if (this._isFocused == isFocused) - return; - - if (isFocused) - this.lastFocus = new Date().getTime(); - - this._isFocused = isFocused; - this._emit("changeFocus"); - }; - -}).call(BrowserFocus.prototype); - - -exports.BrowserFocus = BrowserFocus; -}); From 125629ce1720418f6be0fe56190981c57efaf40e Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 9 Dec 2012 23:16:09 +0400 Subject: [PATCH 09/10] cleanup --- lib/ace/keyboard/textinput.js | 78 ++++++++++++++++------------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index db2a6468..7e5b0ebe 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -3,7 +3,7 @@ * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -40,16 +40,13 @@ var TextInput = function(parentNode, host) { var text = dom.createElement("textarea"); text.className = "ace_text-input"; /*/ debug - text.style.opacity = 1 - text.style.background = "rgba(0, 250, 0, 0.3)" - text.style.outline = "rgba(0, 250, 0, 0.8) solid 1px" - text.style.outlineOffset = "3px" + text.style.cssText = "opacity:1;background:rgba(0, 250, 0, 0.3);outline:rgba(0, 250, 0, 0.8) solid 1px;outline-offset:3px;width:5em;z-index:500"; /**/ if (useragent.isTouchPad) text.setAttribute("x-palm-disable-auto-cap", true); text.wrap = "off"; - text.autocorrect = "off"; + text.autocorrect = "off"; text.autocapitalize = "off"; text.spellcheck = false; @@ -58,7 +55,7 @@ var TextInput = function(parentNode, host) { var PLACEHOLDER = "\x01\x01"; - var cut = false + var cut = false; var copied = false; var pasted = false; var inCompostion = false; @@ -76,12 +73,8 @@ var TextInput = function(parentNode, host) { host.onFocus(); resetSelection(); }); - this.focus = function() { - text.focus(); - }; - this.blur = function() { - text.blur(); - }; + this.focus = function() { text.focus(); }; + this.blur = function() { text.blur(); }; this.isFocused = function() { return isFocused; }; @@ -106,7 +99,7 @@ var TextInput = function(parentNode, host) { try { text.setSelectionRange(selectionStart, selectionEnd); } catch(e){} - }; + } function resetValue() { if (inCompostion) @@ -115,7 +108,7 @@ var TextInput = function(parentNode, host) { //http://code.google.com/p/chromium/issues/detail?id=76516 if (useragent.isWebKit) syncValue.schedule(); - }; + } useragent.isWebKit || host.addEventListener('changeSelection', function() { if (host.selection.isEmpty() != isSelectionEmpty) { @@ -124,7 +117,6 @@ var TextInput = function(parentNode, host) { } }); - resetValue(); if (isFocused) host.onFocus(); @@ -132,7 +124,7 @@ var TextInput = function(parentNode, host) { var isAllSelected = function(text) { return text.selectionStart === 0 && text.selectionEnd === text.value.length; - } + }; // IE8 does not support setSelectionRange if (!text.setSelectionRange && text.createTextRange) { text.setSelectionRange = function(selectionStart, selectionEnd) { @@ -151,8 +143,6 @@ var TextInput = function(parentNode, host) { } } if (useragent.isOldIE) { - var syncProperty = lang.delayedCall(onPropertyChange); - var propertyChangeCounter = 0; var onPropertyChange = function(e){ if (propertyChangeCounter) return; @@ -167,7 +157,9 @@ var TextInput = function(parentNode, host) { propertyChangeCounter++; resetValue(); propertyChangeCounter--; - } + }; + var syncProperty = lang.delayedCall(onPropertyChange); + var propertyChangeCounter = 0; event.addListener(text, "propertychange", onPropertyChange); var keytable = { 13:1, 27:1 }; @@ -228,22 +220,6 @@ var TextInput = function(parentNode, host) { sendText(data); }; - var onCompositionStart = function(e) { - inCompostion = true; - host.onCompositionStart(); - setTimeout(onCompositionUpdate, 0); - }; - - var onCompositionUpdate = function() { - if (!inCompostion) return; - host.onCompositionUpdate(text.value); - }; - - var onCompositionEnd = function(e) { - inCompostion = false; - host.onCompositionEnd(); - }; - var onCut = function(e) { var data = host.getCopyText(); if (!data) { @@ -354,10 +330,27 @@ var TextInput = function(parentNode, host) { // COMPOSITION + var onCompositionStart = function(e) { + inCompostion = true; + host.onCompositionStart(); + setTimeout(onCompositionUpdate, 0); + }; + + var onCompositionUpdate = function() { + if (!inCompostion) return; + host.onCompositionUpdate(text.value); + }; + + var onCompositionEnd = function(e) { + inCompostion = false; + host.onCompositionEnd(); + }; + + event.addListener(text, "compositionstart", onCompositionStart); if (useragent.isGecko) event.addListener(text, "text", onCompositionUpdate); - if (useragent.isWebKit) + else event.addListener(text, "keyup", onCompositionUpdate); event.addListener(text, "compositionend", onCompositionEnd); @@ -370,8 +363,8 @@ var TextInput = function(parentNode, host) { if (!tempStyle) tempStyle = text.style.cssText; - text.style.cssText = "z-index:100000;" + - (useragent.isIE ? "opacity:0.1;" : "")// + "background:rgba(250, 0, 0, 0.3); opacity:1;" + text.style.cssText = "z-index:100000;" + (useragent.isIE ? "opacity:0.1;" : ""); + // text.style.cssText += "background:rgba(250, 0, 0, 0.3); opacity:1;"; resetSelection(host.selection.isEmpty()); host._emit("nativecontextmenu", {target: editor}); @@ -393,7 +386,8 @@ var TextInput = function(parentNode, host) { event.capture(host.container, move, onContextMenuClose); }; - this.onContextMenuClose = function() { + this.onContextMenuClose = onContextMenuClose; + function onContextMenuClose() { setTimeout(function () { if (tempStyle) { text.style.cssText = tempStyle; @@ -404,7 +398,7 @@ var TextInput = function(parentNode, host) { host.renderer.$moveTextAreaToCursor(); } }, 0); - }; + } // firefox fires contextmenu event after opening it if (!useragent.isGecko) { From c8be2ef60d675ee65bc713390619b97a240b6590 Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 13 Dec 2012 18:57:47 +0400 Subject: [PATCH 10/10] use boolean instead of propertyChangeCounter --- lib/ace/keyboard/textinput.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 7e5b0ebe..0f918dcf 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -143,8 +143,9 @@ var TextInput = function(parentNode, host) { } } if (useragent.isOldIE) { + var inPropertyChange = false; var onPropertyChange = function(e){ - if (propertyChangeCounter) + if (inPropertyChange) return; var data = text.value; if (inCompostion || !data || data == PLACEHOLDER) @@ -154,12 +155,12 @@ var TextInput = function(parentNode, host) { return syncProperty.schedule(); sendText(data); - propertyChangeCounter++; + // ie8 calls propertychange handlers synchronously! + inPropertyChange = true; resetValue(); - propertyChangeCounter--; + inPropertyChange = false; }; var syncProperty = lang.delayedCall(onPropertyChange); - var propertyChangeCounter = 0; event.addListener(text, "propertychange", onPropertyChange); var keytable = { 13:1, 27:1 };