/* 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 crypto = require('crypto'); /****************************************************************************** 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 DEFAULT_SETTINGS = { regex: /^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$/i, lineRegex: /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi, linkRegex: /^\[([^\[\]]*)\]\((https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})\)$/i, linkLineRegex: /\[([^\[\]]*)\]\((https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})\)/gi, imageRegex: /\.(gif|jpe?g|tiff?|png|webp|bmp|tga|psd|ai)$/i, shouldReplaceSelection: true, enhanceDefaultPaste: true, websiteBlacklist: "", maximumTitleLength: 0, }; class AutoLinkTitleSettingTab extends obsidian.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; } display() { let { containerEl } = this; containerEl.empty(); new obsidian.Setting(containerEl) .setName("Enhance Default Paste") .setDesc("Fetch the link title when pasting a link in the editor with the default paste command") .addToggle((val) => val .setValue(this.plugin.settings.enhanceDefaultPaste) .onChange((value) => __awaiter(this, void 0, void 0, function* () { console.log(value); this.plugin.settings.enhanceDefaultPaste = value; yield this.plugin.saveSettings(); }))); new obsidian.Setting(containerEl) .setName("Maximum title length") .setDesc("Set the maximum length of the title. Set to 0 to disable.") .addText((val) => val .setValue(this.plugin.settings.maximumTitleLength.toString(10)) .onChange((value) => __awaiter(this, void 0, void 0, function* () { const titleLength = (Number(value)); this.plugin.settings.maximumTitleLength = isNaN(titleLength) || titleLength < 0 ? 0 : titleLength; yield this.plugin.saveSettings(); }))); new obsidian.Setting(containerEl) .setName("Replace Selection") .setDesc("Whether to replace a text selection with link and fetched title") .addToggle((val) => val .setValue(this.plugin.settings.shouldReplaceSelection) .onChange((value) => __awaiter(this, void 0, void 0, function* () { console.log(value); this.plugin.settings.shouldReplaceSelection = value; yield this.plugin.saveSettings(); }))); new obsidian.Setting(containerEl) .setName("Website Blacklist") .setDesc("List of strings (comma separated) that disable autocompleting website titles. Can be URLs or arbitrary text.") .addTextArea((val) => val .setValue(this.plugin.settings.websiteBlacklist) .setPlaceholder("localhost, tiktok.com") .onChange((value) => __awaiter(this, void 0, void 0, function* () { this.plugin.settings.websiteBlacklist = value; yield this.plugin.saveSettings(); }))); } } class CheckIf { static isMarkdownLinkAlready(editor) { let cursor = editor.getCursor(); // Check if the characters before the url are ]( to indicate a markdown link var titleEnd = editor.getRange({ ch: cursor.ch - 2, line: cursor.line }, { ch: cursor.ch, line: cursor.line }); return titleEnd == "]("; } static isAfterQuote(editor) { let cursor = editor.getCursor(); // Check if the characters before the url are " or ' to indicate we want the url directly // This is common in elements like var beforeChar = editor.getRange({ ch: cursor.ch - 1, line: cursor.line }, { ch: cursor.ch, line: cursor.line }); return beforeChar == "\"" || beforeChar == "'"; } static isUrl(text) { let urlRegex = new RegExp(DEFAULT_SETTINGS.regex); return urlRegex.test(text); } static isImage(text) { let imageRegex = new RegExp(DEFAULT_SETTINGS.imageRegex); return imageRegex.test(text); } static isLinkedUrl(text) { let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex); return urlRegex.test(text); } } class EditorExtensions { static getSelectedText(editor) { if (!editor.somethingSelected()) { let wordBoundaries = this.getWordBoundaries(editor); editor.setSelection(wordBoundaries.start, wordBoundaries.end); } return editor.getSelection(); } static cursorWithinBoundaries(cursor, match) { let startIndex = match.index; let endIndex = match.index + match[0].length; return startIndex <= cursor.ch && cursor.ch <= endIndex; } static getWordBoundaries(editor) { let cursor = editor.getCursor(); // If its a normal URL token this is not a markdown link // In this case we can simply overwrite the link boundaries as-is let lineText = editor.getLine(cursor.line); // First check if we're in a link let linksInLine = lineText.matchAll(DEFAULT_SETTINGS.linkLineRegex); for (let match of linksInLine) { if (this.cursorWithinBoundaries(cursor, match)) { return { start: { line: cursor.line, ch: match.index }, end: { line: cursor.line, ch: match.index + match[0].length }, }; } } // If not, check if we're in just a standard ol' URL. let urlsInLine = lineText.matchAll(DEFAULT_SETTINGS.lineRegex); for (let match of urlsInLine) { if (this.cursorWithinBoundaries(cursor, match)) { return { start: { line: cursor.line, ch: match.index }, end: { line: cursor.line, ch: match.index + match[0].length }, }; } } return { start: cursor, end: cursor, }; } static getEditorPositionFromIndex(content, index) { let substr = content.substr(0, index); let l = 0; let offset = -1; let r = -1; for (; (r = substr.indexOf("\n", r + 1)) !== -1; l++, offset = r) ; offset += 1; let ch = content.substr(offset, index - offset).length; return { line: l, ch: ch }; } } function blank(text) { return text === undefined || text === null || text === ''; } function notBlank(text) { return !blank(text); } function scrape(url) { return __awaiter(this, void 0, void 0, function* () { try { const response = yield obsidian.requestUrl(url); if (!response.headers['content-type'].includes('text/html')) return getUrlFinalSegment(url); const html = response.text; const doc = new DOMParser().parseFromString(html, 'text/html'); const title = doc.querySelector('title'); if (blank(title === null || title === void 0 ? void 0 : title.innerText)) { // If site is javascript based and has a no-title attribute when unloaded, use it. var noTitle = title === null || title === void 0 ? void 0 : title.getAttr('no-title'); if (notBlank(noTitle)) { return noTitle; } // Otherwise if the site has no title/requires javascript simply return Title Unknown return url; } return title.innerText; } catch (ex) { console.error(ex); return 'Site Unreachable'; } }); } function getUrlFinalSegment(url) { try { const segments = new URL(url).pathname.split('/'); const last = segments.pop() || segments.pop(); // Handle potential trailing slash return last; } catch (_) { return 'File'; } } function getPageTitle(url) { return __awaiter(this, void 0, void 0, function* () { if (!(url.startsWith('http') || url.startsWith('https'))) { url = 'https://' + url; } return scrape(url); }); } class AutoLinkTitle extends obsidian.Plugin { constructor() { super(...arguments); this.shortTitle = (title) => { if (this.settings.maximumTitleLength === 0) { return title; } if (title.length < this.settings.maximumTitleLength + 3) { return title; } const shortenedTitle = `${title.slice(0, this.settings.maximumTitleLength)}...`; return shortenedTitle; }; } onload() { return __awaiter(this, void 0, void 0, function* () { console.log("loading obsidian-auto-link-title"); yield this.loadSettings(); this.blacklist = this.settings.websiteBlacklist.split(",").map(s => s.trim()).filter(s => s.length > 0); // Listen to paste event this.pasteFunction = this.pasteUrlWithTitle.bind(this); this.addCommand({ id: "auto-link-title-paste", name: "Paste URL and auto fetch title", editorCallback: (editor) => this.manualPasteUrlWithTitle(editor), hotkeys: [], }); this.addCommand({ id: "auto-link-title-normal-paste", name: "Normal paste (no fetching behavior)", editorCallback: (editor) => this.normalPaste(editor), hotkeys: [ { modifiers: ["Mod", "Shift"], key: "v", }, ], }); this.registerEvent(this.app.workspace.on("editor-paste", this.pasteFunction)); this.addCommand({ id: "enhance-url-with-title", name: "Enhance existing URL with link and title", editorCallback: (editor) => this.addTitleToLink(editor), hotkeys: [ { modifiers: ["Mod", "Shift"], key: "e", }, ], }); this.addSettingTab(new AutoLinkTitleSettingTab(this.app, this)); }); } addTitleToLink(editor) { // Only attempt fetch if online if (!navigator.onLine) return; let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim(); // If the cursor is on a raw html link, convert to a markdown link and fetch title if (CheckIf.isUrl(selectedText)) { this.convertUrlToTitledLink(editor, selectedText); } // If the cursor is on the URL part of a markdown link, fetch title and replace existing link title else if (CheckIf.isLinkedUrl(selectedText)) { const link = this.getUrlFromLink(selectedText); this.convertUrlToTitledLink(editor, link); } } normalPaste(editor) { return __awaiter(this, void 0, void 0, function* () { let clipboardText = yield navigator.clipboard.readText(); if (clipboardText === null || clipboardText === "") return; editor.replaceSelection(clipboardText); }); } // Simulate standard paste but using editor.replaceSelection with clipboard text since we can't seem to dispatch a paste event. manualPasteUrlWithTitle(editor) { return __awaiter(this, void 0, void 0, function* () { const clipboardText = yield navigator.clipboard.readText(); // Only attempt fetch if online if (!navigator.onLine) { editor.replaceSelection(clipboardText); return; } if (clipboardText == null || clipboardText == '') return; // If its not a URL, we return false to allow the default paste handler to take care of it. // Similarly, image urls don't have a meaningful attribute so downloading it // to fetch the title is a waste of bandwidth. if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) { editor.replaceSelection(clipboardText); return; } let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim(); if (selectedText && !this.settings.shouldReplaceSelection) { // If there is selected text and shouldReplaceSelection is false, do not fetch title editor.replaceSelection(clipboardText); return; } // If it looks like we're pasting the url into a markdown link already, don't fetch title // as the user has already probably put a meaningful title, also it would lead to the title // being inside the link. if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) { editor.replaceSelection(clipboardText); return; } // At this point we're just pasting a link in a normal fashion, fetch its title. this.convertUrlToTitledLink(editor, clipboardText); return; }); } pasteUrlWithTitle(clipboard, editor) { return __awaiter(this, void 0, void 0, function* () { if (!this.settings.enhanceDefaultPaste) { return; } // Only attempt fetch if online if (!navigator.onLine) return; let clipboardText = clipboard.clipboardData.getData("text/plain"); if (clipboardText === null || clipboardText === "") return; // If its not a URL, we return false to allow the default paste handler to take care of it. // Similarly, image urls don't have a meaningful <title> attribute so downloading it // to fetch the title is a waste of bandwidth. if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) { return; } let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim(); if (selectedText && !this.settings.shouldReplaceSelection) { // If there is selected text and shouldReplaceSelection is false, do not fetch title return; } // We've decided to handle the paste, stop propagation to the default handler. clipboard.stopPropagation(); clipboard.preventDefault(); // If it looks like we're pasting the url into a markdown link already, don't fetch title // as the user has already probably put a meaningful title, also it would lead to the title // being inside the link. if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) { editor.replaceSelection(clipboardText); return; } // At this point we're just pasting a link in a normal fashion, fetch its title. this.convertUrlToTitledLink(editor, clipboardText); return; }); } isBlacklisted(url) { return __awaiter(this, void 0, void 0, function* () { yield this.loadSettings(); this.blacklist = this.settings.websiteBlacklist.split(/,|\n/).map(s => s.trim()).filter(s => s.length > 0); return this.blacklist.some(site => url.contains(site)); }); } convertUrlToTitledLink(editor, url) { return __awaiter(this, void 0, void 0, function* () { if (yield this.isBlacklisted(url)) { let domain = new URL(url).hostname; editor.replaceSelection(`[${domain}](${url})`); return; } // Generate a unique id for find/replace operations for the title. const pasteId = `Fetching Title#${this.createBlockHash()}`; // Instantly paste so you don't wonder if paste is broken editor.replaceSelection(`[${pasteId}](${url})`); // Fetch title from site, replace Fetching Title with actual title const title = yield this.fetchUrlTitle(url); const escapedTitle = this.escapeMarkdown(title); const shortenedTitle = this.shortTitle(escapedTitle); const text = editor.getValue(); const start = text.indexOf(pasteId); if (start < 0) { console.log(`Unable to find text "${pasteId}" in current editor, bailing out; link ${url}`); } else { const end = start + pasteId.length; const startPos = EditorExtensions.getEditorPositionFromIndex(text, start); const endPos = EditorExtensions.getEditorPositionFromIndex(text, end); editor.replaceRange(shortenedTitle, startPos, endPos); } }); } escapeMarkdown(text) { var unescaped = text.replace(/\\(\*|_|`|~|\\|\[|\])/g, '$1'); // unescape any "backslashed" character var escaped = unescaped.replace(/(\*|_|`|<|>|~|\\|\[|\])/g, '\\$1'); // escape *, _, `, ~, \, [, ], <, and > return escaped; } fetchUrlTitle(url) { return __awaiter(this, void 0, void 0, function* () { try { const title = yield getPageTitle(url); return title.replace(/(\r\n|\n|\r)/gm, "").trim(); } catch (error) { console.error(error); return 'Error fetching title'; } }); } getUrlFromLink(link) { let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex); return urlRegex.exec(link)[2]; } createBlockHash() { return crypto.randomBytes(6).toString('hex'); } onunload() { console.log("unloading obsidian-auto-link-title"); } 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 = AutoLinkTitle; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNldHRpbmdzLnRzIiwiY2hlY2tpZi50cyIsImVkaXRvci1lbmhhbmNlbWVudHMudHMiLCJzY3JhcGVyLnRzIiwibWFpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6bnVsbCwibmFtZXMiOlsiUGx1Z2luU2V0dGluZ1RhYiIsIlNldHRpbmciLCJyZXF1ZXN0VXJsIiwiUGx1Z2luIiwicmFuZG9tQnl0ZXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBb0dBO0FBQ08sU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFO0FBQzdELElBQUksU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxLQUFLLFlBQVksQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2hILElBQUksT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsVUFBVSxPQUFPLEVBQUUsTUFBTSxFQUFFO0FBQy9ELFFBQVEsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUNuRyxRQUFRLFNBQVMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUss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