Skip to content

Commit 9085b15

Browse files
committed
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.
1 parent d3d20a6 commit 9085b15

File tree

1 file changed

+63
-42
lines changed

1 file changed

+63
-42
lines changed

lib/scripts/linkwiz.js

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ class LinkWizard {
2222
selected = -1;
2323
/** @var {Object} selection A DokuWiki selection object holding text positions in the editor */
2424
selection = null;
25-
/** @var {Object} val Mechanism to modify the resulting links. See 935ecb0ef751ac1d658932316e06410e70c483e0 */
26-
val = null;
25+
/** @var {Object} val The syntax used. See 935ecb0ef751ac1d658932316e06410e70c483e0 */
26+
val = {
27+
open: '[[',
28+
close: ']]'
29+
};
2730

2831
/**
2932
* Initialize the LinkWizard by creating the needed HTML
@@ -194,7 +197,7 @@ class LinkWizard {
194197
this.autocomplete_exec();
195198
} else {
196199
if (jQuery(a.nextSibling).is('span')) {
197-
this.insertLink(a.nextSibling.innerHTML);
200+
this.insertLink(a.nextSibling.innerText);
198201
} else {
199202
this.insertLink('');
200203
}
@@ -206,56 +209,39 @@ class LinkWizard {
206209
* replacing the current selection or at the cursor position.
207210
* When no selection is available the given title will be used
208211
* as link title instead
212+
*
213+
* @param {string} title The heading text to use as link title if configured
209214
*/
210215
insertLink(title) {
211-
let link = this.$entry.val(),
212-
sel, stxt;
216+
let link = this.$entry.val();
217+
let selection;
218+
let linkTitle;
213219
if (!link) {
214220
return;
215221
}
216222

217-
sel = DWgetSelection(this.textArea);
218-
if (sel.start === 0 && sel.end === 0) {
219-
sel = this.selection;
220-
}
221-
222-
stxt = sel.getText();
223-
224-
// don't include trailing space in selection
225-
if (stxt.charAt(stxt.length - 1) === ' ') {
226-
sel.end--;
227-
stxt = sel.getText();
223+
// use the current selection, if not available use the one that was stored when the wizard was opened
224+
selection = DWgetSelection(this.textArea);
225+
if (selection.start === 0 && selection.end === 0) {
226+
selection = this.selection;
228227
}
229228

230-
if (!stxt && !DOKU_UHC) {
231-
stxt = title;
229+
// if the selection has any text, use it as the link title
230+
linkTitle = selection.getText();
231+
if (linkTitle.charAt(linkTitle.length - 1) === ' ') {
232+
// don't include trailing space in selection
233+
selection.end--;
234+
linkTitle = selection.getText();
232235
}
233236

234-
// prepend colon inside namespaces for non namespace pages
235-
if (this.textArea.form.id.value.indexOf(':') !== -1 &&
236-
link.indexOf(':') === -1) {
237-
link = ':' + link;
237+
// if there is no selection, and useheading is enabled, use the heading text as the link title
238+
if (!linkTitle && !DOKU_UHC) {
239+
linkTitle = title;
238240
}
239241

240-
let so = link.length;
241-
let eo = 0;
242-
if (this.val) {
243-
if (this.val.open) {
244-
so += this.val.open.length;
245-
link = this.val.open + link;
246-
}
247-
link += '|';
248-
so += 1;
249-
if (stxt) {
250-
link += stxt;
251-
}
252-
if (this.val.close) {
253-
link += this.val.close;
254-
eo = this.val.close.length;
255-
}
256-
}
257-
258-
pasteText(sel, link, {startofs: so, endofs: eo});
242+
// paste the link
243+
const syntax = this.createLinkSyntax(link, linkTitle);
244+
pasteText(selection, syntax.link, syntax);
259245
this.hide();
260246

261247
// reset the entry to the parent namespace
@@ -273,6 +259,41 @@ class LinkWizard {
273259
this.$entry.val(entry_value);
274260
}
275261

262+
/**
263+
* Constructs the full syntax and calculates offsets
264+
*
265+
* @param {string} id
266+
* @param {string} title
267+
* @returns {{link: string, startofs: number, endofs: number }}
268+
*/
269+
createLinkSyntax(id, title) {
270+
// construct a relative link, except for external links
271+
let link = id;
272+
if (!id.match(/^(f|ht)tps?:\/\//i)) {
273+
const refId = this.textArea.form.id.value;
274+
link = LinkWizard.createRelativeID(refId, id);
275+
}
276+
277+
let startofs = link.length;
278+
let endofs = 0;
279+
280+
if (this.val.open) {
281+
startofs += this.val.open.length;
282+
link = this.val.open + link;
283+
}
284+
link += '|';
285+
startofs += 1;
286+
if (title) {
287+
link += title;
288+
}
289+
if (this.val.close) {
290+
link += this.val.close;
291+
endofs = this.val.close.length;
292+
}
293+
294+
return {link, startofs, endofs};
295+
}
296+
276297
/**
277298
* Start the page/namespace lookup timer
278299
*
@@ -354,7 +375,7 @@ class LinkWizard {
354375
const sourceNs = ref.split(':');
355376
[/*sourcePage*/] = sourceNs.pop();
356377
const targetNs = id.split(':');
357-
const targetPage = targetNs.pop()
378+
const targetPage = targetNs.pop();
358379
const relativeID = [];
359380

360381
// Find the common prefix length

0 commit comments

Comments
 (0)