diff --git a/src/css/editor-css.js b/src/css/editor-css.js
index cf7768f4a7b..4541f2d2075 100644
--- a/src/css/editor-css.js
+++ b/src/css/editor-css.js
@@ -705,4 +705,8 @@ module.exports = `
.ace_hidden_token {
display: none;
+}
+
+.ace_invisible_hidden {
+ color: transparent !important;
}`;
diff --git a/src/ext/whitespaces_in_selection.js b/src/ext/whitespaces_in_selection.js
index 8595078bd4a..f051acde73b 100644
--- a/src/ext/whitespaces_in_selection.js
+++ b/src/ext/whitespaces_in_selection.js
@@ -15,11 +15,11 @@ var dom = require("../lib/dom");
dom.importCssString(`
.ace_whitespaces_in_selection {
- color: rgba(0,0,0,0.29);
+ color: rgba(0,0,0,0.29) !important;
}
.ace_dark .ace_whitespaces_in_selection {
- color: rgba(187, 181, 181, 0.5);
+ color: rgba(187, 181, 181, 0.5) !important;
}
`, "ace_whitespaces_in_selection", false);
@@ -33,15 +33,14 @@ config.defineOptions(Editor.prototype, "editor", {
this.$boundChangeSelectionForWhitespace = $onChangeSelectionForWhitespace.bind(this);
}
this.on("changeSelection", this.$boundChangeSelectionForWhitespace);
+ $setRenderWhitespaceMarkers(this, true);
} else {
this.off("changeSelection", this.$boundChangeSelectionForWhitespace);
- if (this.session && this.session.$invisibleMarkerId) {
- this.session.removeTextMarker(this.session.$invisibleMarkerId);
- this.session.$invisibleMarkerId = null;
- }
+ $removeWhitespaceMarkers(this.session);
this.$boundChangeSelectionForWhitespace = null;
+ $setRenderWhitespaceMarkers(this, false);
}
},
get: function() {
@@ -51,19 +50,35 @@ config.defineOptions(Editor.prototype, "editor", {
}
});
-function $onChangeSelectionForWhitespace() {
- let invisibleMarkerId = this.session.$invisibleMarkerId;
- if (invisibleMarkerId) {
- this.session.removeTextMarker(invisibleMarkerId);
- this.session.$invisibleMarkerId = null;
+function $setRenderWhitespaceMarkers(editor, render) {
+ var textLayer = editor.renderer && editor.renderer.$textLayer;
+ if (!textLayer || typeof textLayer.setRenderWhitespaceMarkers !== "function")
+ return;
+
+ textLayer.setRenderWhitespaceMarkers(render);
+ editor.renderer.updateText();
+}
+
+function $removeWhitespaceMarkers(session) {
+ if (!session) return;
+
+ var invisibleMarkerIds = session.$invisibleMarkerIds || [];
+ for (var i = 0; i < invisibleMarkerIds.length; i++) {
+ session.removeTextMarker(invisibleMarkerIds[i]);
}
+ session.$invisibleMarkerIds = [];
+}
+
+function $onChangeSelectionForWhitespace() {
+ $removeWhitespaceMarkers(this.session);
- var currentRange = this.selection.getRange();
- if (!currentRange.isEmpty()) {
- this.session.$invisibleMarkerId = this.session.addTextMarker(
- currentRange,
- "ace_whitespaces_in_selection",
- "invisible"
- );
+ var ranges = typeof this.selection.getAllRanges === "function" ? this.selection.getAllRanges()
+ : [this.selection.getRange()];
+
+ for (var j = 0; j < ranges.length; j++) {
+ if (!ranges[j].isEmpty()) {
+ this.session.$invisibleMarkerIds.push(
+ this.session.addTextMarker(ranges[j], "ace_whitespaces_in_selection", "invisible"));
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/ext/whitespaces_in_selection_test.js b/src/ext/whitespaces_in_selection_test.js
index 47552c5a56e..f4d162d0cd7 100644
--- a/src/ext/whitespaces_in_selection_test.js
+++ b/src/ext/whitespaces_in_selection_test.js
@@ -1,9 +1,11 @@
"use strict";
require("../test/mockdom");
+require("../multi_select");
var assert = require("assert");
var EditSession = require("../edit_session").EditSession;
var Editor = require("../editor").Editor;
+var Range = require("../range").Range;
var MockRenderer = require("../test/mockrenderer").MockRenderer;
require("./whitespaces_in_selection");
@@ -25,15 +27,45 @@ module.exports = {
assert.ok(this.editor.$boundChangeSelectionForWhitespace);
},
+ "test: toggling extension updates whitespace marker rendering": function() {
+ var renderValues = [];
+ var updateCount = 0;
+ this.editor.renderer.$textLayer = {
+ setRenderWhitespaceMarkers: function(render) {
+ renderValues.push(render);
+ }
+ };
+ this.editor.renderer.updateText = function() {
+ updateCount++;
+ };
+
+ this.editor.setOption("showWhitespacesInSelection", true);
+ this.editor.setOption("showWhitespacesInSelection", false);
+
+ assert.deepEqual(renderValues, [true, false]);
+ assert.equal(updateCount, 2);
+ },
+
"test: turning off extension": function() {
this.editor.setOption("showWhitespacesInSelection", true);
assert.equal(this.editor.getOption("showWhitespacesInSelection"), true);
this.editor.selection.setRange({start: {row: 0, column: 0}, end: {row: 0, column: 5}});
+ this.editor.selection.addRange(new Range(1, 4, 1, 8));
+
+ var markerIds = this.session.$invisibleMarkerIds.slice();
+ assert.equal(markerIds.length, 2);
+ markerIds.forEach(function(markerId) {
+ assert.ok(this.session.getTextMarkers()[markerId]);
+ }, this);
this.editor.setOption("showWhitespacesInSelection", false);
assert.equal(this.editor.getOption("showWhitespacesInSelection"), false);
assert.equal(this.editor.$boundChangeSelectionForWhitespace, null);
+ assert.deepEqual(this.session.$invisibleMarkerIds, []);
+ markerIds.forEach(function(markerId) {
+ assert.ok(!this.session.getTextMarkers()[markerId]);
+ }, this);
},
"test: marker present after selection": function() {
@@ -41,12 +73,28 @@ module.exports = {
this.editor.selection.setRange({start: {row: 0, column: 0}, end: {row: 0, column: 5}});
- assert.ok(this.session.$invisibleMarkerId);
+ assert.equal(this.session.$invisibleMarkerIds.length, 1);
+
+ var markers = this.session.getTextMarkers();
+ var marker = markers[this.session.$invisibleMarkerIds[0]];
+ assert.ok(marker);
+ assert.equal(marker.className, "ace_whitespaces_in_selection");
+ },
+
+ "test: markers present after multiple selections": function() {
+ this.editor.setOption("showWhitespacesInSelection", true);
+
+ this.editor.selection.setRange(new Range(0, 0, 0, 5));
+ this.editor.selection.addRange(new Range(1, 4, 1, 8));
+
+ assert.equal(this.session.$invisibleMarkerIds.length, 2);
var markers = this.session.getTextMarkers();
- assert.ok(markers[this.session.$invisibleMarkerId]);
- assert.equal(markers[this.session.$invisibleMarkerId].className, "ace_whitespaces_in_selection");
+ this.session.$invisibleMarkerIds.forEach(function(markerId) {
+ assert.ok(markers[markerId]);
+ assert.equal(markers[markerId].className, "ace_whitespaces_in_selection");
+ });
}
};
-require("../test/run")(module);
\ No newline at end of file
+require("../test/run")(module);
diff --git a/src/layer/text.js b/src/layer/text.js
index 286e1303509..017cfb0c7ed 100644
--- a/src/layer/text.js
+++ b/src/layer/text.js
@@ -132,11 +132,15 @@ class Text {
$computeTabString() {
var tabSize = this.session.getTabSize();
this.tabSize = tabSize;
+ var renderTabGlyphs = this.showTabs || this.$renderWhitespaceMarkers;
+ var renderSpaceGlyphs = this.showSpaces || this.$renderWhitespaceMarkers;
/**@type{any}*/var tabStr = this.$tabStrings = [0];
for (var i = 1; i < tabSize + 1; i++) {
- if (this.showTabs) {
+ if (renderTabGlyphs) {
var span = this.dom.createElement("span");
span.className = "ace_invisible ace_invisible_tab";
+ if (!this.showTabs)
+ span.className += " ace_invisible_hidden";
span.textContent = lang.stringRepeat(this.TAB_CHAR, i);
tabStr.push(span);
} else {
@@ -146,13 +150,17 @@ class Text {
if (this.displayIndentGuides) {
this.$indentGuideRe = /\s\S| \t|\t |\s$/;
var className = "ace_indent-guide";
- var spaceClass = this.showSpaces ? " ace_invisible ace_invisible_space" : "";
- var spaceContent = this.showSpaces
+ var spaceClass = renderSpaceGlyphs ? " ace_invisible ace_invisible_space" : "";
+ if (renderSpaceGlyphs && !this.showSpaces)
+ spaceClass += " ace_invisible_hidden";
+ var spaceContent = renderSpaceGlyphs
? lang.stringRepeat(this.SPACE_CHAR, this.tabSize)
: lang.stringRepeat(" ", this.tabSize);
- var tabClass = this.showTabs ? " ace_invisible ace_invisible_tab" : "";
- var tabContent = this.showTabs
+ var tabClass = renderTabGlyphs ? " ace_invisible ace_invisible_tab" : "";
+ if (renderTabGlyphs && !this.showTabs)
+ tabClass += " ace_invisible_hidden";
+ var tabContent = renderTabGlyphs
? lang.stringRepeat(this.TAB_CHAR, this.tabSize)
: spaceContent;
@@ -363,7 +371,7 @@ class Text {
var controlCharacter = m[3];
var cjkSpace = m[4];
- if (!self.showSpaces && simpleSpace)
+ if (!self.showSpaces && !self.$renderWhitespaceMarkers && simpleSpace)
continue;
var before = i != m.index ? value.slice(i, m.index) : "";
@@ -381,9 +389,11 @@ class Text {
valueFragment.appendChild(text);
screenColumn += tabSize - 1;
} else if (simpleSpace) {
- if (self.showSpaces) {
+ if (self.showSpaces || self.$renderWhitespaceMarkers) {
var span = this.dom.createElement("span");
span.className = "ace_invisible ace_invisible_space";
+ if (!self.showSpaces)
+ span.className += " ace_invisible_hidden";
span.textContent = lang.stringRepeat(self.SPACE_CHAR, simpleSpace.length);
valueFragment.appendChild(span);
} else {
@@ -395,9 +405,11 @@ class Text {
span.textContent = lang.stringRepeat(self.SPACE_CHAR, controlCharacter.length);
valueFragment.appendChild(span);
} else if (cjkSpace) {
- if (self.showSpaces) {
+ if (self.showSpaces || self.$renderWhitespaceMarkers) {
var span = this.dom.createElement("span");
span.className = "ace_invisible ace_invisible_space";
+ if (!self.showSpaces)
+ span.className += " ace_invisible_hidden";
span.textContent = lang.stringRepeat(self.CJK_SPACE_CHAR, cjkSpace.length);
valueFragment.appendChild(span);
} else {
@@ -533,12 +545,10 @@ class Text {
return;
}
}
- var childNodes = element.childNodes;
- if (childNodes) {
- let node = childNodes[indentLevel - 1];
- if (node && node.classList && node.classList.contains("ace_indent-guide")) node.classList.add(
- "ace_indent-guide-active");
- }
+ var indentGuides = element.querySelectorAll(".ace_indent-guide");
+ var node = indentGuides[indentLevel - 1];
+ if (node)
+ node.classList.add("ace_indent-guide-active");
}
}
@@ -792,6 +802,7 @@ Text.prototype.showInvisibles = false;
Text.prototype.showSpaces = false;
Text.prototype.showTabs = false;
Text.prototype.showEOL = false;
+Text.prototype.$renderWhitespaceMarkers = false;
Text.prototype.displayIndentGuides = true;
Text.prototype.$highlightIndentGuides = true;
Text.prototype.$tabStrings = [];
diff --git a/src/layer/text_markers.js b/src/layer/text_markers.js
index 2256a8ce077..ea75239c21b 100644
--- a/src/layer/text_markers.js
+++ b/src/layer/text_markers.js
@@ -1,5 +1,4 @@
var Text = require("./text").Text;
-var lang = require("../lib/lang");
/**
* @typedef TextMarker
* @property {import("../../ace-internal").Ace.IRange} range
@@ -16,6 +15,20 @@ var lang = require("../lib/lang");
*/
var textMarkerMixin = {
+ /**
+ * Pre-renders whitespace glyphs so text markers can reveal them without
+ * changing the text layout as the marker range changes.
+ *
+ * @param {boolean} render
+ */
+ setRenderWhitespaceMarkers(render) {
+ render = !!render;
+ if (this.$renderWhitespaceMarkers === render)
+ return;
+
+ this.$renderWhitespaceMarkers = render;
+ this.$computeTabString();
+ },
/**
* @param {string} className
* @this {Text}
@@ -27,12 +40,10 @@ var textMarkerMixin = {
var element = selectedElements[i];
element.classList.remove(className);
- if (element.hasAttribute('data-whitespace')) {
- var originalWhitespace = element.getAttribute('data-whitespace');
- var textNode = this.dom.createTextNode(originalWhitespace, this.element);
- textNode["charCount"] = element["charCount"];
- element.parentNode.replaceChild(textNode, element);
- }
+ if (element.classList.contains("ace_invisible_tab") && !this.showTabs)
+ element.classList.add("ace_invisible_hidden");
+ else if (element.classList.contains("ace_invisible_space") && !this.showSpaces)
+ element.classList.add("ace_invisible_hidden");
}
},
/**
@@ -150,59 +161,50 @@ var textMarkerMixin = {
* @param {Node} node - The DOM node to process
* @param {Node} parentNode - The parent node
* @param {SelectionSegment} selectionSegment
- * @param {object} marker - The marker being applied
+ * @param {object} marker - The marker being applied
*/
$processInvisibleMarker(node, parentNode, selectionSegment, marker) {
- var nodeText = node.textContent || '';
- if (node.nodeType === 3) { // Text node
- var fragment = this.dom.createFragment(this.element);
-
- if (selectionSegment.beforeSelection > 0) {
- fragment.appendChild(
- this.dom.createTextNode(nodeText.substring(0, selectionSegment.beforeSelection), this.element));
- }
+ var element = /** @type {HTMLElement} */ (node.nodeType === 1 ? node : parentNode);
+ if (!element.classList || !element.classList.contains("ace_invisible_hidden"))
+ return;
- if (selectionSegment.selectionLength > 0) {
- var selectedText = selectionSegment.beforeSelection === 0 && selectionSegment.afterSelection === 0
- ? nodeText : nodeText.substring(
- selectionSegment.beforeSelection,
- selectionSegment.beforeSelection + selectionSegment.selectionLength
- );
+ if (selectionSegment.beforeSelection === 0 && selectionSegment.afterSelection === 0) {
+ element.classList.remove("ace_invisible_hidden");
+ element.classList.add(marker.className);
+ return;
+ }
- var segments = selectedText.match(/\s+|[^\s]+/g) || [];
-
- for (let k = 0; k < segments.length; k++) {
- var segment = segments[k];
- let span;
- if (/^\s+$/.test(segment)) {
- span = this.dom.createElement("span");
- span.className = marker.className;
- span.textContent =
- node["charCount"] ? this.TAB_CHAR.repeat(segment.length)
- : segment.replace(/\u3000/g, this.CJK_SPACE_CHAR).replace(/ /g, this.SPACE_CHAR);
- span.setAttribute("data-whitespace", segment);
- fragment.appendChild(span);
- }
- else {
- span = this.dom.createElement("span");
- span.textContent = segment;
- }
- if (node["charCount"] && segments.length === 1) { //this is for real tabs
- span["charCount"] = node["charCount"];
- }
- fragment.appendChild(span);
- }
+ var elementText = element.textContent || "";
+ var fragment = this.dom.createFragment(this.element);
+ var appendSegment = (start, length, selected) => {
+ if (length <= 0)
+ return;
+
+ var segment = /** @type {HTMLElement} */ (element.cloneNode(false));
+ segment.textContent = elementText.substring(start, start + length);
+ if (element.classList.contains("ace_indent-guide") && start + length < elementText.length) {
+ segment.classList.remove("ace_indent-guide");
+ segment.classList.remove("ace_indent-guide-active");
}
-
- if (selectionSegment.afterSelection > 0) {
- fragment.appendChild(this.dom.createTextNode(
- nodeText.substring(selectionSegment.beforeSelection + selectionSegment.selectionLength),
- this.element
- ));
+ if (selected) {
+ segment.classList.remove("ace_invisible_hidden");
+ segment.classList.add(marker.className);
}
+ fragment.appendChild(segment);
+ };
- parentNode.replaceChild(fragment, node);
- }
+ appendSegment(0, selectionSegment.beforeSelection, false);
+ appendSegment(
+ selectionSegment.beforeSelection,
+ selectionSegment.selectionLength,
+ true
+ );
+ appendSegment(
+ selectionSegment.beforeSelection + selectionSegment.selectionLength,
+ selectionSegment.afterSelection,
+ false
+ );
+ element.parentNode.replaceChild(fragment, element);
},
/**
@@ -385,4 +387,4 @@ require("../config").defineOptions(Editor.prototype, "editor", {
});
exports.textMarkerMixin = textMarkerMixin;
-exports.editSessionTextMarkerMixin = editSessionTextMarkerMixin;
\ No newline at end of file
+exports.editSessionTextMarkerMixin = editSessionTextMarkerMixin;
diff --git a/src/layer/text_markers_test.js b/src/layer/text_markers_test.js
index 1a75379e17b..96e16b6cd81 100644
--- a/src/layer/text_markers_test.js
+++ b/src/layer/text_markers_test.js
@@ -8,7 +8,6 @@ var assert = require("../test/assertions");
var EditSession = require("../edit_session").EditSession;
var TextLayer = require("./text").Text;
var JavaScriptMode = require("../mode/javascript").Mode;
-var dom = require("../lib/dom");
var Range = require("../range").Range;
require("./text_markers");
@@ -185,6 +184,7 @@ module.exports = {
"test: invisible marker with mixed whitespace and complete cleanup verification": function() {
var value = "function\t test() { //test comment\n var x = 1;\n}";
this.session.setValue(value);
+ this.textLayer.setRenderWhitespaceMarkers(true);
this.textLayer.update(this.textLayer.config);
@@ -202,18 +202,17 @@ module.exports = {
assert.ok(hasTabSymbol, "Should contain TAB_CHAR symbol");
assert.ok(hasSpaceSymbol, "Should contain SPACE_CHAR symbol");
- var result = normalize(`function
- ————
- ··
- test
- (
- )
- ·
- {·
- `);
- var actual = normalize(this.textLayer.element.childNodes[0].innerHTML);
- assert.equal(actual, result);
+ markerElements.forEach(element => {
+ assert.ok(element.classList.contains("ace_invisible"));
+ assert.ok(!element.classList.contains("ace_invisible_hidden"));
+ });
+
+ var tabMarker = line.querySelector(".ace_invisible_tab.invisible-marker");
+ assert.ok(tabMarker, "Tab marker should be applied");
+ assert.equal(tabMarker["charCount"], 1, "Tab marker should preserve its logical length");
+
+ var hiddenElements = line.querySelectorAll(".ace_invisible_hidden");
+ assert.ok(hiddenElements.length > 0, "Whitespace outside the marker should remain hidden");
this.session.removeTextMarker(markerId);
this.textLayer.$applyTextMarkers();
@@ -222,14 +221,97 @@ module.exports = {
assert.equal(markerElements.length, 0, "Marker class should be removed");
var finalLine = this.textLayer.element.childNodes[0];
- assert.ok(!finalLine.innerHTML.includes(this.textLayer.TAB_CHAR),
- "TAB_CHAR should be removed from DOM");
- assert.ok(!finalLine.innerHTML.includes(this.textLayer.SPACE_CHAR),
- "SPACE_CHAR should be removed from DOM");
+ assert.ok(finalLine.innerHTML.includes(this.textLayer.TAB_CHAR),
+ "TAB_CHAR should remain in the stable DOM");
+ assert.ok(finalLine.innerHTML.includes(this.textLayer.SPACE_CHAR),
+ "SPACE_CHAR should remain in the stable DOM");
+
+ var visibleWhitespace = Array.from(finalLine.querySelectorAll(".ace_invisible")).filter(element => {
+ return !element.classList.contains("ace_invisible_hidden")
+ && (element.classList.contains("ace_invisible_space")
+ || element.classList.contains("ace_invisible_tab"));
+ });
+ assert.equal(visibleWhitespace.length, 0, "All whitespace glyphs should be hidden after cleanup");
+ },
+
+ "test: invisible marker splits a pre-rendered whitespace run": function() {
+ this.session.setValue("//a b");
+ this.textLayer.setRenderWhitespaceMarkers(true);
+ this.textLayer.update(this.textLayer.config);
+
+ this.session.addTextMarker(new Range(0, 5, 0, 7), "invisible-marker", "invisible");
+ this.textLayer.$applyTextMarkers();
+
+ var line = this.textLayer.element.childNodes[0];
+ var markerElements = line.querySelectorAll(".invisible-marker");
+ assert.equal(markerElements.length, 1);
+ assert.equal(markerElements[0].textContent, this.textLayer.SPACE_CHAR.repeat(2));
+
+ var hiddenElements = line.querySelectorAll(".ace_invisible_hidden");
+ assert.equal(hiddenElements.length, 2);
+ assert.equal(hiddenElements[0].textContent, this.textLayer.SPACE_CHAR.repeat(2));
+ assert.equal(hiddenElements[1].textContent, this.textLayer.SPACE_CHAR);
+ },
+
+ "test: splitting an indent guide preserves one guide decoration": function() {
+ this.session.setValue(" value");
+ this.textLayer.setRenderWhitespaceMarkers(true);
+ this.textLayer.update(this.textLayer.config);
+
+ this.session.addTextMarker(new Range(0, 1, 0, 3), "invisible-marker", "invisible");
+ this.textLayer.$applyTextMarkers();
+
+ var line = this.textLayer.element.childNodes[0];
+ assert.equal(line.querySelectorAll(".ace_indent-guide").length, 1);
+ assert.equal(
+ line.querySelector(".invisible-marker").textContent,
+ this.textLayer.SPACE_CHAR.repeat(2)
+ );
+ this.textLayer.$setIndentGuideActive(this.textLayer.$lines.cells[0], 1);
+ assert.equal(line.querySelectorAll(".ace_indent-guide-active").length, 1);
+ },
+
+ "test: invisible marker does not modify globally visible whitespace": function() {
+ this.session.setValue("a b");
+ this.textLayer.setRenderWhitespaceMarkers(true);
+ this.textLayer.setShowInvisibles(true);
+ this.textLayer.update(this.textLayer.config);
+
+ this.session.addTextMarker(new Range(0, 1, 0, 3), "invisible-marker", "invisible");
+ this.textLayer.$applyTextMarkers();
+
+ var line = this.textLayer.element.childNodes[0];
+ assert.equal(line.querySelectorAll(".invisible-marker").length, 0);
+ assert.equal(line.querySelectorAll(".ace_invisible_hidden").length, 0);
+ assert.equal(
+ line.querySelector(".ace_invisible_space").textContent,
+ this.textLayer.SPACE_CHAR.repeat(2)
+ );
+
+ this.textLayer.setShowInvisibles(false);
+ this.textLayer.update(this.textLayer.config);
+ this.textLayer.$applyTextMarkers();
+
+ assert.equal(
+ this.textLayer.element.querySelectorAll(".invisible-marker").length,
+ 1,
+ "The retained marker should reveal whitespace when global invisibles are hidden"
+ );
+ },
+
+ "test: invisible marker supports pre-rendered CJK spaces": function() {
+ this.session.setValue("a b");
+ this.textLayer.setRenderWhitespaceMarkers(true);
+ this.textLayer.update(this.textLayer.config);
+
+ this.session.addTextMarker(new Range(0, 1, 0, 2), "invisible-marker", "invisible");
+ this.textLayer.$applyTextMarkers();
- var elementsWithWhitespace = this.textLayer.element.querySelectorAll('[data-whitespace]');
- assert.equal(elementsWithWhitespace.length, 0, "No data-whitespace attributes should remain");
+ var marker = this.textLayer.element.querySelector(".invisible-marker");
+ assert.ok(marker);
+ assert.equal(marker.textContent, this.textLayer.CJK_SPACE_CHAR);
+ assert.ok(!marker.classList.contains("ace_invisible_hidden"));
},
};
-require("../test/run")(module);
\ No newline at end of file
+require("../test/run")(module);
diff --git a/types/ace-modules.d.ts b/types/ace-modules.d.ts
index 08e4c19aebf..81c7f7c4bdb 100644
--- a/types/ace-modules.d.ts
+++ b/types/ace-modules.d.ts
@@ -47,7 +47,7 @@ declare module "ace-code/src/layer/font_metrics" {
bottom: number;
};
/**
- * Calculates the width of the text up to a specific scrrenColumn on a given screen row.
+ * Calculates the width of the text up to a specific screenColumn on a given screen row.
*
* @param {number} screenRow - The row index on the screen for which the text width is calculated.
* @param {number} screenColumn - The column index up to which the text width is measured.
@@ -594,6 +594,7 @@ declare module "ace-code/src/layer/text" {
export type LayerConfig = import("ace-code").Ace.LayerConfig;
export type EditSession = import("ace-code/src/edit_session").EditSession;
type TextMarkersMixin = {
+ setRenderWhitespaceMarkers(render: boolean): void;
};
import dom = require("ace-code/src/lib/dom");
import { Lines } from "ace-code/src/layer/lines";
@@ -3817,6 +3818,12 @@ declare module "ace-code/src/layer/text_markers" {
afterSelection: number;
};
export namespace textMarkerMixin {
+ /**
+ * Pre-renders whitespace glyphs so text markers can reveal them without
+ * changing the text layout as the marker range changes.
+ *
+ */
+ function setRenderWhitespaceMarkers(render: boolean): void;
function $removeClass(this: Text, className: string): void;
function $applyTextMarkers(this: Text): void;
/**
@@ -3830,7 +3837,7 @@ declare module "ace-code/src/layer/text_markers" {
* Process text nodes for invisible markers (whitespace visualization)
* @param {Node} node - The DOM node to process
* @param {Node} parentNode - The parent node
- * @param {object} marker - The marker being applied
+ * @param {object} marker - The marker being applied
*/
function $processInvisibleMarker(node: Node, parentNode: Node, selectionSegment: SelectionSegment, marker: object): void;
/**