Skip to content

Commit

Permalink
fix: tabs not being selected with fragments that contain unescaped ht…
Browse files Browse the repository at this point in the history
…ml special chars (#214)

* add special char escaping, move url hash parsing to util file

* formatting

* change function to directly select the element

* add null check

* formatting
  • Loading branch information
nobbyfix authored Jan 27, 2025
1 parent 2430ad0 commit 3cc5948
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
32 changes: 32 additions & 0 deletions modules/ext.tabberNeue/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,38 @@ class Util {
element.setAttribute( key, attributes[ key ] );
}
}

/**
* Selects the element of the tab header matching the fragment identifier.
*
* @param {String} urlHash - URL fragment identifier (URL hash with '#' already removed).
* @return {Element} The element of the matching tab header.
*/
static selectElementFromUrlHash( urlHash ) {
if ( !urlHash ) {
return;
}
const decodedHash = mw.util.percentDecodeFragment( urlHash );
const escapedHash = mw.util.escapeIdForAttribute( decodedHash );
const idFromUrlHash = escapedHash.replace( 'tabber-tabpanel-', 'tabber-tab-' );
let activeTabFromUrlHash = document.getElementById( idFromUrlHash );

if ( !activeTabFromUrlHash ) {
// Retry getting the tab after escaping html special chars to correctly select
// the tab for cases where the fragment does not use the escaped version
const specialCharEscapedHash = mw.html.escape( idFromUrlHash );
activeTabFromUrlHash = document.getElementById( specialCharEscapedHash );

if ( !activeTabFromUrlHash ) {
return;
}
}

// Ensures that only tabber elements are selected
if ( activeTabFromUrlHash.classList.contains( 'tabber__tab' ) ) {
return activeTabFromUrlHash;
}
}
}

module.exports = Util;
13 changes: 2 additions & 11 deletions modules/ext.tabberNeue/ext.tabberNeue.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,13 +426,7 @@ class TabberBuilder {
if ( !urlHash ) {
return activeTab;
}
const decodedHash = mw.util.percentDecodeFragment( urlHash );
const escapedHash = mw.util.escapeIdForAttribute( decodedHash );
const idFromUrlHash = escapedHash.replace( 'tabber-tabpanel-', 'tabber-tab-' );
if ( idFromUrlHash === escapedHash ) {
return activeTab;
}
const activeTabFromUrlHash = document.getElementById( idFromUrlHash );
const activeTabFromUrlHash = Util.selectElementFromUrlHash( urlHash );
if ( !activeTabFromUrlHash ) {
return activeTab;
}
Expand Down Expand Up @@ -488,10 +482,7 @@ async function load( tabberEls ) {
TabberAction.toggleAnimation( true );
window.addEventListener( 'hashchange', ( event ) => {
const hash = window.location.hash.slice( 1 );
const decodedHash = mw.util.percentDecodeFragment( hash );
const escapedHash = mw.util.escapeIdForAttribute( decodedHash );
const idFromUrlHash = escapedHash.replace( 'tabber-tabpanel-', 'tabber-tab-' );
const tab = document.getElementById( idFromUrlHash );
const tab = Util.selectElementFromUrlHash( hash );
if ( tab ) {
event.preventDefault();
tab.click();
Expand Down

0 comments on commit 3cc5948

Please sign in to comment.