/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import * as nls from '../../../nls';
import * as arrays from '../../../base/common/arrays';
import { createCancelablePromise, first, timeout } from '../../../base/common/async';
import { CancellationToken } from '../../../base/common/cancellation';
import { onUnexpectedError, onUnexpectedExternalError } from '../../../base/common/errors';
import { Disposable, dispose } from '../../../base/common/lifecycle';
import { EditorAction, registerDefaultLanguageCommand, registerEditorAction, registerEditorContribution } from '../../browser/editorExtensions';
import { Range } from '../../common/core/range';
import { EditorContextKeys } from '../../common/editorContextKeys';
import { OverviewRulerLane } from '../../common/model';
import { ModelDecorationOptions } from '../../common/model/textModel';
import { DocumentHighlightKind, DocumentHighlightProviderRegistry } from '../../common/modes';
import { IContextKeyService, RawContextKey } from '../../../platform/contextkey/common/contextkey';
import { activeContrastBorder, editorSelectionHighlight, editorSelectionHighlightBorder, overviewRulerSelectionHighlightForeground, registerColor } from '../../../platform/theme/common/colorRegistry';
import { registerThemingParticipant, themeColorFromId } from '../../../platform/theme/common/themeService';
export var editorWordHighlight = registerColor('editor.wordHighlightBackground', { dark: '#575757B8', light: '#57575740', hc: null }, nls.localize('wordHighlight', 'Background color of a symbol during read-access, like reading a variable. The color must not be opaque to not hide underlying decorations.'), true);
export var editorWordHighlightStrong = registerColor('editor.wordHighlightStrongBackground', { dark: '#004972B8', light: '#0e639c40', hc: null }, nls.localize('wordHighlightStrong', 'Background color of a symbol during write-access, like writing to a variable. The color must not be opaque to not hide underlying decorations.'), true);
export var editorWordHighlightBorder = registerColor('editor.wordHighlightBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightBorder', 'Border color of a symbol during read-access, like reading a variable.'));
export var editorWordHighlightStrongBorder = registerColor('editor.wordHighlightStrongBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightStrongBorder', 'Border color of a symbol during write-access, like writing to a variable.'));
export var overviewRulerWordHighlightForeground = registerColor('editorOverviewRuler.wordHighlightForeground', { dark: '#A0A0A0CC', light: '#A0A0A0CC', hc: '#A0A0A0CC' }, nls.localize('overviewRulerWordHighlightForeground', 'Overview ruler marker color for symbol highlights. The color must not be opaque to not hide underlying decorations.'), true);
export var overviewRulerWordHighlightStrongForeground = registerColor('editorOverviewRuler.wordHighlightStrongForeground', { dark: '#C0A0C0CC', light: '#C0A0C0CC', hc: '#C0A0C0CC' }, nls.localize('overviewRulerWordHighlightStrongForeground', 'Overview ruler marker color for write-access symbol highlights. The color must not be opaque to not hide underlying decorations.'), true);
export var ctxHasWordHighlights = new RawContextKey('hasWordHighlights', false);
export function getOccurrencesAtPosition(model, position, token) {
    var orderedByScore = DocumentHighlightProviderRegistry.ordered(model);
    // in order of score ask the occurrences provider
    // until someone response with a good result
    // (good = none empty array)
    return first(orderedByScore.map(function (provider) { return function () {
        return Promise.resolve(provider.provideDocumentHighlights(model, position, token))
            .then(undefined, onUnexpectedExternalError);
    }; }), function (result) { return !arrays.isFalsyOrEmpty(result); });
}
var OccurenceAtPositionRequest = /** @class */ (function () {
    function OccurenceAtPositionRequest(model, selection, wordSeparators) {
        var _this = this;
        this._wordRange = this._getCurrentWordRange(model, selection);
        this.result = createCancelablePromise(function (token) { return _this._compute(model, selection, wordSeparators, token); });
    }
    OccurenceAtPositionRequest.prototype._getCurrentWordRange = function (model, selection) {
        var word = model.getWordAtPosition(selection.getPosition());
        if (word) {
            return new Range(selection.startLineNumber, word.startColumn, selection.startLineNumber, word.endColumn);
        }
        return null;
    };
    OccurenceAtPositionRequest.prototype.isValid = function (model, selection, decorationIds) {
        var lineNumber = selection.startLineNumber;
        var startColumn = selection.startColumn;
        var endColumn = selection.endColumn;
        var currentWordRange = this._getCurrentWordRange(model, selection);
        var requestIsValid = Boolean(this._wordRange && this._wordRange.equalsRange(currentWordRange));
        // Even if we are on a different word, if that word is in the decorations ranges, the request is still valid
        // (Same symbol)
        for (var i = 0, len = decorationIds.length; !requestIsValid && i < len; i++) {
            var range = model.getDecorationRange(decorationIds[i]);
            if (range && range.startLineNumber === lineNumber) {
                if (range.startColumn <= startColumn && range.endColumn >= endColumn) {
                    requestIsValid = true;
                }
            }
        }
        return requestIsValid;
    };
    OccurenceAtPositionRequest.prototype.cancel = function () {
        this.result.cancel();
    };
    return OccurenceAtPositionRequest;
}());
var SemanticOccurenceAtPositionRequest = /** @class */ (function (_super) {
    __extends(SemanticOccurenceAtPositionRequest, _super);
    function SemanticOccurenceAtPositionRequest() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    SemanticOccurenceAtPositionRequest.prototype._compute = function (model, selection, wordSeparators, token) {
        return getOccurrencesAtPosition(model, selection.getPosition(), token);
    };
    return SemanticOccurenceAtPositionRequest;
}(OccurenceAtPositionRequest));
var TextualOccurenceAtPositionRequest = /** @class */ (function (_super) {
    __extends(TextualOccurenceAtPositionRequest, _super);
    function TextualOccurenceAtPositionRequest(model, selection, wordSeparators) {
        var _this = _super.call(this, model, selection, wordSeparators) || this;
        _this._selectionIsEmpty = selection.isEmpty();
        return _this;
    }
    TextualOccurenceAtPositionRequest.prototype._compute = function (model, selection, wordSeparators, token) {
        return timeout(250, token).then(function () {
            if (!selection.isEmpty()) {
                return [];
            }
            var word = model.getWordAtPosition(selection.getPosition());
            if (!word) {
                return [];
            }
            var matches = model.findMatches(word.word, true, false, true, wordSeparators, false);
            return matches.map(function (m) {
                return {
                    range: m.range,
                    kind: DocumentHighlightKind.Text
                };
            });
        });
    };
    TextualOccurenceAtPositionRequest.prototype.isValid = function (model, selection, decorationIds) {
        var currentSelectionIsEmpty = selection.isEmpty();
        if (this._selectionIsEmpty !== currentSelectionIsEmpty) {
            return false;
        }
        return _super.prototype.isValid.call(this, model, selection, decorationIds);
    };
    return TextualOccurenceAtPositionRequest;
}(OccurenceAtPositionRequest));
function computeOccurencesAtPosition(model, selection, wordSeparators) {
    if (DocumentHighlightProviderRegistry.has(model)) {
        return new SemanticOccurenceAtPositionRequest(model, selection, wordSeparators);
    }
    return new TextualOccurenceAtPositionRequest(model, selection, wordSeparators);
}
registerDefaultLanguageCommand('_executeDocumentHighlights', function (model, position) { return getOccurrencesAtPosition(model, position, CancellationToken.None); });
var WordHighlighter = /** @class */ (function () {
    function WordHighlighter(editor, contextKeyService) {
        var _this = this;
        this.workerRequestTokenId = 0;
        this.workerRequestCompleted = false;
        this.workerRequestValue = [];
        this.lastCursorPositionChangeTime = 0;
        this.renderDecorationsTimer = -1;
        this.editor = editor;
        this._hasWordHighlights = ctxHasWordHighlights.bindTo(contextKeyService);
        this._ignorePositionChangeEvent = false;
        this.occurrencesHighlight = this.editor.getConfiguration().contribInfo.occurrencesHighlight;
        this.model = this.editor.getModel();
        this.toUnhook = [];
        this.toUnhook.push(editor.onDidChangeCursorPosition(function (e) {
            if (_this._ignorePositionChangeEvent) {
                // We are changing the position => ignore this event
                return;
            }
            if (!_this.occurrencesHighlight) {
                // Early exit if nothing needs to be done!
                // Leave some form of early exit check here if you wish to continue being a cursor position change listener ;)
                return;
            }
            _this._onPositionChanged(e);
        }));
        this.toUnhook.push(editor.onDidChangeModelContent(function (e) {
            _this._stopAll();
        }));
        this.toUnhook.push(editor.onDidChangeConfiguration(function (e) {
            var newValue = _this.editor.getConfiguration().contribInfo.occurrencesHighlight;
            if (_this.occurrencesHighlight !== newValue) {
                _this.occurrencesHighlight = newValue;
                _this._stopAll();
            }
        }));
        this._decorationIds = [];
        this.workerRequestTokenId = 0;
        this.workerRequest = null;
        this.workerRequestCompleted = false;
        this.lastCursorPositionChangeTime = 0;
        this.renderDecorationsTimer = -1;
    }
    WordHighlighter.prototype.hasDecorations = function () {
        return (this._decorationIds.length > 0);
    };
    WordHighlighter.prototype.restore = function () {
        if (!this.occurrencesHighlight) {
            return;
        }
        this._run();
    };
    WordHighlighter.prototype._getSortedHighlights = function () {
        var _this = this;
        return arrays.coalesce(this._decorationIds
            .map(function (id) { return _this.model.getDecorationRange(id); })
            .sort(Range.compareRangesUsingStarts));
    };
    WordHighlighter.prototype.moveNext = function () {
        var _this = this;
        var highlights = this._getSortedHighlights();
        var index = arrays.firstIndex(highlights, function (range) { return range.containsPosition(_this.editor.getPosition()); });
        var newIndex = ((index + 1) % highlights.length);
        var dest = highlights[newIndex];
        try {
            this._ignorePositionChangeEvent = true;
            this.editor.setPosition(dest.getStartPosition());
            this.editor.revealRangeInCenterIfOutsideViewport(dest);
        }
        finally {
            this._ignorePositionChangeEvent = false;
        }
    };
    WordHighlighter.prototype.moveBack = function () {
        var _this = this;
        var highlights = this._getSortedHighlights();
        var index = arrays.firstIndex(highlights, function (range) { return range.containsPosition(_this.editor.getPosition()); });
        var newIndex = ((index - 1 + highlights.length) % highlights.length);
        var dest = highlights[newIndex];
        try {
            this._ignorePositionChangeEvent = true;
            this.editor.setPosition(dest.getStartPosition());
            this.editor.revealRangeInCenterIfOutsideViewport(dest);
        }
        finally {
            this._ignorePositionChangeEvent = false;
        }
    };
    WordHighlighter.prototype._removeDecorations = function () {
        if (this._decorationIds.length > 0) {
            // remove decorations
            this._decorationIds = this.editor.deltaDecorations(this._decorationIds, []);
            this._hasWordHighlights.set(false);
        }
    };
    WordHighlighter.prototype._stopAll = function () {
        // Remove any existing decorations
        this._removeDecorations();
        // Cancel any renderDecorationsTimer
        if (this.renderDecorationsTimer !== -1) {
            clearTimeout(this.renderDecorationsTimer);
            this.renderDecorationsTimer = -1;
        }
        // Cancel any worker request
        if (this.workerRequest !== null) {
            this.workerRequest.cancel();
            this.workerRequest = null;
        }
        // Invalidate any worker request callback
        if (!this.workerRequestCompleted) {
            this.workerRequestTokenId++;
            this.workerRequestCompleted = true;
        }
    };
    WordHighlighter.prototype._onPositionChanged = function (e) {
        // disabled
        if (!this.occurrencesHighlight) {
            this._stopAll();
            return;
        }
        // ignore typing & other
        if (e.reason !== 3 /* Explicit */) {
            this._stopAll();
            return;
        }
        this._run();
    };
    WordHighlighter.prototype._run = function () {
        var _this = this;
        var editorSelection = this.editor.getSelection();
        // ignore multiline selection
        if (editorSelection.startLineNumber !== editorSelection.endLineNumber) {
            this._stopAll();
            return;
        }
        var lineNumber = editorSelection.startLineNumber;
        var startColumn = editorSelection.startColumn;
        var endColumn = editorSelection.endColumn;
        var word = this.model.getWordAtPosition({
            lineNumber: lineNumber,
            column: startColumn
        });
        // The selection must be inside a word or surround one word at most
        if (!word || word.startColumn > startColumn || word.endColumn < endColumn) {
            this._stopAll();
            return;
        }
        // All the effort below is trying to achieve this:
        // - when cursor is moved to a word, trigger immediately a findOccurrences request
        // - 250ms later after the last cursor move event, render the occurrences
        // - no flickering!
        var workerRequestIsValid = (this.workerRequest && this.workerRequest.isValid(this.model, editorSelection, this._decorationIds));
        // There are 4 cases:
        // a) old workerRequest is valid & completed, renderDecorationsTimer fired
        // b) old workerRequest is valid & completed, renderDecorationsTimer not fired
        // c) old workerRequest is valid, but not completed
        // d) old workerRequest is not valid
        // For a) no action is needed
        // For c), member 'lastCursorPositionChangeTime' will be used when installing the timer so no action is needed
        this.lastCursorPositionChangeTime = (new Date()).getTime();
        if (workerRequestIsValid) {
            if (this.workerRequestCompleted && this.renderDecorationsTimer !== -1) {
                // case b)
                // Delay the firing of renderDecorationsTimer by an extra 250 ms
                clearTimeout(this.renderDecorationsTimer);
                this.renderDecorationsTimer = -1;
                this._beginRenderDecorations();
            }
        }
        else {
            // case d)
            // Stop all previous actions and start fresh
            this._stopAll();
            var myRequestId_1 = ++this.workerRequestTokenId;
            this.workerRequestCompleted = false;
            this.workerRequest = computeOccurencesAtPosition(this.model, this.editor.getSelection(), this.editor.getConfiguration().wordSeparators);
            this.workerRequest.result.then(function (data) {
                if (myRequestId_1 === _this.workerRequestTokenId) {
                    _this.workerRequestCompleted = true;
                    _this.workerRequestValue = data || [];
                    _this._beginRenderDecorations();
                }
            }, onUnexpectedError);
        }
    };
    WordHighlighter.prototype._beginRenderDecorations = function () {
        var _this = this;
        var currentTime = (new Date()).getTime();
        var minimumRenderTime = this.lastCursorPositionChangeTime + 250;
        if (currentTime >= minimumRenderTime) {
            // Synchronous
            this.renderDecorationsTimer = -1;
            this.renderDecorations();
        }
        else {
            // Asynchronous
            this.renderDecorationsTimer = setTimeout(function () {
                _this.renderDecorations();
            }, (minimumRenderTime - currentTime));
        }
    };
    WordHighlighter.prototype.renderDecorations = function () {
        this.renderDecorationsTimer = -1;
        var decorations = [];
        for (var i = 0, len = this.workerRequestValue.length; i < len; i++) {
            var info = this.workerRequestValue[i];
            decorations.push({
                range: info.range,
                options: WordHighlighter._getDecorationOptions(info.kind)
            });
        }
        this._decorationIds = this.editor.deltaDecorations(this._decorationIds, decorations);
        this._hasWordHighlights.set(this.hasDecorations());
    };
    WordHighlighter._getDecorationOptions = function (kind) {
        if (kind === DocumentHighlightKind.Write) {
            return this._WRITE_OPTIONS;
        }
        else if (kind === DocumentHighlightKind.Text) {
            return this._TEXT_OPTIONS;
        }
        else {
            return this._REGULAR_OPTIONS;
        }
    };
    WordHighlighter.prototype.dispose = function () {
        this._stopAll();
        this.toUnhook = dispose(this.toUnhook);
    };
    WordHighlighter._WRITE_OPTIONS = ModelDecorationOptions.register({
        stickiness: 1 /* NeverGrowsWhenTypingAtEdges */,
        className: 'wordHighlightStrong',
        overviewRuler: {
            color: themeColorFromId(overviewRulerWordHighlightStrongForeground),
            position: OverviewRulerLane.Center
        }
    });
    WordHighlighter._TEXT_OPTIONS = ModelDecorationOptions.register({
        stickiness: 1 /* NeverGrowsWhenTypingAtEdges */,
        className: 'selectionHighlight',
        overviewRuler: {
            color: themeColorFromId(overviewRulerSelectionHighlightForeground),
            position: OverviewRulerLane.Center
        }
    });
    WordHighlighter._REGULAR_OPTIONS = ModelDecorationOptions.register({
        stickiness: 1 /* NeverGrowsWhenTypingAtEdges */,
        className: 'wordHighlight',
        overviewRuler: {
            color: themeColorFromId(overviewRulerWordHighlightForeground),
            position: OverviewRulerLane.Center
        }
    });
    return WordHighlighter;
}());
var WordHighlighterContribution = /** @class */ (function (_super) {
    __extends(WordHighlighterContribution, _super);
    function WordHighlighterContribution(editor, contextKeyService) {
        var _this = _super.call(this) || this;
        var createWordHighlighterIfPossible = function () {
            if (editor.hasModel()) {
                _this.wordHighligher = new WordHighlighter(editor, contextKeyService);
            }
        };
        _this._register(editor.onDidChangeModel(function (e) {
            if (_this.wordHighligher) {
                _this.wordHighligher.dispose();
                _this.wordHighligher = null;
            }
            createWordHighlighterIfPossible();
        }));
        createWordHighlighterIfPossible();
        return _this;
    }
    WordHighlighterContribution.get = function (editor) {
        return editor.getContribution(WordHighlighterContribution.ID);
    };
    WordHighlighterContribution.prototype.getId = function () {
        return WordHighlighterContribution.ID;
    };
    WordHighlighterContribution.prototype.saveViewState = function () {
        if (this.wordHighligher && this.wordHighligher.hasDecorations()) {
            return true;
        }
        return false;
    };
    WordHighlighterContribution.prototype.moveNext = function () {
        if (this.wordHighligher) {
            this.wordHighligher.moveNext();
        }
    };
    WordHighlighterContribution.prototype.moveBack = function () {
        if (this.wordHighligher) {
            this.wordHighligher.moveBack();
        }
    };
    WordHighlighterContribution.prototype.restoreViewState = function (state) {
        if (this.wordHighligher && state) {
            this.wordHighligher.restore();
        }
    };
    WordHighlighterContribution.prototype.dispose = function () {
        if (this.wordHighligher) {
            this.wordHighligher.dispose();
            this.wordHighligher = null;
        }
        _super.prototype.dispose.call(this);
    };
    WordHighlighterContribution.ID = 'editor.contrib.wordHighlighter';
    WordHighlighterContribution = __decorate([
        __param(1, IContextKeyService)
    ], WordHighlighterContribution);
    return WordHighlighterContribution;
}(Disposable));
var WordHighlightNavigationAction = /** @class */ (function (_super) {
    __extends(WordHighlightNavigationAction, _super);
    function WordHighlightNavigationAction(next, opts) {
        var _this = _super.call(this, opts) || this;
        _this._isNext = next;
        return _this;
    }
    WordHighlightNavigationAction.prototype.run = function (accessor, editor) {
        var controller = WordHighlighterContribution.get(editor);
        if (!controller) {
            return;
        }
        if (this._isNext) {
            controller.moveNext();
        }
        else {
            controller.moveBack();
        }
    };
    return WordHighlightNavigationAction;
}(EditorAction));
var NextWordHighlightAction = /** @class */ (function (_super) {
    __extends(NextWordHighlightAction, _super);
    function NextWordHighlightAction() {
        return _super.call(this, true, {
            id: 'editor.action.wordHighlight.next',
            label: nls.localize('wordHighlight.next.label', "Go to Next Symbol Highlight"),
            alias: 'Go to Next Symbol Highlight',
            precondition: ctxHasWordHighlights,
            kbOpts: {
                kbExpr: EditorContextKeys.editorTextFocus,
                primary: 65 /* F7 */,
                weight: 100 /* EditorContrib */
            }
        }) || this;
    }
    return NextWordHighlightAction;
}(WordHighlightNavigationAction));
var PrevWordHighlightAction = /** @class */ (function (_super) {
    __extends(PrevWordHighlightAction, _super);
    function PrevWordHighlightAction() {
        return _super.call(this, false, {
            id: 'editor.action.wordHighlight.prev',
            label: nls.localize('wordHighlight.previous.label', "Go to Previous Symbol Highlight"),
            alias: 'Go to Previous Symbol Highlight',
            precondition: ctxHasWordHighlights,
            kbOpts: {
                kbExpr: EditorContextKeys.editorTextFocus,
                primary: 1024 /* Shift */ | 65 /* F7 */,
                weight: 100 /* EditorContrib */
            }
        }) || this;
    }
    return PrevWordHighlightAction;
}(WordHighlightNavigationAction));
var TriggerWordHighlightAction = /** @class */ (function (_super) {
    __extends(TriggerWordHighlightAction, _super);
    function TriggerWordHighlightAction() {
        return _super.call(this, {
            id: 'editor.action.wordHighlight.trigger',
            label: nls.localize('wordHighlight.trigger.label', "Trigger Symbol Highlight"),
            alias: 'Trigger Symbol Highlight',
            precondition: ctxHasWordHighlights.toNegated(),
            kbOpts: {
                kbExpr: EditorContextKeys.editorTextFocus,
                primary: 0,
                weight: 100 /* EditorContrib */
            }
        }) || this;
    }
    TriggerWordHighlightAction.prototype.run = function (accessor, editor, args) {
        var controller = WordHighlighterContribution.get(editor);
        if (!controller) {
            return;
        }
        controller.restoreViewState(true);
    };
    return TriggerWordHighlightAction;
}(EditorAction));
registerEditorContribution(WordHighlighterContribution);
registerEditorAction(NextWordHighlightAction);
registerEditorAction(PrevWordHighlightAction);
registerEditorAction(TriggerWordHighlightAction);
registerThemingParticipant(function (theme, collector) {
    var selectionHighlight = theme.getColor(editorSelectionHighlight);
    if (selectionHighlight) {
        collector.addRule(".monaco-editor .focused .selectionHighlight { background-color: " + selectionHighlight + "; }");
        collector.addRule(".monaco-editor .selectionHighlight { background-color: " + selectionHighlight.transparent(0.5) + "; }");
    }
    var wordHighlight = theme.getColor(editorWordHighlight);
    if (wordHighlight) {
        collector.addRule(".monaco-editor .wordHighlight { background-color: " + wordHighlight + "; }");
    }
    var wordHighlightStrong = theme.getColor(editorWordHighlightStrong);
    if (wordHighlightStrong) {
        collector.addRule(".monaco-editor .wordHighlightStrong { background-color: " + wordHighlightStrong + "; }");
    }
    var selectionHighlightBorder = theme.getColor(editorSelectionHighlightBorder);
    if (selectionHighlightBorder) {
        collector.addRule(".monaco-editor .selectionHighlight { border: 1px " + (theme.type === 'hc' ? 'dotted' : 'solid') + " " + selectionHighlightBorder + "; box-sizing: border-box; }");
    }
    var wordHighlightBorder = theme.getColor(editorWordHighlightBorder);
    if (wordHighlightBorder) {
        collector.addRule(".monaco-editor .wordHighlight { border: 1px " + (theme.type === 'hc' ? 'dashed' : 'solid') + " " + wordHighlightBorder + "; box-sizing: border-box; }");
    }
    var wordHighlightStrongBorder = theme.getColor(editorWordHighlightStrongBorder);
    if (wordHighlightStrongBorder) {
        collector.addRule(".monaco-editor .wordHighlightStrong { border: 1px " + (theme.type === 'hc' ? 'dashed' : 'solid') + " " + wordHighlightStrongBorder + "; box-sizing: border-box; }");
    }
});
