aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/lib/scripts
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2024-10-15 14:19:01 +0200
committerAndreas Gohr <andi@splitbrain.org>2024-10-15 14:19:01 +0200
commit9085b15ba88b1e1dc68974a8c494e04e74928754 (patch)
tree20b2d1b56fdd2f404e795d021b3726004dc717bc /lib/scripts
parentd3d20a669a9dfc59495db347cb88a168a1362617 (diff)
downloaddokuwiki-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.js105
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