diff --git a/.github/ISSUE_TEMPLATE/add-to-website.yml b/.github/ISSUE_TEMPLATE/add-to-website.yml new file mode 100644 index 00000000000..99573b72525 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/add-to-website.yml @@ -0,0 +1,51 @@ +--- +name: "🌐 Add a project to the list of project using Ace on its website." +description: Add a project to the list of projects using Ace, displayed on the website. +title: "Add project (project name) to the list of projects using Ace on its website" +labels: [website, needs-triage] +assignees: [] +body: + - type: markdown + attributes: + value: | + The fastest way to get your project to be displayed on the website is to create a PR. + Examples: https://github.com/ajaxorg/ace/pull/5014, https://github.com/ajaxorg/ace/pull/5222. + If for any reason creating a PR is not an option for you, please proceed with filling out this issue. Thanks! + - type: input + id: name + attributes: + label: Project name + description: A name of the project to be used on Ace website. + validations: + required: true + - type: input + id: project-link + attributes: + label: Project link + description: A link to the project's website. + validations: + required: true + - type: input + id: logo-link + attributes: + label: Logo link + description: | + A link to the logo image to be used on the website for the project. If not provided, only the name of the project will be displayed. + + By submitting this link, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. + validations: + required: false + - type: textarea + id: info + attributes: + label: Additional information + description: Any additional information you would like to share. + validations: + required: false + - type: checkboxes + id: ack + attributes: + label: Acknowledgements + options: + - label: I may be able to implement this request. + required: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 743245fe166..c711c2f47ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.23.4](https://github.com/ajaxorg/ace/compare/v1.23.3...v1.23.4) (2023-07-12) + + +### Bug Fixes + +* filterText triggered selection range removal when completions range was present ([#5249](https://github.com/ajaxorg/ace/issues/5249)) ([b586e4d](https://github.com/ajaxorg/ace/commit/b586e4d574bf780fc38f1ac0d034276272b36ad3)) + +### [1.23.3](https://github.com/ajaxorg/ace/compare/v1.23.2...v1.23.3) (2023-07-10) + + +### Bug Fixes + +* android bug when deleting multiple lines ([#5248](https://github.com/ajaxorg/ace/issues/5248)) ([bd066ff](https://github.com/ajaxorg/ace/commit/bd066ffef88ca74f5ac32349d3e868cfa875a47b)), closes [#5087](https://github.com/ajaxorg/ace/issues/5087) +* update jshint version to 2.13.6; change esversion to target ECMAScript 11 ([#5243](https://github.com/ajaxorg/ace/issues/5243)) ([301aee9](https://github.com/ajaxorg/ace/commit/301aee91b5974d9fb31d646466ed301c5c3b8249)) + +### [1.23.2](https://github.com/ajaxorg/ace/compare/v1.23.1...v1.23.2) (2023-07-07) + + +### Bug Fixes + +* **autocomplete:** fix a11y violations ([#5241](https://github.com/ajaxorg/ace/issues/5241)) ([decb615](https://github.com/ajaxorg/ace/commit/decb6154198105289170303b7434c524eaf9fda8)) +* bug in guttertooltip when `tooltipsFollowsMouse` set to false ([#5217](https://github.com/ajaxorg/ace/issues/5217)) ([67d318e](https://github.com/ajaxorg/ace/commit/67d318ed25d5b45789462850e6b96aac2931591f)) +* typo in function name ([#5229](https://github.com/ajaxorg/ace/issues/5229)) ([6e99055](https://github.com/ajaxorg/ace/commit/6e99055c46f443271161e40fe15372d1d8ae9f42)) + +### [1.23.1](https://github.com/ajaxorg/ace/compare/v1.23.0...v1.23.1) (2023-06-27) + ## [1.23.0](https://github.com/ajaxorg/ace/compare/v1.22.1...v1.23.0) (2023-06-21) diff --git a/Makefile.dryice.js b/Makefile.dryice.js index aa9fb3521d6..9f2b69986fe 100755 --- a/Makefile.dryice.js +++ b/Makefile.dryice.js @@ -190,6 +190,7 @@ function buildTypes() { var pathModules = [ "declare module 'ace-builds/webpack-resolver';", + "declare module 'ace-builds/esm-resolver';", "declare module 'ace-builds/src-noconflict/ace';" ].concat(paths.map(function(path) { if (moduleNameRegex.test(path)) { @@ -294,7 +295,7 @@ function jsFileList(path, filter) { filter = /_test/; return fs.readdirSync(path).map(function(x) { - if (x.slice(-3) == ".js" && !filter.test(x) && !/\s|BASE|(\b|_)dummy(\b|_)|\.css\.js$/.test(x)) + if (x.slice(-3) == ".js" && !filter.test(x) && !/\s|BASE|(\b|_)dummy(\b|_)|[\-\.]css\.js$/.test(x)) return x.slice(0, -3); }).filter(Boolean); } diff --git a/build b/build index fd000ba512c..06196affdfb 160000 --- a/build +++ b/build @@ -1 +1 @@ -Subproject commit fd000ba512c70f175d5c2b5f1638b0b9f56ea51c +Subproject commit 06196affdfb41229876086ba5eacd53ccf203709 diff --git a/index.html b/index.html index 4cb44badc46..91eb7f13b13 100644 --- a/index.html +++ b/index.html @@ -1135,20 +1135,28 @@

