1491 lines
		
	
	
		
			65 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1491 lines
		
	
	
		
			65 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
 | 
						|
if you want to view the source visit the plugins github repository
 | 
						|
*/
 | 
						|
 | 
						|
'use strict';
 | 
						|
 | 
						|
var obsidian = require('obsidian');
 | 
						|
var state = require('@codemirror/state');
 | 
						|
var view = require('@codemirror/view');
 | 
						|
var language = require('@codemirror/language');
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
Copyright (c) Microsoft Corporation.
 | 
						|
 | 
						|
Permission to use, copy, modify, and/or distribute this software for any
 | 
						|
purpose with or without fee is hereby granted.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
						|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 | 
						|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 | 
						|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 | 
						|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
						|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
PERFORMANCE OF THIS SOFTWARE.
 | 
						|
***************************************************************************** */
 | 
						|
 | 
						|
function __awaiter(thisArg, _arguments, P, generator) {
 | 
						|
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
 | 
						|
    return new (P || (P = Promise))(function (resolve, reject) {
 | 
						|
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
 | 
						|
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
 | 
						|
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
 | 
						|
        step((generator = generator.apply(thisArg, _arguments || [])).next());
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
 | 
						|
    var e = new Error(message);
 | 
						|
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
 | 
						|
};
 | 
						|
 | 
						|
const matchTypes = {
 | 
						|
    'exact': "Exact match",
 | 
						|
    'contains': "Contains value",
 | 
						|
    'whiteSpace': "Value within whitespace separated words",
 | 
						|
    'startswith': "Starts with this value",
 | 
						|
    'endswith': "Ends with this value"
 | 
						|
};
 | 
						|
const matchSign = {
 | 
						|
    'exact': "",
 | 
						|
    'contains': "*",
 | 
						|
    'startswith': "^",
 | 
						|
    'endswith': "$",
 | 
						|
    'whiteSpace': "~"
 | 
						|
};
 | 
						|
const matchPreview = {
 | 
						|
    'exact': "with value",
 | 
						|
    'contains': "containing",
 | 
						|
    'whiteSpace': "containing",
 | 
						|
    'startswith': "starting with",
 | 
						|
    'endswith': "ending with"
 | 
						|
};
 | 
						|
const matchPreviewPath = {
 | 
						|
    'exact': "is",
 | 
						|
    'contains': "contains",
 | 
						|
    'whiteSpace': "contains",
 | 
						|
    'startswith': "starts with",
 | 
						|
    'endswith': "ends with"
 | 
						|
};
 | 
						|
const selectorType = {
 | 
						|
    'attribute': 'Attribute value',
 | 
						|
    'tag': 'Tag',
 | 
						|
    'path': 'Note path'
 | 
						|
};
 | 
						|
class CSSLink {
 | 
						|
    constructor() {
 | 
						|
        this.type = 'attribute';
 | 
						|
        this.name = "";
 | 
						|
        this.value = "";
 | 
						|
        this.matchCaseSensitive = false;
 | 
						|
        this.match = "exact";
 | 
						|
        let s4 = () => {
 | 
						|
            return Math.floor((1 + Math.random()) * 0x10000)
 | 
						|
                .toString(16)
 | 
						|
                .substring(1);
 | 
						|
        };
 | 
						|
        //return id of format 'aaaaaaaa'-'aaaa'-'aaaa'-'aaaa'-'aaaaaaaaaaaa'
 | 
						|
        this.uid = s4() + "-" + s4();
 | 
						|
        this.selectText = true;
 | 
						|
        this.selectAppend = true;
 | 
						|
        this.selectPrepend = true;
 | 
						|
        this.selectBackground = true;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
function clearExtraAttributes(link) {
 | 
						|
    Object.values(link.attributes).forEach(attr => {
 | 
						|
        if (attr.name.includes("data-link")) {
 | 
						|
            link.removeAttribute(attr.name);
 | 
						|
        }
 | 
						|
    });
 | 
						|
}
 | 
						|
function fetchTargetAttributesSync(app, settings, dest, addDataHref) {
 | 
						|
    var _a;
 | 
						|
    let new_props = { tags: "" };
 | 
						|
    const cache = app.metadataCache.getFileCache(dest);
 | 
						|
    if (!cache)
 | 
						|
        return new_props;
 | 
						|
    const frontmatter = cache.frontmatter;
 | 
						|
    if (frontmatter) {
 | 
						|
        settings.targetAttributes.forEach(attribute => {
 | 
						|
            if (Object.keys(frontmatter).includes(attribute)) {
 | 
						|
                if (attribute === 'tag' || attribute === 'tags') {
 | 
						|
                    new_props['tags'] += frontmatter[attribute];
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    new_props[attribute] = frontmatter[attribute];
 | 
						|
                }
 | 
						|
            }
 | 
						|
        });
 | 
						|
    }
 | 
						|
    if (settings.targetTags) {
 | 
						|
        new_props["tags"] += obsidian.getAllTags(cache).join(' ');
 | 
						|
    }
 | 
						|
    if (addDataHref) {
 | 
						|
        new_props['data-href'] = dest.basename;
 | 
						|
    }
 | 
						|
    new_props['path'] = dest.path;
 | 
						|
    //@ts-ignore
 | 
						|
    const getResults = (api) => {
 | 
						|
        const page = api.page(dest.path);
 | 
						|
        if (!page) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        settings.targetAttributes.forEach((field) => {
 | 
						|
            const value = page[field];
 | 
						|
            if (value)
 | 
						|
                new_props[field] = value;
 | 
						|
        });
 | 
						|
    };
 | 
						|
    if (settings.getFromInlineField && app.plugins.enabledPlugins.has("dataview")) {
 | 
						|
        const api = (_a = app.plugins.plugins.dataview) === null || _a === void 0 ? void 0 : _a.api;
 | 
						|
        if (api) {
 | 
						|
            getResults(api);
 | 
						|
        }
 | 
						|
        // This is crashing for some people. I think ignoring it will be ok. 
 | 
						|
        // else
 | 
						|
        //     this.plugin.registerEvent(
 | 
						|
        //         app.metadataCache.on("dataview:api-ready", (api: any) =>
 | 
						|
        //             getResults(api)
 | 
						|
        //         )
 | 
						|
        //     );
 | 
						|
    }
 | 
						|
    // Replace spaces with hyphens in the keys of new_props
 | 
						|
    const hyphenated_props = {};
 | 
						|
    for (const key in new_props) {
 | 
						|
        const hyphenatedKey = key.replace(/ /g, '-');
 | 
						|
        hyphenated_props[hyphenatedKey] = new_props[key];
 | 
						|
    }
 | 
						|
    new_props = hyphenated_props;
 | 
						|
    return new_props;
 | 
						|
}
 | 
						|
function processKey(key) {
 | 
						|
    // Replace spaces with hyphens (v0.13.4+)
 | 
						|
    return key.replace(/ /g, '-');
 | 
						|
}
 | 
						|
function processValue(key, value) {
 | 
						|
    // TODO: This is a hack specifically for Emile's setup. Should be commented in releases.
 | 
						|
    if (key.contains("publishedIn") && (value === null || value === void 0 ? void 0 : value.length) && value.length === 1 && value[0].startsWith && value[0].startsWith("[[") && value[0].endsWith("]]")) {
 | 
						|
        return value[0].slice(2, -2);
 | 
						|
    }
 | 
						|
    return value;
 | 
						|
}
 | 
						|
function setLinkNewProps(link, new_props) {
 | 
						|
    // @ts-ignore
 | 
						|
    for (const a of link.attributes) {
 | 
						|
        if (a.name.includes("data-link") && !(a.name in new_props)) {
 | 
						|
            link.removeAttribute(a.name);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    Object.keys(new_props).forEach(key => {
 | 
						|
        const dom_key = processKey(key);
 | 
						|
        const name = "data-link-" + dom_key;
 | 
						|
        const curValue = link.getAttribute(name);
 | 
						|
        const newValue = processValue(key, new_props[key]);
 | 
						|
        // Only update if value is different
 | 
						|
        if (!newValue || curValue != newValue) {
 | 
						|
            link.setAttribute(name, newValue);
 | 
						|
            if ((newValue === null || newValue === void 0 ? void 0 : newValue.startsWith) && (newValue.startsWith('http') || newValue.startsWith('data:'))) {
 | 
						|
                link.style.setProperty(`--data-link-${dom_key}`, `url(${newValue})`);
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                link.style.setProperty(`--data-link-${dom_key}`, newValue);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    });
 | 
						|
    if (!link.hasClass("data-link-icon")) {
 | 
						|
        link.addClass("data-link-icon");
 | 
						|
    }
 | 
						|
    if (!link.hasClass("data-link-icon-after")) {
 | 
						|
        link.addClass("data-link-icon-after");
 | 
						|
    }
 | 
						|
    if (!link.hasClass("data-link-text")) {
 | 
						|
        link.addClass("data-link-text");
 | 
						|
    }
 | 
						|
}
 | 
						|
function updateLinkExtraAttributes(app, settings, link, destName) {
 | 
						|
    var _a, _b;
 | 
						|
    const linkHref = (_b = (_a = link.getAttribute('href')) === null || _a === void 0 ? void 0 : _a.split('#')) === null || _b === void 0 ? void 0 : _b[0];
 | 
						|
    if (linkHref) {
 | 
						|
        const dest = app.metadataCache.getFirstLinkpathDest(linkHref, destName);
 | 
						|
        if (dest) {
 | 
						|
            const new_props = fetchTargetAttributesSync(app, settings, dest, false);
 | 
						|
            setLinkNewProps(link, new_props);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
function updateDivExtraAttributes(app, settings, link, destName, linkName, filter_collapsible = false) {
 | 
						|
    if (filter_collapsible && link.parentElement.getAttribute("class").contains('mod-collapsible'))
 | 
						|
        return; // Bookmarks Folder
 | 
						|
    if (!linkName) {
 | 
						|
        linkName = link.textContent;
 | 
						|
    }
 | 
						|
    if (!!link.parentElement.getAttribute('data-path')) {
 | 
						|
        // File Browser
 | 
						|
        linkName = link.parentElement.getAttribute('data-path');
 | 
						|
    }
 | 
						|
    else if (link.parentElement.getAttribute("class") == "suggestion-content" && !!link.nextElementSibling) {
 | 
						|
        // Auto complete
 | 
						|
        linkName = link.nextElementSibling.textContent + linkName;
 | 
						|
    }
 | 
						|
    const dest = app.metadataCache.getFirstLinkpathDest(obsidian.getLinkpath(linkName), destName);
 | 
						|
    if (dest) {
 | 
						|
        const new_props = fetchTargetAttributesSync(app, settings, dest, true);
 | 
						|
        setLinkNewProps(link, new_props);
 | 
						|
    }
 | 
						|
}
 | 
						|
function updateElLinks(app, plugin, el, ctx) {
 | 
						|
    const settings = plugin.settings;
 | 
						|
    const links = el.querySelectorAll('a.internal-link');
 | 
						|
    const destName = ctx.sourcePath.replace(/(.*).md/, "$1");
 | 
						|
    links.forEach((link) => {
 | 
						|
        updateLinkExtraAttributes(app, settings, link, destName);
 | 
						|
    });
 | 
						|
}
 | 
						|
function updatePropertiesPane(propertiesEl, file, app, plugin) {
 | 
						|
    var _a;
 | 
						|
    const frontmatter = (_a = app.metadataCache.getCache(file.path)) === null || _a === void 0 ? void 0 : _a.frontmatter;
 | 
						|
    if (!!frontmatter) {
 | 
						|
        const nodes = propertiesEl.querySelectorAll("div.internal-link > .multi-select-pill-content");
 | 
						|
        for (let i = 0; i < nodes.length; ++i) {
 | 
						|
            const el = nodes[i];
 | 
						|
            const linkText = el.textContent;
 | 
						|
            const keyEl = el.parentElement.parentElement.parentElement.parentElement.children[0].children[1];
 | 
						|
            // @ts-ignore
 | 
						|
            const key = keyEl.value;
 | 
						|
            const listOfLinks = frontmatter[key];
 | 
						|
            let foundS = null;
 | 
						|
            if (!listOfLinks) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
            for (const s of listOfLinks) {
 | 
						|
                if (s.length > 4 && s.startsWith("[[") && s.endsWith("]]")) {
 | 
						|
                    const slicedS = s.slice(2, -2);
 | 
						|
                    const split = slicedS.split("|");
 | 
						|
                    if (split.length == 1 && split[0] == linkText) {
 | 
						|
                        foundS = split[0];
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                    else if (split.length == 2 && split[1] == linkText) {
 | 
						|
                        foundS = split[0];
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (!!foundS) {
 | 
						|
                updateDivExtraAttributes(plugin.app, plugin.settings, el, "", foundS);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        const singleNodes = propertiesEl.querySelectorAll("div.metadata-link-inner");
 | 
						|
        for (let i = 0; i < singleNodes.length; ++i) {
 | 
						|
            const el = singleNodes[i];
 | 
						|
            const linkText = el.textContent;
 | 
						|
            const keyEl = el.parentElement.parentElement.parentElement.children[0].children[1];
 | 
						|
            // @ts-ignore
 | 
						|
            const key = keyEl.value;
 | 
						|
            const link = frontmatter[key];
 | 
						|
            if (!link) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
            let foundS = null;
 | 
						|
            if ((link === null || link === void 0 ? void 0 : link.length) > 4 && link.startsWith("[[") && link.endsWith("]]")) {
 | 
						|
                const slicedS = link.slice(2, -2);
 | 
						|
                const split = slicedS.split("|");
 | 
						|
                if (split.length == 1 && split[0] == linkText) {
 | 
						|
                    foundS = split[0];
 | 
						|
                }
 | 
						|
                else if (split.length == 2 && split[1] == linkText) {
 | 
						|
                    foundS = split[0];
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (!!foundS) {
 | 
						|
                updateDivExtraAttributes(plugin.app, plugin.settings, el, "", foundS);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
function updateVisibleLinks(app, plugin) {
 | 
						|
    const settings = plugin.settings;
 | 
						|
    app.workspace.iterateRootLeaves((leaf) => {
 | 
						|
        var _a, _b;
 | 
						|
        if (leaf.view instanceof obsidian.MarkdownView && leaf.view.file) {
 | 
						|
            const file = leaf.view.file;
 | 
						|
            const cachedFile = app.metadataCache.getFileCache(file);
 | 
						|
            // @ts-ignore
 | 
						|
            const metadata = (_b = (_a = leaf.view) === null || _a === void 0 ? void 0 : _a.metadataEditor) === null || _b === void 0 ? void 0 : _b.contentEl;
 | 
						|
            if (!!metadata) {
 | 
						|
                updatePropertiesPane(metadata, file, app, plugin);
 | 
						|
            }
 | 
						|
            //@ts-ignore
 | 
						|
            const tabHeader = leaf.tabHeaderInnerTitleEl;
 | 
						|
            if (settings.enableTabHeader) {
 | 
						|
                // Supercharge tab headers
 | 
						|
                updateDivExtraAttributes(app, settings, tabHeader, "", file.path);
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                clearExtraAttributes(tabHeader);
 | 
						|
            }
 | 
						|
            if (cachedFile === null || cachedFile === void 0 ? void 0 : cachedFile.links) {
 | 
						|
                cachedFile.links.forEach((link) => {
 | 
						|
                    const fileName = file.path.replace(/(.*).md/, "$1");
 | 
						|
                    const dest = app.metadataCache.getFirstLinkpathDest(link.link, fileName);
 | 
						|
                    if (dest) {
 | 
						|
                        const new_props = fetchTargetAttributesSync(app, settings, dest, false);
 | 
						|
                        const internalLinks = leaf.view.containerEl.querySelectorAll(`a.internal-link[href="${link.link}"]`);
 | 
						|
                        internalLinks.forEach((internalLink) => setLinkNewProps(internalLink, new_props));
 | 
						|
                    }
 | 
						|
                });
 | 
						|
            }
 | 
						|
        }
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
function displayText(link, settings) {
 | 
						|
    if (link.type === 'tag') {
 | 
						|
        if (!link.value) {
 | 
						|
            return "<b>Please choose a tag</b>";
 | 
						|
        }
 | 
						|
        return `<span class="data-link-icon data-link-text data-link-icon-after" data-link-tags="${link.value}">Note</span> has tag <a class="tag">#${link.value}</a>`;
 | 
						|
    }
 | 
						|
    else if (link.type === 'attribute') {
 | 
						|
        if (settings.targetAttributes.length === 0) {
 | 
						|
            return `<b>No attributes added to "Target attributes". Go to plugin settings to add them.</b>`;
 | 
						|
        }
 | 
						|
        if (!link.name) {
 | 
						|
            return "<b>Please choose an attribute name.</b>";
 | 
						|
        }
 | 
						|
        if (!link.value) {
 | 
						|
            return "<b>Please choose an attribute value.</b>";
 | 
						|
        }
 | 
						|
        return `<span class="data-link-icon data-link-text data-link-icon-after" data-link-${link.name}="${link.value}">Note</span> has attribute <b>${link.name.replace(/-/g, ' ')}</b> ${matchPreview[link.match]} <b>${link.value}</b>.`;
 | 
						|
    }
 | 
						|
    if (!link.value) {
 | 
						|
        return "<b>Please choose a path.</b>";
 | 
						|
    }
 | 
						|
    return `The path of the <span class="data-link-icon data-link-text data-link-icon-after" data-link-path="${link.value}">note</span> ${matchPreviewPath[link.match]} <b>${link.value}</b>`;
 | 
						|
}
 | 
						|
function updateDisplay(textArea, link, settings) {
 | 
						|
    let toDisplay = displayText(link, settings);
 | 
						|
    let disabled = false;
 | 
						|
    if (link.type === 'tag') {
 | 
						|
        if (!link.value) {
 | 
						|
            disabled = true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else if (link.type === 'attribute') {
 | 
						|
        if (settings.targetAttributes.length === 0) {
 | 
						|
            disabled = true;
 | 
						|
        }
 | 
						|
        else if (!link.name) {
 | 
						|
            disabled = true;
 | 
						|
        }
 | 
						|
        else if (!link.value) {
 | 
						|
            disabled = true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        if (!link.value) {
 | 
						|
            disabled = true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    textArea.innerHTML = toDisplay;
 | 
						|
    return disabled;
 | 
						|
}
 | 
						|
class CSSBuilderModal extends obsidian.Modal {
 | 
						|
    constructor(plugin, saveCallback, cssLink = null) {
 | 
						|
        super(plugin.app);
 | 
						|
        this.cssLink = cssLink;
 | 
						|
        if (!cssLink) {
 | 
						|
            this.cssLink = new CSSLink();
 | 
						|
        }
 | 
						|
        this.plugin = plugin;
 | 
						|
        this.saveCallback = saveCallback;
 | 
						|
    }
 | 
						|
    onOpen() {
 | 
						|
        this.titleEl.setText(`Select what links to style!`);
 | 
						|
        // is tag
 | 
						|
        const matchAttrPlaceholder = "Attribute value to match.";
 | 
						|
        const matchTagPlaceholder = "Note tag to match (without #).";
 | 
						|
        const matchPathPlaceholder = "File path to match.";
 | 
						|
        const matchAttrTxt = "Attribute value";
 | 
						|
        const matchTagTxt = "Tag";
 | 
						|
        const matchPathTxt = "Path";
 | 
						|
        const cssLink = this.cssLink;
 | 
						|
        const plugin = this.plugin;
 | 
						|
        this.contentEl.addClass("supercharged-modal");
 | 
						|
        // Type
 | 
						|
        new obsidian.Setting(this.contentEl)
 | 
						|
            .setName("Type of selector")
 | 
						|
            .setDesc("Attributes selects YAML and DataView attributes" +
 | 
						|
            ", tags chooses the tags of a note, and path considers the name of the note including in what folder it is.")
 | 
						|
            .addDropdown(dc => {
 | 
						|
            Object.keys(selectorType).forEach((type) => {
 | 
						|
                dc.addOption(type, selectorType[type]);
 | 
						|
                if (type === this.cssLink.type) {
 | 
						|
                    dc.setValue(type);
 | 
						|
                }
 | 
						|
            });
 | 
						|
            dc.onChange((type) => {
 | 
						|
                cssLink.type = type;
 | 
						|
                updateContainer(cssLink.type);
 | 
						|
                saveButton.setDisabled(updateDisplay(preview, this.cssLink, this.plugin.settings));
 | 
						|
            });
 | 
						|
        });
 | 
						|
        // attribute name
 | 
						|
        const attrName = new obsidian.Setting(this.contentEl)
 | 
						|
            .setName("Attribute name")
 | 
						|
            .setDesc("What attribute to target? Make sure to first add target attributes to the settings at the top!")
 | 
						|
            .addDropdown(dc => {
 | 
						|
            plugin.settings.targetAttributes.forEach((attribute) => {
 | 
						|
                const dom_attribute = processKey(attribute);
 | 
						|
                dc.addOption(dom_attribute, attribute);
 | 
						|
                if (dom_attribute === cssLink.name) {
 | 
						|
                    dc.setValue(dom_attribute);
 | 
						|
                }
 | 
						|
            });
 | 
						|
            dc.onChange(name => {
 | 
						|
                cssLink.name = name;
 | 
						|
                saveButton.setDisabled(updateDisplay(preview, cssLink, plugin.settings));
 | 
						|
            });
 | 
						|
        });
 | 
						|
        // attribute value
 | 
						|
        const attrValue = new obsidian.Setting(this.contentEl)
 | 
						|
            .setName("Value to match")
 | 
						|
            .setDesc("TODO")
 | 
						|
            .addText(t => {
 | 
						|
            t.setValue(cssLink.value);
 | 
						|
            t.onChange(value => {
 | 
						|
                cssLink.value = value;
 | 
						|
                saveButton.setDisabled(updateDisplay(preview, cssLink, plugin.settings));
 | 
						|
            });
 | 
						|
        });
 | 
						|
        this.contentEl.createEl('h4', { text: 'Advanced' });
 | 
						|
        // matching type
 | 
						|
        const matchingType = new obsidian.Setting(this.contentEl)
 | 
						|
            .setName("Matching type")
 | 
						|
            .setDesc("How to compare the attribute or path with the given value.")
 | 
						|
            .addDropdown(dc => {
 | 
						|
            Object.keys(matchTypes).forEach((key) => {
 | 
						|
                dc.addOption(key, matchTypes[key]);
 | 
						|
                if (key == cssLink.match) {
 | 
						|
                    dc.setValue(key);
 | 
						|
                }
 | 
						|
            });
 | 
						|
            dc.onChange((value) => {
 | 
						|
                cssLink.match = value;
 | 
						|
                saveButton.setDisabled(updateDisplay(preview, cssLink, plugin.settings));
 | 
						|
            });
 | 
						|
        });
 | 
						|
        // case sensitive
 | 
						|
        const caseSensitiveTogglerContainer = new obsidian.Setting(this.contentEl)
 | 
						|
            .setName("Case sensitive matching")
 | 
						|
            .setDesc("Should the matching of the value be case sensitive?")
 | 
						|
            .addToggle(b => {
 | 
						|
            b.setValue(cssLink.matchCaseSensitive);
 | 
						|
            b.onChange(value => {
 | 
						|
                cssLink.matchCaseSensitive = value;
 | 
						|
                b.setDisabled(updateDisplay(preview, cssLink, plugin.settings));
 | 
						|
            });
 | 
						|
        });
 | 
						|
        if (!this.cssLink.name && this.plugin.settings.targetAttributes.length > 0) {
 | 
						|
            this.cssLink.name = this.plugin.settings.targetAttributes[0];
 | 
						|
        }
 | 
						|
        const updateContainer = function (type) {
 | 
						|
            if (type === 'attribute') {
 | 
						|
                attrName.settingEl.show();
 | 
						|
                attrValue.nameEl.setText(matchAttrTxt);
 | 
						|
                attrValue.descEl.setText(matchAttrPlaceholder);
 | 
						|
                matchingType.settingEl.show();
 | 
						|
                caseSensitiveTogglerContainer.settingEl.show();
 | 
						|
            }
 | 
						|
            else if (type === 'tag') {
 | 
						|
                attrName.settingEl.hide();
 | 
						|
                attrValue.nameEl.setText(matchTagTxt);
 | 
						|
                attrValue.descEl.setText(matchTagPlaceholder);
 | 
						|
                matchingType.settingEl.hide();
 | 
						|
                caseSensitiveTogglerContainer.settingEl.hide();
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                attrName.settingEl.hide();
 | 
						|
                attrValue.nameEl.setText(matchPathTxt);
 | 
						|
                attrValue.descEl.setText(matchPathPlaceholder);
 | 
						|
                matchingType.settingEl.show();
 | 
						|
                caseSensitiveTogglerContainer.settingEl.show();
 | 
						|
            }
 | 
						|
        };
 | 
						|
        new obsidian.Setting(this.contentEl)
 | 
						|
            .setName("Style options")
 | 
						|
            .setDesc("What styling options are active? " +
 | 
						|
            "Disabling options you won't use can improve performance slightly.")
 | 
						|
            .addToggle(t => {
 | 
						|
            t.onChange(value => {
 | 
						|
                cssLink.selectText = value;
 | 
						|
            });
 | 
						|
            t.setValue(cssLink.selectText);
 | 
						|
            t.setTooltip("Style link text");
 | 
						|
        })
 | 
						|
            .addToggle(t => {
 | 
						|
            t.onChange(value => {
 | 
						|
                cssLink.selectPrepend = value;
 | 
						|
            });
 | 
						|
            t.setValue(cssLink.selectPrepend);
 | 
						|
            t.setTooltip("Add content before link");
 | 
						|
        })
 | 
						|
            .addToggle(t => {
 | 
						|
            t.onChange(value => {
 | 
						|
                cssLink.selectAppend = value;
 | 
						|
            });
 | 
						|
            t.setValue(cssLink.selectAppend);
 | 
						|
            t.setTooltip("Add content after link");
 | 
						|
        })
 | 
						|
            .addToggle(t => {
 | 
						|
            t.onChange(value => {
 | 
						|
                cssLink.selectBackground = value;
 | 
						|
            });
 | 
						|
            t.setValue(cssLink.selectBackground);
 | 
						|
            t.setTooltip("Add optional background or underline to link");
 | 
						|
        });
 | 
						|
        this.contentEl.createEl('h4', { text: 'Result' });
 | 
						|
        const modal = this;
 | 
						|
        const saveButton = new obsidian.Setting(this.contentEl)
 | 
						|
            .setName("Preview")
 | 
						|
            .setDesc("")
 | 
						|
            .addButton(b => {
 | 
						|
            b.setButtonText("Save");
 | 
						|
            b.onClick(() => {
 | 
						|
                modal.saveCallback(cssLink);
 | 
						|
                modal.close();
 | 
						|
            });
 | 
						|
        });
 | 
						|
        // generate button
 | 
						|
        const preview = saveButton.nameEl;
 | 
						|
        updateContainer(cssLink.type);
 | 
						|
        saveButton.setDisabled(updateDisplay(preview, this.cssLink, this.plugin.settings));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
const colorSet = [[
 | 
						|
        '#0089BA',
 | 
						|
        '#2C73D2',
 | 
						|
        '#008E9B',
 | 
						|
        '#0081CF',
 | 
						|
        '#008F7A',
 | 
						|
        '#008E9B',
 | 
						|
    ], [
 | 
						|
        '#D65DB1',
 | 
						|
        '#0082C1',
 | 
						|
        '#9270D3',
 | 
						|
        '#007F93',
 | 
						|
        '#007ED9',
 | 
						|
        '#007660',
 | 
						|
    ], [
 | 
						|
        '#FF9671',
 | 
						|
        '#A36AAA',
 | 
						|
        '#F27D88',
 | 
						|
        '#6967A9',
 | 
						|
        '#D26F9D',
 | 
						|
        '#1b6299',
 | 
						|
    ], [
 | 
						|
        '#FFC75F',
 | 
						|
        '#4C9A52',
 | 
						|
        '#C3BB4E',
 | 
						|
        '#00855B',
 | 
						|
        '#88AC4B',
 | 
						|
        '#006F61',
 | 
						|
    ], [
 | 
						|
        '#FF6F91',
 | 
						|
        '#6F7F22',
 | 
						|
        '#E07250',
 | 
						|
        '#257A3E',
 | 
						|
        '#AC7C26',
 | 
						|
        '#006F5F',
 | 
						|
    ], [
 | 
						|
        '#d9d867',
 | 
						|
        '#2FAB63',
 | 
						|
        '#B8E067',
 | 
						|
        '#008E63',
 | 
						|
        '#78C664',
 | 
						|
        '#007160',
 | 
						|
    ]];
 | 
						|
const colors = [];
 | 
						|
for (const i of Array(6).keys()) {
 | 
						|
    for (const j of Array(6).keys()) {
 | 
						|
        colors.push(colorSet[j][i]);
 | 
						|
    }
 | 
						|
}
 | 
						|
function hash(uid) {
 | 
						|
    let hash = 0;
 | 
						|
    for (let i = 0; i < uid.length; i++) {
 | 
						|
        const char = uid.charCodeAt(i);
 | 
						|
        hash = ((hash << 5) - hash) + char;
 | 
						|
        hash = hash & hash; // Convert to 32bit integer
 | 
						|
    }
 | 
						|
    hash = Math.abs(hash);
 | 
						|
    return hash;
 | 
						|
}
 | 
						|
function buildCSS(selectors, plugin) {
 | 
						|
    return __awaiter(this, void 0, void 0, function* () {
 | 
						|
        var _a;
 | 
						|
        const instructions = [
 | 
						|
            "/* WARNING: This file will be overwritten by the plugin.",
 | 
						|
            "Do not edit this file directly! First copy this file and rename it if you want to edit things. */",
 | 
						|
            "",
 | 
						|
            ":root {"
 | 
						|
        ];
 | 
						|
        selectors.forEach((selector, i) => {
 | 
						|
            if (selector.selectText) {
 | 
						|
                instructions.push(`    --${selector.uid}-color: ${colors[hash(selector.uid) % 36]};`);
 | 
						|
                instructions.push(`    --${selector.uid}-weight: initial;`);
 | 
						|
            }
 | 
						|
            if (selector.selectPrepend) {
 | 
						|
                instructions.push(`    --${selector.uid}-before: '';`);
 | 
						|
            }
 | 
						|
            if (selector.selectAppend) {
 | 
						|
                instructions.push(`    --${selector.uid}-after: '';`);
 | 
						|
            }
 | 
						|
            if (selector.selectBackground) {
 | 
						|
                instructions.push(`    --${selector.uid}-background-color: #ffffff;`);
 | 
						|
                instructions.push(`    --${selector.uid}-decoration: initial;`);
 | 
						|
            }
 | 
						|
        });
 | 
						|
        instructions.push("}");
 | 
						|
        selectors.forEach(selector => {
 | 
						|
            let cssSelector;
 | 
						|
            if (selector.type === 'attribute') {
 | 
						|
                cssSelector = `[data-link-${selector.name}${matchSign[selector.match]}="${selector.value}" ${selector.matchCaseSensitive ? "" : " i"}]`;
 | 
						|
            }
 | 
						|
            else if (selector.type === 'tag') {
 | 
						|
                cssSelector = `[data-link-tags*="${selector.value}" i]`;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                cssSelector = `[data-link-path${matchSign[selector.match]}="${selector.value}" ${selector.matchCaseSensitive ? "" : "i"}]`;
 | 
						|
            }
 | 
						|
            if (selector.selectText) {
 | 
						|
                instructions.push(...[
 | 
						|
                    "",
 | 
						|
                    `div[data-id="${selector.uid}"] div.setting-item-description,`,
 | 
						|
                    cssSelector + " {",
 | 
						|
                    `    color: var(--${selector.uid}-color) !important;`,
 | 
						|
                    `    font-weight: var(--${selector.uid}-weight);`,
 | 
						|
                    "}"
 | 
						|
                ]);
 | 
						|
            }
 | 
						|
            if (selector.selectBackground) {
 | 
						|
                instructions.push(...["",
 | 
						|
                    `.c-${selector.uid}-use-background div[data-id="${selector.uid}"] div.setting-item-description,`,
 | 
						|
                    `.c-${selector.uid}-use-background .data-link-text${cssSelector} {`,
 | 
						|
                    `    background-color: var(--${selector.uid}-background-color) !important;`,
 | 
						|
                    `    border-radius: 5px;`,
 | 
						|
                    `    padding-left: 2px;`,
 | 
						|
                    `    padding-right: 2px;`,
 | 
						|
                    `    text-decoration: var(--${selector.uid}-decoration) !important;`,
 | 
						|
                    "}"]);
 | 
						|
            }
 | 
						|
            if (selector.selectPrepend) {
 | 
						|
                instructions.push(...["",
 | 
						|
                    `div[data-id="${selector.uid}"] div.setting-item-description::before,`,
 | 
						|
                    `.data-link-icon${cssSelector}::before {`,
 | 
						|
                    `    content: var(--${selector.uid}-before);`,
 | 
						|
                    "}"]);
 | 
						|
            }
 | 
						|
            if (selector.selectAppend) {
 | 
						|
                instructions.push(...["",
 | 
						|
                    `div[data-id="${selector.uid}"] div.setting-item-description::after,`,
 | 
						|
                    `.data-link-icon-after${cssSelector}::after {`,
 | 
						|
                    `    content: var(--${selector.uid}-after);`,
 | 
						|
                    "}"]);
 | 
						|
            }
 | 
						|
        });
 | 
						|
        instructions.push(...[
 | 
						|
            "/* @settings",
 | 
						|
            "name: Supercharged Links",
 | 
						|
            "id: supercharged-links",
 | 
						|
            "settings:",
 | 
						|
        ]);
 | 
						|
        selectors.forEach((selector, i) => {
 | 
						|
            let name = selector.name;
 | 
						|
            let value = selector.value;
 | 
						|
            if (selector.type === 'tag') {
 | 
						|
                name = 'tag';
 | 
						|
                // value = "\#" + value;
 | 
						|
            }
 | 
						|
            else if (selector.type === 'path') {
 | 
						|
                name = 'path';
 | 
						|
            }
 | 
						|
            instructions.push(...[
 | 
						|
                "    - ",
 | 
						|
                `        id: ${selector.uid}`,
 | 
						|
                `        title: ${name} is ${value}`,
 | 
						|
                `        description: Example note`,
 | 
						|
                "        type: heading",
 | 
						|
                "        collapsed: true",
 | 
						|
                "        level: 3"
 | 
						|
            ]);
 | 
						|
            if (selector.selectText) {
 | 
						|
                instructions.push(...[
 | 
						|
                    "    - ",
 | 
						|
                    `        id: ${selector.uid}-color`,
 | 
						|
                    `        title: Link color`,
 | 
						|
                    "        type: variable-color",
 | 
						|
                    "        format: hex",
 | 
						|
                    `        default: '${colors[hash(selector.uid) % 36]}'`,
 | 
						|
                    "    - ",
 | 
						|
                    `        id: ${selector.uid}-weight`,
 | 
						|
                    `        title: Font weight`,
 | 
						|
                    "        type: variable-select",
 | 
						|
                    `        default: initial`,
 | 
						|
                    `        options:`,
 | 
						|
                    `            - initial`,
 | 
						|
                    `            - lighter`,
 | 
						|
                    `            - normal`,
 | 
						|
                    `            - bold`,
 | 
						|
                    `            - bolder`,
 | 
						|
                    "    - ",
 | 
						|
                    `        id: ${selector.uid}-decoration`,
 | 
						|
                    `        title: Font decoration`,
 | 
						|
                    "        type: variable-select",
 | 
						|
                    `        default: initial`,
 | 
						|
                    `        options:`,
 | 
						|
                    `            - initial`,
 | 
						|
                    `            - underline`,
 | 
						|
                    `            - overline`,
 | 
						|
                    `            - line-through`
 | 
						|
                ]);
 | 
						|
            }
 | 
						|
            if (selector.selectPrepend) {
 | 
						|
                instructions.push(...["    - ",
 | 
						|
                    `        id: ${selector.uid}-before`,
 | 
						|
                    `        title: Prepend text`,
 | 
						|
                    `        description: Add some text, such as an emoji, before the links.`,
 | 
						|
                    "        type: variable-text",
 | 
						|
                    `        default: ''`,
 | 
						|
                    `        quotes: true`]);
 | 
						|
            }
 | 
						|
            if (selector.selectAppend) {
 | 
						|
                instructions.push(...["    - ",
 | 
						|
                    `        id: ${selector.uid}-after`,
 | 
						|
                    `        title: Append text`,
 | 
						|
                    `        description: Add some text, such as an emoji, after the links.`,
 | 
						|
                    "        type: variable-text",
 | 
						|
                    `        default: ''`,
 | 
						|
                    `        quotes: true`]);
 | 
						|
            }
 | 
						|
            if (selector.selectBackground) {
 | 
						|
                instructions.push(...["    - ",
 | 
						|
                    `        id: c-${selector.uid}-use-background`,
 | 
						|
                    `        title: Use background color`,
 | 
						|
                    `        description: Adds a background color to the link. This can look buggy in live preview.`,
 | 
						|
                    "        type: class-toggle",
 | 
						|
                    "    - ",
 | 
						|
                    `        id: ${selector.uid}-background-color`,
 | 
						|
                    `        title: Background color`,
 | 
						|
                    "        type: variable-color",
 | 
						|
                    "        format: hex",
 | 
						|
                    `        default: '#ffffff'`]);
 | 
						|
            }
 | 
						|
        });
 | 
						|
        instructions.push("*/");
 | 
						|
        const vault = plugin.app.vault;
 | 
						|
        const configDir = (_a = vault.configDir) !== null && _a !== void 0 ? _a : ".obsidian";
 | 
						|
        const pathDir = configDir + "/snippets";
 | 
						|
        yield vault.adapter.mkdir(pathDir);
 | 
						|
        const path = pathDir + "/supercharged-links-gen.css";
 | 
						|
        if (yield vault.adapter.exists(path)) {
 | 
						|
            yield vault.adapter.remove(path);
 | 
						|
        }
 | 
						|
        yield plugin.app.vault.create(path, instructions.join('\n'));
 | 
						|
        // Activate snippet
 | 
						|
        if (plugin.settings.activateSnippet) {
 | 
						|
            // @ts-ignore
 | 
						|
            const customCss = plugin.app.customCss;
 | 
						|
            customCss.enabledSnippets.add('supercharged-links-gen');
 | 
						|
            customCss.requestLoadSnippets();
 | 
						|
        }
 | 
						|
        // Ensure Style Settings reads changes
 | 
						|
        plugin.app.workspace.trigger("parse-style-settings");
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
class SuperchargedLinksSettingTab extends obsidian.PluginSettingTab {
 | 
						|
    constructor(app, plugin) {
 | 
						|
        super(app, plugin);
 | 
						|
        this.plugin = plugin;
 | 
						|
        this.debouncedGenerate = obsidian.debounce(this._generateSnippet, 1000, true);
 | 
						|
        // Generate CSS immediately rather than 1 second - feels laggy
 | 
						|
        this._generateSnippet();
 | 
						|
    }
 | 
						|
    display() {
 | 
						|
        let { containerEl } = this;
 | 
						|
        containerEl.empty();
 | 
						|
        /* Managing extra attirbutes for a.internal-link */
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Target Attributes for styling')
 | 
						|
            .setDesc('Frontmatter attributes to target, comma separated')
 | 
						|
            .addTextArea((text) => {
 | 
						|
            text
 | 
						|
                .setPlaceholder('Enter attributes as string, comma separated')
 | 
						|
                .setValue(this.plugin.settings.targetAttributes.join(', '))
 | 
						|
                .onChange((value) => __awaiter(this, void 0, void 0, function* () {
 | 
						|
                this.plugin.settings.targetAttributes = value.split(',').map(attr => attr.trim());
 | 
						|
                if (this.plugin.settings.targetAttributes.length === 1 && !this.plugin.settings.targetAttributes[0]) {
 | 
						|
                    this.plugin.settings.targetAttributes = [];
 | 
						|
                }
 | 
						|
                yield this.plugin.saveSettings();
 | 
						|
            }));
 | 
						|
            text.inputEl.rows = 6;
 | 
						|
            text.inputEl.cols = 25;
 | 
						|
        });
 | 
						|
        containerEl.createEl('h4', { text: 'Styling' });
 | 
						|
        const styleSettingDescription = containerEl.createDiv();
 | 
						|
        styleSettingDescription.innerHTML = `
 | 
						|
Styling can be done using the Style Settings plugin. 
 | 
						|
 <ol>
 | 
						|
 <li>Create selectors down below.</li>
 | 
						|
 <li>Go to the Style Settings tab and style your links!</li>
 | 
						|
</ol>`;
 | 
						|
        const selectorDiv = containerEl.createDiv();
 | 
						|
        this.drawSelectors(selectorDiv);
 | 
						|
        containerEl.createEl('h4', { text: 'Settings' });
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Enable in Editor')
 | 
						|
            .setDesc('If true, this will also supercharge internal links in the editor view of a note.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.enableEditor);
 | 
						|
            toggle.onChange(value => {
 | 
						|
                this.plugin.settings.enableEditor = value;
 | 
						|
                this.plugin.saveSettings();
 | 
						|
                updateVisibleLinks(this.app, this.plugin);
 | 
						|
            });
 | 
						|
        });
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Enable in tab headers')
 | 
						|
            .setDesc('If true, this will also supercharge the headers of a tab.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.enableTabHeader);
 | 
						|
            toggle.onChange(value => {
 | 
						|
                this.plugin.settings.enableTabHeader = value;
 | 
						|
                this.plugin.saveSettings();
 | 
						|
                updateVisibleLinks(this.app, this.plugin);
 | 
						|
            });
 | 
						|
        });
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Enable in File Browser')
 | 
						|
            .setDesc('If true, this will also supercharge the file browser.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.enableFileList);
 | 
						|
            toggle.onChange(value => {
 | 
						|
                this.plugin.settings.enableFileList = value;
 | 
						|
                this.plugin.saveSettings();
 | 
						|
            });
 | 
						|
        });
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Enable in Bases')
 | 
						|
            .setDesc('If true, this will also supercharge Obsidian Bases.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.enableBases);
 | 
						|
            toggle.onChange(value => {
 | 
						|
                this.plugin.settings.enableBases = value;
 | 
						|
                this.plugin.saveSettings();
 | 
						|
            });
 | 
						|
        });
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Enable in Plugins')
 | 
						|
            .setDesc('If true, this will also supercharge plugins like the backlinks and forward links panels.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.enableBacklinks);
 | 
						|
            toggle.onChange(value => {
 | 
						|
                this.plugin.settings.enableBacklinks = value;
 | 
						|
                this.plugin.saveSettings();
 | 
						|
            });
 | 
						|
        });
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Enable in Quick Switcher')
 | 
						|
            .setDesc('If true, this will also supercharge the quick switcher.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.enableQuickSwitcher);
 | 
						|
            toggle.onChange(value => {
 | 
						|
                this.plugin.settings.enableQuickSwitcher = value;
 | 
						|
                this.plugin.saveSettings();
 | 
						|
            });
 | 
						|
        });
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Enable in Link Autocompleter')
 | 
						|
            .setDesc('If true, this will also supercharge the link autocompleter.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.enableSuggestor);
 | 
						|
            toggle.onChange(value => {
 | 
						|
                this.plugin.settings.enableSuggestor = value;
 | 
						|
                this.plugin.saveSettings();
 | 
						|
            });
 | 
						|
        });
 | 
						|
        containerEl.createEl('h4', { text: 'Advanced' });
 | 
						|
        // Managing choice wether you want to parse tags both from normal tags and in the frontmatter
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Parse all tags in the file')
 | 
						|
            .setDesc('Sets the `data-link-tags`-attribute to look for tags both in the frontmatter and in the file as #tag-name')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.targetTags);
 | 
						|
            toggle.onChange((value) => __awaiter(this, void 0, void 0, function* () {
 | 
						|
                this.plugin.settings.targetTags = value;
 | 
						|
                yield this.plugin.saveSettings();
 | 
						|
            }));
 | 
						|
        });
 | 
						|
        // Managing choice wether you get attributes from inline fields and frontmatter or only frontmater
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Search for attribute in Inline fields like <field::>')
 | 
						|
            .setDesc('Sets the `data-link-<field>`-attribute to the value of inline fields')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.getFromInlineField);
 | 
						|
            toggle.onChange((value) => __awaiter(this, void 0, void 0, function* () {
 | 
						|
                this.plugin.settings.getFromInlineField = value;
 | 
						|
                yield this.plugin.saveSettings();
 | 
						|
            }));
 | 
						|
        });
 | 
						|
        // Automatically activate snippet
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName('Automatically activate snippet')
 | 
						|
            .setDesc('If true, this will automatically activate the generated CSS snippet "supercharged-links-gen.css". ' +
 | 
						|
            'Turn this off if you don\'t want this to happen.')
 | 
						|
            .addToggle(toggle => {
 | 
						|
            toggle.setValue(this.plugin.settings.activateSnippet);
 | 
						|
            toggle.onChange((value) => __awaiter(this, void 0, void 0, function* () {
 | 
						|
                this.plugin.settings.activateSnippet = value;
 | 
						|
                yield this.plugin.saveSettings();
 | 
						|
            }));
 | 
						|
        });
 | 
						|
        /* Managing predefined values for properties */
 | 
						|
        /* Manage menu options display*/
 | 
						|
        new obsidian.Setting(containerEl)
 | 
						|
            .setName("Display field options in context menu")
 | 
						|
            .setDesc("This feature has been migrated to metadata-menu plugin https://github.com/mdelobelle/metadatamenu");
 | 
						|
    }
 | 
						|
    generateSnippet() {
 | 
						|
        this.debouncedGenerate();
 | 
						|
    }
 | 
						|
    _generateSnippet() {
 | 
						|
        return __awaiter(this, void 0, void 0, function* () {
 | 
						|
            yield buildCSS(this.plugin.settings.selectors, this.plugin);
 | 
						|
            // new Notice("Generated supercharged-links-gen.css");
 | 
						|
        });
 | 
						|
    }
 | 
						|
    drawSelectors(div) {
 | 
						|
        div.empty();
 | 
						|
        this.generateSnippet();
 | 
						|
        const selectors = this.plugin.settings.selectors;
 | 
						|
        selectors.forEach((selector, i) => {
 | 
						|
            const s = new obsidian.Setting(div)
 | 
						|
                .addButton(button => {
 | 
						|
                button.onClick(() => {
 | 
						|
                    const oldSelector = selectors[i + 1];
 | 
						|
                    selectors[i + 1] = selector;
 | 
						|
                    selectors[i] = oldSelector;
 | 
						|
                    this.drawSelectors(div);
 | 
						|
                });
 | 
						|
                button.setIcon("down-arrow-with-tail");
 | 
						|
                button.setTooltip("Move selector down");
 | 
						|
                if (i === selectors.length - 1) {
 | 
						|
                    button.setDisabled(true);
 | 
						|
                }
 | 
						|
            })
 | 
						|
                .addButton(button => {
 | 
						|
                button.onClick(() => {
 | 
						|
                    const oldSelector = selectors[i - 1];
 | 
						|
                    selectors[i - 1] = selector;
 | 
						|
                    selectors[i] = oldSelector;
 | 
						|
                    this.drawSelectors(div);
 | 
						|
                });
 | 
						|
                button.setIcon("up-arrow-with-tail");
 | 
						|
                button.setTooltip("Move selector up");
 | 
						|
                if (i === 0) {
 | 
						|
                    button.setDisabled(true);
 | 
						|
                }
 | 
						|
            })
 | 
						|
                .addButton(button => {
 | 
						|
                button.onClick(() => {
 | 
						|
                    const formModal = new CSSBuilderModal(this.plugin, (newSelector) => {
 | 
						|
                        this.plugin.settings.selectors[i] = newSelector;
 | 
						|
                        this.plugin.saveSettings();
 | 
						|
                        updateDisplay(s.nameEl, selector, this.plugin.settings);
 | 
						|
                        this.generateSnippet();
 | 
						|
                    }, selector);
 | 
						|
                    formModal.open();
 | 
						|
                });
 | 
						|
                button.setIcon("pencil");
 | 
						|
                button.setTooltip("Edit selector");
 | 
						|
            })
 | 
						|
                .addButton(button => {
 | 
						|
                button.onClick(() => {
 | 
						|
                    this.plugin.settings.selectors.remove(selector);
 | 
						|
                    this.plugin.saveSettings();
 | 
						|
                    this.drawSelectors(div);
 | 
						|
                });
 | 
						|
                button.setIcon("cross");
 | 
						|
                button.setTooltip("Remove selector");
 | 
						|
            });
 | 
						|
            updateDisplay(s.nameEl, selector, this.plugin.settings);
 | 
						|
        });
 | 
						|
        new obsidian.Setting(div)
 | 
						|
            .setName("New selector")
 | 
						|
            .setDesc("Create a new selector to style with Style Settings.")
 | 
						|
            .addButton(button => {
 | 
						|
            button.onClick(() => {
 | 
						|
                const formModal = new CSSBuilderModal(this.plugin, (newSelector) => {
 | 
						|
                    this.plugin.settings.selectors.push(newSelector);
 | 
						|
                    this.plugin.saveSettings();
 | 
						|
                    this.drawSelectors(div);
 | 
						|
                    // TODO: Force redraw somehow?
 | 
						|
                });
 | 
						|
                formModal.open();
 | 
						|
            });
 | 
						|
            button.setButtonText("New");
 | 
						|
        });
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
const DEFAULT_SETTINGS = {
 | 
						|
    targetAttributes: [],
 | 
						|
    targetTags: true,
 | 
						|
    getFromInlineField: false,
 | 
						|
    enableTabHeader: true,
 | 
						|
    activateSnippet: true,
 | 
						|
    enableEditor: true,
 | 
						|
    enableFileList: true,
 | 
						|
    enableBacklinks: true,
 | 
						|
    enableQuickSwitcher: true,
 | 
						|
    enableSuggestor: true,
 | 
						|
    enableBases: true,
 | 
						|
    selectors: []
 | 
						|
};
 | 
						|
 | 
						|
function buildCMViewPlugin(app, _settings) {
 | 
						|
    // Implements the live preview supercharging
 | 
						|
    // Code structure based on https://github.com/nothingislost/obsidian-cm6-attributes/blob/743d71b0aa616407149a0b6ea5ffea28e2154158/src/main.ts
 | 
						|
    // Code help credits to @NothingIsLost! They have been a great help getting this to work properly.
 | 
						|
    class HeaderWidget extends view.WidgetType {
 | 
						|
        constructor(attributes, after) {
 | 
						|
            super();
 | 
						|
            this.attributes = attributes;
 | 
						|
            this.after = after;
 | 
						|
        }
 | 
						|
        toDOM() {
 | 
						|
            var _a;
 | 
						|
            let headerEl = document.createElement("span");
 | 
						|
            headerEl.setAttrs(this.attributes);
 | 
						|
            for (let key in this.attributes) {
 | 
						|
                // CSS doesn't allow interpolation of variables for URLs, so do it beforehand to be nice.
 | 
						|
                if (((_a = this.attributes[key]) === null || _a === void 0 ? void 0 : _a.startsWith) && (this.attributes[key].startsWith('http') || this.attributes[key].startsWith('data:'))) {
 | 
						|
                    headerEl.style.setProperty(`--${key}`, `url(${this.attributes[key]})`);
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    headerEl.style.setProperty(`--${key}`, processValue(key, this.attributes[key]));
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (this.after) {
 | 
						|
                headerEl.addClass('data-link-icon-after');
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                headerEl.addClass('data-link-icon');
 | 
						|
            }
 | 
						|
            // create a naive bread crumb
 | 
						|
            return headerEl;
 | 
						|
        }
 | 
						|
        ignoreEvent() {
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    const settings = _settings;
 | 
						|
    const viewPlugin = view.ViewPlugin.fromClass(class {
 | 
						|
        constructor(view) {
 | 
						|
            this.decorations = this.buildDecorations(view);
 | 
						|
        }
 | 
						|
        update(update) {
 | 
						|
            if (update.docChanged) {
 | 
						|
                this.decorations = this.decorations.map(update.changes);
 | 
						|
                update.changes.iterChanges((fromA, toA, fromB, toB, t) => {
 | 
						|
                    // Update all 'line blocks' between the range changed. Prevents weird graphical bugs
 | 
						|
                    const minFrom = update.view.lineBlockAt(fromB).from;
 | 
						|
                    const maxTo = update.view.lineBlockAt(toB).to;
 | 
						|
                    // remove things within bounds
 | 
						|
                    this.decorations = this.decorations.update({
 | 
						|
                        filter: (from, to) => to < minFrom || from > maxTo
 | 
						|
                    });
 | 
						|
                    // Update decorations within bounds
 | 
						|
                    this.decorations = state.RangeSet.join([this.decorations,
 | 
						|
                        this.buildDecorations(update.view, minFrom, maxTo)]);
 | 
						|
                });
 | 
						|
            }
 | 
						|
            else if (update.viewportChanged) {
 | 
						|
                this.decorations = this.buildDecorations(update.view);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        destroy() {
 | 
						|
        }
 | 
						|
        buildDecorations(view$1, updateFrom = -1, updateTo = -1) {
 | 
						|
            let builder = new state.RangeSetBuilder();
 | 
						|
            if (!settings.enableEditor) {
 | 
						|
                return builder.finish();
 | 
						|
            }
 | 
						|
            const mdView = view$1.state.field(obsidian.editorViewField);
 | 
						|
            let lastAttributes = {};
 | 
						|
            let iconDecoAfter = null;
 | 
						|
            let iconDecoAfterWhere = null;
 | 
						|
            let mdAliasFrom = null;
 | 
						|
            let mdAliasTo = null;
 | 
						|
            for (let { from, to } of view$1.visibleRanges) {
 | 
						|
                // When updating, only changes the range given.
 | 
						|
                if (updateFrom !== -1 && (to < updateFrom || from > updateTo))
 | 
						|
                    continue;
 | 
						|
                language.syntaxTree(view$1.state).iterate({
 | 
						|
                    from,
 | 
						|
                    to,
 | 
						|
                    enter: (node) => {
 | 
						|
                        if (updateFrom !== -1 && (node.to < updateFrom || node.from > updateTo))
 | 
						|
                            return;
 | 
						|
                        const tokenProps = node.type.prop(language.tokenClassNodeProp);
 | 
						|
                        if (tokenProps) {
 | 
						|
                            const props = new Set(tokenProps.split(" "));
 | 
						|
                            // Square Brackets of links both internal (`[[`, `]]`) and md link (`[`, `]`)
 | 
						|
                            const isMDFormatting = props.has('formatting-link') || props.has('formatting-link-string');
 | 
						|
                            if (isMDFormatting)
 | 
						|
                                return;
 | 
						|
                            // Parts of internal links
 | 
						|
                            const isLink = props.has("hmd-internal-link"); // [[`Note` or `|` or `Alias`]]
 | 
						|
                            const isAlias = props.has("link-alias"); // [[Note| `Alias`]]
 | 
						|
                            const isPipe = props.has("link-alias-pipe"); // [[Note `|` Alias]]
 | 
						|
                            // The 'alias' of the md link (or its brackets)
 | 
						|
                            const isMDLink = props.has('link'); // `[` or `Alias` or `]`(URL)
 | 
						|
                            // The 'internal link' of the md link (or its brackets)
 | 
						|
                            const isMDUrl = props.has('url'); // [Alias]`(` or `URL` or `)`
 | 
						|
                            if (isMDLink) {
 | 
						|
                                // This catches the alias of md links i.e. [ `Alias` ](URL)
 | 
						|
                                // We'll apply the styling in the next iteration when we analyze the `URL`
 | 
						|
                                mdAliasFrom = node.from;
 | 
						|
                                mdAliasTo = node.to;
 | 
						|
                            }
 | 
						|
                            if (!isPipe && !isAlias) {
 | 
						|
                                if (iconDecoAfter) {
 | 
						|
                                    builder.add(iconDecoAfterWhere, iconDecoAfterWhere, iconDecoAfter);
 | 
						|
                                    iconDecoAfter = null;
 | 
						|
                                    iconDecoAfterWhere = null;
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            if (isLink && !isAlias && !isPipe || isMDUrl) {
 | 
						|
                                let linkText = view$1.state.doc.sliceString(node.from, node.to);
 | 
						|
                                linkText = linkText.split("#")[0];
 | 
						|
                                let file = app.metadataCache.getFirstLinkpathDest(linkText, mdView.file.basename);
 | 
						|
                                if (isMDUrl && !file) {
 | 
						|
                                    try {
 | 
						|
                                        file = app.vault.getAbstractFileByPath(decodeURIComponent(linkText));
 | 
						|
                                    }
 | 
						|
                                    catch (e) { }
 | 
						|
                                }
 | 
						|
                                if (file) {
 | 
						|
                                    let _attributes = fetchTargetAttributesSync(app, settings, file, true);
 | 
						|
                                    let attributes = {};
 | 
						|
                                    for (let key in _attributes) {
 | 
						|
                                        attributes["data-link-" + key] = _attributes[key];
 | 
						|
                                    }
 | 
						|
                                    let deco = view.Decoration.mark({
 | 
						|
                                        attributes,
 | 
						|
                                        class: "data-link-text"
 | 
						|
                                    });
 | 
						|
                                    let iconDecoBefore = view.Decoration.widget({
 | 
						|
                                        widget: new HeaderWidget(attributes, false),
 | 
						|
                                    });
 | 
						|
                                    iconDecoAfter = view.Decoration.widget({
 | 
						|
                                        widget: new HeaderWidget(attributes, true),
 | 
						|
                                    });
 | 
						|
                                    if (isMDUrl) {
 | 
						|
                                        // Apply retroactively to the alias found before
 | 
						|
                                        let deco = view.Decoration.mark({
 | 
						|
                                            attributes: attributes,
 | 
						|
                                            class: "data-link-text"
 | 
						|
                                        });
 | 
						|
                                        builder.add(mdAliasFrom, mdAliasFrom, iconDecoBefore);
 | 
						|
                                        builder.add(mdAliasFrom, mdAliasTo, deco);
 | 
						|
                                        if (iconDecoAfter) {
 | 
						|
                                            builder.add(mdAliasTo, mdAliasTo, iconDecoAfter);
 | 
						|
                                            iconDecoAfter = null;
 | 
						|
                                            iconDecoAfterWhere = null;
 | 
						|
                                            mdAliasFrom = null;
 | 
						|
                                            mdAliasTo = null;
 | 
						|
                                        }
 | 
						|
                                    }
 | 
						|
                                    else {
 | 
						|
                                        builder.add(node.from, node.from, iconDecoBefore);
 | 
						|
                                    }
 | 
						|
                                    builder.add(node.from, node.to, deco);
 | 
						|
                                    lastAttributes = attributes;
 | 
						|
                                    iconDecoAfterWhere = node.to;
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            else if (isLink && isAlias) {
 | 
						|
                                let deco = view.Decoration.mark({
 | 
						|
                                    attributes: lastAttributes,
 | 
						|
                                    class: "data-link-text"
 | 
						|
                                });
 | 
						|
                                builder.add(node.from, node.to, deco);
 | 
						|
                                if (iconDecoAfter) {
 | 
						|
                                    builder.add(node.to, node.to, iconDecoAfter);
 | 
						|
                                    iconDecoAfter = null;
 | 
						|
                                    iconDecoAfterWhere = null;
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                });
 | 
						|
            }
 | 
						|
            return builder.finish();
 | 
						|
        }
 | 
						|
    }, {
 | 
						|
        decorations: v => v.decorations
 | 
						|
    });
 | 
						|
    return viewPlugin;
 | 
						|
}
 | 
						|
 | 
						|
class SuperchargedLinks extends obsidian.Plugin {
 | 
						|
    constructor() {
 | 
						|
        super(...arguments);
 | 
						|
        this.modalObservers = [];
 | 
						|
    }
 | 
						|
    onload() {
 | 
						|
        return __awaiter(this, void 0, void 0, function* () {
 | 
						|
            console.log('Supercharged links loaded');
 | 
						|
            yield this.loadSettings();
 | 
						|
            this.addSettingTab(new SuperchargedLinksSettingTab(this.app, this));
 | 
						|
            this.registerMarkdownPostProcessor((el, ctx) => {
 | 
						|
                updateElLinks(this.app, this, el, ctx);
 | 
						|
            });
 | 
						|
            const plugin = this;
 | 
						|
            const updateLinks = function (_file) {
 | 
						|
                updateVisibleLinks(plugin.app, plugin);
 | 
						|
                plugin.observers.forEach(([observer, type, own_class]) => {
 | 
						|
                    const leaves = plugin.app.workspace.getLeavesOfType(type);
 | 
						|
                    leaves.forEach(leaf => {
 | 
						|
                        plugin.updateContainer(leaf.view.containerEl, plugin, own_class);
 | 
						|
                    });
 | 
						|
                });
 | 
						|
            };
 | 
						|
            // Live preview
 | 
						|
            const ext = state.Prec.lowest(buildCMViewPlugin(this.app, this.settings));
 | 
						|
            this.registerEditorExtension(ext);
 | 
						|
            this.observers = [];
 | 
						|
            this.app.workspace.onLayoutReady(() => {
 | 
						|
                this.initViewObservers(this);
 | 
						|
                this.initModalObservers(this, document);
 | 
						|
                updateVisibleLinks(this.app, this);
 | 
						|
            });
 | 
						|
            // Initialization
 | 
						|
            this.registerEvent(this.app.workspace.on("window-open", (window, win) => this.initModalObservers(this, window.getContainer().doc)));
 | 
						|
            // Update when
 | 
						|
            // Debounced to prevent lag when writing
 | 
						|
            this.registerEvent(this.app.metadataCache.on('changed', obsidian.debounce(updateLinks, 500, true)));
 | 
						|
            // Update when layout changes
 | 
						|
            // @ts-ignore
 | 
						|
            this.registerEvent(this.app.workspace.on("layout-change", obsidian.debounce(updateLinks, 10, true)));
 | 
						|
            // Update plugin views when layout changes
 | 
						|
            // TODO: This is an expensive operation that seems like it is called fairly frequently. Maybe we can do this more efficiently?
 | 
						|
            this.registerEvent(this.app.workspace.on("layout-change", () => this.initViewObservers(this)));
 | 
						|
            // DEBUG: When adding a new view, to get the proper id of that view, uncomment this and reload the plugin
 | 
						|
            // this.app.workspace.iterateAllLeaves(leaf => {
 | 
						|
            // 	console.log(leaf.view.getViewType());
 | 
						|
            // });
 | 
						|
        });
 | 
						|
    }
 | 
						|
    initViewObservers(plugin) {
 | 
						|
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
 | 
						|
        // Reset observers
 | 
						|
        plugin.observers.forEach(([observer, type]) => {
 | 
						|
            observer.disconnect();
 | 
						|
        });
 | 
						|
        plugin.observers = [];
 | 
						|
        // Register new observers for particular file panes
 | 
						|
        plugin.registerViewType('backlink', plugin, ".tree-item-inner", true);
 | 
						|
        plugin.registerViewType('outgoing-link', plugin, ".tree-item-inner", true);
 | 
						|
        plugin.registerViewType('search', plugin, ".tree-item-inner");
 | 
						|
        if ((_c = (_b = (_a = plugin.app) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.plugins) === null || _c === void 0 ? void 0 : _c.breadcrumbs) {
 | 
						|
            // console.log('Supercharged links: Enabling breadcrumbs support');
 | 
						|
            plugin.registerViewType('bc-matrix-view', plugin, 'span.internal-link');
 | 
						|
            plugin.registerViewType('BC-ducks', plugin, '.internal-link');
 | 
						|
            plugin.registerViewType('bc-tree-view', plugin, 'span.internal-link');
 | 
						|
            // Breadcrumbs codeblock support as suggested by https://github.com/mdelobelle/obsidian_supercharged_links/issues/248#issuecomment-3231706063
 | 
						|
            plugin.registerViewType('markdown', plugin, '.BC-page-views span.internal-link, .BC-codeblock-tree span.internal-link, .nodes a.internal-link');
 | 
						|
        }
 | 
						|
        plugin.registerViewType('graph-analysis', plugin, '.internal-link');
 | 
						|
        plugin.registerViewType('starred', plugin, '.nav-file-title-content');
 | 
						|
        plugin.registerViewType('file-explorer', plugin, '.nav-file-title-content');
 | 
						|
        if ((_f = (_e = (_d = plugin.app) === null || _d === void 0 ? void 0 : _d.plugins) === null || _e === void 0 ? void 0 : _e.plugins) === null || _f === void 0 ? void 0 : _f['folder-notes']) {
 | 
						|
            // console.log('Supercharged links: Enabling folder notes support');
 | 
						|
            plugin.registerViewType('file-explorer', plugin, '.has-folder-note .tree-item-inner');
 | 
						|
        }
 | 
						|
        plugin.registerViewType('recent-files', plugin, '.nav-file-title-content');
 | 
						|
        plugin.registerViewType('bookmarks', plugin, '.tree-item-inner', false, true);
 | 
						|
        // @ts-ignore
 | 
						|
        if (((_k = (_j = (_h = (_g = plugin.app) === null || _g === void 0 ? void 0 : _g.internalPlugins) === null || _h === void 0 ? void 0 : _h.plugins) === null || _j === void 0 ? void 0 : _j.bases) === null || _k === void 0 ? void 0 : _k.enabled) && plugin.settings.enableBases) {
 | 
						|
            // console.log('Supercharged links: Enabling bases support');
 | 
						|
            plugin.registerViewType('bases', plugin, '.internal-link');
 | 
						|
            // For embedded bases
 | 
						|
            plugin.registerViewType('markdown', plugin, 'div.bases-table-cell  .internal-link');
 | 
						|
        }
 | 
						|
        if ((_o = (_m = (_l = plugin.app) === null || _l === void 0 ? void 0 : _l.plugins) === null || _m === void 0 ? void 0 : _m.plugins) === null || _o === void 0 ? void 0 : _o['similar-notes']) {
 | 
						|
            plugin.registerViewType('markdown', plugin, '.similar-notes-pane .tree-item-inner', true);
 | 
						|
        }
 | 
						|
        // If backlinks in editor is on
 | 
						|
        // @ts-ignore
 | 
						|
        if (((_s = (_r = (_q = (_p = plugin.app) === null || _p === void 0 ? void 0 : _p.internalPlugins) === null || _q === void 0 ? void 0 : _q.plugins) === null || _r === void 0 ? void 0 : _r.backlink) === null || _s === void 0 ? void 0 : _s.enabled) && ((_y = (_x = (_w = (_v = (_u = (_t = plugin.app) === null || _t === void 0 ? void 0 : _t.internalPlugins) === null || _u === void 0 ? void 0 : _u.plugins) === null || _v === void 0 ? void 0 : _v.backlink) === null || _w === void 0 ? void 0 : _w.instance) === null || _x === void 0 ? void 0 : _x.options) === null || _y === void 0 ? void 0 : _y.backlinkInDocument)) {
 | 
						|
            // console.log("Supercharged links: Enabling backlinks in document support");
 | 
						|
            plugin.registerViewType('markdown', plugin, '.embedded-backlinks .tree-item-inner', true);
 | 
						|
        }
 | 
						|
        const propertyLeaves = this.app.workspace.getLeavesOfType("file-properties");
 | 
						|
        for (let i = 0; i < propertyLeaves.length; i++) {
 | 
						|
            const container = propertyLeaves[i].view.containerEl;
 | 
						|
            let observer = new MutationObserver((records, _) => {
 | 
						|
                const file = this.app.workspace.getActiveFile();
 | 
						|
                if (!!file) {
 | 
						|
                    updatePropertiesPane(container, this.app.workspace.getActiveFile(), this.app, plugin);
 | 
						|
                }
 | 
						|
            });
 | 
						|
            observer.observe(container, { subtree: true, childList: true, attributes: false });
 | 
						|
            plugin.observers.push([observer, "file-properties" + i, ""]);
 | 
						|
            // TODO: No proper unloading!
 | 
						|
        }
 | 
						|
        plugin.registerViewType('file-properties', plugin, 'div.internal-link > .multi-select-pill-content');
 | 
						|
    }
 | 
						|
    initModalObservers(plugin, doc) {
 | 
						|
        const config = {
 | 
						|
            subtree: false,
 | 
						|
            childList: true,
 | 
						|
            attributes: false
 | 
						|
        };
 | 
						|
        this.modalObservers.push(new MutationObserver(records => {
 | 
						|
            records.forEach((mutation) => {
 | 
						|
                if (mutation.type === 'childList') {
 | 
						|
                    mutation.addedNodes.forEach(n => {
 | 
						|
                        if ('className' in n &&
 | 
						|
                            // @ts-ignore
 | 
						|
                            (n.className.includes('modal-container') && plugin.settings.enableQuickSwitcher
 | 
						|
                                // @ts-ignore
 | 
						|
                                || n.className.includes('suggestion-container') && plugin.settings.enableSuggestor)) {
 | 
						|
                            let selector = ".suggestion-title, .suggestion-note, .another-quick-switcher__item__title, .omnisearch-result__title > span";
 | 
						|
                            // @ts-ignore
 | 
						|
                            if (n.className.includes('suggestion-container')) {
 | 
						|
                                selector = ".suggestion-title, .suggestion-note";
 | 
						|
                            }
 | 
						|
                            plugin.updateContainer(n, plugin, selector);
 | 
						|
                            plugin._watchContainer(null, n, plugin, selector);
 | 
						|
                        }
 | 
						|
                    });
 | 
						|
                }
 | 
						|
            });
 | 
						|
        }));
 | 
						|
        this.modalObservers.last().observe(doc.body, config);
 | 
						|
    }
 | 
						|
    registerViewType(viewTypeName, plugin, selector, updateDynamic = false, filter_collapsible = false) {
 | 
						|
        const leaves = this.app.workspace.getLeavesOfType(viewTypeName);
 | 
						|
        // if (leaves.length > 1) {
 | 
						|
        for (let i = 0; i < leaves.length; i++) {
 | 
						|
            const container = leaves[i].view.containerEl;
 | 
						|
            if (updateDynamic) {
 | 
						|
                plugin._watchContainerDynamic(viewTypeName + i, container, plugin, selector);
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                plugin._watchContainer(viewTypeName + i, container, plugin, selector, filter_collapsible);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        // }
 | 
						|
        // else if (leaves.length < 1) return;
 | 
						|
        // else {
 | 
						|
        // 	const container = leaves[0].view.containerEl;
 | 
						|
        // 	this.updateContainer(container, plugin, selector);
 | 
						|
        // 	if (updateDynamic) {
 | 
						|
        // 		plugin._watchContainerDynamic(viewTypeName, container, plugin, selector)
 | 
						|
        // 	}
 | 
						|
        // 	else {
 | 
						|
        // 		plugin._watchContainer(viewTypeName, container, plugin, selector);
 | 
						|
        // 	}
 | 
						|
        // }
 | 
						|
    }
 | 
						|
    updateContainer(container, plugin, selector, filter_collapsible = false) {
 | 
						|
        if (!plugin.settings.enableBacklinks && container.getAttribute("data-type") !== "file-explorer")
 | 
						|
            return;
 | 
						|
        if (!plugin.settings.enableFileList && container.getAttribute("data-type") === "file-explorer")
 | 
						|
            return;
 | 
						|
        const nodes = container.findAll(selector);
 | 
						|
        for (let i = 0; i < nodes.length; ++i) {
 | 
						|
            const el = nodes[i];
 | 
						|
            updateDivExtraAttributes(plugin.app, plugin.settings, el, "", undefined, filter_collapsible);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    removeFromContainer(container, selector) {
 | 
						|
        const nodes = container.findAll(selector);
 | 
						|
        for (let i = 0; i < nodes.length; ++i) {
 | 
						|
            const el = nodes[i];
 | 
						|
            clearExtraAttributes(el);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    _watchContainer(viewType, container, plugin, selector, filter_collapsible = false) {
 | 
						|
        let observer = new MutationObserver((records, _) => {
 | 
						|
            plugin.updateContainer(container, plugin, selector, filter_collapsible);
 | 
						|
        });
 | 
						|
        observer.observe(container, { subtree: true, childList: true, attributes: false });
 | 
						|
        if (viewType) {
 | 
						|
            plugin.observers.push([observer, viewType, selector]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    _watchContainerDynamic(viewType, container, plugin, selector, parent_class = 'tree-item') {
 | 
						|
        // Used for efficient updating of the backlinks panel
 | 
						|
        // Only loops through newly added DOM nodes instead of changing all of them
 | 
						|
        if (!plugin.settings.enableBacklinks)
 | 
						|
            return;
 | 
						|
        let observer = new MutationObserver((records, _) => {
 | 
						|
            records.forEach((mutation) => {
 | 
						|
                if (mutation.type === 'childList') {
 | 
						|
                    mutation.addedNodes.forEach((n) => {
 | 
						|
                        if ('className' in n) {
 | 
						|
                            // @ts-ignore
 | 
						|
                            if (n.className.includes && typeof n.className.includes === 'function' && n.className.includes(parent_class)) {
 | 
						|
                                const fileDivs = n.findAll(selector);
 | 
						|
                                for (let i = 0; i < fileDivs.length; ++i) {
 | 
						|
                                    const link = fileDivs[i];
 | 
						|
                                    updateDivExtraAttributes(plugin.app, plugin.settings, link, "");
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    });
 | 
						|
                }
 | 
						|
            });
 | 
						|
        });
 | 
						|
        observer.observe(container, { subtree: true, childList: true, attributes: false });
 | 
						|
        plugin.observers.push([observer, viewType, selector]);
 | 
						|
    }
 | 
						|
    onunload() {
 | 
						|
        this.observers.forEach(([observer, type, own_class]) => {
 | 
						|
            observer.disconnect();
 | 
						|
            const leaves = this.app.workspace.getLeavesOfType(type);
 | 
						|
            leaves.forEach(leaf => {
 | 
						|
                this.removeFromContainer(leaf.view.containerEl, own_class);
 | 
						|
            });
 | 
						|
        });
 | 
						|
        for (const observer of this.modalObservers) {
 | 
						|
            observer.disconnect();
 | 
						|
        }
 | 
						|
        console.log('Supercharged links unloaded');
 | 
						|
    }
 | 
						|
    loadSettings() {
 | 
						|
        return __awaiter(this, void 0, void 0, function* () {
 | 
						|
            this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
 | 
						|
        });
 | 
						|
    }
 | 
						|
    saveSettings() {
 | 
						|
        return __awaiter(this, void 0, void 0, function* () {
 | 
						|
            yield this.saveData(this.settings);
 | 
						|
        });
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
module.exports = SuperchargedLinks;
 | 
						|
 | 
						|
 | 
						|
/* nosourcemap */ |