204 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
ace.define("ace/ext/code_lens",["require","exports","module","ace/lib/event","ace/lib/lang","ace/lib/dom","ace/editor","ace/config"], function(require, exports, module){/**
 | 
						|
 * ## Code Lens extension.
 | 
						|
 *
 | 
						|
 * Displaying contextual information and clickable commands above code lines. Supports registering custom providers,
 | 
						|
 * rendering lens widgets with proper positioning and styling, and handling user interactions with lens commands.
 | 
						|
 * @module
 | 
						|
 */
 | 
						|
"use strict";
 | 
						|
var event = require("../lib/event");
 | 
						|
var lang = require("../lib/lang");
 | 
						|
var dom = require("../lib/dom");
 | 
						|
function clearLensElements(renderer) {
 | 
						|
    var textLayer = renderer.$textLayer;
 | 
						|
    var lensElements = textLayer.$lenses;
 | 
						|
    if (lensElements)
 | 
						|
        lensElements.forEach(function (el) { el.remove(); });
 | 
						|
    textLayer.$lenses = null;
 | 
						|
}
 | 
						|
function renderWidgets(changes, renderer) {
 | 
						|
    var changed = changes & renderer.CHANGE_LINES
 | 
						|
        || changes & renderer.CHANGE_FULL
 | 
						|
        || changes & renderer.CHANGE_SCROLL
 | 
						|
        || changes & renderer.CHANGE_TEXT;
 | 
						|
    if (!changed)
 | 
						|
        return;
 | 
						|
    var session = renderer.session;
 | 
						|
    var lineWidgets = renderer.session.lineWidgets;
 | 
						|
    var textLayer = renderer.$textLayer;
 | 
						|
    var lensElements = textLayer.$lenses;
 | 
						|
    if (!lineWidgets) {
 | 
						|
        if (lensElements)
 | 
						|
            clearLensElements(renderer);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    var textCells = renderer.$textLayer.$lines.cells;
 | 
						|
    var config = renderer.layerConfig;
 | 
						|
    var padding = renderer.$padding;
 | 
						|
    if (!lensElements)
 | 
						|
        lensElements = textLayer.$lenses = [];
 | 
						|
    var index = 0;
 | 
						|
    for (var i = 0; i < textCells.length; i++) {
 | 
						|
        var row = textCells[i].row;
 | 
						|
        var widget = lineWidgets[row];
 | 
						|
        var lenses = widget && widget.lenses;
 | 
						|
        if (!lenses || !lenses.length)
 | 
						|
            continue;
 | 
						|
        var lensContainer = lensElements[index];
 | 
						|
        if (!lensContainer) {
 | 
						|
            lensContainer = lensElements[index]
 | 
						|
                = dom.buildDom(["div", { class: "ace_codeLens" }], renderer.container);
 | 
						|
        }
 | 
						|
        lensContainer.style.height = config.lineHeight + "px";
 | 
						|
        index++;
 | 
						|
        for (var j = 0; j < lenses.length; j++) {
 | 
						|
            var el = lensContainer.childNodes[2 * j];
 | 
						|
            if (!el) {
 | 
						|
                if (j != 0)
 | 
						|
                    lensContainer.appendChild(dom.createTextNode("\xa0|\xa0"));
 | 
						|
                el = dom.buildDom(["a"], lensContainer);
 | 
						|
            }
 | 
						|
            el.textContent = lenses[j].title;
 | 
						|
            (el).lensCommand = lenses[j];
 | 
						|
        }
 | 
						|
        while (lensContainer.childNodes.length > 2 * j - 1)
 | 
						|
            lensContainer.lastChild.remove();
 | 
						|
        var top = renderer.$cursorLayer.getPixelPosition({
 | 
						|
            row: row,
 | 
						|
            column: 0
 | 
						|
        }, true).top - config.lineHeight * widget.rowsAbove - config.offset;
 | 
						|
        lensContainer.style.top = top + "px";
 | 
						|
        var left = renderer.gutterWidth;
 | 
						|
        var indent = session.getLine(row).search(/\S|$/);
 | 
						|
        if (indent == -1)
 | 
						|
            indent = 0;
 | 
						|
        left += indent * config.characterWidth;
 | 
						|
        lensContainer.style.paddingLeft = padding + left + "px";
 | 
						|
    }
 | 
						|
    while (index < lensElements.length)
 | 
						|
        lensElements.pop().remove();
 | 
						|
}
 | 
						|
function clearCodeLensWidgets(session) {
 | 
						|
    if (!session.lineWidgets)
 | 
						|
        return;
 | 
						|
    var widgetManager = session.widgetManager;
 | 
						|
    session.lineWidgets.forEach(function (widget) {
 | 
						|
        if (widget && widget.lenses)
 | 
						|
            widgetManager.removeLineWidget(widget);
 | 
						|
    });
 | 
						|
}
 | 
						|
exports.setLenses = function (session, lenses) {
 | 
						|
    var firstRow = Number.MAX_VALUE;
 | 
						|
    clearCodeLensWidgets(session);
 | 
						|
    lenses && lenses.forEach(function (lens) {
 | 
						|
        var row = lens.start.row;
 | 
						|
        var column = lens.start.column;
 | 
						|
        var widget = session.lineWidgets && session.lineWidgets[row];
 | 
						|
        if (!widget || !widget.lenses) {
 | 
						|
            widget = session.widgetManager.$registerLineWidget({
 | 
						|
                rowCount: 1,
 | 
						|
                rowsAbove: 1,
 | 
						|
                row: row,
 | 
						|
                column: column,
 | 
						|
                lenses: []
 | 
						|
            });
 | 
						|
        }
 | 
						|
        widget.lenses.push(lens.command);
 | 
						|
        if (row < firstRow)
 | 
						|
            firstRow = row;
 | 
						|
    });
 | 
						|
    session._emit("changeFold", { data: { start: { row: firstRow } } });
 | 
						|
    return firstRow;
 | 
						|
};
 | 
						|
function attachToEditor(editor) {
 | 
						|
    editor.codeLensProviders = [];
 | 
						|
    editor.renderer.on("afterRender", renderWidgets);
 | 
						|
    if (!editor.$codeLensClickHandler) {
 | 
						|
        editor.$codeLensClickHandler = function (e) {
 | 
						|
            var command = e.target.lensCommand;
 | 
						|
            if (!command)
 | 
						|
                return;
 | 
						|
            editor.execCommand(command.id, command.arguments);
 | 
						|
            editor._emit("codeLensClick", e);
 | 
						|
        };
 | 
						|
        event.addListener(editor.container, "click", editor.$codeLensClickHandler, editor);
 | 
						|
    }
 | 
						|
    editor.$updateLenses = function () {
 | 
						|
        var session = editor.session;
 | 
						|
        if (!session)
 | 
						|
            return;
 | 
						|
        var providersToWaitNum = editor.codeLensProviders.length;
 | 
						|
        var lenses = [];
 | 
						|
        editor.codeLensProviders.forEach(function (provider) {
 | 
						|
            provider.provideCodeLenses(session, function (err, payload) {
 | 
						|
                if (err)
 | 
						|
                    return;
 | 
						|
                payload.forEach(function (lens) {
 | 
						|
                    lenses.push(lens);
 | 
						|
                });
 | 
						|
                providersToWaitNum--;
 | 
						|
                if (providersToWaitNum == 0) {
 | 
						|
                    applyLenses();
 | 
						|
                }
 | 
						|
            });
 | 
						|
        });
 | 
						|
        function applyLenses() {
 | 
						|
            var cursor = session.selection.cursor;
 | 
						|
            var oldRow = session.documentToScreenRow(cursor);
 | 
						|
            var scrollTop = session.getScrollTop();
 | 
						|
            var firstRow = exports.setLenses(session, lenses);
 | 
						|
            var lastDelta = session.$undoManager && session.$undoManager.$lastDelta;
 | 
						|
            if (lastDelta && lastDelta.action == "remove" && lastDelta.lines.length > 1)
 | 
						|
                return;
 | 
						|
            var row = session.documentToScreenRow(cursor);
 | 
						|
            var lineHeight = editor.renderer.layerConfig.lineHeight;
 | 
						|
            var top = session.getScrollTop() + (row - oldRow) * lineHeight;
 | 
						|
            if (firstRow == 0 && scrollTop < lineHeight / 4 && scrollTop > -lineHeight / 4) {
 | 
						|
                top = -lineHeight;
 | 
						|
            }
 | 
						|
            session.setScrollTop(top);
 | 
						|
        }
 | 
						|
    };
 | 
						|
    var updateLenses = lang.delayedCall(editor.$updateLenses);
 | 
						|
    editor.$updateLensesOnInput = function () {
 | 
						|
        updateLenses.delay(250);
 | 
						|
    };
 | 
						|
    editor.on("input", editor.$updateLensesOnInput);
 | 
						|
}
 | 
						|
function detachFromEditor(editor) {
 | 
						|
    editor.off("input", editor.$updateLensesOnInput);
 | 
						|
    editor.renderer.off("afterRender", renderWidgets);
 | 
						|
    if (editor.$codeLensClickHandler)
 | 
						|
        editor.container.removeEventListener("click", editor.$codeLensClickHandler);
 | 
						|
}
 | 
						|
exports.registerCodeLensProvider = function (editor, codeLensProvider) {
 | 
						|
    editor.setOption("enableCodeLens", true);
 | 
						|
    editor.codeLensProviders.push(codeLensProvider);
 | 
						|
    editor.$updateLensesOnInput();
 | 
						|
};
 | 
						|
exports.clear = function (session) {
 | 
						|
    exports.setLenses(session, null);
 | 
						|
};
 | 
						|
var Editor = require("../editor").Editor;
 | 
						|
require("../config").defineOptions(Editor.prototype, "editor", {
 | 
						|
    enableCodeLens: {
 | 
						|
        set: function (val) {
 | 
						|
            if (val) {
 | 
						|
                attachToEditor(this);
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                detachFromEditor(this);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
});
 | 
						|
dom.importCssString("\n.ace_codeLens {\n    position: absolute;\n    color: #aaa;\n    font-size: 88%;\n    background: inherit;\n    width: 100%;\n    display: flex;\n    align-items: flex-end;\n    pointer-events: none;\n}\n.ace_codeLens > a {\n    cursor: pointer;\n    pointer-events: auto;\n}\n.ace_codeLens > a:hover {\n    color: #0000ff;\n    text-decoration: underline;\n}\n.ace_dark > .ace_codeLens > a:hover {\n    color: #4e94ce;\n}\n", "codelense.css", false);
 | 
						|
 | 
						|
});                (function() {
 | 
						|
                    ace.require(["ace/ext/code_lens"], function(m) {
 | 
						|
                        if (typeof module == "object" && typeof exports == "object" && module) {
 | 
						|
                            module.exports = m;
 | 
						|
                        }
 | 
						|
                    });
 | 
						|
                })();
 | 
						|
            
 |