diff options
author | Andreas Gohr <andi@splitbrain.org> | 2024-10-15 14:19:01 +0200 |
---|---|---|
committer | Andreas Gohr <andi@splitbrain.org> | 2024-10-15 14:19:01 +0200 |
commit | 9085b15ba88b1e1dc68974a8c494e04e74928754 (patch) | |
tree | 20b2d1b56fdd2f404e795d021b3726004dc717bc /lib/scripts | |
parent | d3d20a669a9dfc59495db347cb88a168a1362617 (diff) | |
download | dokuwiki-9085b15ba88b1e1dc68974a8c494e04e74928754.tar.gz dokuwiki-9085b15ba88b1e1dc68974a8c494e04e74928754.zip |
use relative links in LinkWizard
When the linked page has a common prefix with the current page,
construct a relative link instead of always inserting absolute links.
Diffstat (limited to 'lib/scripts')
-rw-r--r-- | lib/scripts/linkwiz.js | 105 |
1 files changed, 63 insertions, 42 deletions
diff --git a/lib/scripts/linkwiz.js b/lib/scripts/linkwiz.js index 3db9c67c6..d34ef3899 100644 --- a/lib/scripts/linkwiz.js +++ b/lib/scripts/linkwiz.js @@ -22,8 +22,11 @@ class LinkWizard { selected = -1; /** @var {Object} selection A DokuWiki selection object holding text positions in the editor */ selection = null; - /** @var {Object} val Mechanism to modify the resulting links. See 935ecb0ef751ac1d658932316e06410e70c483e0 */ - val = null; + /** @var {Object} val The syntax used. See 935ecb0ef751ac1d658932316e06410e70c483e0 */ + val = { + open: '[[', + close: ']]' + }; /** * Initialize the LinkWizard by creating the needed HTML @@ -194,7 +197,7 @@ class LinkWizard { this.autocomplete_exec(); } else { if (jQuery(a.nextSibling).is('span')) { - this.insertLink(a.nextSibling.innerHTML); + this.insertLink(a.nextSibling.innerText); } else { this.insertLink(''); } @@ -206,56 +209,39 @@ class LinkWizard { * replacing the current selection or at the cursor position. * When no selection is available the given title will be used * as link title instead + * + * @param {string} title The heading text to use as link title if configured */ insertLink(title) { - let link = this.$entry.val(), - sel, stxt; + let link = this.$entry.val(); + let selection; + let linkTitle; if (!link) { return; } - sel = DWgetSelection(this.textArea); - if (sel.start === 0 && sel.end === 0) { - sel = this.selection; - } - - stxt = sel.getText(); - - // don't include trailing space in selection - if (stxt.charAt(stxt.length - 1) === ' ') { - sel.end--; - stxt = sel.getText(); + // use the current selection, if not available use the one that was stored when the wizard was opened + selection = DWgetSelection(this.textArea); + if (selection.start === 0 && selection.end === 0) { + selection = this.selection; } - if (!stxt && !DOKU_UHC) { - stxt = title; + // if the selection has any text, use it as the link title + linkTitle = selection.getText(); + if (linkTitle.charAt(linkTitle.length - 1) === ' ') { + // don't include trailing space in selection + selection.end--; + linkTitle = selection.getText(); } - // prepend colon inside namespaces for non namespace pages - if (this.textArea.form.id.value.indexOf(':') !== -1 && - link.indexOf(':') === -1) { - link = ':' + link; + // if there is no selection, and useheading is enabled, use the heading text as the link title + if (!linkTitle && !DOKU_UHC) { + linkTitle = title; } - let so = link.length; - let eo = 0; - if (this.val) { - if (this.val.open) { - so += this.val.open.length; - link = this.val.open + link; - } - link += '|'; - so += 1; - if (stxt) { - link += stxt; - } - if (this.val.close) { - link += this.val.close; - eo = this.val.close.length; - } - } - - pasteText(sel, link, {startofs: so, endofs: eo}); + // paste the link + const syntax = this.createLinkSyntax(link, linkTitle); + pasteText(selection, syntax.link, syntax); this.hide(); // reset the entry to the parent namespace @@ -274,6 +260,41 @@ class LinkWizard { } /** + * Constructs the full syntax and calculates offsets + * + * @param {string} id + * @param {string} title + * @returns {{link: string, startofs: number, endofs: number }} + */ + createLinkSyntax(id, title) { + // construct a relative link, except for external links + let link = id; + if (!id.match(/^(f|ht)tps?:\/\//i)) { + const refId = this.textArea.form.id.value; + link = LinkWizard.createRelativeID(refId, id); + } + + let startofs = link.length; + let endofs = 0; + + if (this.val.open) { + startofs += this.val.open.length; + link = this.val.open + link; + } + link += '|'; + startofs += 1; + if (title) { + link += title; + } + if (this.val.close) { + link += this.val.close; + endofs = this.val.close.length; + } + + return {link, startofs, endofs}; + } + + /** * Start the page/namespace lookup timer * * Calls autocomplete_exec when the timer runs out @@ -354,7 +375,7 @@ class LinkWizard { const sourceNs = ref.split(':'); [/*sourcePage*/] = sourceNs.pop(); const targetNs = id.split(':'); - const targetPage = targetNs.pop() + const targetPage = targetNs.pop(); const relativeID = []; // Find the common prefix length |