Created
November 7, 2018 19:17
-
-
Save jpallen/08d0cf3398a76688bebcc945c9f1b8aa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- public/js/ace-1.2.5/ace.js 2018-10-19 12:19:28.000000000 +0100 | |
| +++ public/js/ace-1.2.9/ace.js 2018-11-07 19:12:36.000000000 +0000 | |
| @@ -960,7 +960,7 @@ | |
| if (!doc) | |
| doc = document; | |
| return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement; | |
| -} | |
| +}; | |
| exports.createElement = function(tag, ns) { | |
| return document.createElementNS ? | |
| @@ -1370,10 +1370,12 @@ | |
| exports.isIPad = ua.indexOf("iPad") >= 0; | |
| -exports.isTouchPad = ua.indexOf("TouchPad") >= 0; | |
| - | |
| exports.isChromeOS = ua.indexOf(" CrOS ") >= 0; | |
| +exports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream; | |
| + | |
| +if (exports.isIOS) exports.isMac = true; | |
| + | |
| }); | |
| ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) { | |
| @@ -1456,26 +1458,27 @@ | |
| }; | |
| exports.addTouchMoveListener = function (el, callback) { | |
| - if ("ontouchmove" in el) { | |
| - var startx, starty; | |
| - exports.addListener(el, "touchstart", function (e) { | |
| - var touchObj = e.changedTouches[0]; | |
| - startx = touchObj.clientX; | |
| - starty = touchObj.clientY; | |
| - }); | |
| - exports.addListener(el, "touchmove", function (e) { | |
| - var factor = 1, | |
| - touchObj = e.changedTouches[0]; | |
| + var startx, starty; | |
| + exports.addListener(el, "touchstart", function (e) { | |
| + var touches = e.touches; | |
| + var touchObj = touches[0]; | |
| + startx = touchObj.clientX; | |
| + starty = touchObj.clientY; | |
| + }); | |
| + exports.addListener(el, "touchmove", function (e) { | |
| + var touches = e.touches; | |
| + if (touches.length > 1) return; | |
| + | |
| + var touchObj = touches[0]; | |
| - e.wheelX = -(touchObj.clientX - startx) / factor; | |
| - e.wheelY = -(touchObj.clientY - starty) / factor; | |
| + e.wheelX = startx - touchObj.clientX; | |
| + e.wheelY = starty - touchObj.clientY; | |
| - startx = touchObj.clientX; | |
| - starty = touchObj.clientY; | |
| + startx = touchObj.clientX; | |
| + starty = touchObj.clientY; | |
| - callback(e); | |
| - }); | |
| - } | |
| + callback(e); | |
| + }); | |
| }; | |
| exports.addMouseWheelListener = function(el, callback) { | |
| @@ -1547,7 +1550,7 @@ | |
| clicks = 1; | |
| if (timer) | |
| clearTimeout(timer); | |
| - timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600); | |
| + timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600); | |
| if (clicks == 1) { | |
| startX = e.clientX; | |
| @@ -1568,7 +1571,7 @@ | |
| clicks = 2; | |
| if (timer) | |
| clearTimeout(timer); | |
| - timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600); | |
| + timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600); | |
| eventHandler[callbackName]("mousedown", e); | |
| eventHandler[callbackName](eventNames[clicks], e); | |
| } | |
| @@ -1865,51 +1868,524 @@ | |
| return deferred; | |
| }; | |
| - deferred.isPending = function() { | |
| - return timer; | |
| - }; | |
| + deferred.isPending = function() { | |
| + return timer; | |
| + }; | |
| + | |
| + return deferred; | |
| +}; | |
| + | |
| + | |
| +exports.delayedCall = function(fcn, defaultTimeout) { | |
| + var timer = null; | |
| + var callback = function() { | |
| + timer = null; | |
| + fcn(); | |
| + }; | |
| + | |
| + var _self = function(timeout) { | |
| + if (timer == null) | |
| + timer = setTimeout(callback, timeout || defaultTimeout); | |
| + }; | |
| + | |
| + _self.delay = function(timeout) { | |
| + timer && clearTimeout(timer); | |
| + timer = setTimeout(callback, timeout || defaultTimeout); | |
| + }; | |
| + _self.schedule = _self; | |
| + | |
| + _self.call = function() { | |
| + this.cancel(); | |
| + fcn(); | |
| + }; | |
| + | |
| + _self.cancel = function() { | |
| + timer && clearTimeout(timer); | |
| + timer = null; | |
| + }; | |
| + | |
| + _self.isPending = function() { | |
| + return timer; | |
| + }; | |
| + | |
| + return _self; | |
| +}; | |
| +}); | |
| + | |
| +ace.define("ace/keyboard/textinput_ios",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/lib/keys"], function(require, exports, module) { | |
| +"use strict"; | |
| + | |
| +var event = require("../lib/event"); | |
| +var useragent = require("../lib/useragent"); | |
| +var dom = require("../lib/dom"); | |
| +var lang = require("../lib/lang"); | |
| +var KEYS = require("../lib/keys"); | |
| +var MODS = KEYS.KEY_MODS; | |
| +var BROKEN_SETDATA = useragent.isChrome < 18; | |
| +var USE_IE_MIME_TYPE = useragent.isIE; | |
| + | |
| +var TextInput = function(parentNode, host) { | |
| + var self = this; | |
| + var text = dom.createElement("textarea"); | |
| + text.className = useragent.isIOS ? "ace_text-input ace_text-input-ios" : "ace_text-input"; | |
| + | |
| + if (useragent.isTouchPad) | |
| + text.setAttribute("x-palm-disable-auto-cap", true); | |
| + | |
| + text.setAttribute("wrap", "off"); | |
| + text.setAttribute("autocorrect", "off"); | |
| + text.setAttribute("autocapitalize", "off"); | |
| + text.setAttribute("spellcheck", false); | |
| + | |
| + text.style.opacity = "0"; | |
| + parentNode.insertBefore(text, parentNode.firstChild); | |
| + | |
| + var PLACEHOLDER = "\n aaaa a\n"; | |
| + | |
| + var copied = false; | |
| + var cut = false; | |
| + var pasted = false; | |
| + var inComposition = false; | |
| + var tempStyle = ''; | |
| + var isSelectionEmpty = true; | |
| + try { var isFocused = document.activeElement === text; } catch(e) {} | |
| + | |
| + event.addListener(text, "blur", function(e) { | |
| + host.onBlur(e); | |
| + isFocused = false; | |
| + }); | |
| + event.addListener(text, "focus", function(e) { | |
| + isFocused = true; | |
| + host.onFocus(e); | |
| + resetSelection(); | |
| + }); | |
| + this.focus = function() { | |
| + if (tempStyle) return text.focus(); | |
| + text.style.position = "fixed"; | |
| + text.focus(); | |
| + }; | |
| + this.blur = function() { | |
| + text.blur(); | |
| + }; | |
| + this.isFocused = function() { | |
| + return isFocused; | |
| + }; | |
| + var syncSelection = lang.delayedCall(function() { | |
| + isFocused && resetSelection(isSelectionEmpty); | |
| + }); | |
| + var syncValue = lang.delayedCall(function() { | |
| + if (!inComposition) { | |
| + text.value = PLACEHOLDER; | |
| + isFocused && resetSelection(); | |
| + } | |
| + }); | |
| + | |
| + function resetSelection(isEmpty) { | |
| + if (inComposition) | |
| + return; | |
| + inComposition = true; | |
| + | |
| + if (inputHandler) { | |
| + selectionStart = 0; | |
| + selectionEnd = isEmpty ? 0 : text.value.length - 1; | |
| + } else { | |
| + var selectionStart = 4; | |
| + var selectionEnd = 5; | |
| + } | |
| + try { | |
| + text.setSelectionRange(selectionStart, selectionEnd); | |
| + } catch(e) {} | |
| + | |
| + inComposition = false; | |
| + } | |
| + | |
| + function resetValue() { | |
| + if (inComposition) | |
| + return; | |
| + text.value = PLACEHOLDER; | |
| + if (useragent.isWebKit) | |
| + syncValue.schedule(); | |
| + } | |
| + | |
| + useragent.isWebKit || host.addEventListener('changeSelection', function() { | |
| + if (host.selection.isEmpty() != isSelectionEmpty) { | |
| + isSelectionEmpty = !isSelectionEmpty; | |
| + syncSelection.schedule(); | |
| + } | |
| + }); | |
| + | |
| + resetValue(); | |
| + if (isFocused) | |
| + host.onFocus(); | |
| + | |
| + | |
| + var isAllSelected = function(text) { | |
| + return text.selectionStart === 0 && text.selectionEnd === text.value.length; | |
| + }; | |
| + | |
| + var onSelect = function(e) { | |
| + if (isAllSelected(text)) { | |
| + host.selectAll(); | |
| + resetSelection(); | |
| + } else if (inputHandler) { | |
| + resetSelection(host.selection.isEmpty()); | |
| + } | |
| + }; | |
| + | |
| + var inputHandler = null; | |
| + this.setInputHandler = function(cb) {inputHandler = cb;}; | |
| + this.getInputHandler = function() {return inputHandler;}; | |
| + var afterContextMenu = false; | |
| + | |
| + var sendText = function(data) { | |
| + if (text.selectionStart === 4 && text.selectionEnd === 5) { | |
| + return; | |
| + } | |
| + if (inputHandler) { | |
| + data = inputHandler(data); | |
| + inputHandler = null; | |
| + } | |
| + if (pasted) { | |
| + resetSelection(); | |
| + if (data) | |
| + host.onPaste(data); | |
| + pasted = false; | |
| + } else if (data == PLACEHOLDER.substr(0) && text.selectionStart === 4) { | |
| + if (afterContextMenu) | |
| + host.execCommand("del", {source: "ace"}); | |
| + else // some versions of android do not fire keydown when pressing backspace | |
| + host.execCommand("backspace", {source: "ace"}); | |
| + } else if (!copied) { | |
| + if (data.substring(0, 9) == PLACEHOLDER && data.length > PLACEHOLDER.length) | |
| + data = data.substr(9); | |
| + else if (data.substr(0, 4) == PLACEHOLDER.substr(0, 4)) | |
| + data = data.substr(4, data.length - PLACEHOLDER.length + 1); | |
| + else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) | |
| + data = data.slice(0, -1); | |
| + if (data == PLACEHOLDER.charAt(0)) { | |
| + } else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) | |
| + data = data.slice(0, -1); | |
| + | |
| + if (data) | |
| + host.onTextInput(data); | |
| + } | |
| + if (copied) { | |
| + copied = false; | |
| + } | |
| + if (afterContextMenu) | |
| + afterContextMenu = false; | |
| + }; | |
| + var onInput = function(e) { | |
| + if (inComposition) | |
| + return; | |
| + var data = text.value; | |
| + sendText(data); | |
| + resetValue(); | |
| + }; | |
| + | |
| + var handleClipboardData = function(e, data, forceIEMime) { | |
| + var clipboardData = e.clipboardData || window.clipboardData; | |
| + if (!clipboardData || BROKEN_SETDATA) | |
| + return; | |
| + var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain"; | |
| + try { | |
| + if (data) { | |
| + return clipboardData.setData(mime, data) !== false; | |
| + } else { | |
| + return clipboardData.getData(mime); | |
| + } | |
| + } catch(e) { | |
| + if (!forceIEMime) | |
| + return handleClipboardData(e, data, true); | |
| + } | |
| + }; | |
| + | |
| + var doCopy = function(e, isCut) { | |
| + var data = host.getCopyText(); | |
| + if (!data) | |
| + return event.preventDefault(e); | |
| + | |
| + if (handleClipboardData(e, data)) { | |
| + if (useragent.isIOS) { | |
| + cut = isCut; | |
| + text.value = "\n aa" + data + "a a\n"; | |
| + text.setSelectionRange(4, 4 + data.length); | |
| + copied = { | |
| + value: data | |
| + }; | |
| + } | |
| + isCut ? host.onCut() : host.onCopy(); | |
| + if (!useragent.isIOS) event.preventDefault(e); | |
| + } else { | |
| + copied = true; | |
| + text.value = data; | |
| + text.select(); | |
| + setTimeout(function(){ | |
| + copied = false; | |
| + resetValue(); | |
| + resetSelection(); | |
| + isCut ? host.onCut() : host.onCopy(); | |
| + }); | |
| + } | |
| + }; | |
| + | |
| + var onCut = function(e) { | |
| + doCopy(e, true); | |
| + }; | |
| + | |
| + var onCopy = function(e) { | |
| + doCopy(e, false); | |
| + }; | |
| + | |
| + var onPaste = function(e) { | |
| + var data = handleClipboardData(e); | |
| + if (typeof data == "string") { | |
| + if (data) | |
| + host.onPaste(data, e); | |
| + if (useragent.isIE) | |
| + setTimeout(resetSelection); | |
| + event.preventDefault(e); | |
| + } | |
| + else { | |
| + text.value = ""; | |
| + pasted = true; | |
| + } | |
| + }; | |
| + | |
| + event.addCommandKeyListener(text, host.onCommandKey.bind(host)); | |
| + | |
| + event.addListener(text, "select", onSelect); | |
| + | |
| + event.addListener(text, "input", onInput); | |
| + | |
| + event.addListener(text, "cut", onCut); | |
| + event.addListener(text, "copy", onCopy); | |
| + event.addListener(text, "paste", onPaste); | |
| + var onCompositionStart = function(e) { | |
| + if (inComposition || !host.onCompositionStart || host.$readOnly) | |
| + return; | |
| + inComposition = {}; | |
| + inComposition.canUndo = host.session.$undoManager; | |
| + host.onCompositionStart(); | |
| + setTimeout(onCompositionUpdate, 0); | |
| + host.on("mousedown", onCompositionEnd); | |
| + if (inComposition.canUndo && !host.selection.isEmpty()) { | |
| + host.insert(""); | |
| + host.session.markUndoGroup(); | |
| + host.selection.clearSelection(); | |
| + } | |
| + host.session.markUndoGroup(); | |
| + }; | |
| + | |
| + var onCompositionUpdate = function() { | |
| + if (!inComposition || !host.onCompositionUpdate || host.$readOnly) | |
| + return; | |
| + var val = text.value.replace(/\x01/g, ""); | |
| + if (inComposition.lastValue === val) return; | |
| + | |
| + host.onCompositionUpdate(val); | |
| + if (inComposition.lastValue) | |
| + host.undo(); | |
| + if (inComposition.canUndo) | |
| + inComposition.lastValue = val; | |
| + if (inComposition.lastValue) { | |
| + var r = host.selection.getRange(); | |
| + host.insert(inComposition.lastValue); | |
| + host.session.markUndoGroup(); | |
| + inComposition.range = host.selection.getRange(); | |
| + host.selection.setRange(r); | |
| + host.selection.clearSelection(); | |
| + } | |
| + }; | |
| + | |
| + var onCompositionEnd = function(e) { | |
| + if (!host.onCompositionEnd || host.$readOnly) return; | |
| + var c = inComposition; | |
| + inComposition = false; | |
| + var timer = setTimeout(function() { | |
| + timer = null; | |
| + var str = text.value.replace(/\x01/g, ""); | |
| + if (inComposition) | |
| + return; | |
| + else if (str == c.lastValue) | |
| + resetValue(); | |
| + else if (!c.lastValue && str) { | |
| + resetValue(); | |
| + sendText(str); | |
| + } | |
| + }); | |
| + inputHandler = function compositionInputHandler(str) { | |
| + if (timer) | |
| + clearTimeout(timer); | |
| + str = str.replace(/\x01/g, ""); | |
| + if (str == c.lastValue) | |
| + return ""; | |
| + if (c.lastValue && timer) | |
| + host.undo(); | |
| + return str; | |
| + }; | |
| + host.onCompositionEnd(); | |
| + host.removeListener("mousedown", onCompositionEnd); | |
| + if (e.type == "compositionend" && c.range) { | |
| + host.selection.setRange(c.range); | |
| + } | |
| + var needsOnInput = | |
| + (!!useragent.isChrome && useragent.isChrome >= 53) || | |
| + (!!useragent.isWebKit && useragent.isWebKit >= 603); | |
| + | |
| + if (needsOnInput) { | |
| + onInput(); | |
| + } | |
| + }; | |
| + | |
| + | |
| - return deferred; | |
| -}; | |
| + var syncComposition = lang.delayedCall(onCompositionUpdate, 50); | |
| + event.addListener(text, "compositionstart", onCompositionStart); | |
| + if (useragent.isGecko) { | |
| + event.addListener(text, "text", function(){syncComposition.schedule();}); | |
| + } else { | |
| + event.addListener(text, "keyup", function(){syncComposition.schedule();}); | |
| + event.addListener(text, "keydown", function(){syncComposition.schedule();}); | |
| + } | |
| + event.addListener(text, "compositionend", onCompositionEnd); | |
| -exports.delayedCall = function(fcn, defaultTimeout) { | |
| - var timer = null; | |
| - var callback = function() { | |
| - timer = null; | |
| - fcn(); | |
| + this.getElement = function() { | |
| + return text; | |
| }; | |
| - var _self = function(timeout) { | |
| - if (timer == null) | |
| - timer = setTimeout(callback, timeout || defaultTimeout); | |
| + this.setReadOnly = function(readOnly) { | |
| + text.readOnly = readOnly; | |
| }; | |
| - _self.delay = function(timeout) { | |
| - timer && clearTimeout(timer); | |
| - timer = setTimeout(callback, timeout || defaultTimeout); | |
| + this.onContextMenu = function(e) { | |
| + afterContextMenu = true; | |
| + resetSelection(host.selection.isEmpty()); | |
| + host._emit("nativecontextmenu", {target: host, domEvent: e}); | |
| + this.moveToMouse(e, true); | |
| }; | |
| - _self.schedule = _self; | |
| + | |
| + this.moveToMouse = function(e, bringToFront) { | |
| + if (!tempStyle) | |
| + tempStyle = text.style.cssText; | |
| + text.style.cssText = (bringToFront ? "z-index:100000;" : "") | |
| + + "height:" + text.style.height + ";" | |
| + + (useragent.isIE ? "opacity:0.1;" : ""); | |
| - _self.call = function() { | |
| - this.cancel(); | |
| - fcn(); | |
| - }; | |
| + var rect = host.container.getBoundingClientRect(); | |
| + 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 -2; | |
| + var move = function(e) { | |
| + text.style.left = e.clientX - left - 2 + "px"; | |
| + text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px"; | |
| + }; | |
| + move(e); | |
| - _self.cancel = function() { | |
| - timer && clearTimeout(timer); | |
| - timer = null; | |
| + if (e.type != "mousedown") | |
| + return; | |
| + | |
| + if (host.renderer.$keepTextAreaAtCursor) | |
| + host.renderer.$keepTextAreaAtCursor = null; | |
| + | |
| + clearTimeout(closeTimeout); | |
| + if (useragent.isWin) | |
| + event.capture(host.container, move, onContextMenuClose); | |
| }; | |
| - _self.isPending = function() { | |
| - return timer; | |
| + this.onContextMenuClose = onContextMenuClose; | |
| + var closeTimeout; | |
| + function onContextMenuClose() { | |
| + clearTimeout(closeTimeout); | |
| + closeTimeout = setTimeout(function () { | |
| + if (tempStyle) { | |
| + text.style.cssText = tempStyle; | |
| + tempStyle = ''; | |
| + } | |
| + if (host.renderer.$keepTextAreaAtCursor == null) { | |
| + host.renderer.$keepTextAreaAtCursor = true; | |
| + host.renderer.$moveTextAreaToCursor(); | |
| + } | |
| + }, 0); | |
| + } | |
| + | |
| + var onContextMenu = function(e) { | |
| + host.textInput.onContextMenu(e); | |
| + onContextMenuClose(); | |
| }; | |
| + event.addListener(text, "mouseup", onContextMenu); | |
| + event.addListener(text, "mousedown", function(e) { | |
| + e.preventDefault(); | |
| + onContextMenuClose(); | |
| + }); | |
| + event.addListener(host.renderer.scroller, "contextmenu", onContextMenu); | |
| + event.addListener(text, "contextmenu", onContextMenu); | |
| + | |
| + if (useragent.isIOS) { | |
| + var typingResetTimeout = null; | |
| + var typing = false; | |
| + | |
| + parentNode.addEventListener("keydown", function (e) { | |
| + if (typingResetTimeout) clearTimeout(typingResetTimeout); | |
| + typing = true; | |
| + }); | |
| - return _self; | |
| + parentNode.addEventListener("keyup", function (e) { | |
| + typingResetTimeout = setTimeout(function () { | |
| + typing = false; | |
| + }, 100); | |
| + }); | |
| + var detectArrowKeys = function(e) { | |
| + if (document.activeElement !== text) return; | |
| + if (typing) return; | |
| + | |
| + if (cut) { | |
| + return setTimeout(function () { | |
| + cut = false; | |
| + }, 100); | |
| + } | |
| + var selectionStart = text.selectionStart; | |
| + var selectionEnd = text.selectionEnd; | |
| + text.setSelectionRange(4, 5); | |
| + if (selectionStart == selectionEnd) { | |
| + switch (selectionStart) { | |
| + case 0: host.onCommandKey(null, 0, KEYS.up); break; | |
| + case 1: host.onCommandKey(null, 0, KEYS.home); break; | |
| + case 2: host.onCommandKey(null, MODS.option, KEYS.left); break; | |
| + case 4: host.onCommandKey(null, 0, KEYS.left); break; | |
| + case 5: host.onCommandKey(null, 0, KEYS.right); break; | |
| + case 7: host.onCommandKey(null, MODS.option, KEYS.right); break; | |
| + case 8: host.onCommandKey(null, 0, KEYS.end); break; | |
| + case 9: host.onCommandKey(null, 0, KEYS.down); break; | |
| + } | |
| + } else { | |
| + switch (selectionEnd) { | |
| + case 6: host.onCommandKey(null, MODS.shift, KEYS.right); break; | |
| + case 7: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.right); break; | |
| + case 8: host.onCommandKey(null, MODS.shift, KEYS.end); break; | |
| + case 9: host.onCommandKey(null, MODS.shift, KEYS.down); break; | |
| + } | |
| + switch (selectionStart) { | |
| + case 0: host.onCommandKey(null, MODS.shift, KEYS.up); break; | |
| + case 1: host.onCommandKey(null, MODS.shift, KEYS.home); break; | |
| + case 2: host.onCommandKey(null, MODS.shift | MODS.option, KEYS.left); break; | |
| + case 3: host.onCommandKey(null, MODS.shift, KEYS.left); break; | |
| + } | |
| + } | |
| + }; | |
| + document.addEventListener("selectionchange", detectArrowKeys); | |
| + host.on("destroy", function() { | |
| + document.removeEventListener("selectionchange", detectArrowKeys); | |
| + }); | |
| + } | |
| }; | |
| + | |
| +exports.TextInput = TextInput; | |
| }); | |
| -ace.define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang"], function(require, exports, module) { | |
| +ace.define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/keyboard/textinput_ios"], function(require, exports, module) { | |
| "use strict"; | |
| var event = require("../lib/event"); | |
| @@ -1919,23 +2395,23 @@ | |
| var BROKEN_SETDATA = useragent.isChrome < 18; | |
| var USE_IE_MIME_TYPE = useragent.isIE; | |
| +var TextInputIOS = require("./textinput_ios").TextInput; | |
| var TextInput = function(parentNode, host) { | |
| + if (useragent.isIOS) | |
| + return TextInputIOS.call(this, parentNode, host); | |
| + | |
| var text = dom.createElement("textarea"); | |
| text.className = "ace_text-input"; | |
| - if (useragent.isTouchPad) | |
| - text.setAttribute("x-palm-disable-auto-cap", true); | |
| - | |
| text.setAttribute("wrap", "off"); | |
| text.setAttribute("autocorrect", "off"); | |
| text.setAttribute("autocapitalize", "off"); | |
| text.setAttribute("spellcheck", false); | |
| text.style.opacity = "0"; | |
| - if (useragent.isOldIE) text.style.top = "-1000px"; | |
| parentNode.insertBefore(text, parentNode.firstChild); | |
| - var PLACEHOLDER = "\x01\x01"; | |
| + var PLACEHOLDER = "\u2028\u2028"; | |
| var copied = false; | |
| var pasted = false; | |
| @@ -1987,8 +2463,8 @@ | |
| inComposition = true; | |
| if (inputHandler) { | |
| - selectionStart = 0; | |
| - selectionEnd = isEmpty ? 0 : text.value.length - 1; | |
| + var selectionStart = 0; | |
| + var selectionEnd = isEmpty ? 0 : text.value.length - 1; | |
| } else { | |
| var selectionStart = isEmpty ? 2 : 1; | |
| var selectionEnd = 2; | |
| @@ -2023,54 +2499,6 @@ | |
| var isAllSelected = function(text) { | |
| return text.selectionStart === 0 && text.selectionEnd === text.value.length; | |
| }; | |
| - 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) { | |
| - var inPropertyChange = false; | |
| - var onPropertyChange = function(e){ | |
| - if (inPropertyChange) | |
| - return; | |
| - var data = text.value; | |
| - if (inComposition || !data || data == PLACEHOLDER) | |
| - return; | |
| - if (e && data == PLACEHOLDER[0]) | |
| - return syncProperty.schedule(); | |
| - | |
| - sendText(data); | |
| - inPropertyChange = true; | |
| - resetValue(); | |
| - inPropertyChange = false; | |
| - }; | |
| - var syncProperty = lang.delayedCall(onPropertyChange); | |
| - event.addListener(text, "propertychange", onPropertyChange); | |
| - | |
| - var keytable = { 13:1, 27:1 }; | |
| - event.addListener(text, "keyup", function (e) { | |
| - if (inComposition && (!text.value || keytable[e.keyCode])) | |
| - setTimeout(onCompositionEnd, 0); | |
| - if ((text.value.charCodeAt(0)||0) < 129) { | |
| - return syncProperty.call(); | |
| - } | |
| - inComposition ? onCompositionUpdate() : onCompositionStart(); | |
| - }); | |
| - event.addListener(text, "keydown", function (e) { | |
| - syncProperty.schedule(50); | |
| - }); | |
| - } | |
| var onSelect = function(e) { | |
| if (copied) { | |
| @@ -2084,8 +2512,8 @@ | |
| }; | |
| var inputHandler = null; | |
| - this.setInputHandler = function(cb) {inputHandler = cb}; | |
| - this.getInputHandler = function() {return inputHandler}; | |
| + this.setInputHandler = function(cb) {inputHandler = cb;}; | |
| + this.getInputHandler = function() {return inputHandler;}; | |
| var afterContextMenu = false; | |
| var sendText = function(data) { | |
| @@ -2197,7 +2625,7 @@ | |
| event.addListener(text, "cut", onCut); | |
| event.addListener(text, "copy", onCopy); | |
| event.addListener(text, "paste", onPaste); | |
| - if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)){ | |
| + if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) { | |
| event.addListener(parentNode, "keydown", function(e) { | |
| if ((useragent.isMac && !e.metaKey) || !e.ctrlKey) | |
| return; | |
| @@ -2234,7 +2662,7 @@ | |
| var onCompositionUpdate = function() { | |
| if (!inComposition || !host.onCompositionUpdate || host.$readOnly) | |
| return; | |
| - var val = text.value.replace(/\x01/g, ""); | |
| + var val = text.value.replace(/\u2028/g, ""); | |
| if (inComposition.lastValue === val) return; | |
| host.onCompositionUpdate(val); | |
| @@ -2258,7 +2686,7 @@ | |
| inComposition = false; | |
| var timer = setTimeout(function() { | |
| timer = null; | |
| - var str = text.value.replace(/\x01/g, ""); | |
| + var str = text.value.replace(/\u2028/g, ""); | |
| if (inComposition) | |
| return; | |
| else if (str == c.lastValue) | |
| @@ -2271,7 +2699,7 @@ | |
| inputHandler = function compositionInputHandler(str) { | |
| if (timer) | |
| clearTimeout(timer); | |
| - str = str.replace(/\x01/g, ""); | |
| + str = str.replace(/\u2028/g, ""); | |
| if (str == c.lastValue) | |
| return ""; | |
| if (c.lastValue && timer) | |
| @@ -2298,10 +2726,10 @@ | |
| event.addListener(text, "compositionstart", onCompositionStart); | |
| if (useragent.isGecko) { | |
| - event.addListener(text, "text", function(){syncComposition.schedule()}); | |
| + event.addListener(text, "text", function(){syncComposition.schedule();}); | |
| } else { | |
| - event.addListener(text, "keyup", function(){syncComposition.schedule()}); | |
| - event.addListener(text, "keydown", function(){syncComposition.schedule()}); | |
| + event.addListener(text, "keyup", function(){syncComposition.schedule();}); | |
| + event.addListener(text, "keydown", function(){syncComposition.schedule();}); | |
| } | |
| event.addListener(text, "compositionend", onCompositionEnd); | |
| @@ -2321,8 +2749,6 @@ | |
| }; | |
| this.moveToMouse = function(e, bringToFront) { | |
| - if (!bringToFront && useragent.isOldIE) | |
| - return; | |
| if (!tempStyle) | |
| tempStyle = text.style.cssText; | |
| text.style.cssText = (bringToFront ? "z-index:100000;" : "") | |
| @@ -2347,7 +2773,7 @@ | |
| host.renderer.$keepTextAreaAtCursor = null; | |
| clearTimeout(closeTimeout); | |
| - if (useragent.isWin && !useragent.isOldIE) | |
| + if (useragent.isWin) | |
| event.capture(host.container, move, onContextMenuClose); | |
| }; | |
| @@ -2364,7 +2790,7 @@ | |
| host.renderer.$keepTextAreaAtCursor = true; | |
| host.renderer.$moveTextAreaToCursor(); | |
| } | |
| - }, useragent.isOldIE ? 200 : 0); | |
| + }, 0); | |
| } | |
| var onContextMenu = function(e) { | |
| @@ -2391,6 +2817,7 @@ | |
| var useragent = require("../lib/useragent"); | |
| var DRAG_OFFSET = 0; // pixels | |
| +var SCROLL_COOLDOWN_T = 250; // milliseconds | |
| function DefaultHandlers(mouseHandler) { | |
| mouseHandler.$clickSelection = null; | |
| @@ -2430,9 +2857,12 @@ | |
| if (selectionEmpty || button == 1) | |
| editor.selection.moveToPosition(pos); | |
| editor.$blockScrolling--; | |
| - if (button == 2) | |
| + if (button == 2) { | |
| editor.textInput.onContextMenu(ev.domEvent); | |
| - return; // stopping event here breaks contextmenu on ff mac | |
| + if (!useragent.isMozilla) | |
| + ev.preventDefault(); | |
| + } | |
| + return; | |
| } | |
| this.mousedownEvent.time = Date.now(); | |
| @@ -2592,31 +3022,57 @@ | |
| ev.wheelX = ev.wheelY; | |
| ev.wheelY = 0; | |
| } | |
| - | |
| - var t = ev.domEvent.timeStamp; | |
| - var dt = t - (this.$lastScrollTime||0); | |
| var editor = this.editor; | |
| - var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); | |
| - if (isScrolable || dt < 200) { | |
| - this.$lastScrollTime = t; | |
| - editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); | |
| - return ev.stop(); | |
| - } | |
| - }; | |
| - | |
| - this.onTouchMove = function (ev) { | |
| + | |
| + if (!this.$lastScroll) | |
| + this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 }; | |
| + | |
| + var prevScroll = this.$lastScroll; | |
| var t = ev.domEvent.timeStamp; | |
| - var dt = t - (this.$lastScrollTime || 0); | |
| + var dt = t - prevScroll.t; | |
| + var vx = ev.wheelX / dt; | |
| + var vy = ev.wheelY / dt; | |
| + if (dt < SCROLL_COOLDOWN_T) { | |
| + vx = (vx + prevScroll.vx) / 2; | |
| + vy = (vy + prevScroll.vy) / 2; | |
| + } | |
| + | |
| + var direction = Math.abs(vx / vy); | |
| + | |
| + var canScroll = false; | |
| + if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0)) | |
| + canScroll = true; | |
| + if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed)) | |
| + canScroll = true; | |
| + | |
| + if (canScroll) { | |
| + prevScroll.allowed = t; | |
| + } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) { | |
| + var isSlower = Math.abs(vx) <= 1.1 * Math.abs(prevScroll.vx) | |
| + && Math.abs(vy) <= 1.1 * Math.abs(prevScroll.vy); | |
| + if (isSlower) { | |
| + canScroll = true; | |
| + prevScroll.allowed = t; | |
| + } | |
| + else { | |
| + prevScroll.allowed = 0; | |
| + } | |
| + } | |
| + | |
| + prevScroll.t = t; | |
| + prevScroll.vx = vx; | |
| + prevScroll.vy = vy; | |
| - var editor = this.editor; | |
| - var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); | |
| - if (isScrolable || dt < 200) { | |
| - this.$lastScrollTime = t; | |
| + if (canScroll) { | |
| editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); | |
| return ev.stop(); | |
| } | |
| }; | |
| + | |
| + this.onTouchMove = function(ev) { | |
| + this.editor._emit("mousewheel", ev); | |
| + }; | |
| }).call(DefaultHandlers.prototype); | |
| @@ -2700,6 +3156,13 @@ | |
| this.getWidth = function() { | |
| return this.getElement().offsetWidth; | |
| }; | |
| + | |
| + this.destroy = function() { | |
| + this.isOpen = false; | |
| + if (this.$element && this.$element.parentNode) { | |
| + this.$element.parentNode.removeChild(this.$element); | |
| + } | |
| + }; | |
| }).call(Tooltip.prototype); | |
| @@ -3350,7 +3813,7 @@ | |
| var a = document.createElement('a'); | |
| a.href = url; | |
| return a.href; | |
| -} | |
| +}; | |
| }); | |
| @@ -3412,7 +3875,7 @@ | |
| EventEmitter.setDefaultHandler = function(eventName, callback) { | |
| - var handlers = this._defaultHandlers | |
| + var handlers = this._defaultHandlers; | |
| if (!handlers) | |
| handlers = this._defaultHandlers = {_disabled_: {}}; | |
| @@ -3429,7 +3892,7 @@ | |
| handlers[eventName] = callback; | |
| }; | |
| EventEmitter.removeDefaultHandler = function(eventName, callback) { | |
| - var handlers = this._defaultHandlers | |
| + var handlers = this._defaultHandlers; | |
| if (!handlers) | |
| return; | |
| var disabled = handlers._disabled_[eventName]; | |
| @@ -3788,7 +4251,7 @@ | |
| var focusEditor = function(e) { | |
| var windowBlurred = !document.hasFocus || !document.hasFocus() | |
| - || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement()) | |
| + || !editor.isFocused() && document.activeElement == (editor.textInput && editor.textInput.getElement()); | |
| if (windowBlurred) | |
| window.focus(); | |
| editor.focus(); | |
| @@ -4112,18 +4575,591 @@ | |
| return success; | |
| }; | |
| - this.onCommandKey = function(e, hashId, keyCode) { | |
| - var keyString = keyUtil.keyCodeToString(keyCode); | |
| - this.$callKeyboardHandlers(hashId, keyString, keyCode, e); | |
| + this.onCommandKey = function(e, hashId, keyCode) { | |
| + var keyString = keyUtil.keyCodeToString(keyCode); | |
| + this.$callKeyboardHandlers(hashId, keyString, keyCode, e); | |
| + }; | |
| + | |
| + this.onTextInput = function(text) { | |
| + this.$callKeyboardHandlers(-1, text); | |
| + }; | |
| + | |
| +}).call(KeyBinding.prototype); | |
| + | |
| +exports.KeyBinding = KeyBinding; | |
| +}); | |
| + | |
| +ace.define("ace/lib/bidiutil",["require","exports","module"], function(require, exports, module) { | |
| +"use strict"; | |
| + | |
| +var ArabicAlefBetIntervalsBegine = ['\u0621', '\u0641']; | |
| +var ArabicAlefBetIntervalsEnd = ['\u063A', '\u064a']; | |
| +var dir = 0, hiLevel = 0; | |
| +var lastArabic = false, hasUBAT_AL = false, hasUBAT_B = false, hasUBAT_S = false, hasBlockSep = false, hasSegSep = false; | |
| + | |
| +var impTab_LTR = [ [ 0, 3, 0, 1, 0, 0, 0 ], [ 0, 3, 0, 1, 2, 2, 0 ], [ 0, 3, 0, 0x11, 2, 0, 1 ], [ 0, 3, 5, 5, 4, 1, 0 ], [ 0, 3, 0x15, 0x15, 4, 0, 1 ], [ 0, 3, 5, 5, 4, 2, 0 ] | |
| +]; | |
| + | |
| +var impTab_RTL = [ [ 2, 0, 1, 1, 0, 1, 0 ], [ 2, 0, 1, 1, 0, 2, 0 ], [ 2, 0, 2, 1, 3, 2, 0 ], [ 2, 0, 2, 0x21, 3, 1, 1 ] | |
| +]; | |
| + | |
| +var LTR = 0, RTL = 1; | |
| + | |
| +var L = 0; | |
| +var R = 1; | |
| +var EN = 2; | |
| +var AN = 3; | |
| +var ON = 4; | |
| +var B = 5; | |
| +var S = 6; | |
| +var AL = 7; | |
| +var WS = 8; | |
| +var CS = 9; | |
| +var ES = 10; | |
| +var ET = 11; | |
| +var NSM = 12; | |
| +var LRE = 13; | |
| +var RLE = 14; | |
| +var PDF = 15; | |
| +var LRO = 16; | |
| +var RLO = 17; | |
| +var BN = 18; | |
| + | |
| +var UnicodeTBL00 = [ | |
| +BN,BN,BN,BN,BN,BN,BN,BN,BN,S,B,S,WS,B,BN,BN, | |
| +BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,B,B,B,S, | |
| +WS,ON,ON,ET,ET,ET,ON,ON,ON,ON,ON,ES,CS,ES,CS,CS, | |
| +EN,EN,EN,EN,EN,EN,EN,EN,EN,EN,CS,ON,ON,ON,ON,ON, | |
| +ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L, | |
| +L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,ON, | |
| +ON,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L, | |
| +L,L,L,L,L,L,L,L,L,L,L,ON,ON,ON,ON,BN, | |
| +BN,BN,BN,BN,BN,B,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN, | |
| +BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN,BN, | |
| +CS,ON,ET,ET,ET,ET,ON,ON,ON,ON,L,ON,ON,BN,ON,ON, | |
| +ET,ET,EN,EN,ON,L,ON,ON,ON,EN,L,ON,ON,ON,ON,ON | |
| +]; | |
| + | |
| +var UnicodeTBL20 = [ | |
| +WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,WS,BN,BN,BN,L,R , | |
| +ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON, | |
| +ON,ON,ON,ON,ON,ON,ON,ON,WS,B,LRE,RLE,PDF,LRO,RLO,CS, | |
| +ET,ET,ET,ET,ET,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON, | |
| +ON,ON,ON,ON,CS,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON, | |
| +ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,ON,WS | |
| +]; | |
| + | |
| +function _computeLevels(chars, levels, len, charTypes) { | |
| + var impTab = dir ? impTab_RTL : impTab_LTR | |
| + , prevState = null, newClass = null, newLevel = null, newState = 0 | |
| + , action = null, cond = null, condPos = -1, i = null, ix = null, classes = []; | |
| + | |
| + if (!charTypes) { | |
| + for (i = 0, charTypes = []; i < len; i++) { | |
| + charTypes[i] = _getCharacterType(chars[i]); | |
| + } | |
| + } | |
| + hiLevel = dir; | |
| + lastArabic = false; | |
| + hasUBAT_AL = false; | |
| + hasUBAT_B = false; | |
| + hasUBAT_S = false; | |
| + for (ix = 0; ix < len; ix++){ | |
| + prevState = newState; | |
| + classes[ix] = newClass = _getCharClass(chars, charTypes, classes, ix); | |
| + newState = impTab[prevState][newClass]; | |
| + action = newState & 0xF0; | |
| + newState &= 0x0F; | |
| + levels[ix] = newLevel = impTab[newState][5]; | |
| + if (action > 0){ | |
| + if (action == 0x10){ | |
| + for(i = condPos; i < ix; i++){ | |
| + levels[i] = 1; | |
| + } | |
| + condPos = -1; | |
| + } else { | |
| + condPos = -1; | |
| + } | |
| + } | |
| + cond = impTab[newState][6]; | |
| + if (cond){ | |
| + if(condPos == -1){ | |
| + condPos = ix; | |
| + } | |
| + }else{ | |
| + if (condPos > -1){ | |
| + for(i = condPos; i < ix; i++){ | |
| + levels[i] = newLevel; | |
| + } | |
| + condPos = -1; | |
| + } | |
| + } | |
| + if (charTypes[ix] == B){ | |
| + levels[ix] = 0; | |
| + } | |
| + hiLevel |= newLevel; | |
| + } | |
| + if (hasUBAT_S){ | |
| + for(i = 0; i < len; i++){ | |
| + if(charTypes[i] == S){ | |
| + levels[i] = dir; | |
| + for(var j = i - 1; j >= 0; j--){ | |
| + if(charTypes[j] == WS){ | |
| + levels[j] = dir; | |
| + }else{ | |
| + break; | |
| + } | |
| + } | |
| + } | |
| + } | |
| + } | |
| +} | |
| + | |
| +function _invertLevel(lev, levels, _array) { | |
| + if (hiLevel < lev){ | |
| + return; | |
| + } | |
| + if (lev == 1 && dir == RTL && !hasUBAT_B){ | |
| + _array.reverse(); | |
| + return; | |
| + } | |
| + var len = _array.length, start = 0, end, lo, hi, tmp; | |
| + while(start < len){ | |
| + if (levels[start] >= lev){ | |
| + end = start + 1; | |
| + while(end < len && levels[end] >= lev){ | |
| + end++; | |
| + } | |
| + for(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){ | |
| + tmp = _array[lo]; | |
| + _array[lo] = _array[hi]; | |
| + _array[hi] = tmp; | |
| + } | |
| + start = end; | |
| + } | |
| + start++; | |
| + } | |
| +} | |
| + | |
| +function _getCharClass(chars, types, classes, ix) { | |
| + var cType = types[ix], wType, nType, len, i; | |
| + switch(cType){ | |
| + case L: | |
| + case R: | |
| + lastArabic = false; | |
| + case ON: | |
| + case AN: | |
| + return cType; | |
| + case EN: | |
| + return lastArabic ? AN : EN; | |
| + case AL: | |
| + lastArabic = true; | |
| + hasUBAT_AL = true; | |
| + return R; | |
| + case WS: | |
| + return ON; | |
| + case CS: | |
| + if (ix < 1 || (ix + 1) >= types.length || | |
| + ((wType = classes[ix - 1]) != EN && wType != AN) || | |
| + ((nType = types[ix + 1]) != EN && nType != AN)){ | |
| + return ON; | |
| + } | |
| + if (lastArabic){nType = AN;} | |
| + return nType == wType ? nType : ON; | |
| + case ES: | |
| + wType = ix > 0 ? classes[ix - 1] : B; | |
| + if (wType == EN && (ix + 1) < types.length && types[ix + 1] == EN){ | |
| + return EN; | |
| + } | |
| + return ON; | |
| + case ET: | |
| + if (ix > 0 && classes[ix - 1] == EN){ | |
| + return EN; | |
| + } | |
| + if (lastArabic){ | |
| + return ON; | |
| + } | |
| + i = ix + 1; | |
| + len = types.length; | |
| + while (i < len && types[i] == ET){ | |
| + i++; | |
| + } | |
| + if (i < len && types[i] == EN){ | |
| + return EN; | |
| + } | |
| + return ON; | |
| + case NSM: | |
| + len = types.length; | |
| + i = ix + 1; | |
| + while (i < len && types[i] == NSM){ | |
| + i++; | |
| + } | |
| + if (i < len){ | |
| + var c = chars[ix], rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E; | |
| + | |
| + wType = types[i]; | |
| + if (rtlCandidate && (wType == R || wType == AL)){ | |
| + return R; | |
| + } | |
| + } | |
| + | |
| + if (ix < 1 || (wType = types[ix - 1]) == B){ | |
| + return ON; | |
| + } | |
| + return classes[ix - 1]; | |
| + case B: | |
| + lastArabic = false; | |
| + hasUBAT_B = true; | |
| + return dir; | |
| + case S: | |
| + hasUBAT_S = true; | |
| + return ON; | |
| + case LRE: | |
| + case RLE: | |
| + case LRO: | |
| + case RLO: | |
| + case PDF: | |
| + lastArabic = false; | |
| + case BN: | |
| + return ON; | |
| + } | |
| +} | |
| + | |
| +function _getCharacterType( ch ) { | |
| + var uc = ch.charCodeAt(0), hi = uc >> 8; | |
| + | |
| + if (hi == 0) { | |
| + return ((uc > 0x00BF) ? L : UnicodeTBL00[uc]); | |
| + } else if (hi == 5) { | |
| + return (/[\u0591-\u05f4]/.test(ch) ? R : L); | |
| + } else if (hi == 6) { | |
| + if (/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(ch)) | |
| + return NSM; | |
| + else if (/[\u0660-\u0669\u066b-\u066c]/.test(ch)) | |
| + return AN; | |
| + else if (uc == 0x066A) | |
| + return ET; | |
| + else if (/[\u06f0-\u06f9]/.test(ch)) | |
| + return EN; | |
| + else | |
| + return AL; | |
| + } else if (hi == 0x20 && uc <= 0x205F) { | |
| + return UnicodeTBL20[uc & 0xFF]; | |
| + } else if (hi == 0xFE) { | |
| + return (uc >= 0xFE70 ? AL : ON); | |
| + } | |
| + return ON; | |
| +} | |
| + | |
| +function _isArabicDiacritics( ch ) { | |
| + return (ch >= '\u064b' && ch <= '\u0655'); | |
| +} | |
| +exports.L = L; | |
| +exports.R = R; | |
| +exports.EN = EN; | |
| +exports.ON_R = 3; | |
| +exports.AN = 4; | |
| +exports.R_H = 5; | |
| +exports.B = 6; | |
| + | |
| +exports.DOT = "\xB7"; | |
| +exports.doBidiReorder = function(text, textCharTypes, isRtl) { | |
| + if (text.length < 2) | |
| + return {}; | |
| + | |
| + var chars = text.split(""), logicalFromVisual = new Array(chars.length), | |
| + bidiLevels = new Array(chars.length), levels = []; | |
| + | |
| + dir = isRtl ? RTL : LTR; | |
| + | |
| + _computeLevels(chars, levels, chars.length, textCharTypes); | |
| + | |
| + for (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++); | |
| + | |
| + _invertLevel(2, levels, logicalFromVisual); | |
| + _invertLevel(1, levels, logicalFromVisual); | |
| + | |
| + for (var i = 0; i < logicalFromVisual.length - 1; i++) { //fix levels to reflect character width | |
| + if (textCharTypes[i] === AN) { | |
| + levels[i] = exports.AN; | |
| + } else if (levels[i] === R && ((textCharTypes[i] > AL && textCharTypes[i] < LRE) | |
| + || textCharTypes[i] === ON || textCharTypes[i] === BN)) { | |
| + levels[i] = exports.ON_R; | |
| + } else if ((i > 0 && chars[i - 1] === '\u0644') && /\u0622|\u0623|\u0625|\u0627/.test(chars[i])) { | |
| + levels[i - 1] = levels[i] = exports.R_H; | |
| + i++; | |
| + } | |
| + } | |
| + if (chars[chars.length - 1] === exports.DOT) | |
| + levels[chars.length - 1] = exports.B; | |
| + | |
| + for (var i = 0; i < logicalFromVisual.length; i++) { | |
| + bidiLevels[i] = levels[logicalFromVisual[i]]; | |
| + } | |
| + | |
| + return {'logicalFromVisual': logicalFromVisual, 'bidiLevels': bidiLevels}; | |
| +}; | |
| +exports.hasBidiCharacters = function(text, textCharTypes){ | |
| + var ret = false; | |
| + for (var i = 0; i < text.length; i++){ | |
| + textCharTypes[i] = _getCharacterType(text.charAt(i)); | |
| + if (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL)) | |
| + ret = true; | |
| + } | |
| + return ret; | |
| +}; | |
| +exports.getVisualFromLogicalIdx = function(logIdx, rowMap) { | |
| + for (var i = 0; i < rowMap.logicalFromVisual.length; i++) { | |
| + if (rowMap.logicalFromVisual[i] == logIdx) | |
| + return i; | |
| + } | |
| + return 0; | |
| +}; | |
| + | |
| +}); | |
| + | |
| +ace.define("ace/bidihandler",["require","exports","module","ace/lib/bidiutil","ace/lib/lang","ace/lib/useragent"], function(require, exports, module) { | |
| +"use strict"; | |
| + | |
| +var bidiUtil = require("./lib/bidiutil"); | |
| +var lang = require("./lib/lang"); | |
| +var useragent = require("./lib/useragent"); | |
| +var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; | |
| +var BidiHandler = function(session) { | |
| + this.session = session; | |
| + this.bidiMap = {}; | |
| + this.currentRow = null; | |
| + this.bidiUtil = bidiUtil; | |
| + this.charWidths = []; | |
| + this.EOL = "\xAC"; | |
| + this.showInvisibles = true; | |
| + this.isRtlDir = false; | |
| + this.line = ""; | |
| + this.wrapIndent = 0; | |
| + this.isLastRow = false; | |
| + this.EOF = "\xB6"; | |
| + this.seenBidi = false; | |
| +}; | |
| + | |
| +(function() { | |
| + this.isBidiRow = function(screenRow, docRow, splitIndex) { | |
| + if (!this.seenBidi) | |
| + return false; | |
| + if (screenRow !== this.currentRow) { | |
| + this.currentRow = screenRow; | |
| + this.updateRowLine(docRow, splitIndex); | |
| + this.updateBidiMap(); | |
| + } | |
| + return this.bidiMap.bidiLevels; | |
| + }; | |
| + | |
| + this.onChange = function(delta) { | |
| + if (!this.seenBidi) { | |
| + if (delta.action == "insert" && bidiRE.test(delta.lines.join("\n"))) { | |
| + this.seenBidi = true; | |
| + this.currentRow = null; | |
| + } | |
| + } | |
| + else { | |
| + this.currentRow = null; | |
| + } | |
| + }; | |
| + | |
| + this.getDocumentRow = function() { | |
| + var docRow = 0; | |
| + var rowCache = this.session.$screenRowCache; | |
| + if (rowCache.length) { | |
| + var index = this.session.$getRowCacheIndex(rowCache, this.currentRow); | |
| + if (index >= 0) | |
| + docRow = this.session.$docRowCache[index]; | |
| + } | |
| + | |
| + return docRow; | |
| + }; | |
| + | |
| + this.getSplitIndex = function() { | |
| + var splitIndex = 0; | |
| + var rowCache = this.session.$screenRowCache; | |
| + if (rowCache.length) { | |
| + var currentIndex, prevIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow); | |
| + while (this.currentRow - splitIndex > 0) { | |
| + currentIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow - splitIndex - 1); | |
| + if (currentIndex !== prevIndex) | |
| + break; | |
| + | |
| + prevIndex = currentIndex; | |
| + splitIndex++; | |
| + } | |
| + } | |
| + | |
| + return splitIndex; | |
| + }; | |
| + | |
| + this.updateRowLine = function(docRow, splitIndex) { | |
| + if (docRow === undefined) | |
| + docRow = this.getDocumentRow(); | |
| + | |
| + this.wrapIndent = 0; | |
| + this.isLastRow = (docRow === this.session.getLength() - 1); | |
| + this.line = this.session.getLine(docRow); | |
| + if (this.session.$useWrapMode) { | |
| + var splits = this.session.$wrapData[docRow]; | |
| + if (splits) { | |
| + if (splitIndex === undefined) | |
| + splitIndex = this.getSplitIndex(); | |
| + | |
| + if(splitIndex > 0 && splits.length) { | |
| + this.wrapIndent = splits.indent; | |
| + this.line = (splitIndex < splits.length) ? | |
| + this.line.substring(splits[splitIndex - 1], splits[splits.length - 1]) : | |
| + this.line.substring(splits[splits.length - 1]); | |
| + } else { | |
| + this.line = this.line.substring(0, splits[splitIndex]); | |
| + } | |
| + } | |
| + } | |
| + var session = this.session, shift = 0, size; | |
| + this.line = this.line.replace(/\t|[\u1100-\u2029, \u202F-\uFFE6]/g, function(ch, i){ | |
| + if (ch === '\t' || session.isFullWidth(ch.charCodeAt(0))) { | |
| + size = (ch === '\t') ? session.getScreenTabSize(i + shift) : 2; | |
| + shift += size - 1; | |
| + return lang.stringRepeat(bidiUtil.DOT, size); | |
| + } | |
| + return ch; | |
| + }); | |
| + }; | |
| + | |
| + this.updateBidiMap = function() { | |
| + var textCharTypes = [], endOfLine = this.isLastRow ? this.EOF : this.EOL; | |
| + var line = this.line + (this.showInvisibles ? endOfLine : bidiUtil.DOT); | |
| + if (bidiUtil.hasBidiCharacters(line, textCharTypes)) { | |
| + this.bidiMap = bidiUtil.doBidiReorder(line, textCharTypes, this.isRtlDir); | |
| + } else { | |
| + this.bidiMap = {}; | |
| + } | |
| + }; | |
| + this.markAsDirty = function() { | |
| + this.currentRow = null; | |
| + }; | |
| + this.updateCharacterWidths = function(fontMetrics) { | |
| + if (!this.seenBidi) | |
| + return; | |
| + if (this.characterWidth === fontMetrics.$characterSize.width) | |
| + return; | |
| + | |
| + var characterWidth = this.characterWidth = fontMetrics.$characterSize.width; | |
| + var bidiCharWidth = fontMetrics.$measureCharWidth("\u05d4"); | |
| + | |
| + this.charWidths[bidiUtil.L] = this.charWidths[bidiUtil.EN] = this.charWidths[bidiUtil.ON_R] = characterWidth; | |
| + this.charWidths[bidiUtil.R] = this.charWidths[bidiUtil.AN] = bidiCharWidth; | |
| + this.charWidths[bidiUtil.R_H] = useragent.isChrome ? bidiCharWidth : bidiCharWidth * 0.45; | |
| + this.charWidths[bidiUtil.B] = 0; | |
| + | |
| + this.currentRow = null; | |
| + }; | |
| + | |
| + this.getShowInvisibles = function() { | |
| + return this.showInvisibles; | |
| + }; | |
| + | |
| + this.setShowInvisibles = function(showInvisibles) { | |
| + this.showInvisibles = showInvisibles; | |
| + this.currentRow = null; | |
| + }; | |
| + | |
| + this.setEolChar = function(eolChar) { | |
| + this.EOL = eolChar; | |
| + }; | |
| + | |
| + this.setTextDir = function(isRtlDir) { | |
| + this.isRtlDir = isRtlDir; | |
| + }; | |
| + this.getPosLeft = function(col) { | |
| + col -= this.wrapIndent; | |
| + var visualIdx = bidiUtil.getVisualFromLogicalIdx(col > 0 ? col - 1 : 0, this.bidiMap), | |
| + levels = this.bidiMap.bidiLevels, left = 0; | |
| + | |
| + if (col === 0 && levels[visualIdx] % 2 !== 0) | |
| + visualIdx++; | |
| + | |
| + for (var i = 0; i < visualIdx; i++) { | |
| + left += this.charWidths[levels[i]]; | |
| + } | |
| + | |
| + if (col !== 0 && levels[visualIdx] % 2 === 0) | |
| + left += this.charWidths[levels[visualIdx]]; | |
| + | |
| + if (this.wrapIndent) | |
| + left += this.wrapIndent * this.charWidths[bidiUtil.L]; | |
| + | |
| + return left; | |
| + }; | |
| + this.getSelections = function(startCol, endCol) { | |
| + var map = this.bidiMap, levels = map.bidiLevels, level, offset = this.wrapIndent * this.charWidths[bidiUtil.L], selections = [], | |
| + selColMin = Math.min(startCol, endCol) - this.wrapIndent, selColMax = Math.max(startCol, endCol) - this.wrapIndent, | |
| + isSelected = false, isSelectedPrev = false, selectionStart = 0; | |
| + | |
| + for (var logIdx, visIdx = 0; visIdx < levels.length; visIdx++) { | |
| + logIdx = map.logicalFromVisual[visIdx]; | |
| + level = levels[visIdx]; | |
| + isSelected = (logIdx >= selColMin) && (logIdx < selColMax); | |
| + if (isSelected && !isSelectedPrev) { | |
| + selectionStart = offset; | |
| + } else if (!isSelected && isSelectedPrev) { | |
| + selections.push({left: selectionStart, width: offset - selectionStart}); | |
| + } | |
| + offset += this.charWidths[level]; | |
| + isSelectedPrev = isSelected; | |
| + } | |
| + | |
| + if (isSelected && (visIdx === levels.length)) { | |
| + selections.push({left: selectionStart, width: offset - selectionStart}); | |
| + } | |
| + | |
| + return selections; | |
| }; | |
| + this.offsetToCol = function(posX) { | |
| + var logicalIdx = 0, posX = Math.max(posX, 0), | |
| + offset = 0, visualIdx = 0, levels = this.bidiMap.bidiLevels, | |
| + charWidth = this.charWidths[levels[visualIdx]]; | |
| - this.onTextInput = function(text) { | |
| - this.$callKeyboardHandlers(-1, text); | |
| + if (this.wrapIndent) { | |
| + posX -= this.wrapIndent * this.charWidths[bidiUtil.L]; | |
| + } | |
| + | |
| + while(posX > offset + charWidth/2) { | |
| + offset += charWidth; | |
| + if(visualIdx === levels.length - 1) { | |
| + charWidth = 0; | |
| + break; | |
| + } | |
| + charWidth = this.charWidths[levels[++visualIdx]]; | |
| + } | |
| + | |
| + if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && (levels[visualIdx] % 2 === 0)){ | |
| + if(posX < offset) | |
| + visualIdx--; | |
| + logicalIdx = this.bidiMap.logicalFromVisual[visualIdx]; | |
| + | |
| + } else if (visualIdx > 0 && (levels[visualIdx - 1] % 2 === 0) && (levels[visualIdx] % 2 !== 0)){ | |
| + logicalIdx = 1 + ((posX > offset) ? this.bidiMap.logicalFromVisual[visualIdx] | |
| + : this.bidiMap.logicalFromVisual[visualIdx - 1]); | |
| + | |
| + } else if ((this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && (levels[visualIdx - 1] % 2 === 0)) | |
| + || (!this.isRtlDir && visualIdx === 0 && (levels[visualIdx] % 2 !== 0))){ | |
| + logicalIdx = 1 + this.bidiMap.logicalFromVisual[visualIdx]; | |
| + } else { | |
| + if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && charWidth !== 0) | |
| + visualIdx--; | |
| + logicalIdx = this.bidiMap.logicalFromVisual[visualIdx]; | |
| + } | |
| + | |
| + return (logicalIdx + this.wrapIndent); | |
| }; | |
| -}).call(KeyBinding.prototype); | |
| +}).call(BidiHandler.prototype); | |
| -exports.KeyBinding = KeyBinding; | |
| +exports.BidiHandler = BidiHandler; | |
| }); | |
| ace.define("ace/range",["require","exports","module"], function(require, exports, module) { | |
| @@ -4331,9 +5367,9 @@ | |
| }; | |
| this.collapseRows = function() { | |
| if (this.end.column == 0) | |
| - return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0) | |
| + return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0); | |
| else | |
| - return new Range(this.start.row, 0, this.end.row, 0) | |
| + return new Range(this.start.row, 0, this.end.row, 0); | |
| }; | |
| this.toScreenRange = function(session) { | |
| var screenPosStart = session.documentToScreenPosition(this.start); | |
| @@ -4592,6 +5628,16 @@ | |
| this.moveCursorDown = function() { | |
| this.moveCursorBy(1, 0); | |
| }; | |
| + this.wouldMoveIntoSoftTab = function(cursor, tabSize, direction) { | |
| + var start = cursor.column; | |
| + var end = cursor.column + tabSize; | |
| + | |
| + if (direction < 0) { | |
| + start = cursor.column - tabSize; | |
| + end = cursor.column; | |
| + } | |
| + return this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(start, end).split(" ").length-1 == tabSize; | |
| + }; | |
| this.moveCursorLeft = function() { | |
| var cursor = this.lead.getPosition(), | |
| fold; | |
| @@ -4605,10 +5651,11 @@ | |
| } | |
| else { | |
| var tabSize = this.session.getTabSize(); | |
| - if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize) | |
| + if (this.wouldMoveIntoSoftTab(cursor, tabSize, -1) && !this.session.getNavigateWithinSoftTabs()) { | |
| this.moveCursorBy(0, -tabSize); | |
| - else | |
| + } else { | |
| this.moveCursorBy(0, -1); | |
| + } | |
| } | |
| }; | |
| this.moveCursorRight = function() { | |
| @@ -4625,10 +5672,11 @@ | |
| else { | |
| var tabSize = this.session.getTabSize(); | |
| var cursor = this.lead; | |
| - if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize) | |
| + if (this.wouldMoveIntoSoftTab(cursor, tabSize, 1) && !this.session.getNavigateWithinSoftTabs()) { | |
| this.moveCursorBy(0, tabSize); | |
| - else | |
| + } else { | |
| this.moveCursorBy(0, 1); | |
| + } | |
| } | |
| }; | |
| this.moveCursorLineStart = function() { | |
| @@ -4847,14 +5895,25 @@ | |
| this.lead.column | |
| ); | |
| + var offsetX; | |
| + | |
| if (chars === 0) { | |
| + if (rows !== 0) { | |
| + if (this.session.$bidiHandler.isBidiRow(screenPos.row, this.lead.row)) { | |
| + offsetX = this.session.$bidiHandler.getPosLeft(screenPos.column); | |
| + screenPos.column = Math.round(offsetX / this.session.$bidiHandler.charWidths[0]); | |
| + } else { | |
| + offsetX = screenPos.column * this.session.$bidiHandler.charWidths[0]; | |
| + } | |
| + } | |
| + | |
| if (this.$desiredColumn) | |
| screenPos.column = this.$desiredColumn; | |
| else | |
| this.$desiredColumn = screenPos.column; | |
| } | |
| - var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column); | |
| + var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX); | |
| if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) { | |
| if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) { | |
| @@ -4875,6 +5934,13 @@ | |
| } | |
| this.$keepDesiredColumnOnChange = true; | |
| + var line = this.session.getLine(row); | |
| + if (/[\uDC00-\uDFFF]/.test(line.charAt(column)) && line.charAt(column - 1)) { | |
| + if (this.lead.row == row && this.lead.column == column + 1) | |
| + column = column - 1; | |
| + else | |
| + column = column + 1; | |
| + } | |
| this.lead.setPosition(row, column); | |
| this.$keepDesiredColumnOnChange = false; | |
| @@ -5130,7 +6196,7 @@ | |
| } else if (parenOpen) { | |
| stack++; | |
| if (parenOpen.length != 1) { | |
| - lastCapture.stack = stack | |
| + lastCapture.stack = stack; | |
| lastCapture.start = index; | |
| } | |
| } | |
| @@ -5150,8 +6216,8 @@ | |
| var stack = startState.slice(0); | |
| startState = stack[0]; | |
| if (startState === "#tmp") { | |
| - stack.shift() | |
| - startState = stack.shift() | |
| + stack.shift(); | |
| + startState = stack.shift(); | |
| } | |
| } else | |
| var stack = []; | |
| @@ -5196,7 +6262,7 @@ | |
| rule = state[mapping[i]]; | |
| if (rule.onMatch) | |
| - type = rule.onMatch(value, currentState, stack); | |
| + type = rule.onMatch(value, currentState, stack, line); | |
| else | |
| type = rule.token; | |
| @@ -5218,6 +6284,8 @@ | |
| re = this.regExps[currentState]; | |
| re.lastIndex = index; | |
| } | |
| + if (rule.consumeLineEnd) | |
| + lastIndex = index; | |
| break; | |
| } | |
| @@ -5431,13 +6499,12 @@ | |
| } | |
| } | |
| } | |
| - var includeName = typeof rule == "string" | |
| - ? rule | |
| - : typeof rule.include == "string" | |
| - ? rule.include | |
| - : ""; | |
| + var includeName = typeof rule == "string" ? rule : rule.include; | |
| if (includeName) { | |
| - toInsert = rules[includeName]; | |
| + if (Array.isArray(includeName)) | |
| + toInsert = includeName.map(function(x) { return rules[x]; }); | |
| + else | |
| + toInsert = rules[includeName]; | |
| } | |
| if (toInsert) { | |
| @@ -5475,8 +6542,8 @@ | |
| this.$keywordList = Object.keys(keywords); | |
| map = null; | |
| return ignoreCase | |
| - ? function(value) {return keywords[value.toLowerCase()] || defaultToken } | |
| - : function(value) {return keywords[value] || defaultToken }; | |
| + ? function(value) {return keywords[value.toLowerCase()] || defaultToken; } | |
| + : function(value) {return keywords[value] || defaultToken; }; | |
| }; | |
| this.getKeywords = function() { | |
| @@ -5505,7 +6572,7 @@ | |
| this.$behaviours[name] = {}; | |
| } | |
| this.$behaviours[name][action] = callback; | |
| - } | |
| + }; | |
| this.addBehaviours = function (behaviours) { | |
| for (var key in behaviours) { | |
| @@ -5513,13 +6580,13 @@ | |
| this.add(key, action, behaviours[key][action]); | |
| } | |
| } | |
| - } | |
| + }; | |
| this.remove = function (name) { | |
| if (this.$behaviours && this.$behaviours[name]) { | |
| delete this.$behaviours[name]; | |
| } | |
| - } | |
| + }; | |
| this.inherit = function (mode, filter) { | |
| if (typeof mode === "function") { | |
| @@ -5528,13 +6595,13 @@ | |
| var behaviours = mode.getBehaviours(filter); | |
| } | |
| this.addBehaviours(behaviours); | |
| - } | |
| + }; | |
| this.getBehaviours = function (filter) { | |
| if (!filter) { | |
| return this.$behaviours; | |
| } else { | |
| - var ret = {} | |
| + var ret = {}; | |
| for (var i = 0; i < filter.length; i++) { | |
| if (this.$behaviours[filter[i]]) { | |
| ret[filter[i]] = this.$behaviours[filter[i]]; | |
| @@ -5542,15 +6609,17 @@ | |
| } | |
| return ret; | |
| } | |
| - } | |
| + }; | |
| }).call(Behaviour.prototype); | |
| exports.Behaviour = Behaviour; | |
| }); | |
| -ace.define("ace/token_iterator",["require","exports","module"], function(require, exports, module) { | |
| +ace.define("ace/token_iterator",["require","exports","module","ace/range"], function(require, exports, module) { | |
| "use strict"; | |
| + | |
| +var Range = require("./range").Range; | |
| var TokenIterator = function(session, initialRow, initialColumn) { | |
| this.$session = session; | |
| this.$row = initialRow; | |
| @@ -5619,7 +6688,12 @@ | |
| this.getCurrentTokenPosition = function() { | |
| return {row: this.$row, column: this.getCurrentTokenColumn()}; | |
| }; | |
| - | |
| + this.getCurrentTokenRange = function() { | |
| + var token = this.$rowTokens[this.$tokenIndex]; | |
| + var column = this.getCurrentTokenColumn(); | |
| + return new Range(this.$row, column, this.$row, column + token.value.length); | |
| + }; | |
| + | |
| }).call(TokenIterator.prototype); | |
| exports.TokenIterator = TokenIterator; | |
| @@ -5640,6 +6714,8 @@ | |
| var context; | |
| var contextCache = {}; | |
| +var defaultQuotes = {'"' : '"', "'" : "'"}; | |
| + | |
| var initContext = function(editor) { | |
| var id = -1; | |
| if (editor.multiSelect) { | |
| @@ -5673,7 +6749,7 @@ | |
| }; | |
| }; | |
| -var CstyleBehaviour = function() { | |
| +var CstyleBehaviour = function(options) { | |
| this.add("braces", "insertion", function(state, action, editor, session, text) { | |
| var cursor = editor.getCursorPosition(); | |
| var line = session.doc.getLine(cursor.row); | |
| @@ -5684,7 +6760,7 @@ | |
| if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { | |
| return getWrapped(selection, selected, '{', '}'); | |
| } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { | |
| - if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) { | |
| + if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options && options.braces) { | |
| CstyleBehaviour.recordAutoInsert(editor, session, "}"); | |
| return { | |
| text: '{}', | |
| @@ -5847,14 +6923,15 @@ | |
| }); | |
| this.add("string_dquotes", "insertion", function(state, action, editor, session, text) { | |
| - if (text == '"' || text == "'") { | |
| + var quotes = session.$mode.$quotes || defaultQuotes; | |
| + if (text.length == 1 && quotes[text]) { | |
| if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1) | |
| return; | |
| initContext(editor); | |
| var quote = text; | |
| var selection = editor.getSelectionRange(); | |
| var selected = session.doc.getTextRange(selection); | |
| - if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { | |
| + if (selected !== "" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) { | |
| return getWrapped(selection, selected, quote, quote); | |
| } else if (!selected) { | |
| var cursor = editor.getCursorPosition(); | |
| @@ -6054,7 +7131,7 @@ | |
| }; | |
| (function() { | |
| - this.$behaviour = new CstyleBehaviour(); | |
| + this.$defaultBehaviour = new CstyleBehaviour(); | |
| this.tokenRe = new RegExp("^[" | |
| + unicode.packages.L | |
| @@ -6453,7 +7530,7 @@ | |
| } | |
| break; | |
| } | |
| -} | |
| +}; | |
| }); | |
| ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) { | |
| @@ -6981,6 +8058,9 @@ | |
| } | |
| self.currentLine = currentLine; | |
| + if (endLine == -1) | |
| + endLine = currentLine; | |
| + | |
| if (startLine <= endLine) | |
| self.fireUpdateEvent(startLine, endLine); | |
| }; | |
| @@ -7022,7 +8102,7 @@ | |
| this.scheduleStart = function() { | |
| if (!this.running) | |
| this.running = setTimeout(this.$worker, 700); | |
| - } | |
| + }; | |
| this.$updateOnChange = function(delta) { | |
| var startRow = delta.start.row; | |
| @@ -7563,7 +8643,7 @@ | |
| var Range = require("../range").Range; | |
| var RangeList = require("../range_list").RangeList; | |
| -var oop = require("../lib/oop") | |
| +var oop = require("../lib/oop"); | |
| var Fold = exports.Fold = function(range, placeholder) { | |
| this.foldLine = null; | |
| this.placeholder = placeholder; | |
| @@ -8155,9 +9235,13 @@ | |
| this.getCommentFoldRange = function(row, column, dir) { | |
| var iterator = new TokenIterator(this, row, column); | |
| var token = iterator.getCurrentToken(); | |
| - if (token && /^comment|string/.test(token.type)) { | |
| + var type = token.type; | |
| + if (token && /^comment|string/.test(type)) { | |
| + type = type.match(/comment|string/)[0]; | |
| + if (type == "comment") | |
| + type += "|doc-start"; | |
| + var re = new RegExp(type); | |
| var range = new Range(); | |
| - var re = new RegExp(token.type.replace(/\..*/, "\\.")); | |
| if (dir != 1) { | |
| do { | |
| token = iterator.stepBackward(); | |
| @@ -8171,8 +9255,16 @@ | |
| iterator = new TokenIterator(this, row, column); | |
| if (dir != -1) { | |
| + var lastRow = -1; | |
| do { | |
| token = iterator.stepForward(); | |
| + if (lastRow == -1) { | |
| + var state = this.getState(iterator.$row); | |
| + if (!re.test(state)) | |
| + lastRow = iterator.$row; | |
| + } else if (iterator.$row > lastRow) { | |
| + break; | |
| + } | |
| } while (token && re.test(token.type)); | |
| token = iterator.stepBackward(); | |
| } else | |
| @@ -8580,11 +9672,12 @@ | |
| }); | |
| -ace.define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"], function(require, exports, module) { | |
| +ace.define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/bidihandler","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"], function(require, exports, module) { | |
| "use strict"; | |
| var oop = require("./lib/oop"); | |
| var lang = require("./lib/lang"); | |
| +var BidiHandler = require("./bidihandler").BidiHandler; | |
| var config = require("./config"); | |
| var EventEmitter = require("./lib/event_emitter").EventEmitter; | |
| var Selection = require("./selection").Selection; | |
| @@ -8613,6 +9706,7 @@ | |
| if (typeof text != "object" || !text.getLine) | |
| text = new Document(text); | |
| + this.$bidiHandler = new BidiHandler(this); | |
| this.setDocument(text); | |
| this.selection = new Selection(this); | |
| @@ -8622,6 +9716,8 @@ | |
| }; | |
| +EditSession.$uid = 0; | |
| + | |
| (function() { | |
| oop.implement(this, EventEmitter); | |
| @@ -8689,7 +9785,7 @@ | |
| this.onChange = function(delta) { | |
| this.$modified = true; | |
| - | |
| + this.$bidiHandler.onChange(delta); | |
| this.$resetRowCache(delta.start.row); | |
| var removedFolds = this.$updateInternalDataOnChange(delta); | |
| @@ -8736,7 +9832,7 @@ | |
| var tokens = this.bgTokenizer.getTokens(row); | |
| var token, c = 0; | |
| if (column == null) { | |
| - i = tokens.length - 1; | |
| + var i = tokens.length - 1; | |
| c = this.getLine(row).length; | |
| } else { | |
| for (var i = 0; i < tokens.length; i++) { | |
| @@ -8831,6 +9927,12 @@ | |
| this.isTabStop = function(position) { | |
| return this.$useSoftTabs && (position.column % this.$tabSize === 0); | |
| }; | |
| + this.setNavigateWithinSoftTabs = function (navigateWithinSoftTabs) { | |
| + this.setOption("navigateWithinSoftTabs", navigateWithinSoftTabs); | |
| + }; | |
| + this.getNavigateWithinSoftTabs = function() { | |
| + return this.$navigateWithinSoftTabs; | |
| + }; | |
| this.$overwrite = false; | |
| this.setOverwrite = function(overwrite) { | |
| @@ -9526,6 +10628,7 @@ | |
| if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) { | |
| this.$wrapLimitRange = { min: min, max: max }; | |
| this.$modified = true; | |
| + this.$bidiHandler.markAsDirty(); | |
| if (this.$useWrapMode) | |
| this._signal("changeWrapMode"); | |
| } | |
| @@ -9614,7 +10717,7 @@ | |
| } else { | |
| var args = Array(len); | |
| args.unshift(firstRow, 0); | |
| - var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache | |
| + var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache; | |
| arr.splice.apply(arr, args); | |
| var foldLines = this.$foldData; | |
| var foldLine = this.getFoldLine(firstRow); | |
| @@ -9896,7 +10999,7 @@ | |
| if (this.lineWidgets) | |
| var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; | |
| else | |
| - h = 0 | |
| + h = 0; | |
| if (!this.$useWrapMode || !this.$wrapData[row]) { | |
| return 1 + h; | |
| } else { | |
| @@ -9919,7 +11022,7 @@ | |
| } else { | |
| return 0; | |
| } | |
| - } | |
| + }; | |
| this.getScreenLastRowColumn = function(screenRow) { | |
| var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE); | |
| return this.documentToScreenColumn(pos.row, pos.column); | |
| @@ -9952,7 +11055,7 @@ | |
| this.screenToDocumentColumn = function(screenRow, screenColumn) { | |
| return this.screenToDocumentPosition(screenRow, screenColumn).column; | |
| }; | |
| - this.screenToDocumentPosition = function(screenRow, screenColumn) { | |
| + this.screenToDocumentPosition = function(screenRow, screenColumn, offsetX) { | |
| if (screenRow < 0) | |
| return {row: 0, column: 0}; | |
| @@ -10010,11 +11113,10 @@ | |
| line = this.getLine(docRow); | |
| foldLine = null; | |
| } | |
| - var wrapIndent = 0; | |
| + var wrapIndent = 0, splitIndex = Math.floor(screenRow - row); | |
| if (this.$useWrapMode) { | |
| var splits = this.$wrapData[docRow]; | |
| if (splits) { | |
| - var splitIndex = Math.floor(screenRow - row); | |
| column = splits[splitIndex]; | |
| if(splitIndex > 0 && splits.length) { | |
| wrapIndent = splits.indent; | |
| @@ -10024,6 +11126,9 @@ | |
| } | |
| } | |
| + if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex)) | |
| + screenColumn = this.$bidiHandler.offsetToCol(offsetX); | |
| + | |
| docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1]; | |
| if (this.$useWrapMode && docColumn >= column) | |
| docColumn = column - 1; | |
| @@ -10188,6 +11293,8 @@ | |
| } | |
| this.$stopWorker(); | |
| }; | |
| + | |
| + this.isFullWidth = isFullWidth; | |
| function isFullWidth(c) { | |
| if (c < 0x1100) | |
| return false; | |
| @@ -10310,18 +11417,19 @@ | |
| initialValue: 4, | |
| handlesSet: true | |
| }, | |
| + navigateWithinSoftTabs: {initialValue: false}, | |
| overwrite: { | |
| set: function(val) {this._signal("changeOverwrite");}, | |
| initialValue: false | |
| }, | |
| newLineMode: { | |
| - set: function(val) {this.doc.setNewLineMode(val)}, | |
| - get: function() {return this.doc.getNewLineMode()}, | |
| + set: function(val) {this.doc.setNewLineMode(val);}, | |
| + get: function() {return this.doc.getNewLineMode();}, | |
| handlesSet: true | |
| }, | |
| mode: { | |
| - set: function(val) { this.setMode(val) }, | |
| - get: function() { return this.$modeId } | |
| + set: function(val) { this.setMode(val); }, | |
| + get: function() { return this.$modeId; } | |
| } | |
| }); | |
| @@ -10357,18 +11465,15 @@ | |
| return false; | |
| var firstRange = null; | |
| - iterator.forEach(function(range, row, offset) { | |
| - if (!range.start) { | |
| - var column = range.offset + (offset || 0); | |
| - firstRange = new Range(row, column, row, column + range.length); | |
| - if (!range.length && options.start && options.start.start | |
| - && options.skipCurrent != false && firstRange.isEqual(options.start) | |
| - ) { | |
| - firstRange = null; | |
| - return false; | |
| - } | |
| - } else | |
| - firstRange = range; | |
| + iterator.forEach(function(sr, sc, er, ec) { | |
| + firstRange = new Range(sr, sc, er, ec); | |
| + if (sc == ec && options.start && options.start.start | |
| + && options.skipCurrent != false && firstRange.isEqual(options.start) | |
| + ) { | |
| + firstRange = null; | |
| + return false; | |
| + } | |
| + | |
| return true; | |
| }); | |
| @@ -10471,62 +11576,6 @@ | |
| return replacement; | |
| }; | |
| - this.$matchIterator = function(session, options) { | |
| - var re = this.$assembleRegExp(options); | |
| - if (!re) | |
| - return false; | |
| - | |
| - var callback; | |
| - if (options.$isMultiLine) { | |
| - var len = re.length; | |
| - var matchIterator = function(line, row, offset) { | |
| - var startIndex = line.search(re[0]); | |
| - if (startIndex == -1) | |
| - return; | |
| - for (var i = 1; i < len; i++) { | |
| - line = session.getLine(row + i); | |
| - if (line.search(re[i]) == -1) | |
| - return; | |
| - } | |
| - | |
| - var endIndex = line.match(re[len - 1])[0].length; | |
| - | |
| - var range = new Range(row, startIndex, row + len - 1, endIndex); | |
| - if (re.offset == 1) { | |
| - range.start.row--; | |
| - range.start.column = Number.MAX_VALUE; | |
| - } else if (offset) | |
| - range.start.column += offset; | |
| - | |
| - if (callback(range)) | |
| - return true; | |
| - }; | |
| - } else if (options.backwards) { | |
| - var matchIterator = function(line, row, startIndex) { | |
| - var matches = lang.getMatchOffsets(line, re); | |
| - for (var i = matches.length-1; i >= 0; i--) | |
| - if (callback(matches[i], row, startIndex)) | |
| - return true; | |
| - }; | |
| - } else { | |
| - var matchIterator = function(line, row, startIndex) { | |
| - var matches = lang.getMatchOffsets(line, re); | |
| - for (var i = 0; i < matches.length; i++) | |
| - if (callback(matches[i], row, startIndex)) | |
| - return true; | |
| - }; | |
| - } | |
| - | |
| - var lineIterator = this.$lineIterator(session, options); | |
| - | |
| - return { | |
| - forEach: function(_callback) { | |
| - callback = _callback; | |
| - lineIterator.forEach(matchIterator); | |
| - } | |
| - }; | |
| - }; | |
| - | |
| this.$assembleRegExp = function(options, $disableFakeMultiline) { | |
| if (options.needle instanceof RegExp) | |
| return options.re = options.needle; | |
| @@ -10540,7 +11589,7 @@ | |
| needle = lang.escapeRegExp(needle); | |
| if (options.wholeWord) | |
| - needle = "\\b" + needle + "\\b"; | |
| + needle = addWordBoundary(needle, options); | |
| var modifier = options.caseSensitive ? "gm" : "gmi"; | |
| @@ -10564,16 +11613,13 @@ | |
| } catch(e) { | |
| return false; | |
| } | |
| - if (parts[0] == "") { | |
| - re.shift(); | |
| - re.offset = 1; | |
| - } else { | |
| - re.offset = 0; | |
| - } | |
| return re; | |
| }; | |
| - this.$lineIterator = function(session, options) { | |
| + this.$matchIterator = function(session, options) { | |
| + var re = this.$assembleRegExp(options); | |
| + if (!re) | |
| + return false; | |
| var backwards = options.backwards == true; | |
| var skipCurrent = options.skipCurrent != false; | |
| @@ -10587,48 +11633,114 @@ | |
| var firstRow = range ? range.start.row : 0; | |
| var lastRow = range ? range.end.row : session.getLength() - 1; | |
| - | |
| - var forEach = backwards ? function(callback) { | |
| + | |
| + if (backwards) { | |
| + var forEach = function(callback) { | |
| var row = start.row; | |
| - | |
| - var line = session.getLine(row).substring(0, start.column); | |
| - if (callback(line, row)) | |
| + if (forEachInLine(row, start.column, callback)) | |
| return; | |
| - | |
| for (row--; row >= firstRow; row--) | |
| - if (callback(session.getLine(row), row)) | |
| + if (forEachInLine(row, Number.MAX_VALUE, callback)) | |
| return; | |
| - | |
| if (options.wrap == false) | |
| return; | |
| - | |
| for (row = lastRow, firstRow = start.row; row >= firstRow; row--) | |
| - if (callback(session.getLine(row), row)) | |
| + if (forEachInLine(row, Number.MAX_VALUE, callback)) | |
| return; | |
| - } : function(callback) { | |
| + }; | |
| + } | |
| + else { | |
| + var forEach = function(callback) { | |
| var row = start.row; | |
| - | |
| - var line = session.getLine(row).substr(start.column); | |
| - if (callback(line, row, start.column)) | |
| + if (forEachInLine(row, start.column, callback)) | |
| return; | |
| - | |
| - for (row = row+1; row <= lastRow; row++) | |
| - if (callback(session.getLine(row), row)) | |
| + for (row = row + 1; row <= lastRow; row++) | |
| + if (forEachInLine(row, 0, callback)) | |
| return; | |
| - | |
| if (options.wrap == false) | |
| return; | |
| - | |
| for (row = firstRow, lastRow = start.row; row <= lastRow; row++) | |
| - if (callback(session.getLine(row), row)) | |
| + if (forEachInLine(row, 0, callback)) | |
| return; | |
| }; | |
| + } | |
| + if (options.$isMultiLine) { | |
| + var len = re.length; | |
| + var forEachInLine = function(row, offset, callback) { | |
| + var startRow = backwards ? row - len + 1 : row; | |
| + if (startRow < 0) return; | |
| + var line = session.getLine(startRow); | |
| + var startIndex = line.search(re[0]); | |
| + if (!backwards && startIndex < offset || startIndex === -1) return; | |
| + for (var i = 1; i < len; i++) { | |
| + line = session.getLine(startRow + i); | |
| + if (line.search(re[i]) == -1) | |
| + return; | |
| + } | |
| + var endIndex = line.match(re[len - 1])[0].length; | |
| + if (backwards && endIndex > offset) return; | |
| + if (callback(startRow, startIndex, startRow + len - 1, endIndex)) | |
| + return true; | |
| + }; | |
| + } | |
| + else if (backwards) { | |
| + var forEachInLine = function(row, endIndex, callback) { | |
| + var line = session.getLine(row); | |
| + var matches = []; | |
| + var m, last = 0; | |
| + re.lastIndex = 0; | |
| + while((m = re.exec(line))) { | |
| + var length = m[0].length; | |
| + last = m.index; | |
| + if (!length) { | |
| + if (last >= line.length) break; | |
| + re.lastIndex = last += 1; | |
| + } | |
| + if (m.index + length > endIndex) | |
| + break; | |
| + matches.push(m.index, length); | |
| + } | |
| + for (var i = matches.length - 1; i >= 0; i -= 2) { | |
| + var column = matches[i - 1]; | |
| + var length = matches[i]; | |
| + if (callback(row, column, row, column + length)) | |
| + return true; | |
| + } | |
| + }; | |
| + } | |
| + else { | |
| + var forEachInLine = function(row, startIndex, callback) { | |
| + var line = session.getLine(row); | |
| + var m; | |
| + var last = startIndex; | |
| + re.lastIndex = startIndex; | |
| + while((m = re.exec(line))) { | |
| + var length = m[0].length; | |
| + last = m.index; | |
| + if (callback(row, last, row,last + length)) | |
| + return true; | |
| + if (!length) { | |
| + re.lastIndex = last += 1; | |
| + if (last >= line.length) return false; | |
| + } | |
| + } | |
| + }; | |
| + } | |
| return {forEach: forEach}; | |
| }; | |
| }).call(Search.prototype); | |
| +function addWordBoundary(needle, options) { | |
| + function wordBoundary(c) { | |
| + if (/\w/.test(c) || options.regExp) return "\\b"; | |
| + return ""; | |
| + } | |
| + return wordBoundary(needle[0]) + needle | |
| + + wordBoundary(needle[needle.length - 1]); | |
| +} | |
| + | |
| exports.Search = Search; | |
| }); | |
| @@ -10720,7 +11832,8 @@ | |
| function getPosition(command) { | |
| return typeof command == "object" && command.bindKey | |
| - && command.bindKey.position || 0; | |
| + && command.bindKey.position | |
| + || (command.isDefault ? -100 : 0); | |
| } | |
| this._addCommandToBinding = function(keyId, command, position) { | |
| var ckb = this.commandKeyBinding, i; | |
| @@ -10734,13 +11847,11 @@ | |
| } else if ((i = ckb[keyId].indexOf(command)) != -1) { | |
| ckb[keyId].splice(i, 1); | |
| } | |
| - | |
| + | |
| if (typeof position != "number") { | |
| - if (position || command.isDefault) | |
| - position = -100; | |
| - else | |
| - position = getPosition(command); | |
| + position = getPosition(command); | |
| } | |
| + | |
| var commands = ckb[keyId]; | |
| for (i = 0; i < commands.length; i++) { | |
| var other = commands[i]; | |
| @@ -10790,7 +11901,7 @@ | |
| this.bindKey(command.bindKey, command); | |
| }; | |
| this.parseKeys = function(keys) { | |
| - var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x}); | |
| + var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x;}); | |
| var key = parts.pop(); | |
| var keyCode = keyUtil[key]; | |
| @@ -10882,7 +11993,7 @@ | |
| } | |
| return false; | |
| } | |
| - | |
| + | |
| if (typeof command === "string") | |
| command = this.commands[command]; | |
| @@ -10892,6 +12003,9 @@ | |
| if (editor && editor.$readOnly && !command.readOnly) | |
| return false; | |
| + if (command.isAvailable && !command.isAvailable(editor)) | |
| + return false; | |
| + | |
| var e = {editor: editor, command: command, args: args}; | |
| e.returnValue = this._emit("exec", e); | |
| this._signal("afterExec", e); | |
| @@ -10983,7 +12097,7 @@ | |
| readOnly: true | |
| }, { | |
| name: "goToNextError", | |
| - bindKey: bindKey("Alt-E", "Ctrl-E"), | |
| + bindKey: bindKey("Alt-E", "F4"), | |
| exec: function(editor) { | |
| config.loadModule("ace/ext/error_marker", function(module) { | |
| module.showErrorMarker(editor, 1); | |
| @@ -10993,7 +12107,7 @@ | |
| readOnly: true | |
| }, { | |
| name: "goToPreviousError", | |
| - bindKey: bindKey("Alt-Shift-E", "Ctrl-Shift-E"), | |
| + bindKey: bindKey("Alt-Shift-E", "Shift-F4"), | |
| exec: function(editor) { | |
| config.loadModule("ace/ext/error_marker", function(module) { | |
| module.showErrorMarker(editor, -1); | |
| @@ -11108,7 +12222,7 @@ | |
| name: "find", | |
| bindKey: bindKey("Ctrl-F", "Command-F"), | |
| exec: function(editor) { | |
| - config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)}); | |
| + config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor);}); | |
| }, | |
| readOnly: true | |
| }, { | |
| @@ -11118,7 +12232,7 @@ | |
| readOnly: true | |
| }, { | |
| name: "selecttostart", | |
| - bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"), | |
| + bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Home|Command-Shift-Up"), | |
| exec: function(editor) { editor.getSelection().selectFileStart(); }, | |
| multiSelectAction: "forEach", | |
| readOnly: true, | |
| @@ -11134,7 +12248,7 @@ | |
| aceCommandGroup: "fileJump" | |
| }, { | |
| name: "selectup", | |
| - bindKey: bindKey("Shift-Up", "Shift-Up"), | |
| + bindKey: bindKey("Shift-Up", "Shift-Up|Ctrl-Shift-P"), | |
| exec: function(editor) { editor.getSelection().selectUp(); }, | |
| multiSelectAction: "forEach", | |
| scrollIntoView: "cursor", | |
| @@ -11148,7 +12262,7 @@ | |
| readOnly: true | |
| }, { | |
| name: "selecttoend", | |
| - bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"), | |
| + bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-End|Command-Shift-Down"), | |
| exec: function(editor) { editor.getSelection().selectFileEnd(); }, | |
| multiSelectAction: "forEach", | |
| readOnly: true, | |
| @@ -11164,7 +12278,7 @@ | |
| aceCommandGroup: "fileJump" | |
| }, { | |
| name: "selectdown", | |
| - bindKey: bindKey("Shift-Down", "Shift-Down"), | |
| + bindKey: bindKey("Shift-Down", "Shift-Down|Ctrl-Shift-N"), | |
| exec: function(editor) { editor.getSelection().selectDown(); }, | |
| multiSelectAction: "forEach", | |
| scrollIntoView: "cursor", | |
| @@ -11192,7 +12306,7 @@ | |
| readOnly: true | |
| }, { | |
| name: "selecttolinestart", | |
| - bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"), | |
| + bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left|Ctrl-Shift-A"), | |
| exec: function(editor) { editor.getSelection().selectLineStart(); }, | |
| multiSelectAction: "forEach", | |
| scrollIntoView: "cursor", | |
| @@ -11206,7 +12320,7 @@ | |
| readOnly: true | |
| }, { | |
| name: "selectleft", | |
| - bindKey: bindKey("Shift-Left", "Shift-Left"), | |
| + bindKey: bindKey("Shift-Left", "Shift-Left|Ctrl-Shift-B"), | |
| exec: function(editor) { editor.getSelection().selectLeft(); }, | |
| multiSelectAction: "forEach", | |
| scrollIntoView: "cursor", | |
| @@ -11234,7 +12348,7 @@ | |
| readOnly: true | |
| }, { | |
| name: "selecttolineend", | |
| - bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"), | |
| + bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right|Shift-End|Ctrl-Shift-E"), | |
| exec: function(editor) { editor.getSelection().selectLineEnd(); }, | |
| multiSelectAction: "forEach", | |
| scrollIntoView: "cursor", | |
| @@ -11422,7 +12536,7 @@ | |
| name: "replace", | |
| bindKey: bindKey("Ctrl-H", "Command-Option-F"), | |
| exec: function(editor) { | |
| - config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)}); | |
| + config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true);}); | |
| } | |
| }, { | |
| name: "undo", | |
| @@ -11487,11 +12601,31 @@ | |
| scrollIntoView: "cursor" | |
| }, { | |
| name: "removetolineend", | |
| - bindKey: bindKey("Alt-Delete", "Ctrl-K"), | |
| + bindKey: bindKey("Alt-Delete", "Ctrl-K|Command-Delete"), | |
| exec: function(editor) { editor.removeToLineEnd(); }, | |
| multiSelectAction: "forEach", | |
| scrollIntoView: "cursor" | |
| }, { | |
| + name: "removetolinestarthard", | |
| + bindKey: bindKey("Ctrl-Shift-Backspace", null), | |
| + exec: function(editor) { | |
| + var range = editor.selection.getRange(); | |
| + range.start.column = 0; | |
| + editor.session.remove(range); | |
| + }, | |
| + multiSelectAction: "forEach", | |
| + scrollIntoView: "cursor" | |
| +}, { | |
| + name: "removetolineendhard", | |
| + bindKey: bindKey("Ctrl-Shift-Delete", null), | |
| + exec: function(editor) { | |
| + var range = editor.selection.getRange(); | |
| + range.end.column = Number.MAX_VALUE; | |
| + editor.session.remove(range); | |
| + }, | |
| + multiSelectAction: "forEach", | |
| + scrollIntoView: "cursor" | |
| +}, { | |
| name: "removewordleft", | |
| bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"), | |
| exec: function(editor) { editor.removeWordLeft(); }, | |
| @@ -11547,7 +12681,7 @@ | |
| scrollIntoView: "cursor" | |
| }, { | |
| name: "transposeletters", | |
| - bindKey: bindKey("Ctrl-T", "Ctrl-T"), | |
| + bindKey: bindKey("Alt-Shift-X", "Ctrl-T"), | |
| exec: function(editor) { editor.transposeLetters(); }, | |
| multiSelectAction: function(editor) {editor.transposeSelections(1); }, | |
| scrollIntoView: "cursor" | |
| @@ -11679,13 +12813,17 @@ | |
| var container = renderer.getContainerElement(); | |
| this.container = container; | |
| this.renderer = renderer; | |
| + this.id = "editor" + (++Editor.$uid); | |
| this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); | |
| - this.textInput = new TextInput(renderer.getTextAreaContainer(), this); | |
| - this.renderer.textarea = this.textInput.getElement(); | |
| + if (typeof document == "object") { | |
| + this.textInput = new TextInput(renderer.getTextAreaContainer(), this); | |
| + this.renderer.textarea = this.textInput.getElement(); | |
| + this.$mouseHandler = new MouseHandler(this); | |
| + new FoldHandler(this); | |
| + } | |
| + | |
| this.keyBinding = new KeyBinding(this); | |
| - this.$mouseHandler = new MouseHandler(this); | |
| - new FoldHandler(this); | |
| this.$blockScrolling = 0; | |
| this.$search = new Search().set({ | |
| @@ -11712,12 +12850,14 @@ | |
| config._signal("editor", this); | |
| }; | |
| +Editor.$uid = 0; | |
| + | |
| (function(){ | |
| oop.implement(this, EventEmitter); | |
| this.$initOperationListeners = function() { | |
| - function last(a) {return a[a.length - 1]} | |
| + function last(a) {return a[a.length - 1];} | |
| this.selections = []; | |
| this.commands.on("exec", this.startOperation.bind(this), true); | |
| @@ -11958,6 +13098,9 @@ | |
| oldSession && oldSession._signal("changeEditor", {oldEditor: this}); | |
| session && session._signal("changeEditor", {editor: this}); | |
| + | |
| + if (session && session.bgTokenizer) | |
| + session.bgTokenizer.scheduleStart(); | |
| }; | |
| this.getSession = function() { | |
| return this.session; | |
| @@ -12098,7 +13241,8 @@ | |
| var row = iterator.getCurrentTokenRow(); | |
| var column = iterator.getCurrentTokenColumn(); | |
| var range = new Range(row, column, row, column+token.value.length); | |
| - if (session.$tagHighlight && range.compareRange(session.$backMarkers[session.$tagHighlight].range)!==0) { | |
| + var sbm = session.$backMarkers[session.$tagHighlight]; | |
| + if (session.$tagHighlight && sbm != undefined && range.compareRange(sbm.range) !== 0) { | |
| session.removeMarker(session.$tagHighlight); | |
| session.$tagHighlight = null; | |
| } | |
| @@ -12366,7 +13510,7 @@ | |
| cursor = this.session.remove(range); | |
| this.clearSelection(); | |
| } | |
| - else if (this.session.getOverwrite()) { | |
| + else if (this.session.getOverwrite() && text.indexOf("\n") == -1) { | |
| var range = new Range.fromPoints(cursor, cursor); | |
| range.end.column += text.length; | |
| this.session.remove(range); | |
| @@ -12625,6 +13769,7 @@ | |
| range = new Range(cursor.row, column-2, cursor.row, column); | |
| } | |
| this.session.replace(range, swap); | |
| + this.session.selection.moveToPosition(range.end); | |
| }; | |
| this.toLowerCase = function() { | |
| var originalRange = this.getSelectionRange(); | |
| @@ -12697,7 +13842,7 @@ | |
| var session = this.session; | |
| var lines = []; | |
| - for (i = rows.first; i <= rows.last; i++) | |
| + for (var i = rows.first; i <= rows.last; i++) | |
| lines.push(session.getLine(i)); | |
| lines.sort(function(a, b) { | |
| @@ -13449,7 +14594,7 @@ | |
| behavioursEnabled: {initialValue: true}, | |
| wrapBehavioursEnabled: {initialValue: true}, | |
| autoScrollEditorIntoView: { | |
| - set: function(val) {this.setAutoScrollEditorIntoView(val)} | |
| + set: function(val) {this.setAutoScrollEditorIntoView(val);} | |
| }, | |
| keyboardHandler: { | |
| set: function(val) { this.setKeyboardHandler(val); }, | |
| @@ -13780,7 +14925,7 @@ | |
| var text = lastLineNumber = gutterRenderer | |
| ? gutterRenderer.getText(session, row) | |
| : row + firstLineNumber; | |
| - if (text != cell.textNode.data) | |
| + if (text !== cell.textNode.data) | |
| cell.textNode.data = text; | |
| row++; | |
| @@ -13810,8 +14955,8 @@ | |
| this.$renderer = ""; | |
| this.setShowLineNumbers = function(show) { | |
| this.$renderer = !show && { | |
| - getWidth: function() {return ""}, | |
| - getText: function() {return ""} | |
| + getWidth: function() {return "";}, | |
| + getText: function() {return "";} | |
| }; | |
| }; | |
| @@ -13887,9 +15032,7 @@ | |
| }; | |
| this.update = function(config) { | |
| - var config = config || this.config; | |
| - if (!config) | |
| - return; | |
| + if (!config) return; | |
| this.config = config; | |
| @@ -13909,7 +15052,9 @@ | |
| range = range.toScreenRange(this.session); | |
| if (marker.renderer) { | |
| var top = this.$getTop(range.start.row, config); | |
| - var left = this.$padding + range.start.column * config.characterWidth; | |
| + var left = this.$padding + (this.session.$bidiHandler.isBidiRow(range.start.row) | |
| + ? this.session.$bidiHandler.getPosLeft(range.start.column) | |
| + : range.start.column * config.characterWidth); | |
| marker.renderer(html, range, left, top, config); | |
| } else if (marker.type == "fullLine") { | |
| this.drawFullLineMarker(html, range, marker.clazz, config); | |
| @@ -13921,7 +15066,11 @@ | |
| else | |
| this.drawMultiLineMarker(html, range, marker.clazz, config); | |
| } else { | |
| - this.drawSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config); | |
| + if (this.session.$bidiHandler.isBidiRow(range.start.row)) { | |
| + this.drawBidiSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config); | |
| + } else { | |
| + this.drawSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config); | |
| + } | |
| } | |
| } | |
| this.element.innerHTML = html.join(""); | |
| @@ -13942,6 +15091,7 @@ | |
| var prev = 0; | |
| var curr = 0; | |
| var next = session.getScreenLastRowColumn(row); | |
| + var clazzModified = null; | |
| var lineRange = new Range(row, range.start.column, row, curr); | |
| for (; row <= end; row++) { | |
| lineRange.start.row = lineRange.end.row = row; | |
| @@ -13950,36 +15100,56 @@ | |
| prev = curr; | |
| curr = next; | |
| next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column; | |
| - this.drawSingleLineMarker(stringBuilder, lineRange, | |
| - clazz + (row == start ? " ace_start" : "") + " ace_br" | |
| - + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end), | |
| - layerConfig, row == end ? 0 : 1, extraStyle); | |
| + clazzModified = clazz + (row == start ? " ace_start" : "") + " ace_br" | |
| + + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end); | |
| + | |
| + if (this.session.$bidiHandler.isBidiRow(row)) { | |
| + this.drawBidiSingleLineMarker(stringBuilder, lineRange, clazzModified, | |
| + layerConfig, row == end ? 0 : 1, extraStyle); | |
| + } else { | |
| + this.drawSingleLineMarker(stringBuilder, lineRange, clazzModified, | |
| + layerConfig, row == end ? 0 : 1, extraStyle); | |
| + } | |
| } | |
| }; | |
| this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { | |
| var padding = this.$padding; | |
| - var height = config.lineHeight; | |
| - var top = this.$getTop(range.start.row, config); | |
| - var left = padding + range.start.column * config.characterWidth; | |
| + var height, top, left; | |
| extraStyle = extraStyle || ""; | |
| - | |
| - stringBuilder.push( | |
| - "<div class='", clazz, " ace_br1 ace_start' style='", | |
| - "height:", height, "px;", | |
| - "right:0;", | |
| - "top:", top, "px;", | |
| - "left:", left, "px;", extraStyle, "'></div>" | |
| - ); | |
| - top = this.$getTop(range.end.row, config); | |
| - var width = range.end.column * config.characterWidth; | |
| - | |
| - stringBuilder.push( | |
| - "<div class='", clazz, " ace_br12' style='", | |
| - "height:", height, "px;", | |
| - "width:", width, "px;", | |
| - "top:", top, "px;", | |
| - "left:", padding, "px;", extraStyle, "'></div>" | |
| - ); | |
| + if (this.session.$bidiHandler.isBidiRow(range.start.row)) { | |
| + var range1 = range.clone(); | |
| + range1.end.row = range1.start.row; | |
| + range1.end.column = this.session.getLine(range1.start.row).length; | |
| + this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br1 ace_start", config, null, extraStyle); | |
| + } else { | |
| + height = config.lineHeight; | |
| + top = this.$getTop(range.start.row, config); | |
| + left = padding + range.start.column * config.characterWidth; | |
| + stringBuilder.push( | |
| + "<div class='", clazz, " ace_br1 ace_start' style='", | |
| + "height:", height, "px;", | |
| + "right:0;", | |
| + "top:", top, "px;", | |
| + "left:", left, "px;", extraStyle, "'></div>" | |
| + ); | |
| + } | |
| + if (this.session.$bidiHandler.isBidiRow(range.end.row)) { | |
| + var range1 = range.clone(); | |
| + range1.start.row = range1.end.row; | |
| + range1.start.column = 0; | |
| + this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br12", config, null, extraStyle); | |
| + } else { | |
| + var width = range.end.column * config.characterWidth; | |
| + height = config.lineHeight; | |
| + top = this.$getTop(range.end.row, config); | |
| + stringBuilder.push( | |
| + "<div class='", clazz, " ace_br12' style='", | |
| + "height:", height, "px;", | |
| + "width:", width, "px;", | |
| + "top:", top, "px;", | |
| + "left:", padding, "px;", extraStyle, "'></div>" | |
| + ); | |
| + } | |
| height = (range.end.row - range.start.row - 1) * config.lineHeight; | |
| if (height <= 0) | |
| return; | |
| @@ -14010,6 +15180,20 @@ | |
| "left:", left, "px;", extraStyle || "", "'></div>" | |
| ); | |
| }; | |
| + this.drawBidiSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) { | |
| + var height = config.lineHeight, top = this.$getTop(range.start.row, config), padding = this.$padding; | |
| + var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column); | |
| + | |
| + selections.forEach(function(selection) { | |
| + stringBuilder.push( | |
| + "<div class='", clazz, "' style='", | |
| + "height:", height, "px;", | |
| + "width:", selection.width + (extraLength || 0), "px;", | |
| + "top:", top, "px;", | |
| + "left:", padding + selection.left, "px;", extraStyle || "", "'></div>" | |
| + ); | |
| + }); | |
| + }; | |
| this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { | |
| var top = this.$getTop(range.start.row, config); | |
| @@ -14079,7 +15263,7 @@ | |
| this.EOL_CHAR = EOL_CHAR; | |
| return true; | |
| } | |
| - } | |
| + }; | |
| this.setPadding = function(padding) { | |
| this.$padding = padding; | |
| @@ -14100,7 +15284,7 @@ | |
| this._signal("changeCharacterSize", e); | |
| }.bind(this)); | |
| this.$pollSizeChanges(); | |
| - } | |
| + }; | |
| this.checkForSizeChanges = function() { | |
| this.$fontMetrics.checkForSizeChanges(); | |
| @@ -14310,7 +15494,7 @@ | |
| break; | |
| if (this.$useLineGroups()) | |
| - html.push("<div class='ace_line_group' style='height:", config.lineHeight*this.session.getRowLength(row), "px'>") | |
| + html.push("<div class='ace_line_group' style='height:", config.lineHeight*this.session.getRowLength(row), "px'>"); | |
| this.$renderLine(html, row, false, row == foldStart ? foldLine : false); | |
| @@ -14330,7 +15514,7 @@ | |
| this.$renderToken = function(stringBuilder, screenColumn, token, value) { | |
| var self = this; | |
| - var replaceReg = /\t|&|<|>|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF\uFFF9-\uFFFC])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g; | |
| + var replaceReg = /\t|&|<|>|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF\uFFF9-\uFFFC])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g; | |
| var replaceFunc = function(c, a, b, tabIdx, idx4) { | |
| if (a) { | |
| return self.showInvisibles | |
| @@ -14488,7 +15672,7 @@ | |
| if (this.showInvisibles) { | |
| if (foldLine) | |
| - row = foldLine.end.row | |
| + row = foldLine.end.row; | |
| stringBuilder.push( | |
| "<span class='ace_invisible ace_invisible_eol'>", | |
| @@ -14719,7 +15903,10 @@ | |
| if (!position) | |
| position = this.session.selection.getCursor(); | |
| var pos = this.session.documentToScreenPosition(position); | |
| - var cursorLeft = this.$padding + pos.column * this.config.characterWidth; | |
| + var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row) | |
| + ? this.session.$bidiHandler.getPosLeft(pos.column) | |
| + : pos.column * this.config.characterWidth); | |
| + | |
| var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * | |
| this.config.lineHeight; | |
| @@ -14828,6 +16015,7 @@ | |
| this.width = dom.scrollbarWidth(parent.ownerDocument); | |
| this.inner.style.width = | |
| this.element.style.width = (this.width || 15) + 5 + "px"; | |
| + this.$minWidth = 0; | |
| }; | |
| oop.inherits(VScrollBar, ScrollBar); | |
| @@ -14847,7 +16035,7 @@ | |
| this.skipEvent = false; | |
| }; | |
| this.getWidth = function() { | |
| - return this.isVisible ? this.width : 0; | |
| + return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0); | |
| }; | |
| this.setHeight = function(height) { | |
| this.element.style.height = height + "px"; | |
| @@ -14859,7 +16047,7 @@ | |
| this.coeff = MAX_SCROLL_H / height; | |
| height = MAX_SCROLL_H; | |
| } else if (this.coeff != 1) { | |
| - this.coeff = 1 | |
| + this.coeff = 1; | |
| } | |
| this.inner.style.height = height + "px"; | |
| }; | |
| @@ -15126,6 +16314,7 @@ | |
| font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\ | |
| direction: ltr;\ | |
| text-align: left;\ | |
| +-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\ | |
| }\ | |
| .ace_scroller {\ | |
| position: absolute;\ | |
| @@ -15299,6 +16488,9 @@ | |
| border-left: 2px solid;\ | |
| transform: translatez(0);\ | |
| }\ | |
| +.ace_multiselect .ace_cursor {\ | |
| +border-left-width: 1px;\ | |
| +}\ | |
| .ace_slim-cursors .ace_cursor {\ | |
| border-left-width: 1px;\ | |
| }\ | |
| @@ -15313,9 +16505,6 @@ | |
| -webkit-transition: opacity 0.18s;\ | |
| transition: opacity 0.18s;\ | |
| }\ | |
| -.ace_editor.ace_multiselect .ace_cursor {\ | |
| -border-left-width: 1px;\ | |
| -}\ | |
| .ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\ | |
| position: absolute;\ | |
| z-index: 3;\ | |
| @@ -15493,6 +16682,11 @@ | |
| .ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\ | |
| .ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\ | |
| .ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\ | |
| +.ace_text-input-ios {\ | |
| +position: absolute !important;\ | |
| +top: -100000px !important;\ | |
| +left: -100000px !important;\ | |
| +}\ | |
| "; | |
| dom.importCssString(editorCss, "ace_editor.css"); | |
| @@ -15510,6 +16704,7 @@ | |
| this.$gutter = dom.createElement("div"); | |
| this.$gutter.className = "ace_gutter"; | |
| this.container.appendChild(this.$gutter); | |
| + this.$gutter.setAttribute("aria-hidden", true); | |
| this.scroller = dom.createElement("div"); | |
| this.scroller.className = "ace_scroller"; | |
| @@ -15651,10 +16846,10 @@ | |
| this.$loop.schedule(this.CHANGE_FULL); | |
| this.session.$setFontMetrics(this.$fontMetrics); | |
| - this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null; | |
| + this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null; | |
| this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this); | |
| - this.onChangeNewLineMode() | |
| + this.onChangeNewLineMode(); | |
| this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode); | |
| }; | |
| this.updateLines = function(firstRow, lastRow, force) { | |
| @@ -15688,6 +16883,7 @@ | |
| this.onChangeNewLineMode = function() { | |
| this.$loop.schedule(this.CHANGE_TEXT); | |
| this.$textLayer.$updateEolChar(); | |
| + this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR); | |
| }; | |
| this.onChangeTabSize = function() { | |
| @@ -15823,6 +17019,7 @@ | |
| }; | |
| this.setShowInvisibles = function(showInvisibles) { | |
| this.setOption("showInvisibles", showInvisibles); | |
| + this.session.$bidiHandler.setShowInvisibles(showInvisibles); | |
| }; | |
| this.getShowInvisibles = function() { | |
| return this.getOption("showInvisibles"); | |
| @@ -15854,7 +17051,7 @@ | |
| }; | |
| this.getFadeFoldWidgets = function(){ | |
| - return this.getOption("fadeFoldWidgets") | |
| + return this.getOption("fadeFoldWidgets"); | |
| }; | |
| this.setFadeFoldWidgets = function(show) { | |
| @@ -15950,7 +17147,7 @@ | |
| }; | |
| this.getLastFullyVisibleRow = function() { | |
| var config = this.layerConfig; | |
| - var lastRow = config.lastRow | |
| + var lastRow = config.lastRow; | |
| var top = this.session.documentToScreenRow(lastRow, 0) * config.lineHeight; | |
| if (top - this.session.getScrollTop() > config.height - config.lineHeight) | |
| return lastRow - 1; | |
| @@ -16041,6 +17238,10 @@ | |
| } | |
| this._signal("beforeRender"); | |
| + | |
| + if (this.session && this.session.$bidiHandler) | |
| + this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics); | |
| + | |
| var config = this.layerConfig; | |
| if (changes & this.CHANGE_FULL || | |
| changes & this.CHANGE_SIZE || | |
| @@ -16254,6 +17455,7 @@ | |
| }; | |
| this.$updateLines = function() { | |
| + if (!this.$changedLines) return; | |
| var firstRow = this.$changedLines.firstRow; | |
| var lastRow = this.$changedLines.lastRow; | |
| this.$changedLines = null; | |
| @@ -16482,29 +17684,32 @@ | |
| this.pixelToScreenCoordinates = function(x, y) { | |
| var canvasPos = this.scroller.getBoundingClientRect(); | |
| - var offset = (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth; | |
| + var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding; | |
| + var offset = offsetX / this.characterWidth; | |
| var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight); | |
| var col = Math.round(offset); | |
| - return {row: row, column: col, side: offset - col > 0 ? 1 : -1}; | |
| + return {row: row, column: col, side: offset - col > 0 ? 1 : -1, offsetX: offsetX}; | |
| }; | |
| this.screenToTextCoordinates = function(x, y) { | |
| var canvasPos = this.scroller.getBoundingClientRect(); | |
| - | |
| - var col = Math.round( | |
| - (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth | |
| - ); | |
| + var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding; | |
| + | |
| + var col = Math.round(offsetX / this.characterWidth); | |
| var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight; | |
| - return this.session.screenToDocumentPosition(row, Math.max(col, 0)); | |
| + return this.session.screenToDocumentPosition(row, Math.max(col, 0), offsetX); | |
| }; | |
| this.textToScreenCoordinates = function(row, column) { | |
| var canvasPos = this.scroller.getBoundingClientRect(); | |
| var pos = this.session.documentToScreenPosition(row, column); | |
| - var x = this.$padding + Math.round(pos.column * this.characterWidth); | |
| + var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row) | |
| + ? this.session.$bidiHandler.getPosLeft(pos.column) | |
| + : Math.round(pos.column * this.characterWidth)); | |
| + | |
| var y = pos.row * this.lineHeight; | |
| return { | |
| @@ -16654,7 +17859,7 @@ | |
| initialValue: false | |
| }, | |
| showFoldWidgets: { | |
| - set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)}, | |
| + set: function(show) {this.$gutterLayer.setShowFoldWidgets(show);}, | |
| initialValue: true | |
| }, | |
| showLineNumbers: { | |
| @@ -16750,7 +17955,7 @@ | |
| } | |
| }, | |
| theme: { | |
| - set: function(val) { this.setTheme(val) }, | |
| + set: function(val) { this.setTheme(val); }, | |
| get: function() { return this.$themeId || this.theme; }, | |
| initialValue: "./theme/textmate", | |
| handlesSet: true | |
| @@ -16768,7 +17973,26 @@ | |
| var EventEmitter = require("../lib/event_emitter").EventEmitter; | |
| var config = require("../config"); | |
| -var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl) { | |
| +function $workerBlob(workerUrl) { | |
| + var script = "importScripts('" + net.qualifyURL(workerUrl) + "');"; | |
| + try { | |
| + return new Blob([script], {"type": "application/javascript"}); | |
| + } catch (e) { // Backwards-compatibility | |
| + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; | |
| + var blobBuilder = new BlobBuilder(); | |
| + blobBuilder.append(script); | |
| + return blobBuilder.getBlob("application/javascript"); | |
| + } | |
| +} | |
| + | |
| +function createWorker(workerUrl) { | |
| + var blob = $workerBlob(workerUrl); | |
| + var URL = window.URL || window.webkitURL; | |
| + var blobURL = URL.createObjectURL(blob); | |
| + return new Worker(blobURL); | |
| +} | |
| + | |
| +var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl, importScripts) { | |
| this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); | |
| this.changeListener = this.changeListener.bind(this); | |
| this.onMessage = this.onMessage.bind(this); | |
| @@ -16787,19 +18011,9 @@ | |
| }); | |
| } | |
| - try { | |
| - this.$worker = new Worker(workerUrl); | |
| - } catch(e) { | |
| - if (e instanceof window.DOMException) { | |
| - var blob = this.$workerBlob(workerUrl); | |
| - var URL = window.URL || window.webkitURL; | |
| - var blobURL = URL.createObjectURL(blob); | |
| - | |
| - this.$worker = new Worker(blobURL); | |
| - URL.revokeObjectURL(blobURL); | |
| - } else { | |
| - throw e; | |
| - } | |
| + this.$worker = createWorker(workerUrl); | |
| + if (importScripts) { | |
| + this.send("importScripts", importScripts); | |
| } | |
| this.$worker.postMessage({ | |
| init : true, | |
| @@ -16820,7 +18034,7 @@ | |
| this.onMessage = function(e) { | |
| var msg = e.data; | |
| - switch(msg.type) { | |
| + switch (msg.type) { | |
| case "event": | |
| this._signal(msg.name, {data: msg.data}); | |
| break; | |
| @@ -16881,7 +18095,7 @@ | |
| }; | |
| this.attachToDocument = function(doc) { | |
| - if(this.$doc) | |
| + if (this.$doc) | |
| this.terminate(); | |
| this.$doc = doc; | |
| @@ -16910,18 +18124,6 @@ | |
| this.emit("change", {data: q}); | |
| }; | |
| - this.$workerBlob = function(workerUrl) { | |
| - var script = "importScripts('" + net.qualifyURL(workerUrl) + "');"; | |
| - try { | |
| - return new Blob([script], {"type": "application/javascript"}); | |
| - } catch (e) { // Backwards-compatibility | |
| - var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; | |
| - var blobBuilder = new BlobBuilder(); | |
| - blobBuilder.append(script); | |
| - return blobBuilder.getBlob("application/javascript"); | |
| - } | |
| - }; | |
| - | |
| }).call(WorkerClient.prototype); | |
| @@ -16948,7 +18150,7 @@ | |
| processNext(); | |
| } | |
| }; | |
| - this.setEmitSync = function(val) { emitSync = val }; | |
| + this.setEmitSync = function(val) { emitSync = val; }; | |
| var processNext = function() { | |
| var msg = _self.messageBuffer.shift(); | |
| @@ -16979,6 +18181,8 @@ | |
| exports.UIWorkerClient = UIWorkerClient; | |
| exports.WorkerClient = WorkerClient; | |
| +exports.createWorker = createWorker; | |
| + | |
| }); | |
| @@ -17265,7 +18469,7 @@ | |
| var rectSel = []; | |
| var blockSelect = function() { | |
| var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY); | |
| - var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column); | |
| + var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column, newCursor.offsetX); | |
| if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead)) | |
| return; | |
| @@ -17402,7 +18606,7 @@ | |
| exec: function(editor) { editor.exitMultiSelectMode(); }, | |
| scrollIntoView: "cursor", | |
| readOnly: true, | |
| - isAvailable: function(editor) {return editor && editor.inMultiSelectMode} | |
| + isAvailable: function(editor) {return editor && editor.inMultiSelectMode;} | |
| }]; | |
| var HashHandler = require("../keyboard/hash_handler").HashHandler; | |
| @@ -17604,9 +18808,13 @@ | |
| if (xBackwards) { | |
| var startColumn = screenCursor.column; | |
| var endColumn = screenAnchor.column; | |
| + var startOffsetX = screenCursor.offsetX; | |
| + var endOffsetX = screenAnchor.offsetX; | |
| } else { | |
| var startColumn = screenAnchor.column; | |
| var endColumn = screenCursor.column; | |
| + var startOffsetX = screenAnchor.offsetX; | |
| + var endOffsetX = screenCursor.offsetX; | |
| } | |
| var yBackwards = screenCursor.row < screenAnchor.row; | |
| @@ -17628,8 +18836,8 @@ | |
| for (var row = startRow; row <= endRow; row++) { | |
| var range = Range.fromPoints( | |
| - this.session.screenToDocumentPosition(row, startColumn), | |
| - this.session.screenToDocumentPosition(row, endColumn) | |
| + this.session.screenToDocumentPosition(row, startColumn, startOffsetX), | |
| + this.session.screenToDocumentPosition(row, endColumn, endOffsetX) | |
| ); | |
| if (range.isEmpty()) { | |
| if (docEnd && isSamePoint(range.end, docEnd)) | |
| @@ -17766,7 +18974,7 @@ | |
| if (this.inVirtualSelectionMode) | |
| return; | |
| var keepOrder = options && options.keepOrder; | |
| - var $byLines = options == true || options && options.$byLines | |
| + var $byLines = options == true || options && options.$byLines; | |
| var session = this.session; | |
| var selection = this.selection; | |
| var rangeList = selection.rangeList; | |
| @@ -18654,7 +19862,7 @@ | |
| w.editor.destroy(); | |
| } catch(e){} | |
| if (this.session.lineWidgets) { | |
| - var w1 = this.session.lineWidgets[w.row] | |
| + var w1 = this.session.lineWidgets[w.row]; | |
| if (w1 == w) { | |
| this.session.lineWidgets[w.row] = w.$oldWidget; | |
| if (w.$oldWidget) | |
| @@ -19043,10 +20251,10 @@ | |
| var doc = new EditSession(text, mode); | |
| doc.setUndoManager(new UndoManager()); | |
| return doc; | |
| -} | |
| +}; | |
| exports.EditSession = EditSession; | |
| exports.UndoManager = UndoManager; | |
| -exports.version = "1.2.5"; | |
| +exports.version = "1.2.9"; | |
| }); | |
| (function() { | |
| ace.require(["ace/ace"], function(a) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment