From 911cbb3bfba594464dc521e77166ea3b96551a07 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 2 Feb 2013 18:13:57 +0400 Subject: [PATCH 01/11] improve event_emitter - add once - _signal = fast _emit without side effects (preventdefault) - capturing argument for addListener --- lib/ace/lib/event_emitter.js | 48 ++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/lib/ace/lib/event_emitter.js b/lib/ace/lib/event_emitter.js index 5f4bec86..e572df5e 100644 --- a/lib/ace/lib/event_emitter.js +++ b/lib/ace/lib/event_emitter.js @@ -32,11 +32,13 @@ define(function(require, exports, module) { "use strict"; var EventEmitter = {}; +var stopPropagation = function() { this.propagationStopped = true; }; +var preventDefault = function() { this.defaultPrevented = true; }; EventEmitter._emit = EventEmitter._dispatchEvent = function(eventName, e) { - this._eventRegistry = this._eventRegistry || {}; - this._defaultHandlers = this._defaultHandlers || {}; + this._eventRegistry || (this._eventRegistry = {}); + this._defaultHandlers || (this._defaultHandlers = {}); var listeners = this._eventRegistry[eventName] || []; var defaultHandler = this._defaultHandlers[eventName]; @@ -48,18 +50,12 @@ EventEmitter._dispatchEvent = function(eventName, e) { if (!e.type) e.type = eventName; - - if (!e.stopPropagation) { - e.stopPropagation = function() { - this.propagationStopped = true; - }; - } - - if (!e.preventDefault) { - e.preventDefault = function() { - this.defaultPrevented = true; - }; - } + if (!e.stopPropagation) + e.stopPropagation = stopPropagation; + if (!e.preventDefault) + e.preventDefault = preventDefault; + if (!e.target) + e.target = this; for (var i=0; i Date: Sun, 3 Feb 2013 00:57:37 +0400 Subject: [PATCH 02/11] add afterExec event --- lib/ace/commands/command_manager.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/ace/commands/command_manager.js b/lib/ace/commands/command_manager.js index 86a668e5..b3e0fc6d 100644 --- a/lib/ace/commands/command_manager.js +++ b/lib/ace/commands/command_manager.js @@ -8,7 +8,7 @@ var EventEmitter = require("../lib/event_emitter").EventEmitter; /** * @class CommandManager * - * + * **/ /** @@ -16,7 +16,7 @@ var EventEmitter = require("../lib/event_emitter").EventEmitter; * @param {String} platform Identifier for the platform; must be either `'mac'` or `'win'` * @param {Array} commands A list of commands * - * + * * * **/ @@ -27,7 +27,7 @@ var CommandManager = function(platform, commands) { this.commmandKeyBinding = {}; this.addCommands(commands); - + this.setDefaultHandler("exec", function(e) { return e.command.exec(e.editor, e.args || {}); }); @@ -49,11 +49,9 @@ oop.inherits(CommandManager, HashHandler); if (editor && editor.$readOnly && !command.readOnly) return false; - var retvalue = this._emit("exec", { - editor: editor, - command: command, - args: args - }); + var e = {editor: editor, command: command, args: args}; + var retvalue = this._emit("exec", e); + this._signal("afterExec", e); return retvalue === false ? false : true; }; From ed7750e70e86bcff5122d663949aa741043e99cc Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 4 Feb 2013 00:01:19 +0400 Subject: [PATCH 03/11] improve MouseWheel behavior --- lib/ace/mouse/default_handlers.js | 26 ++++++++------------------ lib/ace/virtual_renderer.js | 4 ++-- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/lib/ace/mouse/default_handlers.js b/lib/ace/mouse/default_handlers.js index a6ce5c61..3a7e97af 100644 --- a/lib/ace/mouse/default_handlers.js +++ b/lib/ace/mouse/default_handlers.js @@ -297,28 +297,18 @@ function DefaultHandlers(mouseHandler) { }; this.onMouseWheel = function(ev) { - if (ev.getShiftKey() || ev.getAccelKey()){ + if (ev.getShiftKey() || ev.getAccelKey()) return; - } + 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) { - this.$passScrollEvent = false; - } else { - if (this.$passScrollEvent) - return; - - if (!this.$scrollStopTimeout) { - var self = this; - this.$scrollStopTimeout = setTimeout(function() { - self.$passScrollEvent = true; - self.$scrollStopTimeout = null; - }, 200); - } + if (isScrolable || dt < 200) { + this.$lastScrollTime = t; + editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); + return ev.stop(); } - - editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); - return ev.preventDefault(); }; }).call(DefaultHandlers.prototype); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 1a9e0721..a95f999d 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -1122,9 +1122,9 @@ var VirtualRenderer = function(container, theme) { * @returns {Boolean} **/ this.isScrollableBy = function(deltaX, deltaY) { - if (deltaY < 0 && this.session.getScrollTop() > 0) + if (deltaY < 0 && this.session.getScrollTop() >= 1) return true; - if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight < this.layerConfig.maxHeight) + if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight - this.layerConfig.maxHeight < -1) return true; // todo: handle horizontal scrolling }; From 83cf35e7ea95c8d13fbae7decce7418036e8b021 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 4 Feb 2013 18:06:43 +0400 Subject: [PATCH 04/11] move textarea and gutter-line-highlight to main cursor --- lib/ace/layer/cursor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index bd0219a4..26ade52b 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -170,7 +170,7 @@ var Cursor = function(parentEl) { selections = [{cursor: null}]; } - for (var i = selections.length; i--; ) { + for (var i = 0, n = selections.length; i < n; i++) { var pixelPos = this.getPixelPosition(selections[i].cursor, true); if ((pixelPos.top > config.height + config.offset || pixelPos.top < -config.offset) && i > 1) { From 72eccd528379bf37fe554cc30190c14e2f2fb04f Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 4 Feb 2013 18:07:04 +0400 Subject: [PATCH 05/11] fix typo in fold_handler --- lib/ace/mouse/fold_handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mouse/fold_handler.js b/lib/ace/mouse/fold_handler.js index 315a1d3b..997ff314 100644 --- a/lib/ace/mouse/fold_handler.js +++ b/lib/ace/mouse/fold_handler.js @@ -77,7 +77,7 @@ function FoldHandler(editor) { while (i >= 0) { var c = fw[i]; if (c == null) - c = fw[i] = session.getFoldWidget(); + c = fw[i] = session.getFoldWidget(i); if (c == "start") { var range = session.getFoldWidgetRange(i); From 29d9737b4cc45d28b5ffd7f75bdabcdb40cead66 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 4 Feb 2013 18:07:35 +0400 Subject: [PATCH 06/11] add beforeRender and after render events --- lib/ace/virtual_renderer.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index a95f999d..4700d3f4 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -632,6 +632,7 @@ var VirtualRenderer = function(container, theme) { if (!force && (!changes || !this.session || !this.container.offsetWidth)) return; + this._signal("beforeRender"); // text, scrolling and resize changes can cause the view port size to change if (changes & this.CHANGE_FULL || changes & this.CHANGE_SIZE || @@ -666,12 +667,12 @@ var VirtualRenderer = function(container, theme) { this.$cursorLayer.update(this.layerConfig); this.$moveTextAreaToCursor(); this.$highlightGutterLine && this.$updateGutterLineHighlight(); + this._signal("afterRender"); return; } // scrolling if (changes & this.CHANGE_SCROLL) { - this.$updateScrollBar(); if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) this.$textLayer.update(this.layerConfig); else @@ -682,8 +683,10 @@ var VirtualRenderer = function(container, theme) { this.$markerBack.update(this.layerConfig); this.$markerFront.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig); - this.$moveTextAreaToCursor(); this.$highlightGutterLine && this.$updateGutterLineHighlight(); + this.$moveTextAreaToCursor(); + this.$updateScrollBar(); + this._signal("afterRender"); return; } @@ -717,6 +720,8 @@ var VirtualRenderer = function(container, theme) { if (changes & this.CHANGE_SIZE) this.$updateScrollBar(); + + this._signal("afterRender"); }; this.$computeLayerConfig = function() { @@ -1231,10 +1236,6 @@ var VirtualRenderer = function(container, theme) { this.$composition = null; }; - this._loadTheme = function(name, callback) { - - }; - /** * [Sets a new theme for the editor. `theme` should exist, and be a directory path, like `ace/theme/textmate`.]{: #VirtualRenderer.setTheme} * @param {String} theme The path to a theme From 3cbb8dda5541c6bde67fbf9dbca62e7f04639561 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 4 Feb 2013 18:34:40 +0400 Subject: [PATCH 07/11] when text is wrapped highlight full gutter row and screen row --- lib/ace/edit_session.js | 4 +--- lib/ace/editor.js | 5 ++++- lib/ace/layer/marker.js | 16 +++++++++++++++- lib/ace/virtual_renderer.js | 12 ++++++++++-- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 24a654dd..d521ec85 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -717,9 +717,7 @@ var EditSession = function(text, mode) { clazz = "ace_step"; var range = new Range(startRow, 0, endRow, Infinity); - - var id = this.addMarker(range, clazz, "fullLine", inFront); - range.id = id; + range.id = this.addMarker(range, clazz, "fullLine", inFront); return range; }; diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 517b69b4..93dfd537 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -507,10 +507,13 @@ var Editor = function(renderer, session) { session.removeMarker(session.$highlightLineMarker.id); session.$highlightLineMarker = null; } else if (!session.$highlightLineMarker && highlight) { - session.$highlightLineMarker = session.highlightLines(highlight.row, highlight.row, "ace_active-line"); + var range = new Range(highlight.row, highlight.column, highlight.row, Infinity); + range.id = session.addMarker(range, "ace_active-line", "screenLine"); + session.$highlightLineMarker = range; } else if (highlight) { session.$highlightLineMarker.start.row = highlight.row; session.$highlightLineMarker.end.row = highlight.row; + session.$highlightLineMarker.start.column = highlight.column; session._emit("changeBackMarker"); } }; diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js index c68d3964..9162a501 100644 --- a/lib/ace/layer/marker.js +++ b/lib/ace/layer/marker.js @@ -82,6 +82,8 @@ var Marker = function(parentEl) { marker.renderer(html, range, left, top, config); } else if (marker.type == "fullLine") { this.drawFullLineMarker(html, range, marker.clazz, config); + } else if (marker.type == "screenLine") { + this.drawScreenLineMarker(html, range, marker.clazz, config); } else if (range.isMultiLine()) { if (marker.type == "text") this.drawTextMarker(html, range, marker.clazz, config); @@ -194,7 +196,19 @@ var Marker = function(parentEl) { "top:", top, "px;", "left:0;right:0;'>" ); - } + }; + + this.drawScreenLineMarker = function(stringBuilder, range, clazz, config) { + var top = this.$getTop(range.start.row, config); + var height = config.lineHeight; + + stringBuilder.push( + "
" + ); + }; }).call(Marker.prototype); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 4700d3f4..a6a61653 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -465,8 +465,16 @@ var VirtualRenderer = function(container, theme) { }; this.$updateGutterLineHighlight = function() { - this.$gutterLineHighlight.style.top = this.$cursorLayer.$pixelPos.top - this.layerConfig.offset + "px"; - this.$gutterLineHighlight.style.height = this.layerConfig.lineHeight + "px"; + var pos = this.$cursorLayer.$pixelPos; + var height = this.layerConfig.lineHeight; + if (this.session.getUseWrapMode()) { + var cursor = this.session.selection.getCursor(); + cursor.column = 0; + pos = this.$cursorLayer.getPixelPosition(cursor, true); + height *= this.session.getRowLength(cursor.row); + } + this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px"; + this.$gutterLineHighlight.style.height = height + "px"; }; this.$updatePrintMargin = function() { From bd6dda68f0544f86d9af10a386a7f8ae377d90d1 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 5 Feb 2013 00:28:13 +0400 Subject: [PATCH 08/11] Issue #1232: Scroll editor into browser view on cursor movement --- demo/scrollable-page.html | 4 +++- lib/ace/editor.js | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/demo/scrollable-page.html b/demo/scrollable-page.html index 308208ed..f96c0876 100644 --- a/demo/scrollable-page.html +++ b/demo/scrollable-page.html @@ -96,7 +96,7 @@ require("ace/commands/default_commands").commands.push({ var editor = ace.edit("editor"); editor.setTheme("ace/theme/twilight"); editor.session.setMode("ace/mode/javascript"); - +editor.setAutoScrollEditorIntoView(); var count = 1; function add() { @@ -113,6 +113,8 @@ function add() { editor = ace.edit(el) editor.setTheme(theme) editor.session.setMode("ace/mode/javascript") + + editor.setAutoScrollEditorIntoView() editor.setValue([ "this is editor number: ", count, "\n", diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 93dfd537..0bffed53 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -2109,6 +2109,47 @@ var Editor = function(renderer, session) { this.destroy = function() { this.renderer.destroy(); }; + + this.setAutoScrollEditorIntoView = function() { + var self = this; + var rect; + var shouldScroll = false; + var scrollAnchor = dom.createElement("div"); + scrollAnchor.style.cssText = "position:absolute"; + this.container.insertBefore(scrollAnchor, this.container.firstChild); + this.on("changeSelection", function() { + shouldScroll = true; + }); + // needed to not trigger sync reflow + this.renderer.on("beforeRender", function() { + if (shouldScroll) + rect = self.renderer.container.getBoundingClientRect() + }); + this.renderer.on("afterRender", function() { + if (shouldScroll && rect && self.isFocused()) { + var renderer = self.renderer; + var pos = renderer.$cursorLayer.$pixelPos; + var config = renderer.layerConfig; + var top = pos.top - config.offset; + if (pos.top >= 0 && top + rect.top < 0) { + shouldScroll = true + } else if (pos.top < config.height && + pos.top + rect.top + config.lineHeight > window.innerHeight) { + shouldScroll = false; + } else { + shouldScroll = null; + } + if (shouldScroll != null) { + scrollAnchor.style.top = top + "px"; + scrollAnchor.style.left = pos.left + "px"; + scrollAnchor.style.height = config.lineHeight + "px"; + scrollAnchor.scrollIntoView(shouldScroll); + + } + shouldScroll = rect = null; + } + }); + }; }).call(Editor.prototype); From c6ba1957aaee1bd67f23a2d764a965ac5210a34d Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 6 Feb 2013 01:06:59 +0400 Subject: [PATCH 09/11] add a way for disabling AutoScrollEditorIntoView --- demo/scrollable-page.html | 1 + lib/ace/editor.js | 33 ++++++++++++++++++++++++--------- lib/ace/lib/event_emitter.js | 1 + 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/demo/scrollable-page.html b/demo/scrollable-page.html index f96c0876..dfc48eba 100644 --- a/demo/scrollable-page.html +++ b/demo/scrollable-page.html @@ -88,6 +88,7 @@ require("ace/commands/default_commands").commands.push({ exec: function(editor) { dom.toggleCssClass(document.body, "fullScreen") dom.toggleCssClass(editor.container, "fullScreen") + editor.setAutoScrollEditorIntoView() editor.resize() } }) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 0bffed53..0dd7f721 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -2110,29 +2110,37 @@ var Editor = function(renderer, session) { this.renderer.destroy(); }; - this.setAutoScrollEditorIntoView = function() { - var self = this; + /** + * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element + * @param {Boolean} enable default true + **/ + this.setAutoScrollEditorIntoView = function(enable) { + if (enable === true) + return; var rect; + var self = this; var shouldScroll = false; - var scrollAnchor = dom.createElement("div"); + if (!this.$scrollAnchor) + this.$scrollAnchor = document.createElement("div"); + var scrollAnchor = this.$scrollAnchor; scrollAnchor.style.cssText = "position:absolute"; this.container.insertBefore(scrollAnchor, this.container.firstChild); - this.on("changeSelection", function() { + var onChangeSelection = this.on("changeSelection", function() { shouldScroll = true; }); // needed to not trigger sync reflow - this.renderer.on("beforeRender", function() { + var onBeforeRender = this.renderer.on("beforeRender", function() { if (shouldScroll) - rect = self.renderer.container.getBoundingClientRect() + rect = self.renderer.container.getBoundingClientRect(); }); - this.renderer.on("afterRender", function() { + var onAfterRender = this.renderer.on("afterRender", function() { if (shouldScroll && rect && self.isFocused()) { var renderer = self.renderer; var pos = renderer.$cursorLayer.$pixelPos; var config = renderer.layerConfig; var top = pos.top - config.offset; if (pos.top >= 0 && top + rect.top < 0) { - shouldScroll = true + shouldScroll = true; } else if (pos.top < config.height && pos.top + rect.top + config.lineHeight > window.innerHeight) { shouldScroll = false; @@ -2144,11 +2152,18 @@ var Editor = function(renderer, session) { scrollAnchor.style.left = pos.left + "px"; scrollAnchor.style.height = config.lineHeight + "px"; scrollAnchor.scrollIntoView(shouldScroll); - } shouldScroll = rect = null; } }); + this.setAutoScrollEditorIntoView = function(enable) { + if (enable === false) + return; + delete this.setAutoScrollEditorIntoView; + this.removeEventListener("changeSelection", onChangeSelection); + this.renderer.removeEventListener("afterRender", onAfterRender); + this.renderer.removeEventListener("beforeRender", onBeforeRender); + }; }; }).call(Editor.prototype); diff --git a/lib/ace/lib/event_emitter.js b/lib/ace/lib/event_emitter.js index e572df5e..a359a9a7 100644 --- a/lib/ace/lib/event_emitter.js +++ b/lib/ace/lib/event_emitter.js @@ -106,6 +106,7 @@ EventEmitter.addEventListener = function(eventName, callback, capturing) { if (listeners.indexOf(callback) == -1) listeners[capturing ? "unshift" : "push"](callback); + return callback; }; EventEmitter.removeListener = From 2f55065e8413ee9d048acc22c92e98194ae8c838 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 9 Feb 2013 15:36:01 +0400 Subject: [PATCH 10/11] fix #1239 on('changeScrollTop') argument is an object instead of number --- demo/kitchen-sink/demo.js | 23 ++++++++++++----------- lib/ace/edit_session.js | 8 ++++---- lib/ace/multi_select.js | 36 ++++++++++++++++++------------------ 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 4bc1c35e..08c5098c 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -360,31 +360,32 @@ bindCheckbox("read_only", function(checked) { env.editor.setReadOnly(checked); }); -var secondSession = null; bindDropdown("split", function(value) { var sp = env.split; - if (value == "none") { - if (sp.getSplits() == 2) { - secondSession = sp.getEditor(1).session; - } + if (value == "none") { sp.setSplits(1); } else { var newEditor = (sp.getSplits() == 1); - if (value == "below") { - sp.setOrientation(sp.BELOW); - } else { - sp.setOrientation(sp.BESIDE); - } + sp.setOrientation(value == "below" ? sp.BELOW : sp.BESIDE); sp.setSplits(2); if (newEditor) { - var session = secondSession || sp.getEditor(0).session; + var session = sp.getEditor(0).session; var newSession = sp.setSession(session, 1); newSession.name = session.name; } } }); +function synchroniseScrolling() { + var s1 = env.split.$editors[0].session; + var s2 = env.split.$editors[1].session; + s1.on('changeScrollTop', function(pos) {s2.setScrollTop(pos)}); + s2.on('changeScrollTop', function(pos) {s1.setScrollTop(pos)}); + s1.on('changeScrollLeft', function(pos) {s2.setScrollLeft(pos)}); + s2.on('changeScrollLeft', function(pos) {s1.setScrollLeft(pos)}); +} + bindCheckbox("highlight_token", function(checked) { var editor = env.editor; if (editor.tokenTooltip && !checked) { diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index d521ec85..72a70034 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -997,11 +997,11 @@ var EditSession = function(text, mode) { **/ this.setScrollTop = function(scrollTop) { scrollTop = Math.round(Math.max(0, scrollTop)); - if (this.$scrollTop === scrollTop) + if (this.$scrollTop === scrollTop || isNaN(scrollTop)) return; this.$scrollTop = scrollTop; - this._emit("changeScrollTop", scrollTop); + this._signal("changeScrollTop", scrollTop); }; /** @@ -1018,11 +1018,11 @@ var EditSession = function(text, mode) { **/ this.setScrollLeft = function(scrollLeft) { scrollLeft = Math.round(Math.max(0, scrollLeft)); - if (this.$scrollLeft === scrollLeft) + if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft)) return; this.$scrollLeft = scrollLeft; - this._emit("changeScrollLeft", scrollLeft); + this._signal("changeScrollLeft", scrollLeft); }; /** diff --git a/lib/ace/multi_select.js b/lib/ace/multi_select.js index 52137ddb..9ae3b847 100644 --- a/lib/ace/multi_select.js +++ b/lib/ace/multi_select.js @@ -66,7 +66,7 @@ var EditSession = require("./edit_session").EditSession; // automatically sorted list of ranges this.rangeList = null; - /** + /** * Adds a range to a selection by entering multiselect mode, if necessary. * @param {Range} range The new range to add * @param {Boolean} $blockChangeEvents Whether or not to block changing events @@ -218,7 +218,7 @@ var EditSession = require("./edit_session").EditSession; var start = range.end, end = range.start; else var start = range.start, end = range.end; - + this.addRange(Range.fromPoints(end, end)); this.addRange(Range.fromPoints(start, start)); return; @@ -261,9 +261,9 @@ var EditSession = require("./edit_session").EditSession; }; /** - * + * * Gets list of ranges composing rectangular block on the screen - * + * * @param {Cursor} screenCursor The cursor to use * @param {Anchor} screenAnchor The anchor to use * @param {Boolean} includeEmptyLines If true, this includes ranges inside the block which are empty due to clipping @@ -339,8 +339,8 @@ var EditSession = require("./edit_session").EditSession; var Editor = require("./editor").Editor; (function() { - /** - * + /** + * * Updates the cursor and marker layers. * @method Editor.updateSelectionMarkers * @@ -350,7 +350,7 @@ var Editor = require("./editor").Editor; this.renderer.updateBackMarkers(); }; - /** + /** * Adds the selection and cursor. * @param {Range} orientedRange A range containing a cursor * @returns {Range} @@ -368,7 +368,7 @@ var Editor = require("./editor").Editor; return orientedRange; }; - /** + /** * Removes the selection marker. * @param {Range} The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]]. * @method Editor.removeSelectionMarker @@ -455,12 +455,12 @@ var Editor = require("./editor").Editor; e.preventDefault(); }; - /** + /** * Executes a command for each selection range. * @param {String} cmd The command to execute * @param {String} args Any arguments for the command * @method Editor.forEachSelection - **/ + **/ this.forEachSelection = function(cmd, args) { if (this.inVirtualSelectionMode) return; @@ -491,7 +491,7 @@ var Editor = require("./editor").Editor; this.onSelectionChange(); }; - /** + /** * Removes all the selections except the last added one. * @method Editor.exitMultiSelectMode **/ @@ -522,7 +522,7 @@ var Editor = require("./editor").Editor; if (this.$readOnly) return; - this._emit("paste", text); + this._signal("paste", text); if (!this.inMultiSelectMode || this.inVirtualSelectionMode) return this.insert(text); @@ -547,7 +547,7 @@ var Editor = require("./editor").Editor; * @param {Object} The search options * @param {Boolean} keeps * - * @returns {Number} The cumulative count of all found matches + * @returns {Number} The cumulative count of all found matches * @method Editor.findAll **/ this.findAll = function(needle, options, additive) { @@ -575,11 +575,11 @@ var Editor = require("./editor").Editor; /** * Adds a cursor above or below the active cursor. - * + * * @param {Number} dir The direction of lines to select: -1 for up, 1 for down * @param {Boolean} skip If `true`, removes the active selection range * - * @method Editor.selectMoreLines + * @method Editor.selectMoreLines */ this.selectMoreLines = function(dir, skip) { var range = this.selection.toOrientedRange(); @@ -619,7 +619,7 @@ var Editor = require("./editor").Editor; this.selection.substractPoint(toRemove); }; - /** + /** * Transposes the selected ranges. * @param {Number} dir The direction to rotate selections * @method Editor.transposeSelections @@ -661,7 +661,7 @@ var Editor = require("./editor").Editor; } }; - /** + /** * Finds the next occurence of text in an active selection and adds it to the selections. * @param {Number} dir The direction of lines to select: -1 for up, 1 for down * @param {Boolean} skip If `true`, removes the active selection range @@ -688,7 +688,7 @@ var Editor = require("./editor").Editor; this.multiSelect.substractPoint(range.cursor); }; - /** + /** * Aligns the cursors or selected text. * @method Editor.alignCursors **/ From 1a9686c6b77f9c52c861e262bc3d7d86adbdaf5d Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 18 Feb 2013 21:52:35 +0400 Subject: [PATCH 11/11] fix contextmenu for editor with border --- lib/ace/keyboard/textinput.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index e4def8b1..397a0917 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -374,9 +374,12 @@ var TextInput = function(parentNode, host) { resetSelection(host.selection.isEmpty()); host._emit("nativecontextmenu", {target: host}); 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 move = function(e) { - text.style.left = e.clientX - rect.left - 2 + "px"; - text.style.top = e.clientY - rect.top - 2 + "px"; + text.style.left = e.clientX - left - 2 + "px"; + text.style.top = e.clientY - top - 2 + "px"; }; move(e);