diff --git a/lib/client/edit.js b/lib/client/edit.js index ab3748fa..44de7838 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -13,6 +13,7 @@ var CloudCmd, Util, DOM, CloudFunc, ace, DiffProto, diff_match_patch; Edit = this, Diff, Ace, + Session, Modelist, Msg, Dialog = DOM.Dialog, @@ -42,8 +43,7 @@ var CloudCmd, Util, DOM, CloudFunc, ace, DiffProto, diff_match_patch; this.show = function(pValue) { var lMode, lName = DOM.getCurrentName(), - lExt = Util.getExtension(lName), - lUseWorker = Util.strCmp(lExt, ['.js', '.json']); + lExt = Util.getExtension(lName); if (!Loading) { Images.showLoad(); @@ -62,18 +62,16 @@ var CloudCmd, Util, DOM, CloudFunc, ace, DiffProto, diff_match_patch; initAce(); } - Ace.setOptions({ - useWorker : lUseWorker, - enableBasicAutocompletion : true, - enableSnippets : true - }); - - if (!Modelist) Modelist = ace.require('ace/ext/modelist'); lMode = Modelist.getModeForPath(lName).mode; - Ace.session.setMode(lMode); + Session.setMode(lMode); + + Ace.setOptions({ + enableBasicAutocompletion : true, + enableSnippets : true + }); if (Util.isString(pValue)) { Ace.setValue(pValue); @@ -119,16 +117,14 @@ var CloudCmd, Util, DOM, CloudFunc, ace, DiffProto, diff_match_patch; } function initAce() { - var lSession; - - Ace = ace.edit(Element); - lSession = Ace.getSession(); + Ace = ace.edit(Element); + Session = Ace.getSession(); Ace.setTheme('ace/theme/tomorrow_night_blue'); Ace.setShowPrintMargin(false); Ace.setShowInvisibles(true); - lSession.setUseSoftTabs(true); + Session.setUseSoftTabs(true); Ace.commands.addCommand({ name : 'hide', @@ -212,8 +208,6 @@ var CloudCmd, Util, DOM, CloudFunc, ace, DiffProto, diff_match_patch; DIR + 'ext-language_tools.js', DIR + 'ext-searchbox.js', DIR + 'ext-modelist.js', - DIR + 'snippets/javascript.js', - DIR + 'mode-javascript.js', ], lAce = DIR + 'ace.js', lURL = CloudFunc.getCombineURL(lFiles); diff --git a/lib/client/edit/ace.js b/lib/client/edit/ace.js index a1beaabc..c688f2f2 100644 --- a/lib/client/edit/ace.js +++ b/lib/client/edit/ace.js @@ -195,7 +195,7 @@ exports.edit = function(el) { var _id = el; var el = document.getElementById(_id); if (!el) - throw "ace.edit can't find div #" + _id; + throw new Error("ace.edit can't find div #" + _id); } if (el.env && el.env.editor instanceof Editor) @@ -1252,7 +1252,7 @@ exports.addListener = function(elem, type, callback) { } if (elem.attachEvent) { var wrapper = function() { - callback(window.event); + callback.call(elem, window.event); }; callback._wrapper = wrapper; elem.attachEvent("on" + type, wrapper); @@ -1299,46 +1299,20 @@ exports.getButton = function(e) { } }; -if (document.documentElement.setCapture) { - exports.capture = function(el, eventHandler, releaseCaptureHandler) { - var called = false; - function onReleaseCapture(e) { - eventHandler(e); +exports.capture = function(el, eventHandler, releaseCaptureHandler) { + function onMouseUp(e) { + eventHandler && eventHandler(e); + releaseCaptureHandler && releaseCaptureHandler(e); - if (!called) { - called = true; - releaseCaptureHandler(e); - } + exports.removeListener(document, "mousemove", eventHandler, true); + exports.removeListener(document, "mouseup", onMouseUp, true); + exports.removeListener(document, "dragstart", onMouseUp, true); + } - exports.removeListener(el, "mousemove", eventHandler); - exports.removeListener(el, "mouseup", onReleaseCapture); - exports.removeListener(el, "losecapture", onReleaseCapture); - - el.releaseCapture(); - } - - exports.addListener(el, "mousemove", eventHandler); - exports.addListener(el, "mouseup", onReleaseCapture); - exports.addListener(el, "losecapture", onReleaseCapture); - el.setCapture(); - }; -} -else { - exports.capture = function(el, eventHandler, releaseCaptureHandler) { - function onMouseUp(e) { - eventHandler && eventHandler(e); - releaseCaptureHandler && releaseCaptureHandler(e); - - document.removeEventListener("mousemove", eventHandler, true); - document.removeEventListener("mouseup", onMouseUp, true); - - e.stopPropagation(); - } - - document.addEventListener("mousemove", eventHandler, true); - document.addEventListener("mouseup", onMouseUp, true); - }; -} + exports.addListener(document, "mousemove", eventHandler, true); + exports.addListener(document, "mouseup", onMouseUp, true); + exports.addListener(document, "dragstart", onMouseUp, true); +}; exports.addMouseWheelListener = function(el, callback) { if ("onmousewheel" in el) { @@ -1385,21 +1359,22 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac exports.addListener(el, "mousedown", function(e) { if (exports.getButton(e) != 0) { clicks = 0; + } else if (e.detail > 1) { + clicks++; + if (clicks > 4) + clicks = 1; } else { - var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5; - - if (!timer || isNewClick) - clicks = 0; - - clicks += 1; - - if (timer) - clearTimeout(timer) - timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600); + clicks = 1; } - if (clicks == 1) { - startX = e.clientX; - startY = e.clientY; + if (useragent.isIE) { + var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5; + if (isNewClick) { + clicks = 1; + } + if (clicks == 1) { + startX = e.clientX; + startY = e.clientY; + } } eventHandler[callbackName]("mousedown", e); @@ -1441,11 +1416,11 @@ function normalizeCommandKeys(callback, e, keyCode) { else return; } - if (keyCode == 18 || keyCode == 17) { + if (keyCode === 18 || keyCode === 17) { var location = e.location || e.keyLocation; - if (keyCode == 17 && location == 1) { + if (keyCode === 17 && location === 1) { ts = e.timeStamp; - } else if (keyCode == 18 && hashId == 3 && location == 2) { + } else if (keyCode === 18 && hashId === 3 && location === 2) { var dt = -ts; ts = e.timeStamp; dt += ts; @@ -1473,12 +1448,12 @@ function normalizeCommandKeys(callback, e, keyCode) { keyCode = 0; } - if (hashId & 8 && (keyCode == 91 || keyCode == 93)) { + if (hashId & 8 && (keyCode === 91 || keyCode === 93)) { keyCode = 0; } - if (!hashId && keyCode == 13) { - if (e.keyLocation || e.location == 3) { + if (!hashId && keyCode === 13) { + if (e.location || e.keyLocation === 3) { callback(e, hashId, -keyCode) if (e.defaultPrevented) return; @@ -1769,6 +1744,15 @@ var Editor = function(renderer, session) { this.commands.on("exec", this.$historyTracker); this.$initOperationListeners(); + + this._$emitInputEvent = lang.delayedCall(function() { + this._signal("input", {}); + this.session.bgTokenizer && this.session.bgTokenizer.scheduleStart(); + }.bind(this)); + + this.on("change", function(_, _self) { + _self._$emitInputEvent.schedule(31); + }); this.setSession(session || new EditSession("")); config.resetOptions(this); @@ -1897,7 +1881,7 @@ var Editor = function(renderer, session) { _self.keyBinding.setKeyboardHandler(module && module.handler); }); } else { - delete this.$keybindingId; + this.$keybindingId = null; this.keyBinding.setKeyboardHandler(keyboardHandler); } }; @@ -2259,13 +2243,12 @@ var Editor = function(renderer, session) { this.$updateHighlightActiveLine(); this.renderer.updateFull(); }; - + this.getSelectedText = function() { + return this.session.getTextRange(this.getSelectionRange()); + }; this.getCopyText = function() { - var text = ""; - if (!this.selection.isEmpty()) - text = this.session.getTextRange(this.getSelectionRange()); - - this._emit("copy", text); + var text = this.getSelectedText(); + this._signal("copy", text); return text; }; this.onCopy = function() { @@ -2761,8 +2744,8 @@ var Editor = function(renderer, session) { return this.session.moveLinesUp(firstRow, lastRow); }); }; - this.moveText = function(range, toPosition) { - return this.session.moveText(range, toPosition); + this.moveText = function(range, toPosition, copy) { + return this.session.moveText(range, toPosition, copy); }; this.copyLinesUp = function() { this.$moveLines(function(firstRow, lastRow) { @@ -3257,7 +3240,10 @@ config.defineOptions(Editor.prototype, "editor", { initialValue: true }, readOnly: { - set: function(readOnly) { this.$resetCursorStyle(); }, + set: function(readOnly) { + this.textInput.setReadOnly(readOnly); + this.$resetCursorStyle(); + }, initialValue: false }, cursorStyle: { @@ -3273,6 +3259,7 @@ config.defineOptions(Editor.prototype, "editor", { wrapBehavioursEnabled: {initialValue: true}, hScrollBarAlwaysVisible: "renderer", + vScrollBarAlwaysVisible: "renderer", highlightGutterLine: "renderer", animatedScroll: "renderer", showInvisibles: "renderer", @@ -3288,9 +3275,11 @@ config.defineOptions(Editor.prototype, "editor", { maxLines: "renderer", minLines: "renderer", scrollPastEnd: "renderer", + fixedWidthGutter: "renderer", scrollSpeed: "$mouseHandler", dragDelay: "$mouseHandler", + dragEnabled: "$mouseHandler", focusTimout: "$mouseHandler", firstLineNumber: "session", @@ -3495,6 +3484,7 @@ var BROKEN_SETDATA = useragent.isChrome < 18; var TextInput = function(parentNode, host) { var text = dom.createElement("textarea"); text.className = "ace_text-input"; + if (useragent.isTouchPad) text.setAttribute("x-palm-disable-auto-cap", true); @@ -3503,7 +3493,7 @@ var TextInput = function(parentNode, host) { text.autocapitalize = "off"; text.spellcheck = false; - text.style.bottom = "2000em"; + text.style.opacity = "0"; parentNode.insertBefore(text, parentNode.firstChild); var PLACEHOLDER = "\x01\x01"; @@ -3655,17 +3645,17 @@ var TextInput = function(parentNode, host) { if (data) host.onPaste(data); pasted = false; - } else if (data == PLACEHOLDER[0]) { + } else if (data == PLACEHOLDER.charAt(0)) { if (afterContextMenu) host.execCommand("del", {source: "ace"}); } else { if (data.substring(0, 2) == PLACEHOLDER) data = data.substr(2); - else if (data[0] == PLACEHOLDER[0]) + else if (data.charAt(0) == PLACEHOLDER.charAt(0)) data = data.substr(1); - else if (data[data.length - 1] == PLACEHOLDER[0]) + else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1); - if (data[data.length - 1] == PLACEHOLDER[0]) + if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1); if (data) @@ -3800,10 +3790,13 @@ var TextInput = function(parentNode, host) { var onCompositionUpdate = function() { if (!inComposition) return; - host.onCompositionUpdate(text.value); + var val = text.value.replace(/\x01/g, ""); + if (inComposition.lastValue === val) return; + + host.onCompositionUpdate(val); if (inComposition.lastValue) host.undo(); - inComposition.lastValue = text.value.replace(/\x01/g, "") + inComposition.lastValue = val; if (inComposition.lastValue) { var r = host.selection.getRange(); host.insert(inComposition.lastValue); @@ -3818,6 +3811,7 @@ var TextInput = function(parentNode, host) { var c = inComposition; inComposition = false; var timer = setTimeout(function() { + timer = null; var str = text.value.replace(/\x01/g, ""); if (inComposition) return @@ -3829,14 +3823,15 @@ var TextInput = function(parentNode, host) { } }); inputHandler = function compositionInputHandler(str) { - clearTimeout(timer); + if (timer) + clearTimeout(timer); str = str.replace(/\x01/g, ""); if (str == c.lastValue) return ""; - if (c.lastValue) + if (c.lastValue && timer) host.undo(); return str; - } + }; host.onCompositionEnd(); host.removeListener("mousedown", onCompositionEnd); if (e.type == "compositionend" && c.range) { @@ -3849,7 +3844,12 @@ var TextInput = function(parentNode, host) { var syncComposition = lang.delayedCall(onCompositionUpdate, 50); event.addListener(text, "compositionstart", onCompositionStart); - event.addListener(text, useragent.isGecko ? "text" : "keyup", function(){syncComposition.schedule()}); + 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); this.getElement = function() { @@ -3903,17 +3903,19 @@ var TextInput = function(parentNode, host) { }, 0); } if (!useragent.isGecko || useragent.isMac) { - event.addListener(text, "contextmenu", function(e) { + var onContextMenu = function(e) { host.textInput.onContextMenu(e); onContextMenuClose(); - }); + }; + event.addListener(host.renderer.scroller, "contextmenu", onContextMenu); + event.addListener(text, "contextmenu", onContextMenu); } }; exports.TextInput = TextInput; }); -ace.define('ace/mouse/mouse_handler', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/mouse/default_handlers', 'ace/mouse/default_gutter_handler', 'ace/mouse/mouse_event', 'ace/mouse/dragdrop', 'ace/config'], function(require, exports, module) { +ace.define('ace/mouse/mouse_handler', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/mouse/default_handlers', 'ace/mouse/default_gutter_handler', 'ace/mouse/mouse_event', 'ace/mouse/dragdrop_handler', 'ace/config'], function(require, exports, module) { var event = require("../lib/event"); @@ -3921,7 +3923,7 @@ var useragent = require("../lib/useragent"); var DefaultHandlers = require("./default_handlers").DefaultHandlers; var DefaultGutterHandler = require("./default_gutter_handler").GutterHandler; var MouseEvent = require("./mouse_event").MouseEvent; -var DragdropHandler = require("./dragdrop").DragdropHandler; +var DragdropHandler = require("./dragdrop_handler").DragdropHandler; var config = require("../config"); var MouseHandler = function(editor) { @@ -3935,6 +3937,10 @@ var MouseHandler = function(editor) { event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click")); event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove")); event.addMultiMouseDownListener(mouseTarget, [300, 300, 250], this, "onMouseEvent"); + if (editor.renderer.scrollBarV) { + event.addMultiMouseDownListener(editor.renderer.scrollBarV.inner, [300, 300, 250], this, "onMouseEvent"); + event.addMultiMouseDownListener(editor.renderer.scrollBarH.inner, [300, 300, 250], this, "onMouseEvent"); + } event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel")); var gutterEl = editor.renderer.$gutter; @@ -3942,12 +3948,11 @@ var MouseHandler = function(editor) { event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick")); event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick")); event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove")); - + event.addListener(mouseTarget, "mousedown", function(e) { editor.focus(); - return event.preventDefault(e); }); - + event.addListener(gutterEl, "mousedown", function(e) { editor.focus(); return event.preventDefault(e); @@ -3980,13 +3985,10 @@ var MouseHandler = function(editor) { this.state = state; }; - this.captureMouse = function(ev, state) { - if (state) - this.setState(state); - + this.captureMouse = function(ev, mouseMoveHandler) { this.x = ev.x; this.y = ev.y; - + this.isMousePressed = true; var renderer = this.editor.renderer; if (renderer.$keepTextAreaAtCursor) @@ -3996,6 +3998,7 @@ var MouseHandler = function(editor) { var onMouseMove = function(e) { self.x = e.clientX; self.y = e.clientY; + mouseMoveHandler && mouseMoveHandler(e); }; var onCaptureEnd = function(e) { @@ -4008,13 +4011,13 @@ var MouseHandler = function(editor) { renderer.$moveTextAreaToCursor(); } self.isMousePressed = false; - self.onMouseEvent("mouseup", e) + self.onMouseEvent("mouseup", e); }; var onCaptureInterval = function() { self[self.state] && self[self.state](); }; - + if (useragent.isOldIE && ev.domEvent.type == "dblclick") { return setTimeout(function() {onCaptureEnd(ev);}); } @@ -4027,6 +4030,7 @@ var MouseHandler = function(editor) { config.defineOptions(MouseHandler.prototype, "mouseHandler", { scrollSpeed: {initialValue: 2}, dragDelay: {initialValue: 150}, + dragEnabled: {initialValue: true}, focusTimout: {initialValue: 0} }); @@ -4034,10 +4038,11 @@ config.defineOptions(MouseHandler.prototype, "mouseHandler", { exports.MouseHandler = MouseHandler; }); -ace.define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/useragent'], function(require, exports, module) { +ace.define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) { var dom = require("../lib/dom"); +var event = require("../lib/event"); var useragent = require("../lib/useragent"); var DRAG_OFFSET = 0; // pixels @@ -4052,8 +4057,8 @@ function DefaultHandlers(mouseHandler) { editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler)); editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler)); - var exports = ["select", "startSelect", "drag", "dragEnd", "dragWait", - "dragWaitEnd", "startDrag", "focusWait"]; + var exports = ["select", "startSelect", "selectEnd", "selectAllEnd", "selectByWordsEnd", + "selectByLinesEnd", "dragWait", "dragWaitEnd", "focusWait"]; exports.forEach(function(x) { mouseHandler[x] = this[x]; @@ -4086,9 +4091,10 @@ function DefaultHandlers(mouseHandler) { if (inSelection && !editor.isFocused()) { editor.focus(); if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) { + this.mousedownEvent.time = (new Date()).getTime(); this.setState("focusWait"); this.captureMouse(ev); - return ev.preventDefault(); + return; } } @@ -4096,22 +4102,28 @@ function DefaultHandlers(mouseHandler) { this.startSelect(pos); } else if (inSelection) { this.mousedownEvent.time = (new Date()).getTime(); - this.setState("dragWait"); + this.startSelect(pos); } - this.captureMouse(ev); return ev.preventDefault(); }; this.startSelect = function(pos) { pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y); - if (this.mousedownEvent.getShiftKey()) { - this.editor.selection.selectToPosition(pos); - } - else if (!this.$clickSelection) { - this.editor.moveCursorToPosition(pos); - this.editor.selection.clearSelection(); + var editor = this.editor; + setTimeout(function(){ + if (this.mousedownEvent.getShiftKey()) { + editor.selection.selectToPosition(pos); + } + else if (!this.$clickSelection) { + editor.moveCursorToPosition(pos); + editor.selection.clearSelection(); + } + }.bind(this), 0); + if (editor.renderer.scroller.setCapture) { + editor.renderer.scroller.setCapture(); } + editor.setStyle("ace_selecting"); this.setState("select"); }; @@ -4170,32 +4182,14 @@ function DefaultHandlers(mouseHandler) { editor.renderer.scrollCursorIntoView(); }; - this.startDrag = function() { - var editor = this.editor; - this.setState("drag"); - this.dragRange = editor.getSelectionRange(); - var style = editor.getSelectionStyle(); - this.dragSelectionMarker = editor.session.addMarker(this.dragRange, "ace_selection", style); - editor.clearSelection(); - dom.addCssClass(editor.container, "ace_dragging"); - if (!this.$dragKeybinding) { - this.$dragKeybinding = { - handleKeyboard: function(data, hashId, keyString, keyCode) { - if (keyString == "esc") - return {command: this.command}; - }, - command: { - exec: function(editor) { - var self = editor.$mouseHandler; - self.dragCursor = null; - self.dragEnd(); - self.startSelect(); - } - } - } + this.selectEnd = + this.selectAllEnd = + this.selectByWordsEnd = + this.selectByLinesEnd = function() { + this.editor.unsetStyle("ace_selecting"); + if (this.editor.renderer.scroller.releaseCapture) { + this.editor.renderer.scroller.releaseCapture(); } - - editor.keyBinding.addKeyboardHandler(this.$dragKeybinding); }; this.focusWait = function() { @@ -4206,59 +4200,6 @@ function DefaultHandlers(mouseHandler) { this.startSelect(this.mousedownEvent.getDocumentPosition()); }; - this.dragWait = function(e) { - var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); - var time = (new Date()).getTime(); - var editor = this.editor; - - if (distance > DRAG_OFFSET) { - this.startSelect(this.mousedownEvent.getDocumentPosition()); - } else if (time - this.mousedownEvent.time > editor.$mouseHandler.$dragDelay) { - this.startDrag(); - } - }; - - this.dragWaitEnd = function(e) { - this.mousedownEvent.domEvent = e; - this.startSelect(); - }; - - this.drag = function() { - var editor = this.editor; - this.dragCursor = editor.renderer.screenToTextCoordinates(this.x, this.y); - editor.moveCursorToPosition(this.dragCursor); - editor.renderer.scrollCursorIntoView(); - }; - - this.dragEnd = function(e) { - var editor = this.editor; - var dragCursor = this.dragCursor; - var dragRange = this.dragRange; - dom.removeCssClass(editor.container, "ace_dragging"); - editor.session.removeMarker(this.dragSelectionMarker); - editor.keyBinding.removeKeyboardHandler(this.$dragKeybinding); - - if (!dragCursor) - return; - - editor.clearSelection(); - if (e && (e.ctrlKey || e.altKey)) { - var session = editor.session; - var newRange = dragRange; - newRange.end = session.insert(dragCursor, session.getTextRange(dragRange)); - newRange.start = dragCursor; - } else if (dragRange.contains(dragCursor.row, dragCursor.column)) { - return; - } else { - var newRange = editor.moveText(dragRange, dragCursor); - } - - if (!newRange) - return; - - editor.selection.setSelectionRange(newRange); - }; - this.onDoubleClick = function(ev) { var pos = ev.getDocumentPosition(); var editor = this.editor; @@ -4292,7 +4233,7 @@ function DefaultHandlers(mouseHandler) { editor.selectAll(); this.$clickSelection = editor.getSelectionRange(); - this.setState("null"); + this.setState("selectAll"); }; this.onMouseWheel = function(ev) { @@ -4363,7 +4304,8 @@ function GutterHandler(mouseHandler) { } mouseHandler.$clickSelection = editor.selection.getLineRange(row); } - mouseHandler.captureMouse(e, "selectByLines"); + mouseHandler.setState("selectByLines"); + mouseHandler.captureMouse(e); return e.preventDefault(); }); @@ -4418,11 +4360,12 @@ function GutterHandler(mouseHandler) { var rect = editor.renderer.$gutter.getBoundingClientRect(); tooltip.style.left = e.x + 15 + "px"; if (e.y + 3 * editor.renderer.lineHeight + 15 < rect.bottom) { - tooltip.style.bottom = ""; + tooltip.style.bottom = ""; tooltip.style.top = e.y + 15 + "px"; } else { - tooltip.style.top = ""; - tooltip.style.bottom = rect.bottom - e.y + 5 + "px"; + tooltip.style.top = ""; + var innerHeight = window.innerHeight || document.documentElement.clientHeight; + tooltip.style.bottom = innerHeight - e.y + 5 + "px"; } } @@ -4512,18 +4455,15 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) { var editor = this.editor; - if (editor.getReadOnly()) { + + var selectionRange = editor.getSelectionRange(); + if (selectionRange.isEmpty()) this.$inSelection = false; - } else { - var selectionRange = editor.getSelectionRange(); - if (selectionRange.isEmpty()) - this.$inSelection = false; - else { - var pos = this.getDocumentPosition(); - this.$inSelection = selectionRange.contains(pos.row, pos.column); - } + var pos = this.getDocumentPosition(); + this.$inSelection = selectionRange.contains(pos.row, pos.column); } + return this.$inSelection; }; this.getButton = function() { @@ -4541,82 +4481,250 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) { }); -ace.define('ace/mouse/dragdrop', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) { +ace.define('ace/mouse/dragdrop_handler', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) { +var dom = require("../lib/dom"); var event = require("../lib/event"); +var useragent = require("../lib/useragent"); + +var AUTOSCROLL_DELAY = 200; +var SCROLL_CURSOR_DELAY = 200; +var SCROLL_CURSOR_HYSTERESIS = 5; + +function DragdropHandler(mouseHandler) { -var DragdropHandler = function(mouseHandler) { var editor = mouseHandler.editor; + + var blankImage = dom.createElement("img"); + blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (useragent.isOpera) + blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;"; + + var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"]; + + exports.forEach(function(x) { + mouseHandler[x] = this[x]; + }, this); + editor.addEventListener("mousedown", this.onMouseDown.bind(mouseHandler)); + + + var mouseTarget = editor.container; var dragSelectionMarker, x, y; var timerId, range; var dragCursor, counter = 0; + var dragOperation; + var isInternal; + var autoScrollStartTime; + var cursorMovedTime; + var cursorPointOnCaretMoved; - var mouseTarget = editor.container; - event.addListener(mouseTarget, "dragenter", function(e) { - if (editor.getReadOnly()) - return; - var types = e.dataTransfer.types; - if (types && Array.prototype.indexOf.call(types, "text/plain") === -1) + this.onDragStart = function(e) { + if (this.cancelDrag || !mouseTarget.draggable) { + var self = this; + setTimeout(function(){ + self.startSelect(); + self.captureMouse(e); + }, 0); + return e.preventDefault(); + } + range = editor.getSelectionRange(); + + var dataTransfer = e.dataTransfer; + dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove"; + if (useragent.isOpera) { + editor.container.appendChild(blankImage); + blankImage._top = blankImage.offsetTop; + } + dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0); + if (useragent.isOpera) { + editor.container.removeChild(blankImage); + } + dataTransfer.clearData(); + dataTransfer.setData("Text", editor.session.getTextRange()); + + isInternal = true; + this.setState("drag"); + }; + + this.onDragEnd = function(e) { + mouseTarget.draggable = false; + isInternal = false; + this.setState(null); + if (!editor.getReadOnly()) { + var dropEffect = e.dataTransfer.dropEffect; + if (!dragOperation && dropEffect == "move") + editor.session.remove(editor.getSelectionRange()); + editor.renderer.$cursorLayer.setBlinking(true); + } + this.editor.unsetStyle("ace_dragging"); + }; + + this.onDragEnter = function(e) { + if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return; if (!dragSelectionMarker) addDragMarker(); counter++; + e.dataTransfer.dropEffect = dragOperation = getDropEffect(e); return event.preventDefault(e); - }); + }; - event.addListener(mouseTarget, "dragover", function(e) { - if (editor.getReadOnly()) - return; - var types = e.dataTransfer.types; - if (types && Array.prototype.indexOf.call(types, "text/plain") === -1) + this.onDragOver = function(e) { + if (editor.getReadOnly() || !canAccept(e.dataTransfer)) return; + if (!dragSelectionMarker) { + addDragMarker(); + counter++; + } if (onMouseMoveTimer !== null) onMouseMoveTimer = null; x = e.clientX; y = e.clientY; - return event.preventDefault(e); - }); - var onDragInterval = function() { - dragCursor = editor.renderer.screenToTextCoordinates(x, y); - editor.moveCursorToPosition(dragCursor); - editor.renderer.scrollCursorIntoView(); + e.dataTransfer.dropEffect = dragOperation = getDropEffect(e); + return event.preventDefault(e); }; - event.addListener(mouseTarget, "dragleave", function(e) { + this.onDragLeave = function(e) { counter--; if (counter <= 0 && dragSelectionMarker) { clearDragMarker(); + dragOperation = null; return event.preventDefault(e); } - }); + }; - event.addListener(mouseTarget, "drop", function(e) { + this.onDrop = function(e) { if (!dragSelectionMarker) return; - range.end = editor.session.insert(dragCursor, e.dataTransfer.getData('Text')); - range.start = dragCursor; + var dataTransfer = e.dataTransfer; + if (isInternal) { + switch (dragOperation) { + case "move": + if (range.contains(dragCursor.row, dragCursor.column)) { + range = { + start: dragCursor, + end: dragCursor + }; + } else { + range = editor.moveText(range, dragCursor); + } + break; + case "copy": + range = editor.moveText(range, dragCursor, true); + break; + } + } else { + var dropData = dataTransfer.getData('Text'); + range = { + start: dragCursor, + end: editor.session.insert(dragCursor, dropData) + }; + editor.focus(); + dragOperation = null; + } clearDragMarker(); - editor.focus(); return event.preventDefault(e); - }); + }; + + event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler)); + event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler)); + event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler)); + event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler)); + event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler)); + event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler)); + + function scrollCursorIntoView(cursor, prevCursor) { + var now = new Date().getTime(); + var vMovement = !prevCursor || cursor.row != prevCursor.row; + var hMovement = !prevCursor || cursor.column != prevCursor.column; + if (!cursorMovedTime || vMovement || hMovement) { + editor.$blockScrolling += 1; + editor.moveCursorToPosition(cursor); + editor.$blockScrolling -= 1; + cursorMovedTime = now; + cursorPointOnCaretMoved = {x: x, y: y}; + } else { + var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y); + if (distance > SCROLL_CURSOR_HYSTERESIS) { + cursorMovedTime = null; + } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) { + editor.renderer.scrollCursorIntoView(); + cursorMovedTime = null; + } + } + } + + function autoScroll(cursor, prevCursor) { + var now = new Date().getTime(); + var lineHeight = editor.renderer.layerConfig.lineHeight; + var characterWidth = editor.renderer.layerConfig.characterWidth; + var editorRect = editor.renderer.scroller.getBoundingClientRect(); + var offsets = { + x: { + left: x - editorRect.left, + right: editorRect.right - x + }, + y: { + top: y - editorRect.top, + bottom: editorRect.bottom - y + } + }; + var nearestXOffset = Math.min(offsets.x.left, offsets.x.right); + var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom); + var scrollCursor = {row: cursor.row, column: cursor.column}; + if (nearestXOffset / characterWidth <= 2) { + scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2); + } + if (nearestYOffset / lineHeight <= 1) { + scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1); + } + var vScroll = cursor.row != scrollCursor.row; + var hScroll = cursor.column != scrollCursor.column; + var vMovement = !prevCursor || cursor.row != prevCursor.row; + if (vScroll || (hScroll && !vMovement)) { + if (!autoScrollStartTime) + autoScrollStartTime = now; + else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY) + editor.renderer.scrollCursorIntoView(scrollCursor); + } else { + autoScrollStartTime = null; + } + } + + function onDragInterval() { + var prevCursor = dragCursor; + dragCursor = editor.renderer.screenToTextCoordinates(x, y); + scrollCursorIntoView(dragCursor, prevCursor); + autoScroll(dragCursor, prevCursor); + } function addDragMarker() { range = editor.selection.toOrientedRange(); dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle()); editor.clearSelection(); + if (editor.isFocused()) + editor.renderer.$cursorLayer.setBlinking(false); clearInterval(timerId); timerId = setInterval(onDragInterval, 20); counter = 0; event.addListener(document, "mousemove", onMouseMove); } + function clearDragMarker() { clearInterval(timerId); editor.session.removeMarker(dragSelectionMarker); dragSelectionMarker = null; + editor.$blockScrolling += 1; editor.selection.fromOrientedRange(range); + editor.$blockScrolling -= 1; + if (editor.isFocused() && !isInternal) + editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly()); + range = null; counter = 0; + autoScrollStartTime = null; + cursorMovedTime = null; event.removeListener(document, "mousemove", onMouseMove); } var onMouseMoveTimer = null; @@ -4628,9 +4736,120 @@ var DragdropHandler = function(mouseHandler) { }, 20); } } -}; + + function canAccept(dataTransfer) { + var types = dataTransfer.types; + return !types || Array.prototype.some.call(types, function(type) { + return type == 'text/plain' || type == 'Text'; + }); + } + + function getDropEffect(e) { + var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized']; + var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized']; + + var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey; + var effectAllowed = "uninitialized"; + try { + effectAllowed = e.dataTransfer.effectAllowed.toLowerCase(); + } catch (e) {} + var dropEffect = "none"; + + if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0) + dropEffect = "copy"; + else if (moveAllowed.indexOf(effectAllowed) >= 0) + dropEffect = "move"; + else if (copyAllowed.indexOf(effectAllowed) >= 0) + dropEffect = "copy"; + + return dropEffect; + } +} + +(function() { + + this.dragWait = function() { + var interval = (new Date()).getTime() - this.mousedownEvent.time; + if (interval > this.editor.getDragDelay()) + this.startDrag(); + }; + + this.dragWaitEnd = function() { + var target = this.editor.container; + target.draggable = false; + this.startSelect(this.mousedownEvent.getDocumentPosition()); + this.selectEnd(); + }; + + this.dragReadyEnd = function(e) { + this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()); + this.editor.unsetStyle("ace_dragging"); + this.dragWaitEnd(); + }; + + this.startDrag = function(){ + this.cancelDrag = false; + var target = this.editor.container; + target.draggable = true; + this.editor.renderer.$cursorLayer.setBlinking(false); + this.editor.setStyle("ace_dragging"); + this.setState("dragReady"); + }; + + this.onMouseDrag = function(e) { + var target = this.editor.container; + if (useragent.isIE && this.state == "dragReady") { + var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); + if (distance > 3) + target.dragDrop(); + } + if (this.state === "dragWait") { + var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); + if (distance > 0) { + target.draggable = false; + this.startSelect(this.mousedownEvent.getDocumentPosition()); + } + } + }; + + this.onMouseDown = function(e) { + if (!this.$dragEnabled) + return; + this.mousedownEvent = e; + var editor = this.editor; + + var inSelection = e.inSelection(); + var button = e.getButton(); + var clickCount = e.domEvent.detail || 1; + if (clickCount === 1 && button === 0 && inSelection) { + this.mousedownEvent.time = (new Date()).getTime(); + var eventTarget = e.domEvent.target || e.domEvent.srcElement; + if ("unselectable" in eventTarget) + eventTarget.unselectable = "on"; + if (editor.getDragDelay()) { + if (useragent.isWebKit) { + self.cancelDrag = true; + var mouseTarget = editor.container; + mouseTarget.draggable = true; + } + this.setState("dragWait"); + } else { + this.startDrag(); + } + this.captureMouse(e, this.onMouseDrag.bind(this)); + e.defaultPrevented = true; + } + }; + +}).call(DragdropHandler.prototype); + + +function calcDistance(ax, ay, bx, by) { + return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); +} exports.DragdropHandler = DragdropHandler; + }); ace.define('ace/config', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/lib/net', 'ace/lib/event_emitter'], function(require, exports, module) { @@ -4683,7 +4902,7 @@ exports.moduleUrl = function(name, component) { var sep = component == "snippets" ? "/" : "-"; var base = parts[parts.length - 1]; if (sep == "-") { - var re = new RegExp("^" + component + "[\-_]|[\-_]" + component + "$", "g"); + var re = new RegExp("^" + component + "[\\-_]|[\\-_]" + component + "$", "g"); base = base.replace(re, ""); } @@ -4714,7 +4933,7 @@ exports.loadModule = function(moduleName, onLoad) { try { module = require(moduleName); - } catch (e) {}; + } catch (e) {} if (module && !exports.$loading[moduleName]) return onLoad && onLoad(module); @@ -4814,8 +5033,11 @@ var optionsProvider = { if (this["$" + name] === value) return; var opt = this.$options[name]; - if (!opt) + if (!opt) { + if (typeof console != "undefined" && console.warn) + console.warn('misspelled option "' + name + '"'); return undefined; + } if (opt.forwardTo) return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value); @@ -4826,8 +5048,11 @@ var optionsProvider = { }, getOption: function(name) { var opt = this.$options[name]; - if (!opt) + if (!opt) { + if (typeof console != "undefined" && console.warn) + console.warn('misspelled option "' + name + '"'); return undefined; + } if (opt.forwardTo) return this[opt.forwardTo] && this[opt.forwardTo].getOption(name); return opt && opt.get ? opt.get.call(this) : this["$" + name]; @@ -4866,7 +5091,7 @@ exports.setDefaultValue = function(path, name, value) { var opts = defaultOptions[path] || (defaultOptions[path] = {}); if (opts[name]) { if (opts.forwardTo) - exports.setDefaultValue(opts.forwardTo, name, value) + exports.setDefaultValue(opts.forwardTo, name, value); else opts[name].value = value; } @@ -4939,6 +5164,7 @@ EventEmitter._dispatchEvent = function(eventName, e) { if (!e.preventDefault) e.preventDefault = preventDefault; + listeners = listeners.slice(); for (var i=0; i= SPACE) - tokens.pop(); wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize); @@ -6368,6 +6599,8 @@ var EditSession = function(text, mode) { var displayLength = tokens.length; var lastSplit = 0, lastDocSplit = 0; + var isCode = this.$wrapAsCode; + function addSplit(screenPos) { var displayed = tokens.slice(lastSplit, screenPos); var len = displayed.length; @@ -6386,16 +6619,11 @@ var EditSession = function(text, mode) { while (displayLength - lastSplit > wrapLimit) { var split = lastSplit + wrapLimit; - if (tokens[split] >= SPACE) { - while (tokens[split] >= SPACE) { - split ++; - } + if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) { addSplit(split); continue; } - if (tokens[split] == PLACEHOLDER_START - || tokens[split] == PLACEHOLDER_BODY) - { + if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) { for (split; split != lastSplit - 1; split--) { if (tokens[split] == PLACEHOLDER_START) { break; @@ -6407,8 +6635,7 @@ var EditSession = function(text, mode) { } split = lastSplit + wrapLimit; for (split; split < tokens.length; split++) { - if (tokens[split] != PLACEHOLDER_BODY) - { + if (tokens[split] != PLACEHOLDER_BODY) { break; } } @@ -6418,12 +6645,21 @@ var EditSession = function(text, mode) { addSplit(split); continue; } - var minSplit = Math.max(split - 10, lastSplit - 1); + var minSplit = Math.max(split - (isCode ? 10 : wrapLimit-(wrapLimit>>2)), lastSplit - 1); while (split > minSplit && tokens[split] < PLACEHOLDER_START) { split --; } - while (split > minSplit && tokens[split] == PUNCTUATION) { - split --; + if (isCode) { + while (split > minSplit && tokens[split] < PLACEHOLDER_START) { + split --; + } + while (split > minSplit && tokens[split] == PUNCTUATION) { + split --; + } + } else { + while (split > minSplit && tokens[split] < SPACE) { + split --; + } } if (split > minSplit) { addSplit(++split); @@ -6789,6 +7025,15 @@ config.defineOptions(EditSession.prototype, "session", { return this.getUseWrapMode() ? this.getWrapLimitRange().min || "free" : "off"; }, handlesSet: true + }, + wrapMethod: { + set: function(val) { + if (val == "auto") + this.$wrapAsCode = this.$mode.type != "text"; + else + this.$wrapAsCode = val != "text"; + }, + initialValue: "auto" }, firstLineNumber: { set: function() {this._emit("changeBreakpoint");}, @@ -7036,7 +7281,7 @@ var Selection = function(session) { } else { rowEnd = rowStart; } - if (excludeLastChar) + if (excludeLastChar === true) return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length); else return new Range(rowStart, 0, rowEnd + 1, 0); @@ -7665,7 +7910,7 @@ var TokenIterator = require("../token_iterator").TokenIterator; var Range = require("../range").Range; var Mode = function() { - this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules()); + this.HighlightRules = TextHighlightRules; this.$behaviour = new Behaviour(); }; @@ -7686,6 +7931,10 @@ var Mode = function() { ); this.getTokenizer = function() { + if (!this.$tokenizer) { + this.$highlightRules = new this.HighlightRules(); + this.$tokenizer = new Tokenizer(this.$highlightRules.getRules()); + } return this.$tokenizer; }; @@ -7895,17 +8144,16 @@ var Mode = function() { }; this.createModeDelegates = function (mapping) { - if (!this.$embeds) { - return; - } + this.$embeds = []; this.$modes = {}; - for (var i = 0; i < this.$embeds.length; i++) { - if (mapping[this.$embeds[i]]) { - this.$modes[this.$embeds[i]] = new mapping[this.$embeds[i]](); + for (var i in mapping) { + if (mapping[i]) { + this.$embeds.push(i); + this.$modes[i] = new mapping[i](); } } - var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction']; + var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction', 'getCompletions']; for (var i = 0; i < delegations.length; i++) { (function(scope) { @@ -7978,6 +8226,24 @@ var Mode = function() { return completionKeywords.concat(this.$keywordList || []); }; + this.$createKeywordList = function() { + if (!this.$highlightRules) + this.getTokenizer(); + return this.$keywordList = this.$highlightRules.$keywordList || []; + } + + this.getCompletions = function(state, session, pos, prefix) { + var keywords = this.$keywordList || this.$createKeywordList(); + return keywords.map(function(word) { + return { + name: word, + value: word, + score: 0, + meta: "keyword" + }; + }); + }; + }).call(Mode.prototype); exports.Mode = Mode; @@ -8061,6 +8327,10 @@ var Tokenizer = function(rules) { }; (function() { + this.$setMaxTokenCount = function(m) { + MAX_TOKEN_COUNT = m | 0; + }; + this.$applyToken = function(str) { var values = this.splitRegex.exec(str).slice(1); var types = this.token.apply(this, values); @@ -8434,6 +8704,9 @@ var TextHighlightRules = function() { for (var i = list.length; i--; ) keywords[list[i]] = className; }); + if (Object.getPrototypeOf(keywords)) { + keywords.__proto__ = null; + } this.$keywordList = Object.keys(keywords); map = null; return ignoreCase @@ -8830,6 +9103,8 @@ var Document = function(text) { return end; }; this.remove = function(range) { + if (!range instanceof Range) + range = Range.fromPoints(range.start, range.end); range.start = this.$clipPosition(range.start); range.end = this.$clipPosition(range.end); @@ -8913,6 +9188,8 @@ var Document = function(text) { this._emit("change", { data: delta }); }; this.replace = function(range, text) { + if (!range instanceof Range) + range = Range.fromPoints(range.start, range.end); if (text.length == 0 && range.isEmpty()) return range.start; if (text == this.getTextRange(range)) @@ -9010,6 +9287,7 @@ var Anchor = exports.Anchor = function(doc, row, column) { this.getDocument = function() { return this.document; }; + this.$insertRight = false; this.onChange = function(e) { var delta = e.data; var range = delta.range; @@ -9030,7 +9308,8 @@ var Anchor = exports.Anchor = function(doc, row, column) { if (delta.action === "insertText") { if (start.row === row && start.column <= column) { - if (start.row === end.row) { + if (start.column === column && this.$insertRight) { + } else if (start.row === end.row) { column += end.column - start.column; } else { column -= start.column; @@ -9213,6 +9492,11 @@ var BackgroundTokenizer = function(tokenizer, editor) { this.stop(); this.running = setTimeout(this.$worker, 700); }; + + this.scheduleStart = function() { + if (!this.running) + this.running = setTimeout(this.$worker, 700); + } this.$updateOnChange = function(delta) { var range = delta.range; @@ -9234,7 +9518,6 @@ var BackgroundTokenizer = function(tokenizer, editor) { this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength()); this.stop(); - this.running = setTimeout(this.$worker, 700); }; this.stop = function() { if (this.running) @@ -9519,8 +9802,9 @@ function Folding() { var startColumn = fold.start.column; var endRow = fold.end.row; var endColumn = fold.end.column; - if (startRow == endRow && endColumn - startColumn < 2) - throw "The range has to be at least 2 characters width"; + if (!(startRow < endRow || + startRow == endRow && startColumn <= endColumn - 2)) + throw new Error("The range has to be at least 2 characters width"); var startFold = this.getFoldAt(startRow, startColumn, 1); var endFold = this.getFoldAt(endRow, endColumn, -1); @@ -9531,7 +9815,7 @@ function Folding() { (startFold && !startFold.range.isStart(startRow, startColumn)) || (endFold && !endFold.range.isEnd(endRow, endColumn)) ) { - throw "A fold can't intersect already existing fold" + fold.range + startFold.range; + throw new Error("A fold can't intersect already existing fold" + fold.range + startFold.range); } var folds = this.getFoldsInRange(fold.range); if (folds.length > 0) { @@ -9842,17 +10126,22 @@ function Folding() { depth = 100000; // JSON.stringify doesn't hanle Infinity var foldWidgets = this.foldWidgets; endRow = endRow || this.getLength(); - for (var row = startRow || 0; row < endRow; row++) { + startRow = startRow || 0; + for (var row = startRow; row < endRow; row++) { if (foldWidgets[row] == null) foldWidgets[row] = this.getFoldWidget(row); if (foldWidgets[row] != "start") continue; var range = this.getFoldWidgetRange(row); - if (range && range.end.row <= endRow) try { + var rangeEndRow = range.end.row; + if (range && range.isMultiLine() + && rangeEndRow <= endRow + && range.start.row >= startRow + ) try { var fold = this.addFold("...", range); fold.collapseChildren = depth; - row = range.end.row; + row = rangeEndRow; } catch(e) {} } }; @@ -10035,7 +10324,7 @@ function FoldLine(foldData, folds) { this.addFold = function(fold) { if (fold.sameRow) { if (fold.start.row < this.startRow || fold.endRow > this.endRow) { - throw "Can't add a fold to this FoldLine as it has no connection"; + throw new Error("Can't add a fold to this FoldLine as it has no connection"); } this.folds.push(fold); this.folds.sort(function(a, b) { @@ -10057,7 +10346,7 @@ function FoldLine(foldData, folds) { this.start.row = fold.start.row; this.start.column = fold.start.column; } else { - throw "Trying to add fold to FoldRow that doesn't have a matching row"; + throw new Error("Trying to add fold to FoldRow that doesn't have a matching row"); } fold.foldLine = this; } @@ -10264,7 +10553,7 @@ oop.inherits(Fold, RangeList); return; if (!this.range.containsRange(fold)) - throw "A fold can't intersect already existing fold" + fold.range + this.range; + throw new Error("A fold can't intersect already existing fold" + fold.range + this.range); consumeRange(fold, this.start); var row = fold.start.row, column = fold.start.column; @@ -10286,7 +10575,7 @@ oop.inherits(Fold, RangeList); var afterEnd = this.subFolds[j]; if (cmp == 0) - throw "A fold can't intersect already existing fold" + fold.range + this.range; + throw new Error("A fold can't intersect already existing fold" + fold.range + this.range); var consumedFolds = this.subFolds.splice(i, j - i, fold); fold.setFoldLine(this.foldLine); @@ -10495,11 +10784,16 @@ var RangeList = function() { break; if (r.start.row == startRow && r.start.column >= start.column ) { - - r.start.column += colDiff; - r.start.row += lineDif; + if (r.start.column == start.column && this.$insertRight) { + } else { + r.start.column += colDiff; + r.start.row += lineDif; + } } if (r.end.row == startRow && r.end.column >= start.column) { + if (r.end.column == start.column && this.$insertRight) { + continue; + } if (r.end.column == start.column && colDiff > 0 && i < n - 1) { if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column) r.end.column -= colDiff; @@ -11000,12 +11294,8 @@ var HashHandler = require("../keyboard/hash_handler").HashHandler; var EventEmitter = require("../lib/event_emitter").EventEmitter; var CommandManager = function(platform, commands) { - this.platform = platform; - this.commands = this.byName = {}; - this.commmandKeyBinding = {}; - - this.addCommands(commands); - + HashHandler.call(this, commands, platform); + this.byName = this.commands; this.setDefaultHandler("exec", function(e) { return e.command.exec(e.editor, e.args || {}); }); @@ -11105,7 +11395,26 @@ var useragent = require("../lib/useragent"); function HashHandler(config, platform) { this.platform = platform || (useragent.isMac ? "mac" : "win"); this.commands = {}; - this.commmandKeyBinding = {}; + this.commandKeyBinding = {}; + if (this.__defineGetter__ && this.__defineSetter__ && typeof console != "undefined" && console.error) { + var warned = false; + var warn = function() { + if (!warned) { + warned = true; + console.error("commmandKeyBinding has too many m's. use commandKeyBinding"); + } + }; + this.__defineGetter__("commmandKeyBinding", function() { + warn(); + return this.commandKeyBinding; + }); + this.__defineSetter__("commmandKeyBinding", function(val) { + warn(); + return this.commandKeyBinding = val; + }); + } else { + this.commmandKeyBinding = this.commandKeyBinding; + } this.addCommands(config); }; @@ -11126,7 +11435,7 @@ function HashHandler(config, platform) { var name = (typeof command === 'string' ? command : command.name); command = this.commands[name]; delete this.commands[name]; - var ckb = this.commmandKeyBinding; + var ckb = this.commandKeyBinding; for (var hashId in ckb) { for (var key in ckb[hashId]) { if (ckb[hashId][key] == command) @@ -11143,7 +11452,7 @@ function HashHandler(config, platform) { return; } - var ckb = this.commmandKeyBinding; + var ckb = this.commandKeyBinding; key.split("|").forEach(function(keyPart) { var binding = this.parseKeys(keyPart, command); var hashId = binding.hashId; @@ -11154,6 +11463,9 @@ function HashHandler(config, platform) { this.addCommands = function(commands) { commands && Object.keys(commands).forEach(function(name) { var command = commands[name]; + if (!command) + return; + if (typeof command === "string") return this.bindKey(command, name); @@ -11216,7 +11528,7 @@ function HashHandler(config, platform) { }; this.findKeyCommand = function findKeyCommand(hashId, keyString) { - var ckbr = this.commmandKeyBinding; + var ckbr = this.commandKeyBinding; return ckbr[hashId] && ckbr[hashId][keyString]; }; @@ -11594,7 +11906,7 @@ exports.commands = [{ exec: function(editor) { editor.moveLinesDown(); } }, { name: "del", - bindKey: bindKey("Delete", "Delete|Ctrl-D"), + bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"), exec: function(editor) { editor.remove("right"); }, multiSelectAction: "forEach" }, { @@ -11605,6 +11917,17 @@ exports.commands = [{ ), exec: function(editor) { editor.remove("left"); }, multiSelectAction: "forEach" +}, { + name: "cut_or_delete", + bindKey: bindKey("Shift-Delete", null), + exec: function(editor) { + if (editor.selection.isEmpty()) { + editor.remove("left"); + } else { + return false; + } + }, + multiSelectAction: "forEach" }, { name: "removetolinestart", bindKey: bindKey("Alt-Backspace", "Command-Backspace"), @@ -11768,6 +12091,10 @@ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', mo font-size: 12px;\ line-height: normal;\ color: black;\ +-ms-user-select: none;\ +-moz-user-select: none;\ +-webkit-user-select: none;\ +user-select: none;\ }\ .ace_scroller {\ position: absolute;\ @@ -11783,6 +12110,25 @@ position: absolute;\ box-sizing: border-box;\ cursor: text;\ }\ +.ace_dragging, .ace_dragging * {\ +cursor: move !important;\ +}\ +.ace_dragging .ace_scroller:before{\ +position: absolute;\ +top: 0;\ +left: 0;\ +right: 0;\ +bottom: 0;\ +content: '';\ +background: rgba(250, 250, 250, 0.01);\ +z-index: 1000;\ +}\ +.ace_dragging.ace_dark .ace_scroller:before{\ +background: rgba(0, 0, 0, 0.01);\ +}\ +.ace_selecting, .ace_selecting * {\ +cursor: text !important;\ +}\ .ace_gutter {\ position: absolute;\ overflow : hidden;\ @@ -11824,16 +12170,18 @@ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCA }\ .ace_scrollbar {\ position: absolute;\ -overflow: hidden;\ +overflow-x: hidden;\ overflow-y: auto;\ right: 0;\ top: 0;\ bottom: 0;\ +z-index: 6;\ }\ .ace_scrollbar-inner {\ position: absolute;\ -width: 1px;\ +cursor: text;\ left: 0;\ +top: 0;\ }\ .ace_scrollbar-h {\ position: absolute;\ @@ -11842,11 +12190,7 @@ overflow-y: hidden;\ right: 0;\ left: 0;\ bottom: 0;\ -}\ -.ace_scrollbar-inner {\ -position: absolute;\ -height: 1px;\ -left: 0;\ +z-index: 6;\ }\ .ace_print-margin {\ position: absolute;\ @@ -11868,12 +12212,14 @@ overflow: hidden;\ font: inherit;\ padding: 0 1px;\ margin: 0 -1px;\ +text-indent: -1em;\ }\ .ace_text-input.ace_composition {\ background: #f8f8f8;\ color: #111;\ z-index: 1000;\ opacity: 1;\ +text-indent: 0;\ }\ .ace_layer {\ z-index: 1;\ @@ -11911,6 +12257,14 @@ position: absolute;\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ +border-left: 2px solid\ +}\ +.ace_slim-cursors .ace_cursor {\ +border-left-width: 1px;\ +}\ +.ace_overwrite-cursors .ace_cursor {\ +border-left-width: 0px;\ +border-bottom: 1px solid;\ }\ .ace_hidden-cursors .ace_cursor {\ opacity: 0.2;\ @@ -11984,9 +12338,6 @@ url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08 background-repeat: no-repeat, repeat-x;\ background-position: center center, top left;\ }\ -.ace_editor.ace_dragging .ace_content {\ -cursor: move;\ -}\ .ace_gutter-tooltip {\ background-color: #FFF;\ background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\ @@ -11999,7 +12350,7 @@ display: inline-block;\ max-width: 500px;\ padding: 4px;\ position: fixed;\ -z-index: 300;\ +z-index: 999999;\ -moz-box-sizing: border-box;\ -webkit-box-sizing: border-box;\ box-sizing: border-box;\ @@ -12123,7 +12474,7 @@ var VirtualRenderer = function(container, theme) { var _self = this; this.container = container || dom.createElement("div"); - this.$keepTextAreaAtCursor = !useragent.isIE; + this.$keepTextAreaAtCursor = true; dom.addCssClass(this.container, "ace_editor"); @@ -12194,8 +12545,8 @@ var VirtualRenderer = function(container, theme) { firstRow : 0, firstRowScreen: 0, lastRow : 0, - lineHeight : 1, - characterWidth : 1, + lineHeight : 0, + characterWidth : 0, minHeight : 1, maxHeight : 1, offset : 0, @@ -12330,7 +12681,7 @@ var VirtualRenderer = function(container, theme) { if (force) this.$renderChanges(changes, true); else - this.$loop.schedule(changes || this.$changes); + this.$loop.schedule(changes | this.$changes); if (this.resizing) this.resizing = 0; @@ -12339,6 +12690,12 @@ var VirtualRenderer = function(container, theme) { this.$updateCachedSize = function(force, gutterWidth, width, height) { var changes = 0; var size = this.$size; + var oldSize = { + width: size.width, + height: size.height, + scrollerHeight: size.scrollerHeight, + scrollerWidth: size.scrollerWidth + }; if (height && (force || size.height != height)) { size.height = height; changes = this.CHANGE_SIZE; @@ -12376,7 +12733,7 @@ var VirtualRenderer = function(container, theme) { } if (changes) - this._signal("resize"); + this._signal("resize", oldSize); return changes; }; @@ -12384,7 +12741,7 @@ var VirtualRenderer = function(container, theme) { this.onGutterResize = function() { var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0; if (gutterWidth != this.gutterWidth) - this.$changes != this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height); + this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height); if (this.session.getUseWrapMode() && this.adjustWrapLimit()) this.$loop.schedule(this.CHANGE_FULL); @@ -12590,8 +12947,13 @@ var VirtualRenderer = function(container, theme) { this.$changes |= changes; return; } - if (!this.$size.width) + if (!this.$size.width) { + this.$changes |= changes; return this.onResize(true); + } + if (!this.lineHeight) { + this.$textLayer.checkForSizeChanges(); + } this._signal("beforeRender"); if (changes & this.CHANGE_FULL || @@ -12608,7 +12970,6 @@ var VirtualRenderer = function(container, theme) { this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left"; } if (changes & this.CHANGE_FULL) { - this.$textLayer.checkForSizeChanges(); this.$updateScrollBarV(); this.$updateScrollBarH(); this.$textLayer.update(this.layerConfig); @@ -12817,7 +13178,7 @@ var VirtualRenderer = function(container, theme) { this.$getLongestLine = function() { var charCount = this.session.getScreenWidth(); - if (this.$textLayer.showInvisibles) + if (this.showInvisibles && !this.session.$useWrapMode) charCount += 1; return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth)); @@ -12999,6 +13360,10 @@ var VirtualRenderer = function(container, theme) { this.scrollLeft = scrollLeft; this.$loop.schedule(this.CHANGE_H_SCROLL); }; + this.scrollTo = function(x, y) { + this.session.setScrollTop(y); + this.session.setScrollLeft(y); + }; this.scrollBy = function(deltaX, deltaY) { deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY); deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX); @@ -13010,7 +13375,10 @@ var VirtualRenderer = function(container, theme) { - this.layerConfig.maxHeight - (this.$size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd < -1 + this.scrollMargin.bottom) return true; - if (deltaX) + if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left) + return true; + if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth + - this.layerConfig.width < -1 + this.scrollMargin.right) return true; }; @@ -13109,7 +13477,7 @@ var VirtualRenderer = function(container, theme) { dom.addCssClass(_self.container, module.cssClass); dom.setCssClass(_self.container, "ace_dark", module.isDark); - var padding = module.padding || 4; + var padding = "padding" in module ? module.padding : 4; if (_self.$padding && padding != _self.$padding) _self.setPadding(padding); if (_self.$size) { @@ -13124,12 +13492,15 @@ var VirtualRenderer = function(container, theme) { this.getTheme = function() { return this.$themeValue; }; - this.setStyle = function setStyle(style, include) { + this.setStyle = function(style, include) { dom.setCssClass(this.container, style, include != false); }; - this.unsetStyle = function unsetStyle(style) { + this.unsetStyle = function(style) { dom.removeCssClass(this.container, style); }; + this.setMouseCursor = function(cursorStyle) { + this.content.style.cursor = cursorStyle; + }; this.destroy = function() { this.$textLayer.destroy(); this.$cursorLayer.destroy(); @@ -13255,6 +13626,12 @@ config.defineOptions(VirtualRenderer.prototype, "renderer", { }, initialValue: 0, handlesSet: true + }, + fixedWidthGutter: { + set: function(val) { + this.$gutterLayer.$fixedWidth = !!val; + this.$loop.schedule(this.CHANGE_GUTTER); + } } }); @@ -13279,6 +13656,8 @@ var Gutter = function(parentEl) { this.$annotations = []; this.$updateAnnotations = this.$updateAnnotations.bind(this); + + this.$cells = []; }; (function() { @@ -13348,11 +13727,9 @@ var Gutter = function(parentEl) { }; this.update = function(config) { - var emptyAnno = {className: ""}; - var html = []; - var i = config.firstRow; + var firstRow = config.firstRow; var lastRow = config.lastRow; - var fold = this.session.getNextFoldLine(i); + var fold = this.session.getNextFoldLine(firstRow); var foldStart = fold ? fold.start.row : Infinity; var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets; var breakpoints = this.session.$breakpoints; @@ -13360,48 +13737,89 @@ var Gutter = function(parentEl) { var firstLineNumber = this.session.$firstLineNumber; var lastLineNumber = 0; + var cell = null; + var index = -1; + var row = firstRow; while (true) { - if(i > foldStart) { - i = fold.end.row + 1; - fold = this.session.getNextFoldLine(i, fold); - foldStart = fold ?fold.start.row :Infinity; + if (row > foldStart) { + row = fold.end.row + 1; + fold = this.session.getNextFoldLine(row, fold); + foldStart = fold ? fold.start.row : Infinity; } - if(i > lastRow) + if (row > lastRow) { + while (this.$cells.length > index + 1) { + cell = this.$cells.pop(); + this.element.removeChild(cell.element); + } break; + } - var annotation = this.$annotations[i] || emptyAnno; - html.push( - "
", - lastLineNumber = i + firstLineNumber - ); + cell = this.$cells[++index]; + if (!cell) { + cell = {element: null, textNode: null, foldWidget: null}; + cell.element = dom.createElement("div"); + cell.textNode = document.createTextNode(''); + cell.element.appendChild(cell.textNode); + this.element.appendChild(cell.element); + this.$cells[index] = cell; + } + + var className = "ace_gutter-cell "; + if (breakpoints[row]) + className += breakpoints[row]; + if (decorations[row]) + className += decorations[row]; + if (this.$annotations[row]) + className += this.$annotations[row].className; + if (cell.element.className != className) + cell.element.className = className; + + var height = this.session.getRowLength(row) * config.lineHeight + "px"; + if (height != cell.element.style.height) + cell.element.style.height = height; + + var text = lastLineNumber = row + firstLineNumber; + if (text != cell.textNode.data) + cell.textNode.data = text; if (foldWidgets) { - var c = foldWidgets[i]; + var c = foldWidgets[row]; if (c == null) - c = foldWidgets[i] = this.session.getFoldWidget(i); - if (c) - html.push( - "" - ); + c = foldWidgets[row] = this.session.getFoldWidget(row); } - html.push("
"); + if (c) { + if (!cell.foldWidget) { + cell.foldWidget = dom.createElement("span"); + cell.element.appendChild(cell.foldWidget); + } + var className = "ace_fold-widget ace_" + c; + if (c == "start" && row == foldStart && row < fold.end.row) + className += " ace_closed"; + else + className += " ace_open"; + if (cell.foldWidget.className != className) + cell.foldWidget.className = className; - i++; + var height = config.lineHeight + "px"; + if (cell.foldWidget.style.height != height) + cell.foldWidget.style.height = height; + } else { + if (cell.foldWidget != null) { + cell.element.removeChild(cell.foldWidget); + cell.foldWidget = null; + } + } + + row++; } - this.element = dom.setInnerHtml(this.element, html.join("")); this.element.style.height = config.minHeight + "px"; - - if (this.session.$useWrapMode) + + if (this.$fixedWidth || this.session.$useWrapMode) lastLineNumber = this.session.getLength(); - - var gutterWidth = ("" + lastLineNumber).length * config.characterWidth; + + var gutterWidth = lastLineNumber.toString().length * config.characterWidth; var padding = this.$padding || this.$computePadding(); gutterWidth += padding.left + padding.right; if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) { @@ -13411,6 +13829,8 @@ var Gutter = function(parentEl) { } }; + this.$fixedWidth = false; + this.$showFoldWidgets = true; this.setShowFoldWidgets = function(show) { if (show) @@ -13661,11 +14081,11 @@ var Text = function(parentEl) { }; this.getLineHeight = function() { - return this.$characterSize.height || 1; + return this.$characterSize.height || 0; }; this.getCharacterWidth = function() { - return this.$characterSize.width || 1; + return this.$characterSize.width || 0; }; this.checkForSizeChanges = function() { @@ -13748,8 +14168,7 @@ var Text = function(parentEl) { style.position = "fixed"; style.overflow = "visible"; style.whiteSpace = "nowrap"; - - measureNode.innerHTML = "X"; + measureNode.innerHTML = lang.stringRepeat("X", 100); var container = this.element.parentNode; while (container && !dom.hasCssClass(container, "ace_editor")) @@ -13765,7 +14184,7 @@ var Text = function(parentEl) { var size = { height: rect.height, - width: rect.width + width: rect.width / 100 }; if (size.width == 0 || size.height == 0) return null; @@ -14035,9 +14454,9 @@ var Text = function(parentEl) { return screenColumn + value.length; }; - this.renderIndentGuide = function(stringBuilder, value) { + this.renderIndentGuide = function(stringBuilder, value, max) { var cols = value.search(this.$indentGuideRe); - if (cols <= 0) + if (cols <= 0 || cols >= max) return value; if (value[0] == " ") { cols -= cols % this.tabSize; @@ -14061,7 +14480,7 @@ var Text = function(parentEl) { var value = token.value; if (i == 0 && this.displayIndentGuides) { chars = value.length; - value = this.renderIndentGuide(stringBuilder, value); + value = this.renderIndentGuide(stringBuilder, value, splitChars); if (!value) continue; chars -= value.length; @@ -14433,12 +14852,16 @@ var ScrollBarV = function(parent, renderer) { parent.appendChild(this.element); renderer.$scrollbarWidth = this.width = dom.scrollbarWidth(parent.ownerDocument); + renderer.$scrollbarWidth = + this.width = dom.scrollbarWidth(parent.ownerDocument); this.fullWidth = this.width; + this.inner.style.width = this.element.style.width = (this.width || 15) + 5 + "px"; this.setVisible(false); this.element.style.overflowY = "scroll"; event.addListener(this.element, "scroll", this.onScrollV.bind(this)); + event.addListener(this.element, "mousedown", event.preventDefault); }; var ScrollBarH = function(parent, renderer) { @@ -14452,11 +14875,13 @@ var ScrollBarH = function(parent, renderer) { parent.appendChild(this.element); this.height = renderer.$scrollbarWidth; this.fullHeight = this.height; + this.inner.style.height = this.element.style.height = (this.height || 15) + 5 + "px"; this.setVisible(false); this.element.style.overflowX = "scroll"; event.addListener(this.element, "scroll", this.onScrollH.bind(this)); + event.addListener(this.element, "mousedown", event.preventDefault); }; (function() { @@ -14698,7 +15123,7 @@ var EditSession = require("./edit_session").EditSession; this.rangeCount = 0; }; this.getAllRanges = function() { - return this.rangeList.ranges.concat(); + return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()]; }; this.splitIntoLines = function () { @@ -14967,7 +15392,7 @@ var Editor = require("./editor").Editor; this.multiSelect.toSingleRange(); }; - this.getCopyText = function() { + this.getSelectedText = function() { var text = ""; if (this.inMultiSelectMode && !this.inVirtualSelectionMode) { var ranges = this.multiSelect.rangeList.ranges; @@ -14982,7 +15407,6 @@ var Editor = require("./editor").Editor; } else if (!this.selection.isEmpty()) { text = this.session.getTextRange(this.getSelectionRange()); } - this._signal("copy", text); return text; }; this.onPaste = function(text) { @@ -15109,8 +15533,9 @@ var Editor = require("./editor").Editor; var range = sel.toOrientedRange(); if (range.isEmpty()) { var range = session.getWordRange(range.start.row, range.start.column); - range.cursor = range.end; + range.cursor = dir == -1 ? range.start : range.end; this.multiSelect.addRange(range); + return; } var needle = session.getTextRange(range); @@ -15286,23 +15711,22 @@ function MultiSelect(editor) { function addAltCursorListeners(editor){ var el = editor.textInput.getElement(); var altCursor = false; - var contentEl = editor.renderer.content; event.addListener(el, "keydown", function(e) { if (e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey)) { if (!altCursor) { - contentEl.style.cursor = "crosshair"; + editor.renderer.setMouseCursor("crosshair"); altCursor = true; } } else if (altCursor) { - contentEl.style.cursor = ""; + reset(); } }); event.addListener(el, "keyup", reset); event.addListener(el, "blur", reset); - function reset() { + function reset(e) { if (altCursor) { - contentEl.style.cursor = ""; + editor.renderer.setMouseCursor(""); altCursor = false; } } @@ -15995,11 +16419,7 @@ background-color: #6B72E6;\ background-color: #FFFFFF;\ }\ .ace-tm .ace_cursor {\ -border-left: 2px solid black;\ -}\ -.ace-tm .ace_overwrite-cursors .ace_cursor {\ -border-left: 0px;\ -border-bottom: 1px solid black;\ +color: black;\ }\ .ace-tm .ace_invisible {\ color: rgb(191, 191, 191);\ diff --git a/lib/client/edit/theme-tomorrow_night_blue.js b/lib/client/edit/theme-tomorrow_night_blue.js index 30e1146e..2587658a 100644 --- a/lib/client/edit/theme-tomorrow_night_blue.js +++ b/lib/client/edit/theme-tomorrow_night_blue.js @@ -48,11 +48,7 @@ color: #FFFFFF\ color: #FFFFFF\ }\ .ace-tomorrow-night-blue .ace_cursor {\ -border-left: 2px solid #FFFFFF\ -}\ -.ace-tomorrow-night-blue .ace_overwrite-cursors .ace_cursor {\ -border-left: 0px;\ -border-bottom: 1px solid #FFFFFF\ +color: #FFFFFF\ }\ .ace-tomorrow-night-blue .ace_marker-layer .ace_selection {\ background: #003F8E\