mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-24 23:55:53 +00:00
72 lines
1.9 KiB
JavaScript
72 lines
1.9 KiB
JavaScript
|
/**
|
||
|
* Appends a query param to the `href` attribute of any clicked anchor element
|
||
|
* or anchor element that is the parent of a clicked HTMLElement. Links that
|
||
|
* lead to different origins or have the same pathname and have a hash fragment
|
||
|
* are ignored.
|
||
|
*
|
||
|
* @param {string} key
|
||
|
* @param {string} value
|
||
|
* @return {Function} A cleanup function is returned that
|
||
|
* removes any event listeners that were added.
|
||
|
*/
|
||
|
function linkHijack( key, value ) {
|
||
|
/**
|
||
|
* @param {MouseEvent} e
|
||
|
*/
|
||
|
function handleClick( e ) {
|
||
|
if ( !e.target || !( e.target instanceof HTMLElement ) ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const anchor = e.target.closest( 'a' );
|
||
|
if ( !anchor ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let locationUrl;
|
||
|
let oldUrl;
|
||
|
try {
|
||
|
// eslint-disable-next-line compat/compat
|
||
|
locationUrl = new URL( location.href );
|
||
|
// eslint-disable-next-line compat/compat
|
||
|
oldUrl = new URL( anchor.href );
|
||
|
|
||
|
} catch ( error ) {
|
||
|
// A TypeError may be thrown for invalid URLs. In that case, return
|
||
|
// gracefully.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
locationUrl.origin !== oldUrl.origin ||
|
||
|
( locationUrl.pathname === oldUrl.pathname && oldUrl.hash )
|
||
|
) {
|
||
|
// Return early if link leads to host outside the current one or if the
|
||
|
// url contains a pathname that is the same as the current one and also
|
||
|
// has a hash fragment (e.g. this occurs with links in the TOC and we
|
||
|
// don't want to trigger a refresh of the page by appending a query
|
||
|
// param).
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// eslint-disable-next-line compat/compat
|
||
|
const params = new URLSearchParams( oldUrl.search );
|
||
|
if ( !params.has( key ) ) {
|
||
|
params.append( key, value );
|
||
|
}
|
||
|
|
||
|
// eslint-disable-next-line compat/compat
|
||
|
const newUrl = new URL( `${oldUrl.origin}${oldUrl.pathname}?${params}${oldUrl.hash}` );
|
||
|
anchor.setAttribute( 'href', newUrl.toString() );
|
||
|
|
||
|
}
|
||
|
|
||
|
document.body.addEventListener( 'click', handleClick );
|
||
|
|
||
|
return () => {
|
||
|
document.body.removeEventListener( 'click', handleClick );
|
||
|
};
|
||
|
}
|
||
|
|
||
|
module.exports = linkHijack;
|