WikiPartner (talk | contribs) No edit summary |
WikiPartner (talk | contribs) No edit summary |
||
| Line 18: | Line 18: | ||
function getSavedTheme() { | function getSavedTheme() { | ||
try { | try { | ||
var saved = window.localStorage.getItem( | var saved = window.localStorage.getItem(STORAGE_KEY); | ||
if ( | if (saved === LIGHT || saved === DARK) { | ||
return saved; | return saved; | ||
} | } | ||
| Line 53: | Line 48: | ||
function getCurrentTheme() { | function getCurrentTheme() { | ||
return document.documentElement | return document.documentElement.classList.contains( | ||
'wp-theme-dark' | |||
) | |||
? DARK | ? DARK | ||
: LIGHT; | : LIGHT; | ||
| Line 67: | Line 61: | ||
function applyTheme(theme, shouldSave) { | function applyTheme(theme, shouldSave) { | ||
var html = | var html = document.documentElement; | ||
var isDark = theme === DARK; | |||
var isDark = | |||
html.classList.toggle( | html.classList.toggle( | ||
| Line 84: | Line 74: | ||
); | ); | ||
html.classList.remove( | html.classList.remove( | ||
'skin-theme-clientpref-day', | 'skin-theme-clientpref-day', | ||
| Line 93: | Line 79: | ||
'skin-theme-clientpref-os' | 'skin-theme-clientpref-os' | ||
); | ); | ||
html.classList.add( | html.classList.add( | ||
| Line 100: | Line 85: | ||
: 'skin-theme-clientpref-day' | : 'skin-theme-clientpref-day' | ||
); | ); | ||
html.setAttribute( | html.setAttribute( | ||
'data-wikipartner-theme', | 'data-wikipartner-theme', | ||
isDark | isDark ? DARK : LIGHT | ||
); | ); | ||
if (shouldSave !== false) { | if (shouldSave !== false) { | ||
saveTheme(theme); | saveTheme(theme); | ||
} | } | ||
updateThemeButton(); | updateThemeButton(); | ||
| Line 126: | Line 106: | ||
return [ | return [ | ||
'<svg viewBox="0 0 24 24" aria-hidden="true">', | '<svg viewBox="0 0 24 24" aria-hidden="true">', | ||
'<path d="M20.3 15.2A8.4 8.4 0 0 1 8.8 3.7 8.5 8.5 0 1 0 11.5 11.5Z"></path>', | '<path d="M20.3 15.2A8.4 8.4 0 0 1 8.8 3.7 8.5 8.5 0 1 0 11.5 11.5Z"></path>', | ||
'<path class="wp-theme-star" d="M17.5 4v3M16 5.5h3"></path>', | '<path class="wp-theme-star" d="M17.5 4v3M16 5.5h3"></path>', | ||
'</svg>' | '</svg>' | ||
].join(''); | ].join(''); | ||
| Line 139: | Line 116: | ||
return [ | return [ | ||
'<svg viewBox="0 0 24 24" aria-hidden="true">', | '<svg viewBox="0 0 24 24" aria-hidden="true">', | ||
'<circle cx="12" cy="12" r="3.8"></circle>', | '<circle cx="12" cy="12" r="3.8"></circle>', | ||
'<path d="M12 2.3v2.1"></path>', | '<path d="M12 2.3v2.1"></path>', | ||
'<path d="M12 19.6v2.1"></path>', | '<path d="M12 19.6v2.1"></path>', | ||
'<path d="M4.93 4.93l1.5 1.5"></path>', | '<path d="M4.93 4.93l1.5 1.5"></path>', | ||
'<path d="M17.57 17.57l1.5 1.5"></path>', | '<path d="M17.57 17.57l1.5 1.5"></path>', | ||
'<path d="M2.3 12h2.1"></path>', | '<path d="M2.3 12h2.1"></path>', | ||
'<path d="M19.6 12h2.1"></path>', | '<path d="M19.6 12h2.1"></path>', | ||
'<path d="M4.93 19.07l1.5-1.5"></path>', | '<path d="M4.93 19.07l1.5-1.5"></path>', | ||
'<path d="M17.57 6.43l1.5-1.5"></path>', | '<path d="M17.57 6.43l1.5-1.5"></path>', | ||
'</svg>' | '</svg>' | ||
].join(''); | ].join(''); | ||
| Line 164: | Line 135: | ||
function updateThemeButton() { | function updateThemeButton() { | ||
var button = | var button = document.getElementById( | ||
'wikipartner-theme-toggle' | |||
); | |||
if (!button) { | if (!button) { | ||
return; | return; | ||
} | } | ||
var isDark = | var isDark = | ||
getCurrentTheme() === DARK; | getCurrentTheme() === DARK; | ||
button.innerHTML = | button.innerHTML = | ||
| Line 187: | Line 154: | ||
) + | ) + | ||
'</span>'; | '</span>'; | ||
button.setAttribute( | button.setAttribute( | ||
| Line 195: | Line 161: | ||
: 'Switch to dark mode' | : 'Switch to dark mode' | ||
); | ); | ||
button.setAttribute( | button.setAttribute( | ||
| Line 211: | Line 176: | ||
function createThemeToggle(list) { | function createThemeToggle(list) { | ||
var existing = | var existing = document.getElementById( | ||
'wikipartner-theme-item' | |||
); | |||
if (existing) { | if (existing) { | ||
| Line 221: | Line 184: | ||
} | } | ||
var item = document.createElement('li'); | |||
var item = | |||
item.id = | item.id = | ||
'wikipartner-theme-item'; | 'wikipartner-theme-item'; | ||
item.className = | item.className = | ||
'mw-list-item | 'mw-list-item wikipartner-theme-item'; | ||
var button = | var button = | ||
document.createElement( | document.createElement('button'); | ||
button.id = | button.id = | ||
'wikipartner-theme-toggle'; | 'wikipartner-theme-toggle'; | ||
button.className = | button.className = | ||
'wikipartner-theme-toggle'; | 'wikipartner-theme-toggle'; | ||
button.type = | button.type = | ||
| Line 256: | Line 209: | ||
'click', | 'click', | ||
function () { | function () { | ||
var nextTheme = | var nextTheme = | ||
getCurrentTheme() === DARK | getCurrentTheme() === DARK | ||
? LIGHT | ? LIGHT | ||
: DARK; | : DARK; | ||
applyTheme( | applyTheme( | ||
| Line 271: | Line 222: | ||
item.appendChild( | item.appendChild(button); | ||
updateThemeButton(); | updateThemeButton(); | ||
return item; | return item; | ||
| Line 299: | Line 246: | ||
/* ======================================================== | /* ======================================================== | ||
CLEAN DUPLICATE USERNAME | |||
======================================================== */ | ======================================================== */ | ||
| Line 306: | Line 253: | ||
list | list | ||
) { | ) { | ||
var username = | var username = mw.config.get( | ||
'wgUserName' | |||
); | |||
if (!username) { | if (!username) { | ||
return; | return; | ||
} | } | ||
var items = | var items = | ||
| Line 330: | Line 265: | ||
list.children | list.children | ||
); | ); | ||
items.forEach( | items.forEach( | ||
function (item) { | function (item) { | ||
var link = | var link = | ||
item.querySelector('a'); | item.querySelector('a'); | ||
var linkText = | var linkText = | ||
| Line 343: | Line 275: | ||
? link.textContent.trim() | ? link.textContent.trim() | ||
: ''; | : ''; | ||
var isUserPageId = | var isUserPageId = | ||
item.id === 'pt-userpage' || | item.id === 'pt-userpage' || | ||
item.id === 'pt-userpage-2'; | item.id === 'pt-userpage-2'; | ||
var isUsername = | var isUsername = | ||
linkText === username; | linkText === username; | ||
if ( | if ( | ||
| Line 358: | Line 287: | ||
isUsername | isUsername | ||
) { | ) { | ||
if ( | if ( | ||
primary && | primary && | ||
!primary.querySelector('li') | !primary.querySelector('li') | ||
) { | ) { | ||
primary.appendChild(item); | |||
primary.appendChild( | |||
} else { | } else { | ||
item.remove(); | item.remove(); | ||
} | } | ||
} | } | ||
| Line 398: | Line 316: | ||
'wp-is-logged-out' | 'wp-is-logged-out' | ||
); | ); | ||
var loginItem = | var loginItem = | ||
| Line 404: | Line 321: | ||
'#pt-login' | '#pt-login' | ||
); | ); | ||
/* | /* | ||
* | * Layout: | ||
* | * | ||
* Create account | Theme | Log in | * Create account | Theme | Log in | ||
| Line 413: | Line 329: | ||
if (loginItem) { | if (loginItem) { | ||
list.insertBefore( | list.insertBefore( | ||
themeItem, | themeItem, | ||
loginItem | loginItem | ||
); | ); | ||
} else { | } else { | ||
list.appendChild( | list.appendChild( | ||
themeItem | themeItem | ||
); | ); | ||
} | } | ||
} | } | ||
| Line 454: | Line 366: | ||
/* | /* | ||
* | * Prevent duplicate dropdown. | ||
*/ | */ | ||
| Line 462: | Line 373: | ||
'.wp-user-dropdown' | '.wp-user-dropdown' | ||
); | ); | ||
if (oldDropdown) { | if (oldDropdown) { | ||
| Line 470: | Line 380: | ||
/* ==================================================== | /* ==================================================== | ||
DROPDOWN WRAPPER | |||
==================================================== */ | ==================================================== */ | ||
var dropdown = | var dropdown = | ||
document.createElement('li'); | document.createElement('li'); | ||
dropdown.className = | dropdown.className = | ||
| Line 486: | Line 395: | ||
var trigger = | var trigger = | ||
document.createElement( | document.createElement('button'); | ||
trigger.type = | trigger.type = | ||
'button'; | 'button'; | ||
trigger.className = | trigger.className = | ||
'wp-user-menu-trigger'; | 'wp-user-menu-trigger'; | ||
trigger.setAttribute( | trigger.setAttribute( | ||
| Line 503: | Line 407: | ||
'Open user menu' | 'Open user menu' | ||
); | ); | ||
trigger.setAttribute( | trigger.setAttribute( | ||
| Line 509: | Line 412: | ||
'User menu' | 'User menu' | ||
); | ); | ||
trigger.setAttribute( | trigger.setAttribute( | ||
| Line 515: | Line 417: | ||
'false' | 'false' | ||
); | ); | ||
trigger.innerHTML = | trigger.innerHTML = | ||
| Line 522: | Line 423: | ||
/* ==================================================== | /* ==================================================== | ||
DROPDOWN | DROPDOWN MENU | ||
==================================================== */ | ==================================================== */ | ||
var menu = | var menu = | ||
document.createElement('ul'); | document.createElement('ul'); | ||
menu.className = | menu.className = | ||
'wp-user-dropdown-menu'; | 'wp-user-dropdown-menu'; | ||
menu.hidden = | menu.hidden = | ||
| Line 538: | Line 437: | ||
/* | /* | ||
* Move | * Move all user controls into the | ||
* | * hamburger except the theme button. | ||
* | * | ||
* Username | * Username already lives separately | ||
* | * inside .wp-user-primary. | ||
*/ | */ | ||
| Line 551: | Line 450: | ||
.forEach( | .forEach( | ||
function (item) { | function (item) { | ||
if ( | if ( | ||
item !== themeItem && | item !== themeItem && | ||
item !== dropdown | item !== dropdown | ||
) { | ) { | ||
menu.appendChild(item); | |||
menu.appendChild( | |||
} | } | ||
} | } | ||
| Line 565: | Line 460: | ||
dropdown.appendChild( | dropdown.appendChild(trigger); | ||
dropdown.appendChild(menu); | |||
dropdown.appendChild( | |||
/* | /* | ||
* | * Final logged-in header layout: | ||
* | * | ||
* Username | Theme | ☰ | * Username | Theme | ☰ | ||
*/ | */ | ||
list.appendChild( | list.appendChild(themeItem); | ||
list.appendChild(dropdown); | |||
list.appendChild( | |||
| Line 602: | Line 482: | ||
'is-open' | 'is-open' | ||
); | ); | ||
menu.hidden = | menu.hidden = | ||
true; | true; | ||
trigger.setAttribute( | trigger.setAttribute( | ||
| Line 619: | Line 497: | ||
'is-open' | 'is-open' | ||
); | ); | ||
menu.hidden = | menu.hidden = | ||
false; | false; | ||
trigger.setAttribute( | trigger.setAttribute( | ||
| Line 633: | Line 509: | ||
/* ==================================================== | /* ==================================================== | ||
CLICK | HAMBURGER CLICK | ||
==================================================== */ | ==================================================== */ | ||
| Line 639: | Line 515: | ||
'click', | 'click', | ||
function (event) { | function (event) { | ||
event.preventDefault(); | event.preventDefault(); | ||
event.stopPropagation(); | event.stopPropagation(); | ||
if ( | if ( | ||
| Line 649: | Line 523: | ||
) | ) | ||
) { | ) { | ||
closeMenu(); | closeMenu(); | ||
} else { | } else { | ||
openMenu(); | openMenu(); | ||
} | } | ||
} | } | ||
| Line 668: | Line 538: | ||
'click', | 'click', | ||
function (event) { | function (event) { | ||
event.stopPropagation(); | event.stopPropagation(); | ||
} | } | ||
); | ); | ||
| Line 682: | Line 550: | ||
'click', | 'click', | ||
function (event) { | function (event) { | ||
if ( | if ( | ||
!dropdown.contains( | !dropdown.contains( | ||
| Line 688: | Line 555: | ||
) | ) | ||
) { | ) { | ||
closeMenu(); | closeMenu(); | ||
} | } | ||
} | } | ||
| Line 703: | Line 568: | ||
'keydown', | 'keydown', | ||
function (event) { | function (event) { | ||
if ( | if ( | ||
event.key === 'Escape' && | event.key === 'Escape' && | ||
| Line 710: | Line 574: | ||
) | ) | ||
) { | ) { | ||
closeMenu(); | closeMenu(); | ||
trigger.focus(); | trigger.focus(); | ||
} | } | ||
| Line 721: | Line 583: | ||
/* ======================================================== | /* ======================================================== | ||
INITIALIZE | INITIALIZE USER AREA | ||
======================================================== */ | ======================================================== */ | ||
| Line 729: | Line 591: | ||
'.wp-user-primary' | '.wp-user-primary' | ||
); | ); | ||
var list = | var list = | ||
| Line 735: | Line 596: | ||
'.wp-user-menu-list' | '.wp-user-menu-list' | ||
); | ); | ||
if (!list) { | if (!list) { | ||
| Line 743: | Line 603: | ||
/* | /* | ||
* | * Hide empty username container | ||
* | * for anonymous users. | ||
*/ | */ | ||
| Line 751: | Line 611: | ||
!primary.querySelector('li') | !primary.querySelector('li') | ||
) { | ) { | ||
primary.classList.add( | primary.classList.add( | ||
'is-empty' | 'is-empty' | ||
| Line 759: | Line 618: | ||
var themeItem = | var themeItem = | ||
createThemeToggle( | createThemeToggle(list); | ||
var username = | var username = | ||
| Line 771: | Line 627: | ||
if (username) { | if (username) { | ||
buildLoggedInLayout( | buildLoggedInLayout( | ||
primary, | primary, | ||
| Line 777: | Line 632: | ||
themeItem | themeItem | ||
); | ); | ||
} else { | } else { | ||
buildLoggedOutLayout( | buildLoggedOutLayout( | ||
list, | list, | ||
| Line 814: | Line 667: | ||
'loading' | 'loading' | ||
) { | ) { | ||
document.addEventListener( | document.addEventListener( | ||
'DOMContentLoaded', | 'DOMContentLoaded', | ||
initialize | initialize | ||
); | ); | ||
} else { | } else { | ||
initialize(); | initialize(); | ||
} | } | ||
})(); | })(); | ||
/* ============================================================ | /* ============================================================ | ||
| Line 835: | Line 685: | ||
(function () { | (function () { | ||
'use strict'; | 'use strict'; | ||
function initializeArticleContents() { | function initializeArticleContents() { | ||
var toc = | |||
document.getElementById( | |||
'wp-toc' | |||
); | |||
var | var article = | ||
document.querySelector( | |||
'.wp-article-body' | |||
); | |||
if (!toc || !article) { | if (!toc || !article) { | ||
| Line 849: | Line 704: | ||
var linksContainer = toc.querySelector( | var linksContainer = | ||
toc.querySelector( | |||
'.wp-toc-links' | |||
); | |||
if (!linksContainer) { | if (!linksContainer) { | ||
| Line 859: | Line 716: | ||
/* ==================================================== | /* ==================================================== | ||
FIND | FIND ARTICLE HEADINGS | ||
==================================================== */ | ==================================================== */ | ||
var headings = Array.prototype.slice.call( | var headings = | ||
Array.prototype.slice.call( | |||
article.querySelectorAll( | |||
'h2, h3, h4, h5, h6' | |||
) | |||
); | |||
headings = headings.filter( | headings = | ||
headings.filter( | |||
function (heading) { | |||
var text = | |||
heading.textContent | |||
.replace(/\[edit\]/gi, '') | |||
.trim(); | |||
return text.length > 0; | |||
} | |||
); | |||
/* ==================================================== | /* ==================================================== | ||
NO HEADINGS | NO HEADINGS = NO CONTENTS BUTTON | ||
==================================================== */ | ==================================================== */ | ||
if (!headings.length) { | if (!headings.length) { | ||
toc.classList.remove( | toc.classList.remove( | ||
'wp-toc-ready' | 'wp-toc-ready' | ||
); | ); | ||
toc.open = false; | toc.open = | ||
false; | |||
return; | return; | ||
| Line 907: | Line 760: | ||
==================================================== */ | ==================================================== */ | ||
linksContainer.innerHTML = ''; | linksContainer.innerHTML = | ||
''; | |||
var oldHeading = | |||
toc.querySelector( | |||
'.wp-toc-heading' | |||
); | |||
if (oldHeading) { | if (oldHeading) { | ||
oldHeading.style.display = 'none'; | oldHeading.style.display = | ||
'none'; | |||
} | } | ||
/* ==================================================== | /* ==================================================== | ||
BUILD | BUILD CONTENTS FROM REAL HEADINGS | ||
==================================================== */ | ==================================================== */ | ||
headings.forEach( | headings.forEach( | ||
function (heading, index) { | function ( | ||
heading, | |||
index | |||
) { | |||
if (!heading.id) { | if (!heading.id) { | ||
heading.id = | heading.id = | ||
'wikipartner-section-' + | 'wikipartner-section-' + | ||
| Line 944: | Line 793: | ||
var level = parseInt( | var level = | ||
parseInt( | |||
heading.tagName.substring(1), | |||
10 | |||
); | |||
| Line 972: | Line 822: | ||
headingText; | headingText; | ||
link.addEventListener( | link.addEventListener( | ||
'click', | 'click', | ||
function () { | function () { | ||
toc.open = | |||
toc.open = false; | false; | ||
} | } | ||
); | ); | ||
| Line 991: | Line 835: | ||
link | link | ||
); | ); | ||
} | } | ||
); | ); | ||
| Line 997: | Line 840: | ||
/* ==================================================== | /* ==================================================== | ||
SHOW CONTENTS BUTTON | |||
==================================================== */ | ==================================================== */ | ||
| Line 1,007: | Line 849: | ||
if (document.readyState === 'loading') { | if ( | ||
document.readyState === | |||
'loading' | |||
) { | |||
document.addEventListener( | document.addEventListener( | ||
'DOMContentLoaded', | 'DOMContentLoaded', | ||
initializeArticleContents | initializeArticleContents | ||
); | ); | ||
} else { | |||
initializeArticleContents(); | |||
} | |||
})(); | |||
/* ============================================================ | |||
WIKIPARTNER | |||
WHAT LINKS HERE — CURRENT PAGE | |||
============================================================ */ | |||
(function () { | |||
'use strict'; | |||
function initializeWhatLinksHere() { | |||
var link = | |||
document.getElementById( | |||
'wp-what-links-here' | |||
); | |||
if (!link) { | |||
return; | |||
} | |||
var pageName = | |||
mw.config.get( | |||
'wgPageName' | |||
); | |||
if (!pageName) { | |||
return; | |||
} | |||
} | /* | ||
* Use MediaWiki's own URL builder | |||
* instead of html-title. | |||
*/ | |||
mw.loader | |||
.using( | |||
'mediawiki.util' | |||
) | |||
.then( | |||
function () { | |||
link.href = | |||
mw.util.getUrl( | |||
'Special:WhatLinksHere/' + | |||
pageName | |||
); | |||
} | |||
); | |||
} | |||
if ( | |||
document.readyState === | |||
'loading' | |||
) { | |||
document.addEventListener( | |||
'DOMContentLoaded', | |||
initializeWhatLinksHere | |||
); | |||
} else { | |||
initializeWhatLinksHere(); | |||
} | } | ||
})(); | })(); | ||
Revision as of 02:14, 20 August 2026
/* ============================================================
WIKIPARTNER
THEME + USER MENU
============================================================ */
(function () {
'use strict';
var STORAGE_KEY = 'wikipartner-theme';
var LIGHT = 'light';
var DARK = 'dark';
/* ========================================================
THEME STORAGE
======================================================== */
function getSavedTheme() {
try {
var saved = window.localStorage.getItem(STORAGE_KEY);
if (saved === LIGHT || saved === DARK) {
return saved;
}
} catch (e) {
/* localStorage unavailable */
}
return LIGHT;
}
function saveTheme(theme) {
try {
window.localStorage.setItem(
STORAGE_KEY,
theme
);
} catch (e) {
/* localStorage unavailable */
}
}
/* ========================================================
CURRENT THEME
======================================================== */
function getCurrentTheme() {
return document.documentElement.classList.contains(
'wp-theme-dark'
)
? DARK
: LIGHT;
}
/* ========================================================
APPLY THEME
======================================================== */
function applyTheme(theme, shouldSave) {
var html = document.documentElement;
var isDark = theme === DARK;
html.classList.toggle(
'wp-theme-dark',
isDark
);
html.classList.toggle(
'wp-theme-light',
!isDark
);
html.classList.remove(
'skin-theme-clientpref-day',
'skin-theme-clientpref-night',
'skin-theme-clientpref-os'
);
html.classList.add(
isDark
? 'skin-theme-clientpref-night'
: 'skin-theme-clientpref-day'
);
html.setAttribute(
'data-wikipartner-theme',
isDark ? DARK : LIGHT
);
if (shouldSave !== false) {
saveTheme(theme);
}
updateThemeButton();
}
/* ========================================================
THEME ICONS
======================================================== */
function getMoonIcon() {
return [
'<svg viewBox="0 0 24 24" aria-hidden="true">',
'<path d="M20.3 15.2A8.4 8.4 0 0 1 8.8 3.7 8.5 8.5 0 1 0 11.5 11.5Z"></path>',
'<path class="wp-theme-star" d="M17.5 4v3M16 5.5h3"></path>',
'</svg>'
].join('');
}
function getSunIcon() {
return [
'<svg viewBox="0 0 24 24" aria-hidden="true">',
'<circle cx="12" cy="12" r="3.8"></circle>',
'<path d="M12 2.3v2.1"></path>',
'<path d="M12 19.6v2.1"></path>',
'<path d="M4.93 4.93l1.5 1.5"></path>',
'<path d="M17.57 17.57l1.5 1.5"></path>',
'<path d="M2.3 12h2.1"></path>',
'<path d="M19.6 12h2.1"></path>',
'<path d="M4.93 19.07l1.5-1.5"></path>',
'<path d="M17.57 6.43l1.5-1.5"></path>',
'</svg>'
].join('');
}
/* ========================================================
UPDATE THEME BUTTON
======================================================== */
function updateThemeButton() {
var button = document.getElementById(
'wikipartner-theme-toggle'
);
if (!button) {
return;
}
var isDark =
getCurrentTheme() === DARK;
button.innerHTML =
'<span class="wp-theme-icon">' +
(
isDark
? getSunIcon()
: getMoonIcon()
) +
'</span>';
button.setAttribute(
'aria-label',
isDark
? 'Switch to light mode'
: 'Switch to dark mode'
);
button.setAttribute(
'title',
isDark
? 'Light mode'
: 'Dark mode'
);
}
/* ========================================================
CREATE THEME BUTTON
======================================================== */
function createThemeToggle(list) {
var existing = document.getElementById(
'wikipartner-theme-item'
);
if (existing) {
return existing;
}
var item = document.createElement('li');
item.id =
'wikipartner-theme-item';
item.className =
'mw-list-item wikipartner-theme-item';
var button =
document.createElement('button');
button.id =
'wikipartner-theme-toggle';
button.className =
'wikipartner-theme-toggle';
button.type =
'button';
button.addEventListener(
'click',
function () {
var nextTheme =
getCurrentTheme() === DARK
? LIGHT
: DARK;
applyTheme(
nextTheme,
true
);
}
);
item.appendChild(button);
updateThemeButton();
return item;
}
/* ========================================================
HAMBURGER ICON
======================================================== */
function getMenuIcon() {
return [
'<span class="wp-menu-bars" aria-hidden="true">',
'<span></span>',
'<span></span>',
'<span></span>',
'</span>'
].join('');
}
/* ========================================================
CLEAN DUPLICATE USERNAME
======================================================== */
function cleanUsernameDuplicates(
primary,
list
) {
var username = mw.config.get(
'wgUserName'
);
if (!username) {
return;
}
var items =
Array.prototype.slice.call(
list.children
);
items.forEach(
function (item) {
var link =
item.querySelector('a');
var linkText =
link
? link.textContent.trim()
: '';
var isUserPageId =
item.id === 'pt-userpage' ||
item.id === 'pt-userpage-2';
var isUsername =
linkText === username;
if (
isUserPageId ||
isUsername
) {
if (
primary &&
!primary.querySelector('li')
) {
primary.appendChild(item);
} else {
item.remove();
}
}
}
);
}
/* ========================================================
LOGGED OUT LAYOUT
======================================================== */
function buildLoggedOutLayout(
list,
themeItem
) {
list.classList.remove(
'wp-is-logged-in'
);
list.classList.add(
'wp-is-logged-out'
);
var loginItem =
list.querySelector(
'#pt-login'
);
/*
* Layout:
*
* Create account | Theme | Log in
*/
if (loginItem) {
list.insertBefore(
themeItem,
loginItem
);
} else {
list.appendChild(
themeItem
);
}
}
/* ========================================================
LOGGED IN LAYOUT
======================================================== */
function buildLoggedInLayout(
primary,
list,
themeItem
) {
list.classList.remove(
'wp-is-logged-out'
);
list.classList.add(
'wp-is-logged-in'
);
cleanUsernameDuplicates(
primary,
list
);
/*
* Prevent duplicate dropdown.
*/
var oldDropdown =
list.querySelector(
'.wp-user-dropdown'
);
if (oldDropdown) {
return;
}
/* ====================================================
DROPDOWN WRAPPER
==================================================== */
var dropdown =
document.createElement('li');
dropdown.className =
'wp-user-dropdown';
/* ====================================================
HAMBURGER BUTTON
==================================================== */
var trigger =
document.createElement('button');
trigger.type =
'button';
trigger.className =
'wp-user-menu-trigger';
trigger.setAttribute(
'aria-label',
'Open user menu'
);
trigger.setAttribute(
'title',
'User menu'
);
trigger.setAttribute(
'aria-expanded',
'false'
);
trigger.innerHTML =
getMenuIcon();
/* ====================================================
DROPDOWN MENU
==================================================== */
var menu =
document.createElement('ul');
menu.className =
'wp-user-dropdown-menu';
menu.hidden =
true;
/*
* Move all user controls into the
* hamburger except the theme button.
*
* Username already lives separately
* inside .wp-user-primary.
*/
Array.prototype
.slice.call(
list.children
)
.forEach(
function (item) {
if (
item !== themeItem &&
item !== dropdown
) {
menu.appendChild(item);
}
}
);
dropdown.appendChild(trigger);
dropdown.appendChild(menu);
/*
* Final logged-in header layout:
*
* Username | Theme | ☰
*/
list.appendChild(themeItem);
list.appendChild(dropdown);
/* ====================================================
OPEN / CLOSE
==================================================== */
function closeMenu() {
dropdown.classList.remove(
'is-open'
);
menu.hidden =
true;
trigger.setAttribute(
'aria-expanded',
'false'
);
}
function openMenu() {
dropdown.classList.add(
'is-open'
);
menu.hidden =
false;
trigger.setAttribute(
'aria-expanded',
'true'
);
}
/* ====================================================
HAMBURGER CLICK
==================================================== */
trigger.addEventListener(
'click',
function (event) {
event.preventDefault();
event.stopPropagation();
if (
dropdown.classList.contains(
'is-open'
)
) {
closeMenu();
} else {
openMenu();
}
}
);
/* ====================================================
CLICK INSIDE MENU
==================================================== */
menu.addEventListener(
'click',
function (event) {
event.stopPropagation();
}
);
/* ====================================================
CLICK OUTSIDE
==================================================== */
document.addEventListener(
'click',
function (event) {
if (
!dropdown.contains(
event.target
)
) {
closeMenu();
}
}
);
/* ====================================================
ESCAPE
==================================================== */
document.addEventListener(
'keydown',
function (event) {
if (
event.key === 'Escape' &&
dropdown.classList.contains(
'is-open'
)
) {
closeMenu();
trigger.focus();
}
}
);
}
/* ========================================================
INITIALIZE USER AREA
======================================================== */
function initializeUserArea() {
var primary =
document.querySelector(
'.wp-user-primary'
);
var list =
document.querySelector(
'.wp-user-menu-list'
);
if (!list) {
return;
}
/*
* Hide empty username container
* for anonymous users.
*/
if (
primary &&
!primary.querySelector('li')
) {
primary.classList.add(
'is-empty'
);
}
var themeItem =
createThemeToggle(list);
var username =
mw.config.get(
'wgUserName'
);
if (username) {
buildLoggedInLayout(
primary,
list,
themeItem
);
} else {
buildLoggedOutLayout(
list,
themeItem
);
}
updateThemeButton();
}
/* ========================================================
APPLY SAVED THEME
======================================================== */
applyTheme(
getSavedTheme(),
false
);
/* ========================================================
START
======================================================== */
function initialize() {
initializeUserArea();
}
if (
document.readyState ===
'loading'
) {
document.addEventListener(
'DOMContentLoaded',
initialize
);
} else {
initialize();
}
})();
/* ============================================================
WIKIPARTNER
ARTICLE CONTENTS MENU
============================================================ */
(function () {
'use strict';
function initializeArticleContents() {
var toc =
document.getElementById(
'wp-toc'
);
var article =
document.querySelector(
'.wp-article-body'
);
if (!toc || !article) {
return;
}
var linksContainer =
toc.querySelector(
'.wp-toc-links'
);
if (!linksContainer) {
return;
}
/* ====================================================
FIND ARTICLE HEADINGS
==================================================== */
var headings =
Array.prototype.slice.call(
article.querySelectorAll(
'h2, h3, h4, h5, h6'
)
);
headings =
headings.filter(
function (heading) {
var text =
heading.textContent
.replace(/\[edit\]/gi, '')
.trim();
return text.length > 0;
}
);
/* ====================================================
NO HEADINGS = NO CONTENTS BUTTON
==================================================== */
if (!headings.length) {
toc.classList.remove(
'wp-toc-ready'
);
toc.open =
false;
return;
}
/* ====================================================
CLEAR OLD CONTENTS
==================================================== */
linksContainer.innerHTML =
'';
var oldHeading =
toc.querySelector(
'.wp-toc-heading'
);
if (oldHeading) {
oldHeading.style.display =
'none';
}
/* ====================================================
BUILD CONTENTS FROM REAL HEADINGS
==================================================== */
headings.forEach(
function (
heading,
index
) {
if (!heading.id) {
heading.id =
'wikipartner-section-' +
(index + 1);
}
var level =
parseInt(
heading.tagName.substring(1),
10
);
var headingText =
heading.textContent
.replace(/\[edit\]/gi, '')
.trim();
var link =
document.createElement('a');
link.href =
'#' + heading.id;
link.className =
'wp-toc-level-' +
level;
link.textContent =
headingText;
link.addEventListener(
'click',
function () {
toc.open =
false;
}
);
linksContainer.appendChild(
link
);
}
);
/* ====================================================
SHOW CONTENTS BUTTON
==================================================== */
toc.classList.add(
'wp-toc-ready'
);
}
if (
document.readyState ===
'loading'
) {
document.addEventListener(
'DOMContentLoaded',
initializeArticleContents
);
} else {
initializeArticleContents();
}
})();
/* ============================================================
WIKIPARTNER
WHAT LINKS HERE — CURRENT PAGE
============================================================ */
(function () {
'use strict';
function initializeWhatLinksHere() {
var link =
document.getElementById(
'wp-what-links-here'
);
if (!link) {
return;
}
var pageName =
mw.config.get(
'wgPageName'
);
if (!pageName) {
return;
}
/*
* Use MediaWiki's own URL builder
* instead of html-title.
*/
mw.loader
.using(
'mediawiki.util'
)
.then(
function () {
link.href =
mw.util.getUrl(
'Special:WhatLinksHere/' +
pageName
);
}
);
}
if (
document.readyState ===
'loading'
) {
document.addEventListener(
'DOMContentLoaded',
initializeWhatLinksHere
);
} else {
initializeWhatLinksHere();
}
})();