Projects Using Ace

trinket -
  • +
  • GoOnlineTools
  • -
  • +
  • SQLize.online
  • -
  • +
  • PHPize.online
  • +
  • + + Domoticz +
  • +
  • + + Nixx Web Tools +
  • +

    - Your Site Here + Your Site Here
  • diff --git a/lib/ace/loader_build.js b/lib/ace/loader_build.js index 9b9fd068560..77505a27cdd 100644 --- a/lib/ace/loader_build.js +++ b/lib/ace/loader_build.js @@ -17,6 +17,7 @@ var global = (function() { module.exports = function(ace) { config.init = init; + config.$require = require; /** * Provides access to require in packed noconflict mode diff --git a/lib/ace/mode/javascript/jshint.js b/lib/ace/mode/javascript/jshint.js index 6b9535d9886..6c6054618e8 100644 --- a/lib/ace/mode/javascript/jshint.js +++ b/lib/ace/mode/javascript/jshint.js @@ -2392,13 +2392,13 @@ module.exports = slice; exports.noConflict = function () { global._ = current; return exports; }; }())); }(this, (function () { - // Underscore.js 1.13.4 + // Underscore.js 1.13.6 // https://underscorejs.org // (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. // Current version. - var VERSION = '1.13.4'; + var VERSION = '1.13.6'; // Establish the root object, `window` (`self`) in the browser, `global` // on the server, or `this` in some virtual machines. We use `self` @@ -4461,7 +4461,7 @@ module.exports = slice; /*exported console */ var _ = _dereq_("underscore"); -_.clone = _dereq_("lodash.clone"); +_.clone = _dereq_("lodash.clone"); var events = _dereq_("events"); var vars = _dereq_("./vars.js"); var messages = _dereq_("./messages.js"); @@ -8930,7 +8930,7 @@ var JSHINT = (function() { var id = state.tokens.prev; value = expression(context, 10); if (value) { - if (value.identifier && value.value === "undefined") { + if (!isConst && value.identifier && value.value === "undefined") { warning("W080", id, id.value); } if (!lone) { @@ -13527,7 +13527,7 @@ var errors = { // Constants E011: "'{a}' has already been declared.", - E012: "const '{a}' is initialized to 'undefined'.", + E012: "Missing initializer for constant '{a}'.", E013: "Attempting to override '{a}' which is a constant.", // Regular expressions @@ -15122,7 +15122,7 @@ exports.regexpDot = /(^|[^\\])(\\\\)*\./; */ var _ = _dereq_("underscore"); -_.slice = _dereq_("lodash.slice"); +_.slice = _dereq_("lodash.slice"); var events = _dereq_("events"); // Used to denote membership in lookup tables (a primitive value such as `true` diff --git a/lib/ace/mode/javascript_worker.js b/lib/ace/mode/javascript_worker.js index d2a071a9416..3bf6ceb6f38 100644 --- a/lib/ace/mode/javascript_worker.js +++ b/lib/ace/mode/javascript_worker.js @@ -79,7 +79,7 @@ oop.inherits(JavaScriptWorker, Mirror); this.options = options || { // undef: true, // unused: true, - esnext: true, + esversion: 11, moz: true, devel: true, browser: true, diff --git a/package.json b/package.json index 265e930d689..5e333824408 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ace-code", "description": "Ajax.org Code Editor is a full featured source code highlighting editor that powers the Cloud9 IDE", - "version": "1.23.0", + "version": "1.23.4", "homepage": "http://github.com/ajaxorg/ace", "engines": { "node": ">= 0.6.0" diff --git a/src/autocomplete.js b/src/autocomplete.js index 3fbd71dbbfd..5dadc4e5a4b 100644 --- a/src/autocomplete.js +++ b/src/autocomplete.js @@ -611,7 +611,7 @@ class CompletionProvider { // TODO add support for options.deleteSuffix if (!this.completions) return false; - if (this.completions.filterText) { + if (this.completions.filterText && !data.range) { var ranges; if (editor.selection.getAllRanges) { ranges = editor.selection.getAllRanges(); diff --git a/src/autocomplete/popup.js b/src/autocomplete/popup.js index 01fd01f04e2..5fd15bc7221 100644 --- a/src/autocomplete/popup.js +++ b/src/autocomplete/popup.js @@ -50,8 +50,9 @@ class AcePopup { popup.renderer.setStyle("ace_autocomplete"); // Set aria attributes for the popup - popup.renderer.container.setAttribute("role", "listbox"); - popup.renderer.container.setAttribute("aria-label", nls("Autocomplete suggestions")); + popup.renderer.$textLayer.element.setAttribute("role", "listbox"); + popup.renderer.$textLayer.element.setAttribute("aria-label", nls("Autocomplete suggestions")); + popup.renderer.textarea.setAttribute("aria-hidden", "true"); popup.setOption("displayIndentGuides", false); popup.setOption("dragDelay", 150); @@ -133,12 +134,12 @@ class AcePopup { dom.addCssClass(selected, "ace_selected"); var ariaId = getAriaId(row); selected.id = ariaId; - popup.renderer.container.setAttribute("aria-activedescendant", ariaId); + t.element.setAttribute("aria-activedescendant", ariaId); el.setAttribute("aria-activedescendant", ariaId); selected.setAttribute("role", "option"); selected.setAttribute("aria-label", popup.getData(row).value); selected.setAttribute("aria-setsize", popup.data.length); - selected.setAttribute("aria-posinset", row); + selected.setAttribute("aria-posinset", row+1); selected.setAttribute("aria-describedby", "doc-tooltip"); } }); diff --git a/src/autocomplete_test.js b/src/autocomplete_test.js index 2b13d575f3f..34a1e479e00 100644 --- a/src/autocomplete_test.js +++ b/src/autocomplete_test.js @@ -32,6 +32,13 @@ function initEditor(value) { return editor; } +function afterRenderCheck(popup, callback) { + popup.renderer.on("afterRender", function wait() { + popup.renderer.off("afterRender", wait); + callback(); + }); +} + module.exports = { tearDown: function() { if (editor) { @@ -48,16 +55,16 @@ module.exports = { assert.ok(!editor.container.querySelector("style")); sendKey("a"); - checkInnerHTML('arraysort localalooooooooooooooooooooooooooooong_word local', function() { + checkInnerHTML('arraysort localalooooooooooooooooooooooooooooong_word local', function() { sendKey("rr"); - checkInnerHTML('arraysort local', function() { + checkInnerHTML('arraysort local', function() { sendKey("r"); - checkInnerHTML('arraysort local', function() { + checkInnerHTML('arraysort local', function() { sendKey("Return"); assert.equal(editor.getValue(), "arraysort\narraysort alooooooooooooooooooooooooooooong_word"); editor.execCommand("insertstring", " looooooooooooooooooooooooooooong_"); - checkInnerHTML('alooooooooooooooooooooooooooooong_word local', function() { + checkInnerHTML('alooooooooooooooooooooooooooooong_word local', function() { sendKey("Return"); editor.destroy(); editor.container.remove(); @@ -95,7 +102,7 @@ module.exports = { snippet: "will: $1", meta: "snippet", command: "startAutocomplete", - range: new Range(0, 4, 0, 6) + range: new Range(0, 4, 0, 7) }, { caption: "here", value: "-here", @@ -110,12 +117,12 @@ module.exports = { editor.moveCursorTo(0, 6); sendKey("w"); var popup = editor.completer.popup; - check(function () { + afterRenderCheck(popup, function () { assert.equal(popup.data.length, 1); editor.onCommandKey(null, 0, 13); assert.equal(popup.data.length, 2); assert.equal(editor.getValue(), "goodwill: "); - check(function () { + afterRenderCheck(popup, function () { editor.onCommandKey(null, 0, 13); assert.equal(editor.getValue(), "goodwill-here"); editor.destroy(); @@ -123,14 +130,37 @@ module.exports = { done(); }); }); - - function check(callback) { - popup = editor.completer.popup; - popup.renderer.on("afterRender", function wait() { - popup.renderer.off("afterRender", wait); - callback(); - }); - } + }, + "test: filterText does not trigger selection range removal when completions range is present": function (done) { + var editor = initEditor("{}"); + editor.completers = [ + { + getCompletions: function (editor, session, pos, prefix, callback) { + var completions = [ + { + caption: "apple", + snippet: "apple: $1", + meta: "snippet", + range: new Range(0, 1, 0, 2) + }, { + caption: "pineapple", + value: "pineapple", + range: new Range(0, 1, 0, 2) + } + ]; + callback(null, completions); + } + } + ]; + editor.moveCursorTo(0, 1); + sendKey("a"); + var popup = editor.completer.popup; + afterRenderCheck(popup, function () { + assert.equal(popup.data.length, 2); + editor.onCommandKey(null, 0, 13); + assert.equal(editor.getValue(), "{apple: }"); + done(); + }); }, "test: different completers tooltips": function (done) { var editor = initEditor(""); diff --git a/src/config.js b/src/config.js index 007d9f3da84..939a02f8ea0 100644 --- a/src/config.js +++ b/src/config.js @@ -77,14 +77,6 @@ exports.setModuleUrl = function(name, subst) { var loader = function(moduleName, cb) { if (moduleName === "ace/theme/textmate" || moduleName === "./theme/textmate") return cb(null, require("./theme/textmate")); - if (typeof module.require == "function") { - // backwards compatibility for node - try { - var req = "require"; - return cb(null, module[req](moduleName)); - } catch (e) { - } - } if (customLoader) return customLoader(moduleName, cb); console.error("loader is not configured"); @@ -98,7 +90,7 @@ exports.dynamicModules = Object.create(null); exports.$loading = {}; exports.$loaded = {}; exports.loadModule = function(moduleName, onLoad) { - var module, moduleType; + var loadedModule, moduleType; if (Array.isArray(moduleName)) { moduleType = moduleName[0]; moduleName = moduleName[1]; @@ -142,7 +134,18 @@ exports.loadModule = function(moduleName, onLoad) { } }); } else { - load(module || exports.$loaded[moduleName]); + // backwards compatibility for node and packaged version + try { + loadedModule = this.$require(moduleName); + } catch (e) {} + load(loadedModule || exports.$loaded[moduleName]); + } +}; + +exports.$require = function(moduleName) { + if (typeof module.require == "function") { + var req = "require"; + return module[req](moduleName); } }; @@ -165,6 +168,6 @@ var reportErrorIfPathIsNotConfigured = function() { } }; -exports.version = "1.23.0"; +exports.version = "1.23.4"; diff --git a/src/ext/options.js b/src/ext/options.js index 2e2beb36f0d..f82b82dcc5e 100644 --- a/src/ext/options.js +++ b/src/ext/options.js @@ -203,6 +203,10 @@ var optionGroups = { }, "Keyboard Accessibility Mode": { path: "enableKeyboardAccessibility" + }, + "Gutter tooltip follows mouse": { + path: "tooltipFollowsMouse", + defaultValue: true } } }; diff --git a/src/ext/searchbox.css.js b/src/ext/searchbox-css.js similarity index 100% rename from src/ext/searchbox.css.js rename to src/ext/searchbox-css.js diff --git a/src/ext/searchbox.js b/src/ext/searchbox.js index 625faa508e9..3b766dd68a4 100644 --- a/src/ext/searchbox.js +++ b/src/ext/searchbox.js @@ -3,7 +3,7 @@ var dom = require("../lib/dom"); var lang = require("../lib/lang"); var event = require("../lib/event"); -var searchboxCss = require("./searchbox.css"); +var searchboxCss = require("./searchbox-css"); var HashHandler = require("../keyboard/hash_handler").HashHandler; var keyUtil = require("../lib/keys"); var nls = require("../config").nls; diff --git a/src/ext/static.css.js b/src/ext/static-css.js similarity index 100% rename from src/ext/static.css.js rename to src/ext/static-css.js diff --git a/src/ext/static_highlight.js b/src/ext/static_highlight.js index 060c3bb684d..191ebc80ddd 100644 --- a/src/ext/static_highlight.js +++ b/src/ext/static_highlight.js @@ -2,7 +2,7 @@ var EditSession = require("../edit_session").EditSession; var TextLayer = require("../layer/text").Text; -var baseStyles = require("./static.css"); +var baseStyles = require("./static-css"); var config = require("../config"); var dom = require("../lib/dom"); var escapeHTML = require("../lib/lang").escapeHTML; diff --git a/src/keyboard/textinput.js b/src/keyboard/textinput.js index b3bdd04c64d..af04ada492b 100644 --- a/src/keyboard/textinput.js +++ b/src/keyboard/textinput.js @@ -83,8 +83,6 @@ var TextInput = function(parentNode, host) { if (ignoreFocusEvents) return; host.onBlur(e); isFocused = false; - if (isMobile && !isIOS) - document.removeEventListener("selectionchange", detectSelectionChange); }, host); event.addListener(text, "focus", function(e) { if (ignoreFocusEvents) return; @@ -101,8 +99,6 @@ var TextInput = function(parentNode, host) { setTimeout(resetSelection); else resetSelection(); - if (isMobile && !isIOS) - document.addEventListener("selectionchange", detectSelectionChange); }, host); this.$focusScroll = false; this.focus = function() { @@ -291,25 +287,6 @@ var TextInput = function(parentNode, host) { } }; - function detectSelectionChange(e) { - if (!text || !text.parentNode) - document.removeEventListener("selectionchange", detectSelectionChange); - if (inComposition) return; - - if (text.selectionStart !== text.selectionEnd) return; - var startDiff = text.selectionStart - lastSelectionStart; - var oldLenght = lastSelectionEnd - lastSelectionStart; - if (startDiff > 0) { - startDiff = Math.max(startDiff - oldLenght, 1); - } else if (startDiff === 0 && oldLenght) { - startDiff = -1; - } - var repeat = Math.abs(startDiff); - var key = startDiff > 0 ? KEYS.right : KEYS.left; - for (var i = 0; i < repeat; i++) { - host.onCommandKey({}, 0, key); - } - } var inputHandler = null; this.setInputHandler = function(cb) {inputHandler = cb;}; diff --git a/src/keyboard/textinput_test.js b/src/keyboard/textinput_test.js index 9cf3f385f1b..dc49019271b 100644 --- a/src/keyboard/textinput_test.js +++ b/src/keyboard/textinput_test.js @@ -153,46 +153,6 @@ module.exports = { assert.equal(editor.getValue(), "y"); }, - "test: android spacebar moves cursor": function() { - setUserAgentForTests(true, false); - var value = "Juhu kinners!"; - editor.setValue(value); - editor.blur(); - editor.focus(); - var lastCommand = ""; - editor.commands.on("exec", function(e) { - lastCommand += e.command.name; - }); - - textarea.selectionStart = textarea.selectionEnd; - document.dispatchEvent(new CustomEvent("selectionchange")); - assert.equal(lastCommand, "gotoright"); - lastCommand = ""; - - textarea.selectionStart = - textarea.selectionEnd = textarea.selectionStart - 1; - document.dispatchEvent(new CustomEvent("selectionchange")); - assert.equal(lastCommand, "gotoleft"); - lastCommand = ""; - - assert.equal(editor.getSelectedText(), ""); - textarea.selectionStart = 0; - textarea.selectionEnd = textarea.value.length; - textarea.dispatchEvent(new CustomEvent("select")); - assert.equal(editor.getSelectedText(), value); - - textarea.selectionEnd = textarea.selectionStart; - document.dispatchEvent(new CustomEvent("selectionchange")); - assert.equal(lastCommand, "gotoleft"); - lastCommand = ""; - - textarea.selectionStart = - textarea.selectionEnd = textarea.selectionEnd + 2; - document.dispatchEvent(new CustomEvent("selectionchange")); - assert.equal(lastCommand, "gotorightgotoright"); - lastCommand = ""; - }, - "test: composition with visible textarea": function() { var data = [ // select ll diff --git a/src/mode/nsis_highlight_rules.js b/src/mode/nsis_highlight_rules.js index 56d8434e493..eb75a92c0e3 100644 --- a/src/mode/nsis_highlight_rules.js +++ b/src/mode/nsis_highlight_rules.js @@ -10,7 +10,7 @@ var NSISHighlightRules = function() { this.$rules = { start: [{ token: "keyword.compiler.nsis", - regex: /^\s*!(?:include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|pragma|finalize|getdllversion|gettlbversion|system|tempfile|warning|verbose|define|undef|insertmacro|macro|macroend|makensis|searchparse|searchreplace|uninstfinalize)\b/, + regex: /^\s*!(?:include|addincludedir|addplugindir|appendfile|assert|cd|delfile|echo|error|execute|packhdr|pragma|finalize|getdllversion|gettlbversion|system|tempfile|warning|verbose|define|undef|insertmacro|macro|macroend|makensis|searchparse|searchreplace|uninstfinalize)\b/, caseInsensitive: true }, { token: "keyword.command.nsis", diff --git a/src/mouse/default_gutter_handler.js b/src/mouse/default_gutter_handler.js index c53fd57e9c4..91c78ad37bb 100644 --- a/src/mouse/default_gutter_handler.js +++ b/src/mouse/default_gutter_handler.js @@ -57,11 +57,17 @@ function GutterHandler(mouseHandler) { if (mouseHandler.$tooltipFollowsMouse) { moveTooltip(mouseEvent); } else { - var gutterElement = gutter.$lines.cells[row].element.querySelector("[class*=ace_icon]"); - var rect = gutterElement.getBoundingClientRect(); - var style = tooltip.getElement().style; - style.left = rect.right + "px"; - style.top = rect.bottom + "px"; + var gutterRow = mouseEvent.getGutterRow(); + var gutterCell = gutter.$lines.get(gutterRow); + if (gutterCell) { + var gutterElement = gutterCell.element.querySelector(".ace_gutter_annotation"); + var rect = gutterElement.getBoundingClientRect(); + var style = tooltip.getElement().style; + style.left = rect.right + "px"; + style.top = rect.bottom + "px"; + } else { + moveTooltip(mouseEvent); + } } } diff --git a/src/mouse/default_gutter_handler_test.js b/src/mouse/default_gutter_handler_test.js index 03a23d4989f..92e8ed68a87 100644 --- a/src/mouse/default_gutter_handler_test.js +++ b/src/mouse/default_gutter_handler_test.js @@ -217,6 +217,33 @@ module.exports = { // Annotation node should NOT have fold class. var annotation = lines.cells[0].element.children[2]; assert.notOk(/fold/.test(annotation.className)); + },"test: sets position correctly when tooltipFollowsMouse false" : function(done) { + var editor = this.editor; + var value = ""; + + editor.session.setMode(new Mode()); + editor.setValue(value, -1); + editor.session.setAnnotations([{row: 0, column: 0, text: "error test", type: "error"}]); + editor.setOption("tooltipFollowsMouse", false); + editor.setOption("useSvgGutterIcons", true); + editor.renderer.$loop._flush(); + + var lines = editor.renderer.$gutterLayer.$lines; + var annotation = lines.cells[0].element.childNodes[2].firstChild; + assert.ok(/ace_error/.test(annotation.className)); + + var rect = annotation.getBoundingClientRect(); + annotation.dispatchEvent(new MouseEvent("move", {x: rect.left, y: rect.top})); + + // Wait for the tooltip to appear after its timeout. + setTimeout(function() { + editor.renderer.$loop._flush(); + var tooltip = editor.container.querySelector(".ace_tooltip"); + assert.ok(/error test/.test(tooltip.textContent)); + assert.equal(tooltip.style.left, `${rect.right}px`); + assert.equal(tooltip.style.top, `${rect.bottom}px`); + done(); + }, 100); }, tearDown : function() { diff --git a/src/mouse/mouse_event.js b/src/mouse/mouse_event.js index c0f242fa4d2..eca34f95ce3 100644 --- a/src/mouse/mouse_event.js +++ b/src/mouse/mouse_event.js @@ -48,6 +48,18 @@ class MouseEvent { this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY); return this.$pos; } + + /** + * Get the relative position within the gutter. + * + * @return {Number} 'row' within the gutter. + */ + getGutterRow() { + var documentRow = this.getDocumentPosition().row; + var screenRow = this.editor.session.documentToScreenRow(documentRow, 0); + var screenTopRow = this.editor.session.documentToScreenRow(this.editor.renderer.$gutterLayer.$lines.get(0).row, 0); + return screenRow - screenTopRow; + } /** * Check if the mouse cursor is inside of the text selection diff --git a/src/virtual_renderer.js b/src/virtual_renderer.js index 13f8581f8f4..3947f44f24f 100644 --- a/src/virtual_renderer.js +++ b/src/virtual_renderer.js @@ -462,7 +462,7 @@ class VirtualRenderer { getShowInvisibles() { return this.getOption("showInvisibles"); } - getDisplayIndentGuide() { + getDisplayIndentGuides() { return this.getOption("displayIndentGuides"); } diff --git a/tool/esm_resolver_generator.js b/tool/esm_resolver_generator.js index acd05ccac29..b07e52ec20e 100644 --- a/tool/esm_resolver_generator.js +++ b/tool/esm_resolver_generator.js @@ -8,7 +8,10 @@ function buildResolver() { return `ace.config.setModuleLoader('${moduleName}', () => import('./${moduleName.replace("ace", "src") + ".js"}'));`; }).join('\n') + "\n\nexport * as default from \"./src/ace\";"; + var declaration = 'export * from "./ace"'; + fs.writeFileSync(__dirname + '/../esm-resolver.js', loader, "utf8"); + fs.writeFileSync(__dirname + '/../esm-resolver.d.ts', declaration, "utf8"); } function getModuleNames() { diff --git a/tool/tmtheme.js b/tool/tmtheme.js index 89ea68356fc..eff23f2b777 100755 --- a/tool/tmtheme.js +++ b/tool/tmtheme.js @@ -4,11 +4,9 @@ var util = require("util"); var cssParse = require("css-parse"); var cssStringify = require("css-stringify"); -var parseString = require("plist").parseString; +var parse = require("plist").parse; function parseTheme(themeXml, callback) { - parseString(themeXml, function(_, theme) { - callback(theme[0]) - }); + callback(parse(themeXml)); } var unsupportedScopes = { };