@@ -336,6 +336,69 @@ class LinkWizard {
336
336
this . hide ( ) ;
337
337
}
338
338
}
339
+
340
+ /**
341
+ * Create a relative ID from a given reference ID and a full ID to link to
342
+ *
343
+ * Both IDs are expected to be clean, (eg. the result of cleanID()). No relative paths,
344
+ * leading colons or similar things are alowed. As long as pages have a common prefix,
345
+ * a relative link is constructed.
346
+ *
347
+ * This method is static and meant to be reused by other scripts if needed.
348
+ *
349
+ * @todo does currently not create page relative links using ~
350
+ * @param {string } ref The ID of a page the link is used on
351
+ * @param {string } id The ID to link to
352
+ */
353
+ static createRelativeID ( ref , id ) {
354
+ const sourceNs = ref . split ( ':' ) ;
355
+ [ /*sourcePage*/ ] = sourceNs . pop ( ) ;
356
+ const targetNs = id . split ( ':' ) ;
357
+ const targetPage = targetNs . pop ( )
358
+ const relativeID = [ ] ;
359
+
360
+ // Find the common prefix length
361
+ let commonPrefixLength = 0 ;
362
+ while (
363
+ commonPrefixLength < sourceNs . length &&
364
+ commonPrefixLength < targetNs . length &&
365
+ sourceNs [ commonPrefixLength ] === targetNs [ commonPrefixLength ]
366
+ ) {
367
+ commonPrefixLength ++ ;
368
+ }
369
+
370
+
371
+ if ( sourceNs . length ) {
372
+ // special treatment is only needed when the reference is a namespaced page
373
+ if ( commonPrefixLength ) {
374
+ if ( commonPrefixLength === sourceNs . length && commonPrefixLength === targetNs . length ) {
375
+ // both pages are in the same namespace
376
+ // link consists of simple page only
377
+ // namespaces are irrelevant
378
+ } else if ( commonPrefixLength < sourceNs . length ) {
379
+ // add .. for each missing namespace from common to the target
380
+ relativeID . push ( '..' . repeat ( sourceNs . length - commonPrefixLength ) ) ;
381
+ } else {
382
+ // target is below common prefix, add .
383
+ relativeID . push ( '.' ) ;
384
+ }
385
+ } else if ( targetNs . length === 0 ) {
386
+ // target is in the root namespace, but source is not, make it absolute
387
+ relativeID . push ( '' ) ;
388
+ }
389
+ // add any remaining parts of targetNS
390
+ relativeID . push ( ...targetNs . slice ( commonPrefixLength ) ) ;
391
+ } else {
392
+ // source is in the root namespace, just use target as is
393
+ relativeID . push ( ...targetNs ) ;
394
+ }
395
+
396
+ // add targetPage
397
+ relativeID . push ( targetPage ) ;
398
+
399
+ return relativeID . join ( ':' ) ;
400
+ }
401
+
339
402
}
340
403
341
404
const dw_linkwiz = new LinkWizard ( ) ;
0 commit comments