diff --git a/index.html b/index.html index 59504235..9c1b03c9 100644 --- a/index.html +++ b/index.html @@ -938,11 +938,10 @@ if (match) { Debuggex
  • -
    S
    + -webkit-font-smoothing: antialiased; text-align: center; position: absolute;">S Slim Text
  • @@ -952,7 +951,7 @@ if (match) { Decor
  • - Divshot
  • @@ -1050,14 +1049,13 @@ if (match) { RunPHPCode
  • - + InstaEDU
  • - CloudCmd + Cloud Commander
  • md browserify-markdown-editor
  • +
  • + + Siteleaf +
  • +
  • +
    + ColorSublime +
  • +
  • + + iMDone +
  • BakeMyCss
  • +
  • + + Code Combat +
  • +
  • +
    + Spark Core +
  • Sky Edit
  • @@ -1153,7 +1178,7 @@ if (match) {
  • +

    - Your Site Here + Your Site Here
  • diff --git a/lib/ace/ace.js b/lib/ace/ace.js index 773f2279..a2261355 100644 --- a/lib/ace/ace.js +++ b/lib/ace/ace.js @@ -54,6 +54,7 @@ require("./keyboard/hash_handler"); require("./placeholder"); require("./mode/folding/fold_mode"); require("./theme/textmate"); +require("./ext/error_marker"); exports.config = require("./config"); diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index e4a8212e..b3a0c3a0 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -52,6 +52,26 @@ exports.commands = [{ }); }, readOnly: true +}, { + name: "goToNextError", + bindKey: bindKey("Alt-E", "Ctrl-E"), + exec: function(editor) { + config.loadModule("ace/ext/error_marker", function(module) { + module.showErrorMarker(editor, 1); + }); + }, + scrollIntoView: "center", + readOnly: true +}, { + name: "goToPreviousError", + bindKey: bindKey("Alt-Shift-E", "Ctrl-Shift-E"), + exec: function(editor) { + config.loadModule("ace/ext/error_marker", function(module) { + module.showErrorMarker(editor, -1); + }); + }, + scrollIntoView: "center", + readOnly: true }, { name: "selectall", bindKey: bindKey("Ctrl-A", "Command-A"), @@ -165,6 +185,7 @@ exports.commands = [{ exec: function(editor) { editor.getSelection().selectFileStart(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "gotostart", @@ -172,6 +193,7 @@ exports.commands = [{ exec: function(editor) { editor.navigateFileStart(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "selectup", @@ -191,6 +213,7 @@ exports.commands = [{ exec: function(editor) { editor.getSelection().selectFileEnd(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "gotoend", @@ -198,90 +221,105 @@ exports.commands = [{ exec: function(editor) { editor.navigateFileEnd(); }, multiSelectAction: "forEach", readOnly: true, + scrollIntoView: "animate", aceCommandGroup: "fileJump" }, { name: "selectdown", bindKey: bindKey("Shift-Down", "Shift-Down"), exec: function(editor) { editor.getSelection().selectDown(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "golinedown", bindKey: bindKey("Down", "Down|Ctrl-N"), exec: function(editor, args) { editor.navigateDown(args.times); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectwordleft", bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"), exec: function(editor) { editor.getSelection().selectWordLeft(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotowordleft", bindKey: bindKey("Ctrl-Left", "Option-Left"), exec: function(editor) { editor.navigateWordLeft(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selecttolinestart", bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"), exec: function(editor) { editor.getSelection().selectLineStart(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotolinestart", bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"), exec: function(editor) { editor.navigateLineStart(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectleft", bindKey: bindKey("Shift-Left", "Shift-Left"), exec: function(editor) { editor.getSelection().selectLeft(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotoleft", bindKey: bindKey("Left", "Left|Ctrl-B"), exec: function(editor, args) { editor.navigateLeft(args.times); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectwordright", bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"), exec: function(editor) { editor.getSelection().selectWordRight(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotowordright", bindKey: bindKey("Ctrl-Right", "Option-Right"), exec: function(editor) { editor.navigateWordRight(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selecttolineend", bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"), exec: function(editor) { editor.getSelection().selectLineEnd(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotolineend", bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"), exec: function(editor) { editor.navigateLineEnd(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectright", bindKey: bindKey("Shift-Right", "Shift-Right"), exec: function(editor) { editor.getSelection().selectRight(); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "gotoright", bindKey: bindKey("Right", "Right|Ctrl-F"), exec: function(editor, args) { editor.navigateRight(args.times); }, multiSelectAction: "forEach", + scrollIntoView: "cursor", readOnly: true }, { name: "selectpagedown", diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index a63ceeef..5b2eb747 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -2478,7 +2478,14 @@ config.defineOptions(EditSession.prototype, "session", { this.$wrap = value; }, get: function() { - return this.getUseWrapMode() ? this.getWrapLimitRange().min || "free" : "off"; + if (this.getUseWrapMode()) { + if (this.$wrap == -1) + return "printMargin"; + if (!this.getWrapLimitRange().min) + return "free"; + return this.$wrap; + } + return "off"; }, handlesSet: true }, diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index 474818b2..09d67b95 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -454,13 +454,16 @@ function Folding() { if (expandInner) { this.removeFolds(folds); } else { - // TODO: might need to remove and add folds in one go instead of using + var subFolds = folds; + // TODO: might be better to remove and add folds in one go instead of using // expandFolds several times. - while (folds.length) { - this.expandFolds(folds); - folds = this.getFoldsInRangeList(range); + while (subFolds.length) { + this.expandFolds(subFolds); + subFolds = this.getFoldsInRangeList(range); } } + if (folds.length) + return folds; }; /* diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 6486a881..dfca96b8 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -133,7 +133,6 @@ var Editor = function(renderer, session) { if (command.aceCommandGroup == "fileJump") { if (this.lastFileJumpPos && !this.curOp.selectionChanged) { this.selection.fromJSON(this.lastFileJumpPos); - return; } } this.endOperation(e); @@ -168,7 +167,8 @@ var Editor = function(renderer, session) { this.$opResetTimer.schedule(); this.curOp = { command: commadEvent.command || {}, - args: commadEvent.args + args: commadEvent.args, + scrollTop: this.renderer.scrollTop }; var command = this.curOp.command; @@ -187,16 +187,24 @@ var Editor = function(renderer, session) { case "center": this.renderer.scrollCursorIntoView(null, 0.5); break; + case "animate": case "cursor": this.renderer.scrollCursorIntoView(); break; case "selectionPart": - this.renderer.scrollCursorIntoView(); + var range = this.selection.getRange(); + var config = this.renderer.layerConfig; + if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) { + this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead); + } break; default: break; } + if (command.scrollIntoView == "animate") + this.renderer.animateScrolling(this.curOp.scrollTop); } + this.prevOp = this.curOp; this.curOp = null; } @@ -243,7 +251,6 @@ var Editor = function(renderer, session) { * Sets a new key handler, such as "vim" or "windows". * @param {String} keyboardHandler The new key handler * - * **/ this.setKeyboardHandler = function(keyboardHandler) { if (!keyboardHandler) { @@ -277,7 +284,6 @@ var Editor = function(renderer, session) { * @event changeSession * @param {Object} e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s. * - * **/ /** * Sets a new editsession to use. This method also emits the `'changeSession'` event. @@ -875,7 +881,7 @@ var Editor = function(renderer, session) { } if (text == "\n" || text == "\r\n") { - var line = session.getLine(cursor.row) + var line = session.getLine(cursor.row); if (cursor.column > line.search(/\S|$/)) { var d = line.substr(cursor.column).search(/\S|$/); session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d); @@ -1202,7 +1208,7 @@ var Editor = function(renderer, session) { var state = session.getState(range.start.row); var new_range = session.getMode().transformAction(state, 'deletion', this, session, range); - if (range.end.column == 0) { + if (range.end.column === 0) { var text = session.getTextRange(range); if (text[text.length - 1] == "\n") { var line = session.getLine(range.end.row); @@ -1361,7 +1367,7 @@ var Editor = function(renderer, session) { } } - var line = session.getLine(range.start.row) + var line = session.getLine(range.start.row); var position = range.start; var size = session.getTabSize(); var column = session.documentToScreenColumn(position.row, position.column); @@ -1632,7 +1638,7 @@ var Editor = function(renderer, session) { var last = rows.end.row; var first = rows.start.row; while (i--) { - var rows = ranges[i].collapseRows(); + rows = ranges[i].collapseRows(); if (first - rows.end.row <= 1) first = rows.end.row; else @@ -1736,11 +1742,11 @@ var Editor = function(renderer, session) { var rows = dir * Math.floor(config.height / config.lineHeight); this.$blockScrolling++; - if (select == true) { + if (select === true) { this.selection.$moveSelection(function(){ this.moveCursorBy(rows, 0); }); - } else if (select == false) { + } else if (select === false) { this.selection.moveCursorBy(rows, 0); this.selection.clearSelection(); } @@ -2069,10 +2075,8 @@ var Editor = function(renderer, session) { * Moves the cursor to the end of the current file. Note that this does de-select the current selection. **/ this.navigateFileEnd = function() { - var scrollTop = this.renderer.scrollTop; this.selection.moveCursorFileEnd(); this.clearSelection(); - this.renderer.animateScrolling(scrollTop); }; /** @@ -2080,10 +2084,8 @@ var Editor = function(renderer, session) { * Moves the cursor to the start of the current file. Note that this does de-select the current selection. **/ this.navigateFileStart = function() { - var scrollTop = this.renderer.scrollTop; this.selection.moveCursorFileStart(); this.clearSelection(); - this.renderer.animateScrolling(scrollTop); }; /** @@ -2266,7 +2268,7 @@ var Editor = function(renderer, session) { var scrollTop = this.renderer.scrollTop; this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5); - if (animate != false) + if (animate !== false) this.renderer.animateScrolling(scrollTop); }; diff --git a/lib/ace/ext/error_marker.js b/lib/ace/ext/error_marker.js new file mode 100644 index 00000000..a55e9a25 --- /dev/null +++ b/lib/ace/ext/error_marker.js @@ -0,0 +1,212 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; +var LineWidgets = require("ace/line_widgets").LineWidgets; +var dom = require("ace/lib/dom"); +var Range = require("ace/range").Range; + +function binarySearch(array, needle, comparator) { + var first = 0; + var last = array.length - 1; + + while (first <= last) { + var mid = (first + last) >> 1; + var c = comparator(needle, array[mid]); + if (c > 0) + first = mid + 1; + else if (c < 0) + last = mid - 1; + else + return mid; + } + + // Return the nearest lesser index, "-1" means "0, "-2" means "1", etc. + return -(first + 1); +} + +function findAnnotations(session, row, dir) { + var annotations = session.getAnnotations().sort(Range.comparePoints); + if (!annotations.length) + return; + + var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints); + if (i < 0) + i = -i - 1; + + if (i >= annotations.length - 1) + i = dir > 0 ? 0 : annotations.length - 1; + else if (i === 0 && dir < 0) + i = annotations.length - 1; + + var annotation = annotations[i]; + if (!annotation || !dir) + return; + + if (annotation.row === row) { + do { + annotation = annotations[i += dir]; + } while (annotation && annotation.row === row); + if (!annotation) + return annotations.slice(); + } + + + var matched = []; + row = annotation.row; + do { + matched[dir < 0 ? "unshift" : "push"](annotation); + annotation = annotations[i += dir]; + } while (annotation && annotation.row == row); + return matched.length && matched; +} + +exports.showErrorMarker = function(editor, dir) { + var session = editor.session; + if (!session.widgetManager) { + session.widgetManager = new LineWidgets(session); + session.widgetManager.attach(editor); + } + + var pos = editor.getCursorPosition(); + var row = pos.row; + var oldWidget = session.lineWidgets && session.lineWidgets[row]; + if (oldWidget) { + oldWidget.destroy(); + } else { + row -= dir; + } + var annotations = findAnnotations(session, row, dir); + var gutterAnno; + if (annotations) { + var annotation = annotations[0]; + if (annotation.pos && annotation.column == null) + pos.column = annotation.pos.sc; + pos.row = annotation.row; + gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row]; + } else if (oldWidget) { + return; + } else { + gutterAnno = { + text: ["Looks good!"], + className: "ace_ok" + }; + } + editor.session.unfold(pos.row); + editor.selection.moveCursorToPosition(pos); + editor.selection.clearSelection(); + + var w = { + row: pos.row, + fixedWidth: true, + coverGutter: true, + el: dom.createElement("div") + }; + var el = w.el.appendChild(dom.createElement("div")); + var arrow = w.el.appendChild(dom.createElement("div")); + arrow.className = "error_widget_arrow " + gutterAnno.className; + + var left = editor.renderer.$cursorLayer + .getPixelPosition(pos).left; + arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px"; + + w.el.className = "error_widget_wrapper"; + el.className = "error_widget " + gutterAnno.className; + el.innerHTML = gutterAnno.text.join("
    "); + + var kb = { + handleKeyboard:function(_,hashId, keyString) { + if (hashId === 0 && keyString === "esc") { + w.destroy(); + return true; + } + } + }; + + w.destroy = function() { + if (editor.$mouseHandler.isMousePressed) + return; + editor.keyBinding.removeKeyboardHandler(kb); + session.widgetManager.removeLineWidget(w); + editor.off("changeSelection", w.destroy); + editor.off("changeSession", w.destroy); + editor.off("mouseup", w.destroy); + editor.off("change", w.destroy); + }; + + editor.keyBinding.addKeyboardHandler(kb); + editor.on("changeSelection", w.destroy); + editor.on("changeSession", w.destroy); + editor.on("mouseup", w.destroy); + editor.on("change", w.destroy); + + editor.session.widgetManager.addLineWidget(w); + + w.el.onmousedown = editor.focus.bind(editor); +}; + + +dom.importCssString("\ + .error_widget_wrapper {\ + background: inherit;\ + color: inherit;\ + border:none\ + }\ + .error_widget {\ + border-top: solid 2px;\ + border-bottom: solid 2px;\ + margin: 5px 0;\ + padding: 10px 40px;\ + white-space: pre-wrap;\ + }\ + .error_widget.ace_error, .error_widget_arrow.ace_error{\ + border-color: #ff5a5a\ + }\ + .error_widget.ace_warning, .error_widget_arrow.ace_warning{\ + border-color: #F1D817\ + }\ + .error_widget.ace_info, .error_widget_arrow.ace_info{\ + border-color: #5a5a5a\ + }\ + .error_widget.ace_ok, .error_widget_arrow.ace_ok{\ + border-color: #5aaa5a\ + }\ + .error_widget_arrow {\ + position: absolute;\ + border: solid 5px;\ + border-top-color: transparent!important;\ + border-right-color: transparent!important;\ + border-left-color: transparent!important;\ + top: -5px;\ + }\ +", ""); + +}); \ No newline at end of file diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js index 4d407dfc..36250d2f 100644 --- a/lib/ace/lib/event.js +++ b/lib/ace/lib/event.js @@ -118,8 +118,8 @@ exports.capture = function(el, eventHandler, releaseCaptureHandler) { exports.addMouseWheelListener = function(el, callback) { if ("onmousewheel" in el) { - var factor = 8; exports.addListener(el, "mousewheel", function(e) { + var factor = 8; if (e.wheelDeltaX !== undefined) { e.wheelX = -e.wheelDeltaX / factor; e.wheelY = -e.wheelDeltaY / factor; @@ -131,8 +131,19 @@ exports.addMouseWheelListener = function(el, callback) { }); } else if ("onwheel" in el) { exports.addListener(el, "wheel", function(e) { - e.wheelX = (e.deltaX || 0) * 5; - e.wheelY = (e.deltaY || 0) * 5; + var factor = 0.35; + switch (e.deltaMode) { + case e.DOM_DELTA_PIXEL: + e.wheelX = e.deltaX * factor || 0; + e.wheelY = e.deltaY * factor || 0; + break; + case e.DOM_DELTA_LINE: + case e.DOM_DELTA_PAGE: + e.wheelX = (e.deltaX || 0) * 5; + e.wheelY = (e.deltaY || 0) * 5; + break; + } + callback(e); }); } else { diff --git a/lib/ace/line_widgets.js b/lib/ace/line_widgets.js index 597b3ca2..94ad9ddf 100644 --- a/lib/ace/line_widgets.js +++ b/lib/ace/line_widgets.js @@ -48,12 +48,13 @@ function LineWidgets(session) { this.detach = this.detach.bind(this); this.session.on("change", this.updateOnChange); -}; +} (function() { this.getRowLength = function(row) { + var h; if (this.lineWidgets) - var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; + h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; else h = 0; if (!this.$useWrapMode || !this.$wrapData[row]) { @@ -104,7 +105,8 @@ function LineWidgets(session) { editor.renderer.off("beforeRender", this.measureWidgets); editor.renderer.off("afterRender", this.renderWidgets); - this.session.lineWidgets.forEach(function(w) { + var lineWidgets = this.session.lineWidgets; + lineWidgets && lineWidgets.forEach(function(w) { if (w && w.el && w.el.parentNode) { w._inDocument = false; w.el.parentNode.removeChild(w.el); @@ -113,8 +115,8 @@ function LineWidgets(session) { }; this.updateOnChange = function(e) { - var cells = this.session.lineWidgets; - if (!cells) return; + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; var delta = e.data; var range = delta.range; @@ -124,24 +126,24 @@ function LineWidgets(session) { if (len === 0) { // return } else if (delta.action == "removeText" || delta.action == "removeLines") { - var removed = cells.splice(startRow + 1, len); + var removed = lineWidgets.splice(startRow + 1, len); removed.forEach(function(w) { w && this.removeLineWidget(w); }, this); this.$updateRows(); } else { - var args = Array(len); + var args = new Array(len); args.unshift(startRow, 0); - cells.splice.apply(cells, args); + lineWidgets.splice.apply(lineWidgets, args); this.$updateRows(); } }; this.$updateRows = function() { - var lw = this.session.lineWidgets; - if (!lw) return; + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; var noWidgets = true; - lw.forEach(function(w, i) { + lineWidgets.forEach(function(w, i) { if (w) { noWidgets = false; w.row = i; @@ -149,11 +151,11 @@ function LineWidgets(session) { }); if (noWidgets) this.session.lineWidgets = null; - } + }; this.addLineWidget = function(w) { if (!this.session.lineWidgets) - this.session.lineWidgets = Array(this.session.getLength()) + this.session.lineWidgets = new Array(this.session.getLength()); this.session.lineWidgets[w.row] = w; @@ -164,6 +166,8 @@ function LineWidgets(session) { } if (w.el) { dom.addCssClass(w.el, "ace_lineWidgetContainer"); + w.el.style.position = "absolute"; + w.el.style.zIndex = 5; renderer.container.appendChild(w.el); w._inDocument = true; } @@ -191,7 +195,8 @@ function LineWidgets(session) { if (w.editor && w.editor.destroy) try { w.editor.destroy(); } catch(e){} - this.session.lineWidgets[w.row] = undefined; + if (this.session.lineWidgets) + this.session.lineWidgets[w.row] = undefined; this.session._emit("changeFold", {data:{start:{row: w.row}}}); this.$updateRows(); }; @@ -202,13 +207,13 @@ function LineWidgets(session) { }; this.measureWidgets = function(e, renderer) { - var ws = this.session._changedWidgets; + var changedWidgets = this.session._changedWidgets; var config = renderer.layerConfig; - if (!ws || !ws.length) return; + if (!changedWidgets || !changedWidgets.length) return; var min = Infinity; - for (var i = 0; i < ws.length; i++) { - var w = ws[i].lineWidget; + for (var i = 0; i < changedWidgets.length; i++) { + var w = changedWidgets[i]; if (!w._inDocument) { w._inDocument = true; renderer.container.appendChild(w.el); @@ -242,13 +247,13 @@ function LineWidgets(session) { this.renderWidgets = function(e, renderer) { var config = renderer.layerConfig; - var ws = this.session.lineWidgets; - if (!ws) + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; var first = Math.min(this.firstRow, config.firstRow); - var last = Math.max(this.lastRow, config.lastRow, ws.length); + var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length); - while (first > 0 && !ws[first]) + while (first > 0 && !lineWidgets[first]) first--; this.firstRow = config.firstRow; @@ -256,7 +261,7 @@ function LineWidgets(session) { renderer.$cursorLayer.config = config; for (var i = first; i <= last; i++) { - var w = ws[i]; + var w = lineWidgets[i]; if (!w || !w.el) continue; if (!w._inDocument) { diff --git a/lib/ace/mode/_test/text_javascript.txt b/lib/ace/mode/_test/text_javascript.txt index 6e180795..48d4af7d 100644 --- a/lib/ace/mode/_test/text_javascript.txt +++ b/lib/ace/mode/_test/text_javascript.txt @@ -10,7 +10,7 @@ a/=b/c //test tokenize reg exps a=/b/g a+/b/g -a = 1 + /2 + 1/b +a = 1 + /2 + 1/gimyxk a=/a/ / /a/ case /a/.test(c) //test tokenize multi-line comment containing a single line comment diff --git a/lib/ace/mode/_test/tokens_javascript.json b/lib/ace/mode/_test/tokens_javascript.json index 5044f21e..f527aa98 100644 --- a/lib/ace/mode/_test/tokens_javascript.json +++ b/lib/ace/mode/_test/tokens_javascript.json @@ -96,7 +96,8 @@ ["text"," "], ["string.regexp","/2 "], ["constant.language.escape","+"], - ["string.regexp"," 1/b"] + ["string.regexp"," 1/gimyx"], + ["identifier","k"] ],[ "no_regex", ["identifier","a"], diff --git a/lib/ace/mode/c9search_highlight_rules.js b/lib/ace/mode/c9search_highlight_rules.js index ce11bf5d..3e9af29d 100644 --- a/lib/ace/mode/c9search_highlight_rules.js +++ b/lib/ace/mode/c9search_highlight_rules.js @@ -75,6 +75,8 @@ var C9SearchHighlightRules = function() { tokens.push({type: types[2], value: skipped}); if (m[0]) tokens.push({type: types[3], value: m[0]}); + else if (!skipped) + break; } } if (last < str.length) @@ -99,7 +101,7 @@ var C9SearchHighlightRules = function() { search = lang.escapeRegExp(search); if (/whole/.test(options)) search = "\\b" + search + "\\b"; - var regex = safeCreateRegexp( + var regex = search && safeCreateRegexp( "(" + search + ")", / sensitive/.test(options) ? "g" : "ig" ); diff --git a/lib/ace/mode/css_highlight_rules.js b/lib/ace/mode/css_highlight_rules.js index 12b3d8fa..b9c20423 100644 --- a/lib/ace/mode/css_highlight_rules.js +++ b/lib/ace/mode/css_highlight_rules.js @@ -37,7 +37,7 @@ var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; /* All exports are for Stylus highlighter */ -var supportType = exports.supportType = "animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index"; +var supportType = exports.supportType = "animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index"; var supportFunction = exports.supportFunction = "rgb|rgba|url|attr|counter|counters"; var supportConstant = exports.supportConstant = "absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero"; var supportConstantColor = exports.supportConstantColor = "aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow"; diff --git a/lib/ace/mode/javascript/jshint.js b/lib/ace/mode/javascript/jshint.js index 04f36539..84254ffa 100644 --- a/lib/ace/mode/javascript/jshint.js +++ b/lib/ace/mode/javascript/jshint.js @@ -3228,7 +3228,8 @@ var JSHINT = (function () { if (this.id === "++" || this.id === "--") { if (state.option.plusplus) { warning("W016", this, this.id); - } else if ((!this.right.identifier || isReserved(this.right)) && + } else if (this.right && + (!this.right.identifier || isReserved(this.right)) && this.right.id !== "." && this.right.id !== "[") { warning("W017", this); } diff --git a/lib/ace/mode/javascript_highlight_rules.js b/lib/ace/mode/javascript_highlight_rules.js index f950da89..98247565 100644 --- a/lib/ace/mode/javascript_highlight_rules.js +++ b/lib/ace/mode/javascript_highlight_rules.js @@ -242,7 +242,7 @@ var JavaScriptHighlightRules = function() { }, { // flag token: "string.regexp", - regex: "/\\w*", + regex: "/[sxngimy]*", next: "no_regex" }, { // invalid operators @@ -251,7 +251,7 @@ var JavaScriptHighlightRules = function() { }, { // operators token : "constant.language.escape", - regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?]/ + regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ }, { token : "constant.language.delimiter", regex: /\|/ diff --git a/lib/ace/mouse/dragdrop_handler.js b/lib/ace/mouse/dragdrop_handler.js index 3a4bc188..b3b10608 100644 --- a/lib/ace/mouse/dragdrop_handler.js +++ b/lib/ace/mouse/dragdrop_handler.js @@ -384,6 +384,8 @@ function DragdropHandler(mouseHandler) { var button = e.getButton(); var clickCount = e.domEvent.detail || 1; if (clickCount === 1 && button === 0 && inSelection) { + if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey())) + return; this.mousedownEvent.time = Date.now(); var eventTarget = e.domEvent.target || e.domEvent.srcElement; if ("unselectable" in eventTarget) @@ -391,7 +393,7 @@ function DragdropHandler(mouseHandler) { if (editor.getDragDelay()) { // https://code.google.com/p/chromium/issues/detail?id=286700 if (useragent.isWebKit) { - self.cancelDrag = true; + this.cancelDrag = true; var mouseTarget = editor.container; mouseTarget.draggable = true; } diff --git a/lib/ace/mouse/multi_select_handler.js b/lib/ace/mouse/multi_select_handler.js index 2e0cda7b..dc01bd6c 100644 --- a/lib/ace/mouse/multi_select_handler.js +++ b/lib/ace/mouse/multi_select_handler.js @@ -105,7 +105,8 @@ function onMouseDown(e) { } var oldRange = selection.rangeList.rangeAtPoint(pos); - + + editor.$blockScrolling++; editor.once("mouseup", function() { var tmpSel = selection.toOrientedRange(); @@ -118,6 +119,7 @@ function onMouseDown(e) { } selection.addRange(tmpSel); } + editor.$blockScrolling--; }); } else if (alt && button == 0) { diff --git a/lib/ace/renderloop.js b/lib/ace/renderloop.js index ccbe98e1..6d31bd13 100644 --- a/lib/ace/renderloop.js +++ b/lib/ace/renderloop.js @@ -55,7 +55,7 @@ var RenderLoop = function(onRender, win) { //this.onRender(change); //return; this.changes = this.changes | change; - if (!this.pending) { + if (!this.pending && this.changes) { this.pending = true; var _self = this; event.nextFrame(function() { diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index dbf02aee..ae85c4f0 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -127,7 +127,7 @@ var VirtualRenderer = function(container, theme) { this.$textLayer.addEventListener("changeCharacterSize", function() { _self.updateCharacterSize(); - _self.onResize(true); + _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height); _self._signal("changeCharacterSize"); }); @@ -1272,10 +1272,11 @@ var VirtualRenderer = function(container, theme) { clearInterval(this.$timer); _self.session.setScrollTop(steps.shift()); + // trick session to think it's already scrolled to not loose toValue + _self.session.$scrollTop = toValue; this.$timer = setInterval(function() { if (steps.length) { _self.session.setScrollTop(steps.shift()); - // trick session to think it's already scrolled to not loose toValue _self.session.$scrollTop = toValue; } else if (toValue != null) { _self.session.$scrollTop = -1; @@ -1494,6 +1495,11 @@ var VirtualRenderer = function(container, theme) { if (_self.theme) dom.removeCssClass(_self.container, _self.theme.cssClass); + var padding = "padding" in module ? module.padding + : "padding" in (_self.theme || {}) ? 4 : _self.$padding; + if (_self.$padding && padding != _self.$padding) + _self.setPadding(padding); + // this is kept only for backwards compatibility _self.$theme = module.cssClass; @@ -1501,10 +1507,6 @@ var VirtualRenderer = function(container, theme) { dom.addCssClass(_self.container, module.cssClass); dom.setCssClass(_self.container, "ace_dark", module.isDark); - var padding = "padding" in module ? module.padding : 4; - if (_self.$padding && padding != _self.$padding) - _self.setPadding(padding); - // force re-measure of the gutter width if (_self.$size) { _self.$size.width = 0; @@ -1534,7 +1536,7 @@ var VirtualRenderer = function(container, theme) { * **/ this.setStyle = function(style, include) { - dom.setCssClass(this.container, style, include != false); + dom.setCssClass(this.container, style, include !== false); }; /** @@ -1545,6 +1547,11 @@ var VirtualRenderer = function(container, theme) { this.unsetStyle = function(style) { dom.removeCssClass(this.container, style); }; + + this.setCursorStyle = function(style) { + if (this.content.style.cursor != style) + this.content.style.cursor = style; + }; /** * @param {String} cursorStyle A css cursor style