monaco-editor11 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/monaco-editor11.es.js +11 -16
- package/dist/monaco-editor11.umd.js +1 -1
- package/package.json +2 -2
- package/dist/monaco.d.ts +0 -8
- package/dist/workers/common/initialize.js +0 -16
- package/dist/workers/common/workers.js +0 -141
- package/dist/workers/editor/common/abstractSyntaxTokenBackend.js +0 -128
- package/dist/workers/editor/common/abstractText.js +0 -89
- package/dist/workers/editor/common/ast.js +0 -485
- package/dist/workers/editor/common/autoIndent.js +0 -390
- package/dist/workers/editor/common/beforeEditPositionMapper.js +0 -110
- package/dist/workers/editor/common/bracketPairsImpl.js +0 -717
- package/dist/workers/editor/common/bracketPairsTree.js +0 -343
- package/dist/workers/editor/common/brackets.js +0 -108
- package/dist/workers/editor/common/characterClassifier.js +0 -59
- package/dist/workers/editor/common/characterPair.js +0 -40
- package/dist/workers/editor/common/colorizedBracketPairsDecorationProvider.js +0 -97
- package/dist/workers/editor/common/columnRange.js +0 -35
- package/dist/workers/editor/common/combineTextEditInfos.js +0 -124
- package/dist/workers/editor/common/common.js +0 -20
- package/dist/workers/editor/common/computeMovedLines.js +0 -249
- package/dist/workers/editor/common/concat23Trees.js +0 -192
- package/dist/workers/editor/common/contiguousMultilineTokens.js +0 -32
- package/dist/workers/editor/common/contiguousMultilineTokensBuilder.js +0 -23
- package/dist/workers/editor/common/contiguousTokensEditing.js +0 -128
- package/dist/workers/editor/common/contiguousTokensStore.js +0 -207
- package/dist/workers/editor/common/coordinatesConverter.js +0 -51
- package/dist/workers/editor/common/cursor.js +0 -899
- package/dist/workers/editor/common/cursorAtomicMoveOperations.js +0 -145
- package/dist/workers/editor/common/cursorCollection.js +0 -194
- package/dist/workers/editor/common/cursorColumnSelection.js +0 -93
- package/dist/workers/editor/common/cursorColumns.js +0 -112
- package/dist/workers/editor/common/cursorCommon.js +0 -250
- package/dist/workers/editor/common/cursorContext.js +0 -15
- package/dist/workers/editor/common/cursorDeleteOperations.js +0 -231
- package/dist/workers/editor/common/cursorMoveCommands.js +0 -676
- package/dist/workers/editor/common/cursorMoveOperations.js +0 -290
- package/dist/workers/editor/common/cursorTypeEditOperations.js +0 -968
- package/dist/workers/editor/common/cursorTypeOperations.js +0 -173
- package/dist/workers/editor/common/cursorUtils.js +0 -75
- package/dist/workers/editor/common/cursorWordOperations.js +0 -720
- package/dist/workers/editor/common/defaultDocumentColorsComputer.js +0 -138
- package/dist/workers/editor/common/defaultLinesDiffComputer.js +0 -188
- package/dist/workers/editor/common/diffAlgorithm.js +0 -139
- package/dist/workers/editor/common/diffEditor.js +0 -38
- package/dist/workers/editor/common/dynamicProgrammingDiffing.js +0 -101
- package/dist/workers/editor/common/edit.js +0 -183
- package/dist/workers/editor/common/editOperation.js +0 -36
- package/dist/workers/editor/common/editStack.js +0 -363
- package/dist/workers/editor/common/editorAction.js +0 -26
- package/dist/workers/editor/common/editorBaseApi.js +0 -43
- package/dist/workers/editor/common/editorColorRegistry.js +0 -102
- package/dist/workers/editor/common/editorCommon.js +0 -13
- package/dist/workers/editor/common/editorConfigurationSchema.js +0 -338
- package/dist/workers/editor/common/editorContextKeys.js +0 -84
- package/dist/workers/editor/common/editorFeatures.js +0 -17
- package/dist/workers/editor/common/editorOptions.js +0 -3440
- package/dist/workers/editor/common/editorTheme.js +0 -23
- package/dist/workers/editor/common/editorWebWorker.js +0 -299
- package/dist/workers/editor/common/editorWorker.js +0 -9
- package/dist/workers/editor/common/editorWorkerHost.js +0 -15
- package/dist/workers/editor/common/editorZoom.js +0 -26
- package/dist/workers/editor/common/electricCharacter.js +0 -55
- package/dist/workers/editor/common/encodedTokenAttributes.js +0 -79
- package/dist/workers/editor/common/enterAction.js +0 -53
- package/dist/workers/editor/common/eolCounter.js +0 -44
- package/dist/workers/editor/common/findSectionHeaders.js +0 -128
- package/dist/workers/editor/common/fixBrackets.js +0 -67
- package/dist/workers/editor/common/fixedArray.js +0 -70
- package/dist/workers/editor/common/fontInfo.js +0 -172
- package/dist/workers/editor/common/fontInfoFromSettings.js +0 -29
- package/dist/workers/editor/common/getIconClasses.js +0 -106
- package/dist/workers/editor/common/getPositionOffsetTransformerFromTextModel.js +0 -24
- package/dist/workers/editor/common/glyphLanesModel.js +0 -61
- package/dist/workers/editor/common/guidesTextModelPart.js +0 -405
- package/dist/workers/editor/common/heuristicSequenceOptimizations.js +0 -374
- package/dist/workers/editor/common/indentRules.js +0 -63
- package/dist/workers/editor/common/indentation.js +0 -39
- package/dist/workers/editor/common/indentationGuesser.js +0 -178
- package/dist/workers/editor/common/indentationLineProcessor.js +0 -193
- package/dist/workers/editor/common/inlineDecorations.js +0 -26
- package/dist/workers/editor/common/inplaceReplaceSupport.js +0 -87
- package/dist/workers/editor/common/inputMode.js +0 -22
- package/dist/workers/editor/common/intervalTree.js +0 -1002
- package/dist/workers/editor/common/language.js +0 -9
- package/dist/workers/editor/common/languageBracketsConfiguration.js +0 -133
- package/dist/workers/editor/common/languageConfiguration.js +0 -138
- package/dist/workers/editor/common/languageConfigurationRegistry.js +0 -361
- package/dist/workers/editor/common/languageFeatureDebounce.js +0 -137
- package/dist/workers/editor/common/languageFeatureRegistry.js +0 -180
- package/dist/workers/editor/common/languageFeatures.js +0 -9
- package/dist/workers/editor/common/languageFeaturesService.js +0 -47
- package/dist/workers/editor/common/languageSelector.js +0 -112
- package/dist/workers/editor/common/languageService.js +0 -92
- package/dist/workers/editor/common/languages.js +0 -522
- package/dist/workers/editor/common/languagesAssociations.js +0 -193
- package/dist/workers/editor/common/languagesRegistry.js +0 -237
- package/dist/workers/editor/common/legacyLinesDiffComputer.js +0 -468
- package/dist/workers/editor/common/length.js +0 -129
- package/dist/workers/editor/common/lineDecorations.js +0 -208
- package/dist/workers/editor/common/lineEdit.js +0 -75
- package/dist/workers/editor/common/lineHeights.js +0 -370
- package/dist/workers/editor/common/linePart.js +0 -25
- package/dist/workers/editor/common/lineRange.js +0 -312
- package/dist/workers/editor/common/lineSequence.js +0 -36
- package/dist/workers/editor/common/lineTokens.js +0 -405
- package/dist/workers/editor/common/linesDiffComputer.js +0 -29
- package/dist/workers/editor/common/linesDiffComputers.js +0 -13
- package/dist/workers/editor/common/linesLayout.js +0 -765
- package/dist/workers/editor/common/linesSliceCharSequence.js +0 -205
- package/dist/workers/editor/common/linkComputer.js +0 -269
- package/dist/workers/editor/common/markerDecorations.js +0 -9
- package/dist/workers/editor/common/markerDecorationsService.js +0 -248
- package/dist/workers/editor/common/minimapTokensColorTracker.js +0 -58
- package/dist/workers/editor/common/mirrorTextModel.js +0 -117
- package/dist/workers/editor/common/model.js +0 -9
- package/dist/workers/editor/common/modelLineProjection.js +0 -350
- package/dist/workers/editor/common/modelLineProjectionData.js +0 -297
- package/dist/workers/editor/common/modelService.js +0 -413
- package/dist/workers/editor/common/modesRegistry.js +0 -75
- package/dist/workers/editor/common/monospaceLineBreaksComputer.js +0 -473
- package/dist/workers/editor/common/myersDiffAlgorithm.js +0 -159
- package/dist/workers/editor/common/nodeReader.js +0 -127
- package/dist/workers/editor/common/nullTokenize.js +0 -29
- package/dist/workers/editor/common/offsetRange.js +0 -225
- package/dist/workers/editor/common/onEnter.js +0 -109
- package/dist/workers/editor/common/oneCursor.js +0 -117
- package/dist/workers/editor/common/overviewZoneManager.js +0 -176
- package/dist/workers/editor/common/parser.js +0 -121
- package/dist/workers/editor/common/pieceTreeBase.js +0 -1473
- package/dist/workers/editor/common/pieceTreeTextBuffer.js +0 -461
- package/dist/workers/editor/common/pieceTreeTextBufferBuilder.js +0 -140
- package/dist/workers/editor/common/point.js +0 -50
- package/dist/workers/editor/common/position.js +0 -142
- package/dist/workers/editor/common/positionToOffset.js +0 -17
- package/dist/workers/editor/common/positionToOffsetImpl.js +0 -98
- package/dist/workers/editor/common/prefixSumComputer.js +0 -226
- package/dist/workers/editor/common/range.js +0 -421
- package/dist/workers/editor/common/rangeMapping.js +0 -229
- package/dist/workers/editor/common/rangeSingleLine.js +0 -17
- package/dist/workers/editor/common/rbTreeBase.js +0 -362
- package/dist/workers/editor/common/rect.js +0 -163
- package/dist/workers/editor/common/replaceCommand.js +0 -158
- package/dist/workers/editor/common/resolverService.js +0 -5
- package/dist/workers/editor/common/rgba.js +0 -35
- package/dist/workers/editor/common/richEditBrackets.js +0 -356
- package/dist/workers/editor/common/selection.js +0 -145
- package/dist/workers/editor/common/semanticTokensDto.js +0 -82
- package/dist/workers/editor/common/semanticTokensProviderStyling.js +0 -263
- package/dist/workers/editor/common/semanticTokensStyling.js +0 -9
- package/dist/workers/editor/common/semanticTokensStylingService.js +0 -47
- package/dist/workers/editor/common/shiftCommand.js +0 -241
- package/dist/workers/editor/common/smallImmutableSet.js +0 -108
- package/dist/workers/editor/common/sparseMultilineTokens.js +0 -548
- package/dist/workers/editor/common/sparseTokensStore.js +0 -210
- package/dist/workers/editor/common/standaloneEnums.js +0 -1017
- package/dist/workers/editor/common/standaloneStrings.js +0 -42
- package/dist/workers/editor/common/stringBuilder.js +0 -122
- package/dist/workers/editor/common/stringEdit.js +0 -165
- package/dist/workers/editor/common/supports.js +0 -58
- package/dist/workers/editor/common/surroundSelectionCommand.js +0 -44
- package/dist/workers/editor/common/textChange.js +0 -248
- package/dist/workers/editor/common/textEdit.js +0 -269
- package/dist/workers/editor/common/textLength.js +0 -87
- package/dist/workers/editor/common/textModel.js +0 -2031
- package/dist/workers/editor/common/textModelBracketPairs.js +0 -45
- package/dist/workers/editor/common/textModelDefaults.js +0 -18
- package/dist/workers/editor/common/textModelEditSource.js +0 -166
- package/dist/workers/editor/common/textModelEvents.js +0 -216
- package/dist/workers/editor/common/textModelGuides.js +0 -40
- package/dist/workers/editor/common/textModelPart.js +0 -23
- package/dist/workers/editor/common/textModelSearch.js +0 -455
- package/dist/workers/editor/common/textModelStringEdit.js +0 -11
- package/dist/workers/editor/common/textModelSync.impl.js +0 -307
- package/dist/workers/editor/common/textModelText.js +0 -26
- package/dist/workers/editor/common/textModelTokens.js +0 -436
- package/dist/workers/editor/common/textResourceConfiguration.js +0 -6
- package/dist/workers/editor/common/textToHtmlTokenizer.js +0 -139
- package/dist/workers/editor/common/tokenStore.js +0 -407
- package/dist/workers/editor/common/tokenWithTextArray.js +0 -73
- package/dist/workers/editor/common/tokenization.js +0 -287
- package/dist/workers/editor/common/tokenizationRegistry.js +0 -123
- package/dist/workers/editor/common/tokenizationTextModelPart.js +0 -275
- package/dist/workers/editor/common/tokenizer.js +0 -301
- package/dist/workers/editor/common/tokenizerSyntaxTokenBackend.js +0 -261
- package/dist/workers/editor/common/treeSitterLibraryService.js +0 -9
- package/dist/workers/editor/common/treeSitterSyntaxTokenBackend.js +0 -167
- package/dist/workers/editor/common/treeSitterThemeService.js +0 -9
- package/dist/workers/editor/common/treeSitterTokenizationImpl.js +0 -713
- package/dist/workers/editor/common/treeSitterTree.js +0 -395
- package/dist/workers/editor/common/treeViewsDnd.js +0 -24
- package/dist/workers/editor/common/treeViewsDndService.js +0 -12
- package/dist/workers/editor/common/trimTrailingWhitespaceCommand.js +0 -98
- package/dist/workers/editor/common/unicodeTextModelHighlighter.js +0 -188
- package/dist/workers/editor/common/utils.js +0 -62
- package/dist/workers/editor/common/viewContext.js +0 -22
- package/dist/workers/editor/common/viewEventHandler.js +0 -186
- package/dist/workers/editor/common/viewEvents.js +0 -180
- package/dist/workers/editor/common/viewLayout.js +0 -368
- package/dist/workers/editor/common/viewLineRenderer.js +0 -948
- package/dist/workers/editor/common/viewLinesViewportData.js +0 -30
- package/dist/workers/editor/common/viewModel.js +0 -98
- package/dist/workers/editor/common/viewModelDecoration.js +0 -55
- package/dist/workers/editor/common/viewModelDecorations.js +0 -132
- package/dist/workers/editor/common/viewModelEventDispatcher.js +0 -398
- package/dist/workers/editor/common/viewModelImpl.js +0 -1163
- package/dist/workers/editor/common/viewModelLines.js +0 -938
- package/dist/workers/editor/common/wordCharacterClassifier.js +0 -87
- package/dist/workers/editor/common/wordHelper.js +0 -127
- package/dist/workers/language/cssMode.js +0 -198
- package/dist/workers/language/cssWorker.js +0 -183
- package/dist/workers/language/htmlMode.js +0 -213
- package/dist/workers/language/htmlWorker.js +0 -126
- package/dist/workers/language/jsonMode.js +0 -224
- package/dist/workers/language/jsonWorker.js +0 -187
- package/dist/workers/language/languageFeatures.js +0 -1009
- package/dist/workers/language/lib.index.js +0 -103
- package/dist/workers/language/lib.js +0 -1107
- package/dist/workers/language/lspLanguageFeatures.js +0 -716
- package/dist/workers/language/monaco.contribution.js +0 -144
- package/dist/workers/language/tokenization.js +0 -189
- package/dist/workers/language/tsMode.js +0 -212
- package/dist/workers/language/tsWorker.js +0 -352
- package/dist/workers/language/typescriptServices.js +0 -210154
- package/dist/workers/language/typescriptServicesMetadata.js +0 -3
- package/dist/workers/language/workerManager.js +0 -65
- /package/dist/workers/{language/css.worker.js → css.worker.js} +0 -0
- /package/dist/workers/{editor/editor.worker.js → editor.worker.js} +0 -0
- /package/dist/workers/{language/html.worker.js → html.worker.js} +0 -0
- /package/dist/workers/{language/json.worker.js → json.worker.js} +0 -0
- /package/dist/workers/{language/ts.worker.js → ts.worker.js} +0 -0
|
@@ -1,1002 +0,0 @@
|
|
|
1
|
-
/*---------------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
-
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
function getNodeColor(node) {
|
|
6
|
-
return ((node.metadata & 1 /* Constants.ColorMask */) >>> 0 /* Constants.ColorOffset */);
|
|
7
|
-
}
|
|
8
|
-
function setNodeColor(node, color) {
|
|
9
|
-
node.metadata = ((node.metadata & 254 /* Constants.ColorMaskInverse */) | (color << 0 /* Constants.ColorOffset */));
|
|
10
|
-
}
|
|
11
|
-
function getNodeIsVisited(node) {
|
|
12
|
-
return ((node.metadata & 2 /* Constants.IsVisitedMask */) >>> 1 /* Constants.IsVisitedOffset */) === 1;
|
|
13
|
-
}
|
|
14
|
-
function setNodeIsVisited(node, value) {
|
|
15
|
-
node.metadata = ((node.metadata & 253 /* Constants.IsVisitedMaskInverse */) | ((value ? 1 : 0) << 1 /* Constants.IsVisitedOffset */));
|
|
16
|
-
}
|
|
17
|
-
function getNodeIsForValidation(node) {
|
|
18
|
-
return ((node.metadata & 4 /* Constants.IsForValidationMask */) >>> 2 /* Constants.IsForValidationOffset */) === 1;
|
|
19
|
-
}
|
|
20
|
-
function setNodeIsForValidation(node, value) {
|
|
21
|
-
node.metadata = ((node.metadata & 251 /* Constants.IsForValidationMaskInverse */) | ((value ? 1 : 0) << 2 /* Constants.IsForValidationOffset */));
|
|
22
|
-
}
|
|
23
|
-
function getNodeIsInGlyphMargin(node) {
|
|
24
|
-
return ((node.metadata & 64 /* Constants.IsMarginMask */) >>> 6 /* Constants.IsMarginOffset */) === 1;
|
|
25
|
-
}
|
|
26
|
-
function setNodeIsInGlyphMargin(node, value) {
|
|
27
|
-
node.metadata = ((node.metadata & 191 /* Constants.IsMarginMaskInverse */) | ((value ? 1 : 0) << 6 /* Constants.IsMarginOffset */));
|
|
28
|
-
}
|
|
29
|
-
function getNodeAffectsFont(node) {
|
|
30
|
-
return ((node.metadata & 128 /* Constants.AffectsFontMask */) >>> 7 /* Constants.AffectsFontOffset */) === 1;
|
|
31
|
-
}
|
|
32
|
-
function setNodeAffectsFont(node, value) {
|
|
33
|
-
node.metadata = ((node.metadata & 127 /* Constants.AffectsFontMaskInverse */) | ((value ? 1 : 0) << 7 /* Constants.AffectsFontOffset */));
|
|
34
|
-
}
|
|
35
|
-
function getNodeStickiness(node) {
|
|
36
|
-
return ((node.metadata & 24 /* Constants.StickinessMask */) >>> 3 /* Constants.StickinessOffset */);
|
|
37
|
-
}
|
|
38
|
-
function _setNodeStickiness(node, stickiness) {
|
|
39
|
-
node.metadata = ((node.metadata & 231 /* Constants.StickinessMaskInverse */) | (stickiness << 3 /* Constants.StickinessOffset */));
|
|
40
|
-
}
|
|
41
|
-
function getCollapseOnReplaceEdit(node) {
|
|
42
|
-
return ((node.metadata & 32 /* Constants.CollapseOnReplaceEditMask */) >>> 5 /* Constants.CollapseOnReplaceEditOffset */) === 1;
|
|
43
|
-
}
|
|
44
|
-
function setCollapseOnReplaceEdit(node, value) {
|
|
45
|
-
node.metadata = ((node.metadata & 223 /* Constants.CollapseOnReplaceEditMaskInverse */) | ((value ? 1 : 0) << 5 /* Constants.CollapseOnReplaceEditOffset */));
|
|
46
|
-
}
|
|
47
|
-
class IntervalNode {
|
|
48
|
-
constructor(id, start, end) {
|
|
49
|
-
this.metadata = 0;
|
|
50
|
-
this.parent = this;
|
|
51
|
-
this.left = this;
|
|
52
|
-
this.right = this;
|
|
53
|
-
setNodeColor(this, 1 /* NodeColor.Red */);
|
|
54
|
-
this.start = start;
|
|
55
|
-
this.end = end;
|
|
56
|
-
// FORCE_OVERFLOWING_TEST: this.delta = start;
|
|
57
|
-
this.delta = 0;
|
|
58
|
-
this.maxEnd = end;
|
|
59
|
-
this.id = id;
|
|
60
|
-
this.ownerId = 0;
|
|
61
|
-
this.options = null;
|
|
62
|
-
setNodeIsForValidation(this, false);
|
|
63
|
-
setNodeIsInGlyphMargin(this, false);
|
|
64
|
-
_setNodeStickiness(this, 1 /* TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */);
|
|
65
|
-
setCollapseOnReplaceEdit(this, false);
|
|
66
|
-
setNodeAffectsFont(this, false);
|
|
67
|
-
this.cachedVersionId = 0;
|
|
68
|
-
this.cachedAbsoluteStart = start;
|
|
69
|
-
this.cachedAbsoluteEnd = end;
|
|
70
|
-
this.range = null;
|
|
71
|
-
setNodeIsVisited(this, false);
|
|
72
|
-
}
|
|
73
|
-
reset(versionId, start, end, range) {
|
|
74
|
-
this.start = start;
|
|
75
|
-
this.end = end;
|
|
76
|
-
this.maxEnd = end;
|
|
77
|
-
this.cachedVersionId = versionId;
|
|
78
|
-
this.cachedAbsoluteStart = start;
|
|
79
|
-
this.cachedAbsoluteEnd = end;
|
|
80
|
-
this.range = range;
|
|
81
|
-
}
|
|
82
|
-
setOptions(options) {
|
|
83
|
-
this.options = options;
|
|
84
|
-
const className = this.options.className;
|
|
85
|
-
setNodeIsForValidation(this, (className === "squiggly-error" /* ClassName.EditorErrorDecoration */
|
|
86
|
-
|| className === "squiggly-warning" /* ClassName.EditorWarningDecoration */
|
|
87
|
-
|| className === "squiggly-info" /* ClassName.EditorInfoDecoration */));
|
|
88
|
-
setNodeIsInGlyphMargin(this, this.options.glyphMarginClassName !== null);
|
|
89
|
-
_setNodeStickiness(this, this.options.stickiness);
|
|
90
|
-
setCollapseOnReplaceEdit(this, this.options.collapseOnReplaceEdit);
|
|
91
|
-
setNodeAffectsFont(this, this.options.affectsFont ?? false);
|
|
92
|
-
}
|
|
93
|
-
setCachedOffsets(absoluteStart, absoluteEnd, cachedVersionId) {
|
|
94
|
-
if (this.cachedVersionId !== cachedVersionId) {
|
|
95
|
-
this.range = null;
|
|
96
|
-
}
|
|
97
|
-
this.cachedVersionId = cachedVersionId;
|
|
98
|
-
this.cachedAbsoluteStart = absoluteStart;
|
|
99
|
-
this.cachedAbsoluteEnd = absoluteEnd;
|
|
100
|
-
}
|
|
101
|
-
detach() {
|
|
102
|
-
this.parent = null;
|
|
103
|
-
this.left = null;
|
|
104
|
-
this.right = null;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const SENTINEL = new IntervalNode(null, 0, 0);
|
|
108
|
-
SENTINEL.parent = SENTINEL;
|
|
109
|
-
SENTINEL.left = SENTINEL;
|
|
110
|
-
SENTINEL.right = SENTINEL;
|
|
111
|
-
setNodeColor(SENTINEL, 0 /* NodeColor.Black */);
|
|
112
|
-
class IntervalTree {
|
|
113
|
-
constructor() {
|
|
114
|
-
this.root = SENTINEL;
|
|
115
|
-
this.requestNormalizeDelta = false;
|
|
116
|
-
}
|
|
117
|
-
intervalSearch(start, end, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations) {
|
|
118
|
-
if (this.root === SENTINEL) {
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
return intervalSearch(this, start, end, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
122
|
-
}
|
|
123
|
-
search(filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations) {
|
|
124
|
-
if (this.root === SENTINEL) {
|
|
125
|
-
return [];
|
|
126
|
-
}
|
|
127
|
-
return search(this, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations);
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Will not set `cachedAbsoluteStart` nor `cachedAbsoluteEnd` on the returned nodes!
|
|
131
|
-
*/
|
|
132
|
-
collectNodesFromOwner(ownerId) {
|
|
133
|
-
return collectNodesFromOwner(this, ownerId);
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Will not set `cachedAbsoluteStart` nor `cachedAbsoluteEnd` on the returned nodes!
|
|
137
|
-
*/
|
|
138
|
-
collectNodesPostOrder() {
|
|
139
|
-
return collectNodesPostOrder(this);
|
|
140
|
-
}
|
|
141
|
-
insert(node) {
|
|
142
|
-
rbTreeInsert(this, node);
|
|
143
|
-
this._normalizeDeltaIfNecessary();
|
|
144
|
-
}
|
|
145
|
-
delete(node) {
|
|
146
|
-
rbTreeDelete(this, node);
|
|
147
|
-
this._normalizeDeltaIfNecessary();
|
|
148
|
-
}
|
|
149
|
-
resolveNode(node, cachedVersionId) {
|
|
150
|
-
const initialNode = node;
|
|
151
|
-
let delta = 0;
|
|
152
|
-
while (node !== this.root) {
|
|
153
|
-
if (node === node.parent.right) {
|
|
154
|
-
delta += node.parent.delta;
|
|
155
|
-
}
|
|
156
|
-
node = node.parent;
|
|
157
|
-
}
|
|
158
|
-
const nodeStart = initialNode.start + delta;
|
|
159
|
-
const nodeEnd = initialNode.end + delta;
|
|
160
|
-
initialNode.setCachedOffsets(nodeStart, nodeEnd, cachedVersionId);
|
|
161
|
-
}
|
|
162
|
-
acceptReplace(offset, length, textLength, forceMoveMarkers) {
|
|
163
|
-
// Our strategy is to remove all directly impacted nodes, and then add them back to the tree.
|
|
164
|
-
// (1) collect all nodes that are intersecting this edit as nodes of interest
|
|
165
|
-
const nodesOfInterest = searchForEditing(this, offset, offset + length);
|
|
166
|
-
// (2) remove all nodes that are intersecting this edit
|
|
167
|
-
for (let i = 0, len = nodesOfInterest.length; i < len; i++) {
|
|
168
|
-
const node = nodesOfInterest[i];
|
|
169
|
-
rbTreeDelete(this, node);
|
|
170
|
-
}
|
|
171
|
-
this._normalizeDeltaIfNecessary();
|
|
172
|
-
// (3) edit all tree nodes except the nodes of interest
|
|
173
|
-
noOverlapReplace(this, offset, offset + length, textLength);
|
|
174
|
-
this._normalizeDeltaIfNecessary();
|
|
175
|
-
// (4) edit the nodes of interest and insert them back in the tree
|
|
176
|
-
for (let i = 0, len = nodesOfInterest.length; i < len; i++) {
|
|
177
|
-
const node = nodesOfInterest[i];
|
|
178
|
-
node.start = node.cachedAbsoluteStart;
|
|
179
|
-
node.end = node.cachedAbsoluteEnd;
|
|
180
|
-
nodeAcceptEdit(node, offset, (offset + length), textLength, forceMoveMarkers);
|
|
181
|
-
node.maxEnd = node.end;
|
|
182
|
-
rbTreeInsert(this, node);
|
|
183
|
-
}
|
|
184
|
-
this._normalizeDeltaIfNecessary();
|
|
185
|
-
}
|
|
186
|
-
_normalizeDeltaIfNecessary() {
|
|
187
|
-
if (!this.requestNormalizeDelta) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
this.requestNormalizeDelta = false;
|
|
191
|
-
normalizeDelta(this);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
//#region Delta Normalization
|
|
195
|
-
function normalizeDelta(T) {
|
|
196
|
-
let node = T.root;
|
|
197
|
-
let delta = 0;
|
|
198
|
-
while (node !== SENTINEL) {
|
|
199
|
-
if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
|
|
200
|
-
// go left
|
|
201
|
-
node = node.left;
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
|
|
205
|
-
// go right
|
|
206
|
-
delta += node.delta;
|
|
207
|
-
node = node.right;
|
|
208
|
-
continue;
|
|
209
|
-
}
|
|
210
|
-
// handle current node
|
|
211
|
-
node.start = delta + node.start;
|
|
212
|
-
node.end = delta + node.end;
|
|
213
|
-
node.delta = 0;
|
|
214
|
-
recomputeMaxEnd(node);
|
|
215
|
-
setNodeIsVisited(node, true);
|
|
216
|
-
// going up from this node
|
|
217
|
-
setNodeIsVisited(node.left, false);
|
|
218
|
-
setNodeIsVisited(node.right, false);
|
|
219
|
-
if (node === node.parent.right) {
|
|
220
|
-
delta -= node.parent.delta;
|
|
221
|
-
}
|
|
222
|
-
node = node.parent;
|
|
223
|
-
}
|
|
224
|
-
setNodeIsVisited(T.root, false);
|
|
225
|
-
}
|
|
226
|
-
function adjustMarkerBeforeColumn(markerOffset, markerStickToPreviousCharacter, checkOffset, moveSemantics) {
|
|
227
|
-
if (markerOffset < checkOffset) {
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
230
|
-
if (markerOffset > checkOffset) {
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
|
-
if (moveSemantics === 1 /* MarkerMoveSemantics.ForceMove */) {
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
if (moveSemantics === 2 /* MarkerMoveSemantics.ForceStay */) {
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
return markerStickToPreviousCharacter;
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* This is a lot more complicated than strictly necessary to maintain the same behaviour
|
|
243
|
-
* as when decorations were implemented using two markers.
|
|
244
|
-
*/
|
|
245
|
-
function nodeAcceptEdit(node, start, end, textLength, forceMoveMarkers) {
|
|
246
|
-
const nodeStickiness = getNodeStickiness(node);
|
|
247
|
-
const startStickToPreviousCharacter = (nodeStickiness === 0 /* TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges */
|
|
248
|
-
|| nodeStickiness === 2 /* TrackedRangeStickiness.GrowsOnlyWhenTypingBefore */);
|
|
249
|
-
const endStickToPreviousCharacter = (nodeStickiness === 1 /* TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */
|
|
250
|
-
|| nodeStickiness === 2 /* TrackedRangeStickiness.GrowsOnlyWhenTypingBefore */);
|
|
251
|
-
const deletingCnt = (end - start);
|
|
252
|
-
const insertingCnt = textLength;
|
|
253
|
-
const commonLength = Math.min(deletingCnt, insertingCnt);
|
|
254
|
-
const nodeStart = node.start;
|
|
255
|
-
let startDone = false;
|
|
256
|
-
const nodeEnd = node.end;
|
|
257
|
-
let endDone = false;
|
|
258
|
-
if (start <= nodeStart && nodeEnd <= end && getCollapseOnReplaceEdit(node)) {
|
|
259
|
-
// This edit encompasses the entire decoration range
|
|
260
|
-
// and the decoration has asked to become collapsed
|
|
261
|
-
node.start = start;
|
|
262
|
-
startDone = true;
|
|
263
|
-
node.end = start;
|
|
264
|
-
endDone = true;
|
|
265
|
-
}
|
|
266
|
-
{
|
|
267
|
-
const moveSemantics = forceMoveMarkers ? 1 /* MarkerMoveSemantics.ForceMove */ : (deletingCnt > 0 ? 2 /* MarkerMoveSemantics.ForceStay */ : 0 /* MarkerMoveSemantics.MarkerDefined */);
|
|
268
|
-
if (!startDone && adjustMarkerBeforeColumn(nodeStart, startStickToPreviousCharacter, start, moveSemantics)) {
|
|
269
|
-
startDone = true;
|
|
270
|
-
}
|
|
271
|
-
if (!endDone && adjustMarkerBeforeColumn(nodeEnd, endStickToPreviousCharacter, start, moveSemantics)) {
|
|
272
|
-
endDone = true;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
if (commonLength > 0 && !forceMoveMarkers) {
|
|
276
|
-
const moveSemantics = (deletingCnt > insertingCnt ? 2 /* MarkerMoveSemantics.ForceStay */ : 0 /* MarkerMoveSemantics.MarkerDefined */);
|
|
277
|
-
if (!startDone && adjustMarkerBeforeColumn(nodeStart, startStickToPreviousCharacter, start + commonLength, moveSemantics)) {
|
|
278
|
-
startDone = true;
|
|
279
|
-
}
|
|
280
|
-
if (!endDone && adjustMarkerBeforeColumn(nodeEnd, endStickToPreviousCharacter, start + commonLength, moveSemantics)) {
|
|
281
|
-
endDone = true;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
{
|
|
285
|
-
const moveSemantics = forceMoveMarkers ? 1 /* MarkerMoveSemantics.ForceMove */ : 0 /* MarkerMoveSemantics.MarkerDefined */;
|
|
286
|
-
if (!startDone && adjustMarkerBeforeColumn(nodeStart, startStickToPreviousCharacter, end, moveSemantics)) {
|
|
287
|
-
node.start = start + insertingCnt;
|
|
288
|
-
startDone = true;
|
|
289
|
-
}
|
|
290
|
-
if (!endDone && adjustMarkerBeforeColumn(nodeEnd, endStickToPreviousCharacter, end, moveSemantics)) {
|
|
291
|
-
node.end = start + insertingCnt;
|
|
292
|
-
endDone = true;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
// Finish
|
|
296
|
-
const deltaColumn = (insertingCnt - deletingCnt);
|
|
297
|
-
if (!startDone) {
|
|
298
|
-
node.start = Math.max(0, nodeStart + deltaColumn);
|
|
299
|
-
}
|
|
300
|
-
if (!endDone) {
|
|
301
|
-
node.end = Math.max(0, nodeEnd + deltaColumn);
|
|
302
|
-
}
|
|
303
|
-
if (node.start > node.end) {
|
|
304
|
-
node.end = node.start;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
function searchForEditing(T, start, end) {
|
|
308
|
-
// https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
|
|
309
|
-
// Now, it is known that two intervals A and B overlap only when both
|
|
310
|
-
// A.low <= B.high and A.high >= B.low. When searching the trees for
|
|
311
|
-
// nodes overlapping with a given interval, you can immediately skip:
|
|
312
|
-
// a) all nodes to the right of nodes whose low value is past the end of the given interval.
|
|
313
|
-
// b) all nodes that have their maximum 'high' value below the start of the given interval.
|
|
314
|
-
let node = T.root;
|
|
315
|
-
let delta = 0;
|
|
316
|
-
let nodeMaxEnd = 0;
|
|
317
|
-
let nodeStart = 0;
|
|
318
|
-
let nodeEnd = 0;
|
|
319
|
-
const result = [];
|
|
320
|
-
let resultLen = 0;
|
|
321
|
-
while (node !== SENTINEL) {
|
|
322
|
-
if (getNodeIsVisited(node)) {
|
|
323
|
-
// going up from this node
|
|
324
|
-
setNodeIsVisited(node.left, false);
|
|
325
|
-
setNodeIsVisited(node.right, false);
|
|
326
|
-
if (node === node.parent.right) {
|
|
327
|
-
delta -= node.parent.delta;
|
|
328
|
-
}
|
|
329
|
-
node = node.parent;
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (!getNodeIsVisited(node.left)) {
|
|
333
|
-
// first time seeing this node
|
|
334
|
-
nodeMaxEnd = delta + node.maxEnd;
|
|
335
|
-
if (nodeMaxEnd < start) {
|
|
336
|
-
// cover case b) from above
|
|
337
|
-
// there is no need to search this node or its children
|
|
338
|
-
setNodeIsVisited(node, true);
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
if (node.left !== SENTINEL) {
|
|
342
|
-
// go left
|
|
343
|
-
node = node.left;
|
|
344
|
-
continue;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
// handle current node
|
|
348
|
-
nodeStart = delta + node.start;
|
|
349
|
-
if (nodeStart > end) {
|
|
350
|
-
// cover case a) from above
|
|
351
|
-
// there is no need to search this node or its right subtree
|
|
352
|
-
setNodeIsVisited(node, true);
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
nodeEnd = delta + node.end;
|
|
356
|
-
if (nodeEnd >= start) {
|
|
357
|
-
node.setCachedOffsets(nodeStart, nodeEnd, 0);
|
|
358
|
-
result[resultLen++] = node;
|
|
359
|
-
}
|
|
360
|
-
setNodeIsVisited(node, true);
|
|
361
|
-
if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
|
|
362
|
-
// go right
|
|
363
|
-
delta += node.delta;
|
|
364
|
-
node = node.right;
|
|
365
|
-
continue;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
setNodeIsVisited(T.root, false);
|
|
369
|
-
return result;
|
|
370
|
-
}
|
|
371
|
-
function noOverlapReplace(T, start, end, textLength) {
|
|
372
|
-
// https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
|
|
373
|
-
// Now, it is known that two intervals A and B overlap only when both
|
|
374
|
-
// A.low <= B.high and A.high >= B.low. When searching the trees for
|
|
375
|
-
// nodes overlapping with a given interval, you can immediately skip:
|
|
376
|
-
// a) all nodes to the right of nodes whose low value is past the end of the given interval.
|
|
377
|
-
// b) all nodes that have their maximum 'high' value below the start of the given interval.
|
|
378
|
-
let node = T.root;
|
|
379
|
-
let delta = 0;
|
|
380
|
-
let nodeMaxEnd = 0;
|
|
381
|
-
let nodeStart = 0;
|
|
382
|
-
const editDelta = (textLength - (end - start));
|
|
383
|
-
while (node !== SENTINEL) {
|
|
384
|
-
if (getNodeIsVisited(node)) {
|
|
385
|
-
// going up from this node
|
|
386
|
-
setNodeIsVisited(node.left, false);
|
|
387
|
-
setNodeIsVisited(node.right, false);
|
|
388
|
-
if (node === node.parent.right) {
|
|
389
|
-
delta -= node.parent.delta;
|
|
390
|
-
}
|
|
391
|
-
recomputeMaxEnd(node);
|
|
392
|
-
node = node.parent;
|
|
393
|
-
continue;
|
|
394
|
-
}
|
|
395
|
-
if (!getNodeIsVisited(node.left)) {
|
|
396
|
-
// first time seeing this node
|
|
397
|
-
nodeMaxEnd = delta + node.maxEnd;
|
|
398
|
-
if (nodeMaxEnd < start) {
|
|
399
|
-
// cover case b) from above
|
|
400
|
-
// there is no need to search this node or its children
|
|
401
|
-
setNodeIsVisited(node, true);
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
if (node.left !== SENTINEL) {
|
|
405
|
-
// go left
|
|
406
|
-
node = node.left;
|
|
407
|
-
continue;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
// handle current node
|
|
411
|
-
nodeStart = delta + node.start;
|
|
412
|
-
if (nodeStart > end) {
|
|
413
|
-
node.start += editDelta;
|
|
414
|
-
node.end += editDelta;
|
|
415
|
-
node.delta += editDelta;
|
|
416
|
-
if (node.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || node.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
|
|
417
|
-
T.requestNormalizeDelta = true;
|
|
418
|
-
}
|
|
419
|
-
// cover case a) from above
|
|
420
|
-
// there is no need to search this node or its right subtree
|
|
421
|
-
setNodeIsVisited(node, true);
|
|
422
|
-
continue;
|
|
423
|
-
}
|
|
424
|
-
setNodeIsVisited(node, true);
|
|
425
|
-
if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
|
|
426
|
-
// go right
|
|
427
|
-
delta += node.delta;
|
|
428
|
-
node = node.right;
|
|
429
|
-
continue;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
setNodeIsVisited(T.root, false);
|
|
433
|
-
}
|
|
434
|
-
//#endregion
|
|
435
|
-
//#region Searching
|
|
436
|
-
function collectNodesFromOwner(T, ownerId) {
|
|
437
|
-
let node = T.root;
|
|
438
|
-
const result = [];
|
|
439
|
-
let resultLen = 0;
|
|
440
|
-
while (node !== SENTINEL) {
|
|
441
|
-
if (getNodeIsVisited(node)) {
|
|
442
|
-
// going up from this node
|
|
443
|
-
setNodeIsVisited(node.left, false);
|
|
444
|
-
setNodeIsVisited(node.right, false);
|
|
445
|
-
node = node.parent;
|
|
446
|
-
continue;
|
|
447
|
-
}
|
|
448
|
-
if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
|
|
449
|
-
// go left
|
|
450
|
-
node = node.left;
|
|
451
|
-
continue;
|
|
452
|
-
}
|
|
453
|
-
// handle current node
|
|
454
|
-
if (node.ownerId === ownerId) {
|
|
455
|
-
result[resultLen++] = node;
|
|
456
|
-
}
|
|
457
|
-
setNodeIsVisited(node, true);
|
|
458
|
-
if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
|
|
459
|
-
// go right
|
|
460
|
-
node = node.right;
|
|
461
|
-
continue;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
setNodeIsVisited(T.root, false);
|
|
465
|
-
return result;
|
|
466
|
-
}
|
|
467
|
-
function collectNodesPostOrder(T) {
|
|
468
|
-
let node = T.root;
|
|
469
|
-
const result = [];
|
|
470
|
-
let resultLen = 0;
|
|
471
|
-
while (node !== SENTINEL) {
|
|
472
|
-
if (getNodeIsVisited(node)) {
|
|
473
|
-
// going up from this node
|
|
474
|
-
setNodeIsVisited(node.left, false);
|
|
475
|
-
setNodeIsVisited(node.right, false);
|
|
476
|
-
node = node.parent;
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
|
|
480
|
-
// go left
|
|
481
|
-
node = node.left;
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
|
|
485
|
-
// go right
|
|
486
|
-
node = node.right;
|
|
487
|
-
continue;
|
|
488
|
-
}
|
|
489
|
-
// handle current node
|
|
490
|
-
result[resultLen++] = node;
|
|
491
|
-
setNodeIsVisited(node, true);
|
|
492
|
-
}
|
|
493
|
-
setNodeIsVisited(T.root, false);
|
|
494
|
-
return result;
|
|
495
|
-
}
|
|
496
|
-
function search(T, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations) {
|
|
497
|
-
let node = T.root;
|
|
498
|
-
let delta = 0;
|
|
499
|
-
let nodeStart = 0;
|
|
500
|
-
let nodeEnd = 0;
|
|
501
|
-
const result = [];
|
|
502
|
-
let resultLen = 0;
|
|
503
|
-
while (node !== SENTINEL) {
|
|
504
|
-
if (getNodeIsVisited(node)) {
|
|
505
|
-
// going up from this node
|
|
506
|
-
setNodeIsVisited(node.left, false);
|
|
507
|
-
setNodeIsVisited(node.right, false);
|
|
508
|
-
if (node === node.parent.right) {
|
|
509
|
-
delta -= node.parent.delta;
|
|
510
|
-
}
|
|
511
|
-
node = node.parent;
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
if (node.left !== SENTINEL && !getNodeIsVisited(node.left)) {
|
|
515
|
-
// go left
|
|
516
|
-
node = node.left;
|
|
517
|
-
continue;
|
|
518
|
-
}
|
|
519
|
-
// handle current node
|
|
520
|
-
nodeStart = delta + node.start;
|
|
521
|
-
nodeEnd = delta + node.end;
|
|
522
|
-
node.setCachedOffsets(nodeStart, nodeEnd, cachedVersionId);
|
|
523
|
-
let include = true;
|
|
524
|
-
if (filterOwnerId && node.ownerId && node.ownerId !== filterOwnerId) {
|
|
525
|
-
include = false;
|
|
526
|
-
}
|
|
527
|
-
if (filterOutValidation && getNodeIsForValidation(node)) {
|
|
528
|
-
include = false;
|
|
529
|
-
}
|
|
530
|
-
if (filterFontDecorations && getNodeAffectsFont(node)) {
|
|
531
|
-
include = false;
|
|
532
|
-
}
|
|
533
|
-
if (onlyMarginDecorations && !getNodeIsInGlyphMargin(node)) {
|
|
534
|
-
include = false;
|
|
535
|
-
}
|
|
536
|
-
if (include) {
|
|
537
|
-
result[resultLen++] = node;
|
|
538
|
-
}
|
|
539
|
-
setNodeIsVisited(node, true);
|
|
540
|
-
if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
|
|
541
|
-
// go right
|
|
542
|
-
delta += node.delta;
|
|
543
|
-
node = node.right;
|
|
544
|
-
continue;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
setNodeIsVisited(T.root, false);
|
|
548
|
-
return result;
|
|
549
|
-
}
|
|
550
|
-
function intervalSearch(T, intervalStart, intervalEnd, filterOwnerId, filterOutValidation, filterFontDecorations, cachedVersionId, onlyMarginDecorations) {
|
|
551
|
-
// https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
|
|
552
|
-
// Now, it is known that two intervals A and B overlap only when both
|
|
553
|
-
// A.low <= B.high and A.high >= B.low. When searching the trees for
|
|
554
|
-
// nodes overlapping with a given interval, you can immediately skip:
|
|
555
|
-
// a) all nodes to the right of nodes whose low value is past the end of the given interval.
|
|
556
|
-
// b) all nodes that have their maximum 'high' value below the start of the given interval.
|
|
557
|
-
let node = T.root;
|
|
558
|
-
let delta = 0;
|
|
559
|
-
let nodeMaxEnd = 0;
|
|
560
|
-
let nodeStart = 0;
|
|
561
|
-
let nodeEnd = 0;
|
|
562
|
-
const result = [];
|
|
563
|
-
let resultLen = 0;
|
|
564
|
-
while (node !== SENTINEL) {
|
|
565
|
-
if (getNodeIsVisited(node)) {
|
|
566
|
-
// going up from this node
|
|
567
|
-
setNodeIsVisited(node.left, false);
|
|
568
|
-
setNodeIsVisited(node.right, false);
|
|
569
|
-
if (node === node.parent.right) {
|
|
570
|
-
delta -= node.parent.delta;
|
|
571
|
-
}
|
|
572
|
-
node = node.parent;
|
|
573
|
-
continue;
|
|
574
|
-
}
|
|
575
|
-
if (!getNodeIsVisited(node.left)) {
|
|
576
|
-
// first time seeing this node
|
|
577
|
-
nodeMaxEnd = delta + node.maxEnd;
|
|
578
|
-
if (nodeMaxEnd < intervalStart) {
|
|
579
|
-
// cover case b) from above
|
|
580
|
-
// there is no need to search this node or its children
|
|
581
|
-
setNodeIsVisited(node, true);
|
|
582
|
-
continue;
|
|
583
|
-
}
|
|
584
|
-
if (node.left !== SENTINEL) {
|
|
585
|
-
// go left
|
|
586
|
-
node = node.left;
|
|
587
|
-
continue;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
// handle current node
|
|
591
|
-
nodeStart = delta + node.start;
|
|
592
|
-
if (nodeStart > intervalEnd) {
|
|
593
|
-
// cover case a) from above
|
|
594
|
-
// there is no need to search this node or its right subtree
|
|
595
|
-
setNodeIsVisited(node, true);
|
|
596
|
-
continue;
|
|
597
|
-
}
|
|
598
|
-
nodeEnd = delta + node.end;
|
|
599
|
-
if (nodeEnd >= intervalStart) {
|
|
600
|
-
// There is overlap
|
|
601
|
-
node.setCachedOffsets(nodeStart, nodeEnd, cachedVersionId);
|
|
602
|
-
let include = true;
|
|
603
|
-
if (filterOwnerId && node.ownerId && node.ownerId !== filterOwnerId) {
|
|
604
|
-
include = false;
|
|
605
|
-
}
|
|
606
|
-
if (filterOutValidation && getNodeIsForValidation(node)) {
|
|
607
|
-
include = false;
|
|
608
|
-
}
|
|
609
|
-
if (filterFontDecorations && getNodeAffectsFont(node)) {
|
|
610
|
-
include = false;
|
|
611
|
-
}
|
|
612
|
-
if (onlyMarginDecorations && !getNodeIsInGlyphMargin(node)) {
|
|
613
|
-
include = false;
|
|
614
|
-
}
|
|
615
|
-
if (include) {
|
|
616
|
-
result[resultLen++] = node;
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
setNodeIsVisited(node, true);
|
|
620
|
-
if (node.right !== SENTINEL && !getNodeIsVisited(node.right)) {
|
|
621
|
-
// go right
|
|
622
|
-
delta += node.delta;
|
|
623
|
-
node = node.right;
|
|
624
|
-
continue;
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
setNodeIsVisited(T.root, false);
|
|
628
|
-
return result;
|
|
629
|
-
}
|
|
630
|
-
//#endregion
|
|
631
|
-
//#region Insertion
|
|
632
|
-
function rbTreeInsert(T, newNode) {
|
|
633
|
-
if (T.root === SENTINEL) {
|
|
634
|
-
newNode.parent = SENTINEL;
|
|
635
|
-
newNode.left = SENTINEL;
|
|
636
|
-
newNode.right = SENTINEL;
|
|
637
|
-
setNodeColor(newNode, 0 /* NodeColor.Black */);
|
|
638
|
-
T.root = newNode;
|
|
639
|
-
return T.root;
|
|
640
|
-
}
|
|
641
|
-
treeInsert(T, newNode);
|
|
642
|
-
recomputeMaxEndWalkToRoot(newNode.parent);
|
|
643
|
-
// repair tree
|
|
644
|
-
let x = newNode;
|
|
645
|
-
while (x !== T.root && getNodeColor(x.parent) === 1 /* NodeColor.Red */) {
|
|
646
|
-
if (x.parent === x.parent.parent.left) {
|
|
647
|
-
const y = x.parent.parent.right;
|
|
648
|
-
if (getNodeColor(y) === 1 /* NodeColor.Red */) {
|
|
649
|
-
setNodeColor(x.parent, 0 /* NodeColor.Black */);
|
|
650
|
-
setNodeColor(y, 0 /* NodeColor.Black */);
|
|
651
|
-
setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
|
|
652
|
-
x = x.parent.parent;
|
|
653
|
-
}
|
|
654
|
-
else {
|
|
655
|
-
if (x === x.parent.right) {
|
|
656
|
-
x = x.parent;
|
|
657
|
-
leftRotate(T, x);
|
|
658
|
-
}
|
|
659
|
-
setNodeColor(x.parent, 0 /* NodeColor.Black */);
|
|
660
|
-
setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
|
|
661
|
-
rightRotate(T, x.parent.parent);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
else {
|
|
665
|
-
const y = x.parent.parent.left;
|
|
666
|
-
if (getNodeColor(y) === 1 /* NodeColor.Red */) {
|
|
667
|
-
setNodeColor(x.parent, 0 /* NodeColor.Black */);
|
|
668
|
-
setNodeColor(y, 0 /* NodeColor.Black */);
|
|
669
|
-
setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
|
|
670
|
-
x = x.parent.parent;
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
if (x === x.parent.left) {
|
|
674
|
-
x = x.parent;
|
|
675
|
-
rightRotate(T, x);
|
|
676
|
-
}
|
|
677
|
-
setNodeColor(x.parent, 0 /* NodeColor.Black */);
|
|
678
|
-
setNodeColor(x.parent.parent, 1 /* NodeColor.Red */);
|
|
679
|
-
leftRotate(T, x.parent.parent);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
setNodeColor(T.root, 0 /* NodeColor.Black */);
|
|
684
|
-
return newNode;
|
|
685
|
-
}
|
|
686
|
-
function treeInsert(T, z) {
|
|
687
|
-
let delta = 0;
|
|
688
|
-
let x = T.root;
|
|
689
|
-
const zAbsoluteStart = z.start;
|
|
690
|
-
const zAbsoluteEnd = z.end;
|
|
691
|
-
while (true) {
|
|
692
|
-
const cmp = intervalCompare(zAbsoluteStart, zAbsoluteEnd, x.start + delta, x.end + delta);
|
|
693
|
-
if (cmp < 0) {
|
|
694
|
-
// this node should be inserted to the left
|
|
695
|
-
// => it is not affected by the node's delta
|
|
696
|
-
if (x.left === SENTINEL) {
|
|
697
|
-
z.start -= delta;
|
|
698
|
-
z.end -= delta;
|
|
699
|
-
z.maxEnd -= delta;
|
|
700
|
-
x.left = z;
|
|
701
|
-
break;
|
|
702
|
-
}
|
|
703
|
-
else {
|
|
704
|
-
x = x.left;
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
else {
|
|
708
|
-
// this node should be inserted to the right
|
|
709
|
-
// => it is not affected by the node's delta
|
|
710
|
-
if (x.right === SENTINEL) {
|
|
711
|
-
z.start -= (delta + x.delta);
|
|
712
|
-
z.end -= (delta + x.delta);
|
|
713
|
-
z.maxEnd -= (delta + x.delta);
|
|
714
|
-
x.right = z;
|
|
715
|
-
break;
|
|
716
|
-
}
|
|
717
|
-
else {
|
|
718
|
-
delta += x.delta;
|
|
719
|
-
x = x.right;
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
z.parent = x;
|
|
724
|
-
z.left = SENTINEL;
|
|
725
|
-
z.right = SENTINEL;
|
|
726
|
-
setNodeColor(z, 1 /* NodeColor.Red */);
|
|
727
|
-
}
|
|
728
|
-
//#endregion
|
|
729
|
-
//#region Deletion
|
|
730
|
-
function rbTreeDelete(T, z) {
|
|
731
|
-
let x;
|
|
732
|
-
let y;
|
|
733
|
-
// RB-DELETE except we don't swap z and y in case c)
|
|
734
|
-
// i.e. we always delete what's pointed at by z.
|
|
735
|
-
if (z.left === SENTINEL) {
|
|
736
|
-
x = z.right;
|
|
737
|
-
y = z;
|
|
738
|
-
// x's delta is no longer influenced by z's delta
|
|
739
|
-
x.delta += z.delta;
|
|
740
|
-
if (x.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || x.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
|
|
741
|
-
T.requestNormalizeDelta = true;
|
|
742
|
-
}
|
|
743
|
-
x.start += z.delta;
|
|
744
|
-
x.end += z.delta;
|
|
745
|
-
}
|
|
746
|
-
else if (z.right === SENTINEL) {
|
|
747
|
-
x = z.left;
|
|
748
|
-
y = z;
|
|
749
|
-
}
|
|
750
|
-
else {
|
|
751
|
-
y = leftest(z.right);
|
|
752
|
-
x = y.right;
|
|
753
|
-
// y's delta is no longer influenced by z's delta,
|
|
754
|
-
// but we don't want to walk the entire right-hand-side subtree of x.
|
|
755
|
-
// we therefore maintain z's delta in y, and adjust only x
|
|
756
|
-
x.start += y.delta;
|
|
757
|
-
x.end += y.delta;
|
|
758
|
-
x.delta += y.delta;
|
|
759
|
-
if (x.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || x.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
|
|
760
|
-
T.requestNormalizeDelta = true;
|
|
761
|
-
}
|
|
762
|
-
y.start += z.delta;
|
|
763
|
-
y.end += z.delta;
|
|
764
|
-
y.delta = z.delta;
|
|
765
|
-
if (y.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || y.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
|
|
766
|
-
T.requestNormalizeDelta = true;
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
if (y === T.root) {
|
|
770
|
-
T.root = x;
|
|
771
|
-
setNodeColor(x, 0 /* NodeColor.Black */);
|
|
772
|
-
z.detach();
|
|
773
|
-
resetSentinel();
|
|
774
|
-
recomputeMaxEnd(x);
|
|
775
|
-
T.root.parent = SENTINEL;
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
const yWasRed = (getNodeColor(y) === 1 /* NodeColor.Red */);
|
|
779
|
-
if (y === y.parent.left) {
|
|
780
|
-
y.parent.left = x;
|
|
781
|
-
}
|
|
782
|
-
else {
|
|
783
|
-
y.parent.right = x;
|
|
784
|
-
}
|
|
785
|
-
if (y === z) {
|
|
786
|
-
x.parent = y.parent;
|
|
787
|
-
}
|
|
788
|
-
else {
|
|
789
|
-
if (y.parent === z) {
|
|
790
|
-
x.parent = y;
|
|
791
|
-
}
|
|
792
|
-
else {
|
|
793
|
-
x.parent = y.parent;
|
|
794
|
-
}
|
|
795
|
-
y.left = z.left;
|
|
796
|
-
y.right = z.right;
|
|
797
|
-
y.parent = z.parent;
|
|
798
|
-
setNodeColor(y, getNodeColor(z));
|
|
799
|
-
if (z === T.root) {
|
|
800
|
-
T.root = y;
|
|
801
|
-
}
|
|
802
|
-
else {
|
|
803
|
-
if (z === z.parent.left) {
|
|
804
|
-
z.parent.left = y;
|
|
805
|
-
}
|
|
806
|
-
else {
|
|
807
|
-
z.parent.right = y;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
if (y.left !== SENTINEL) {
|
|
811
|
-
y.left.parent = y;
|
|
812
|
-
}
|
|
813
|
-
if (y.right !== SENTINEL) {
|
|
814
|
-
y.right.parent = y;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
z.detach();
|
|
818
|
-
if (yWasRed) {
|
|
819
|
-
recomputeMaxEndWalkToRoot(x.parent);
|
|
820
|
-
if (y !== z) {
|
|
821
|
-
recomputeMaxEndWalkToRoot(y);
|
|
822
|
-
recomputeMaxEndWalkToRoot(y.parent);
|
|
823
|
-
}
|
|
824
|
-
resetSentinel();
|
|
825
|
-
return;
|
|
826
|
-
}
|
|
827
|
-
recomputeMaxEndWalkToRoot(x);
|
|
828
|
-
recomputeMaxEndWalkToRoot(x.parent);
|
|
829
|
-
if (y !== z) {
|
|
830
|
-
recomputeMaxEndWalkToRoot(y);
|
|
831
|
-
recomputeMaxEndWalkToRoot(y.parent);
|
|
832
|
-
}
|
|
833
|
-
// RB-DELETE-FIXUP
|
|
834
|
-
let w;
|
|
835
|
-
while (x !== T.root && getNodeColor(x) === 0 /* NodeColor.Black */) {
|
|
836
|
-
if (x === x.parent.left) {
|
|
837
|
-
w = x.parent.right;
|
|
838
|
-
if (getNodeColor(w) === 1 /* NodeColor.Red */) {
|
|
839
|
-
setNodeColor(w, 0 /* NodeColor.Black */);
|
|
840
|
-
setNodeColor(x.parent, 1 /* NodeColor.Red */);
|
|
841
|
-
leftRotate(T, x.parent);
|
|
842
|
-
w = x.parent.right;
|
|
843
|
-
}
|
|
844
|
-
if (getNodeColor(w.left) === 0 /* NodeColor.Black */ && getNodeColor(w.right) === 0 /* NodeColor.Black */) {
|
|
845
|
-
setNodeColor(w, 1 /* NodeColor.Red */);
|
|
846
|
-
x = x.parent;
|
|
847
|
-
}
|
|
848
|
-
else {
|
|
849
|
-
if (getNodeColor(w.right) === 0 /* NodeColor.Black */) {
|
|
850
|
-
setNodeColor(w.left, 0 /* NodeColor.Black */);
|
|
851
|
-
setNodeColor(w, 1 /* NodeColor.Red */);
|
|
852
|
-
rightRotate(T, w);
|
|
853
|
-
w = x.parent.right;
|
|
854
|
-
}
|
|
855
|
-
setNodeColor(w, getNodeColor(x.parent));
|
|
856
|
-
setNodeColor(x.parent, 0 /* NodeColor.Black */);
|
|
857
|
-
setNodeColor(w.right, 0 /* NodeColor.Black */);
|
|
858
|
-
leftRotate(T, x.parent);
|
|
859
|
-
x = T.root;
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
else {
|
|
863
|
-
w = x.parent.left;
|
|
864
|
-
if (getNodeColor(w) === 1 /* NodeColor.Red */) {
|
|
865
|
-
setNodeColor(w, 0 /* NodeColor.Black */);
|
|
866
|
-
setNodeColor(x.parent, 1 /* NodeColor.Red */);
|
|
867
|
-
rightRotate(T, x.parent);
|
|
868
|
-
w = x.parent.left;
|
|
869
|
-
}
|
|
870
|
-
if (getNodeColor(w.left) === 0 /* NodeColor.Black */ && getNodeColor(w.right) === 0 /* NodeColor.Black */) {
|
|
871
|
-
setNodeColor(w, 1 /* NodeColor.Red */);
|
|
872
|
-
x = x.parent;
|
|
873
|
-
}
|
|
874
|
-
else {
|
|
875
|
-
if (getNodeColor(w.left) === 0 /* NodeColor.Black */) {
|
|
876
|
-
setNodeColor(w.right, 0 /* NodeColor.Black */);
|
|
877
|
-
setNodeColor(w, 1 /* NodeColor.Red */);
|
|
878
|
-
leftRotate(T, w);
|
|
879
|
-
w = x.parent.left;
|
|
880
|
-
}
|
|
881
|
-
setNodeColor(w, getNodeColor(x.parent));
|
|
882
|
-
setNodeColor(x.parent, 0 /* NodeColor.Black */);
|
|
883
|
-
setNodeColor(w.left, 0 /* NodeColor.Black */);
|
|
884
|
-
rightRotate(T, x.parent);
|
|
885
|
-
x = T.root;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
setNodeColor(x, 0 /* NodeColor.Black */);
|
|
890
|
-
resetSentinel();
|
|
891
|
-
}
|
|
892
|
-
function leftest(node) {
|
|
893
|
-
while (node.left !== SENTINEL) {
|
|
894
|
-
node = node.left;
|
|
895
|
-
}
|
|
896
|
-
return node;
|
|
897
|
-
}
|
|
898
|
-
function resetSentinel() {
|
|
899
|
-
SENTINEL.parent = SENTINEL;
|
|
900
|
-
SENTINEL.delta = 0; // optional
|
|
901
|
-
SENTINEL.start = 0; // optional
|
|
902
|
-
SENTINEL.end = 0; // optional
|
|
903
|
-
}
|
|
904
|
-
//#endregion
|
|
905
|
-
//#region Rotations
|
|
906
|
-
function leftRotate(T, x) {
|
|
907
|
-
const y = x.right; // set y.
|
|
908
|
-
y.delta += x.delta; // y's delta is no longer influenced by x's delta
|
|
909
|
-
if (y.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || y.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
|
|
910
|
-
T.requestNormalizeDelta = true;
|
|
911
|
-
}
|
|
912
|
-
y.start += x.delta;
|
|
913
|
-
y.end += x.delta;
|
|
914
|
-
x.right = y.left; // turn y's left subtree into x's right subtree.
|
|
915
|
-
if (y.left !== SENTINEL) {
|
|
916
|
-
y.left.parent = x;
|
|
917
|
-
}
|
|
918
|
-
y.parent = x.parent; // link x's parent to y.
|
|
919
|
-
if (x.parent === SENTINEL) {
|
|
920
|
-
T.root = y;
|
|
921
|
-
}
|
|
922
|
-
else if (x === x.parent.left) {
|
|
923
|
-
x.parent.left = y;
|
|
924
|
-
}
|
|
925
|
-
else {
|
|
926
|
-
x.parent.right = y;
|
|
927
|
-
}
|
|
928
|
-
y.left = x; // put x on y's left.
|
|
929
|
-
x.parent = y;
|
|
930
|
-
recomputeMaxEnd(x);
|
|
931
|
-
recomputeMaxEnd(y);
|
|
932
|
-
}
|
|
933
|
-
function rightRotate(T, y) {
|
|
934
|
-
const x = y.left;
|
|
935
|
-
y.delta -= x.delta;
|
|
936
|
-
if (y.delta < -1073741824 /* Constants.MIN_SAFE_DELTA */ || y.delta > 1073741824 /* Constants.MAX_SAFE_DELTA */) {
|
|
937
|
-
T.requestNormalizeDelta = true;
|
|
938
|
-
}
|
|
939
|
-
y.start -= x.delta;
|
|
940
|
-
y.end -= x.delta;
|
|
941
|
-
y.left = x.right;
|
|
942
|
-
if (x.right !== SENTINEL) {
|
|
943
|
-
x.right.parent = y;
|
|
944
|
-
}
|
|
945
|
-
x.parent = y.parent;
|
|
946
|
-
if (y.parent === SENTINEL) {
|
|
947
|
-
T.root = x;
|
|
948
|
-
}
|
|
949
|
-
else if (y === y.parent.right) {
|
|
950
|
-
y.parent.right = x;
|
|
951
|
-
}
|
|
952
|
-
else {
|
|
953
|
-
y.parent.left = x;
|
|
954
|
-
}
|
|
955
|
-
x.right = y;
|
|
956
|
-
y.parent = x;
|
|
957
|
-
recomputeMaxEnd(y);
|
|
958
|
-
recomputeMaxEnd(x);
|
|
959
|
-
}
|
|
960
|
-
//#endregion
|
|
961
|
-
//#region max end computation
|
|
962
|
-
function computeMaxEnd(node) {
|
|
963
|
-
let maxEnd = node.end;
|
|
964
|
-
if (node.left !== SENTINEL) {
|
|
965
|
-
const leftMaxEnd = node.left.maxEnd;
|
|
966
|
-
if (leftMaxEnd > maxEnd) {
|
|
967
|
-
maxEnd = leftMaxEnd;
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
if (node.right !== SENTINEL) {
|
|
971
|
-
const rightMaxEnd = node.right.maxEnd + node.delta;
|
|
972
|
-
if (rightMaxEnd > maxEnd) {
|
|
973
|
-
maxEnd = rightMaxEnd;
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
return maxEnd;
|
|
977
|
-
}
|
|
978
|
-
function recomputeMaxEnd(node) {
|
|
979
|
-
node.maxEnd = computeMaxEnd(node);
|
|
980
|
-
}
|
|
981
|
-
function recomputeMaxEndWalkToRoot(node) {
|
|
982
|
-
while (node !== SENTINEL) {
|
|
983
|
-
const maxEnd = computeMaxEnd(node);
|
|
984
|
-
if (node.maxEnd === maxEnd) {
|
|
985
|
-
// no need to go further
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
node.maxEnd = maxEnd;
|
|
989
|
-
node = node.parent;
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
//#endregion
|
|
993
|
-
//#region utils
|
|
994
|
-
function intervalCompare(aStart, aEnd, bStart, bEnd) {
|
|
995
|
-
if (aStart === bStart) {
|
|
996
|
-
return aEnd - bEnd;
|
|
997
|
-
}
|
|
998
|
-
return aStart - bStart;
|
|
999
|
-
}
|
|
1000
|
-
//#endregion
|
|
1001
|
-
|
|
1002
|
-
export { IntervalNode, IntervalTree, SENTINEL, getNodeColor, intervalCompare, nodeAcceptEdit, recomputeMaxEnd };
|