미디어위키:Gadget-Vector.js: 두 판 사이의 차이

식물 vs 좀비 위키
둘러보기로 이동 검색으로 이동
편집 요약 없음
태그: 되돌려진 기여
편집 요약 없음
태그: 수동 되돌리기
 
(같은 사용자의 중간 판 17개는 보이지 않습니다)
255번째 줄: 255번째 줄:
'use strict';
'use strict';


var FONT_VALUES = ['small', 'normal', 'large'];
function removeObsoleteInterface() {
var WIDTH_VALUES = ['narrow', 'normal', 'wide'];
var ids = [
var FONT_KEY = 'pvz-vector-font-size';
'pvz-related-toggle',
var WIDTH_KEY = 'pvz-vector-content-width';
'pvz-related-menu',
'pvz-right-panel',
'pvz-left-panel-toggle',
'pvz-right-panel-toggle'
];


function readPreference(key, allowed, fallback) {
ids.forEach(function (id) {
var value;
var element = document.getElementById(id);


try {
if (element) {
value = window.localStorage.getItem(key);
element.remove();
} catch (error) {
}
value = null;
});
}
}


return allowed.indexOf(value) !== -1 ? value : fallback;
function restoreLogoToPanel(panel) {
}
var wrapper = document.getElementById('pvz-sidebar-logo');
var logo =
(wrapper && wrapper.querySelector('#p-logo')) ||
document.querySelector('#p-logo');


function savePreference(key, value) {
if (!panel || !logo) {
try {
return;
window.localStorage.setItem(key, value);
} catch (error) {
/* 저장소를 사용할 수 없는 환경에서는 현재 화면에만 적용한다. */
}
}
}


function replacePreferenceClass(prefix, allowed, value) {
if (logo.parentNode !== panel) {
var root = document.documentElement;
panel.insertBefore(logo, panel.firstChild);
}


allowed.forEach(function (item) {
if (wrapper) {
root.classList.remove(prefix + item);
wrapper.remove();
});
}
 
root.classList.add(prefix + value);
}
}


function applyFontSize(value, shouldSave) {
function syncPanelTop() {
replacePreferenceClass('pvz-font-', FONT_VALUES, value);
var content = document.querySelector('.skin-vector-legacy #content');
var top;


if (shouldSave) {
if (!content) {
savePreference(FONT_KEY, value);
return;
}
}


updateControlStates();
top = content.getBoundingClientRect().top + window.scrollY;
document.documentElement.style.setProperty('--pvz-content-top', top + 'px');
}
}


function applyContentWidth(value, shouldSave) {
function syncSearchLeft() {
replacePreferenceClass('pvz-width-', WIDTH_VALUES, value);
var content = document.querySelector('.skin-vector-legacy #content');
var left;


if (value !== 'wide') {
if (!content) {
document.documentElement.classList.remove(
return;
'pvz-left-panel-open',
'pvz-right-panel-open'
);
}
}


if (shouldSave) {
left = content.getBoundingClientRect().left + window.scrollX;
savePreference(WIDTH_KEY, value);
document.documentElement.style.setProperty('--pvz-content-left', left + 'px');
}
}


updateControlStates();
function installV27Interface() {
updateToggleStates();
var panel = document.querySelector('.skin-vector-legacy #mw-panel');
window.requestAnimationFrame(syncPanelTop);
window.requestAnimationFrame(syncSearchLeft);
}


function applyStoredPreferences() {
removeObsoleteInterface();
applyFontSize(
restoreLogoToPanel(panel);
readPreference(FONT_KEY, FONT_VALUES, 'normal'),
syncPanelTop();
false
syncSearchLeft();
);
applyContentWidth(
readPreference(WIDTH_KEY, WIDTH_VALUES, 'normal'),
false
);
}
}


function moveLogoOutsidePanel(panel) {
function initV27Interface() {
var logo = panel && panel.querySelector('#p-logo');
installV27Interface();
var wrapper = document.getElementById('pvz-sidebar-logo');


if (!logo || !document.body) {
window.addEventListener('resize', function () {
return;
syncPanelTop();
}
syncSearchLeft();
}, { passive: true });


if (!wrapper) {
window.addEventListener('orientationchange', function () {
wrapper = document.createElement('div');
syncPanelTop();
wrapper.id = 'pvz-sidebar-logo';
syncSearchLeft();
document.body.appendChild(wrapper);
}, { passive: true });
}
 
if (logo.parentNode !== wrapper) {
wrapper.appendChild(logo);
}
}
}


function makeOption(label, group, value) {
if (document.readyState === 'loading') {
var button = document.createElement('button');
document.addEventListener('DOMContentLoaded', initV27Interface, { once: true });
 
} else {
button.type = 'button';
initV27Interface();
button.className = 'pvz-settings-option';
button.textContent = label;
button.setAttribute('data-pvz-setting-group', group);
button.setAttribute('data-pvz-setting-value', value);
button.setAttribute('aria-pressed', 'false');
 
return button;
}
}
}());


function makeSettingsSection(title, group, options) {
var section = document.createElement('section');
var heading = document.createElement('h3');
var optionList = document.createElement('div');


section.className = 'pvz-settings-section';
(function () {
heading.className = 'pvz-settings-heading';
'use strict';
heading.textContent = title;
optionList.className = 'pvz-settings-options';
optionList.setAttribute('role', 'group');
optionList.setAttribute('aria-label', title);


options.forEach(function (option) {
function installGrassDividers(root) {
optionList.appendChild(
var scope = root || document;
makeOption(option.label, group, option.value)
var wrappers;
);
var legacyHeadings;
});


section.appendChild(heading);
wrappers = scope.querySelectorAll(
section.appendChild(optionList);
'.skin-vector-legacy .mw-parser-output .mw-heading2'
);


return section;
Array.prototype.forEach.call(wrappers, function (wrapper) {
}
var divider;


function buildRightPanel() {
wrapper.classList.add('pvz-grass-heading');
var rightPanel = document.getElementById('pvz-right-panel');


if (!document.body) {
divider = wrapper.querySelector(
return;
':scope > .pvz-grass-divider'
}
);


if (!rightPanel) {
if (!divider) {
rightPanel = document.createElement('aside');
divider = document.createElement('span');
rightPanel.id = 'pvz-right-panel';
divider.className = 'pvz-grass-divider';
rightPanel.setAttribute('aria-label', '화면 설정');
divider.setAttribute('aria-hidden', 'true');
document.body.appendChild(rightPanel);
wrapper.appendChild(divider);
}
}
 
});
rightPanel.textContent = '';
 
rightPanel.appendChild(
makeSettingsSection('글자 크기', 'font', [
{ label: '작게', value: 'small' },
{ label: '보통', value: 'normal' },
{ label: '크게', value: 'large' }
])
);


rightPanel.appendChild(
legacyHeadings = scope.querySelectorAll(
makeSettingsSection('화면 너비', 'width', [
'.skin-vector-legacy .mw-parser-output > h2'
{ label: '좁게', value: 'narrow' },
{ label: '보통', value: 'normal' },
{ label: '넓게', value: 'wide' }
])
);
);


rightPanel.addEventListener('click', function (event) {
Array.prototype.forEach.call(legacyHeadings, function (heading) {
var option = event.target.closest('.pvz-settings-option');
var divider;
var group;
var value;


if (!option) {
if (heading.closest('.mw-heading2')) {
return;
return;
}
}


group = option.getAttribute('data-pvz-setting-group');
heading.classList.add('pvz-grass-heading');
value = option.getAttribute('data-pvz-setting-value');


if (group === 'font' && FONT_VALUES.indexOf(value) !== -1) {
divider = heading.querySelector(
applyFontSize(value, true);
':scope > .pvz-grass-divider'
}
);


if (group === 'width' && WIDTH_VALUES.indexOf(value) !== -1) {
if (!divider) {
applyContentWidth(value, true);
divider = document.createElement('span');
divider.className = 'pvz-grass-divider';
divider.setAttribute('aria-hidden', 'true');
heading.appendChild(divider);
}
}
});
});
}


updateControlStates();
function initGrassDividers() {
}
var observer;


function makePanelToggle(id, label, side) {
installGrassDividers(document);
var button = document.getElementById(id);
var lines;


if (!button) {
observer = new MutationObserver(function (mutations) {
button = document.createElement('button');
mutations.forEach(function (mutation) {
button.id = id;
Array.prototype.forEach.call(
button.type = 'button';
mutation.addedNodes,
button.className = 'pvz-panel-toggle';
function (node) {
button.setAttribute('aria-label', label);
if (node.nodeType !== Node.ELEMENT_NODE) {
button.setAttribute('title', label);
return;
button.setAttribute('aria-expanded', 'false');
}
button.setAttribute('data-pvz-panel-side', side);


lines = document.createElement('span');
if (
lines.className = 'pvz-panel-toggle-lines';
node.matches(
lines.setAttribute('aria-hidden', 'true');
'.mw-heading2, .mw-parser-output > h2'
button.appendChild(lines);
)
) {
installGrassDividers(node.parentNode);
return;
}


document.body.appendChild(button);
installGrassDividers(node);
}
}
);
});
});


return button;
observer.observe(document.body, {
childList: true,
subtree: true
});
}
}


function installPanelToggles() {
if (document.readyState === 'loading') {
var leftToggle = makePanelToggle(
document.addEventListener(
'pvz-left-panel-toggle',
'DOMContentLoaded',
'왼쪽 보조창 열기',
initGrassDividers,
'left'
{ once: true }
);
var rightToggle = makePanelToggle(
'pvz-right-panel-toggle',
'오른쪽 설정창 열기',
'right'
);
);
} else {
initGrassDividers();
}
}());


[leftToggle, rightToggle].forEach(function (button) {
(function () {
if (button.getAttribute('data-pvz-toggle-ready') === 'true') {
'use strict';
return;
}


button.setAttribute('data-pvz-toggle-ready', 'true');
var ACTION_OFFSET = 230;
var SEARCH_WIDTH = 205;
var SEARCH_DOWN_OFFSET = 5;
var CONTENT_TOP = 24;


button.addEventListener('click', function () {
function getCactionsParts() {
var root = document.documentElement;
var menu = document.getElementById('p-cactions');
var side = button.getAttribute('data-pvz-panel-side');
var targetClass =
side === 'left'
? 'pvz-left-panel-open'
: 'pvz-right-panel-open';
var otherClass =
side === 'left'
? 'pvz-right-panel-open'
: 'pvz-left-panel-open';
var willOpen = !root.classList.contains(targetClass);


root.classList.remove(otherClass);
if (!menu) {
root.classList.toggle(targetClass, willOpen);
return null;
updateToggleStates();
}
});
});


updateToggleStates();
return {
menu: menu,
label:
document.getElementById('p-cactions-label') ||
menu.querySelector('.vector-menu-heading'),
checkbox: menu.querySelector(
'input.vector-menu-checkbox, input[type="checkbox"]'
),
content: menu.querySelector('.vector-menu-content')
};
}
}


function updateControlStates() {
function isCactionsOpen(parts) {
var root = document.documentElement;
if (!parts) {
var options = document.querySelectorAll('.pvz-settings-option');
return false;
}
 
if (parts.checkbox && parts.checkbox.checked) {
return true;
}


Array.prototype.forEach.call(options, function (option) {
if (
var group = option.getAttribute('data-pvz-setting-group');
parts.menu.classList.contains('vector-menu-dropdown-active') ||
var value = option.getAttribute('data-pvz-setting-value');
parts.menu.classList.contains('pvz-cactions-open')
var active =
) {
(group === 'font' && root.classList.contains('pvz-font-' + value)) ||
return true;
(group === 'width' && root.classList.contains('pvz-width-' + value));
}


option.classList.toggle('is-active', active);
if (parts.label) {
option.setAttribute('aria-pressed', active ? 'true' : 'false');
return parts.label.getAttribute('aria-expanded') === 'true';
});
}
 
return false;
}
}


function updateToggleStates() {
function closeCactions(parts) {
var root = document.documentElement;
if (!parts) {
var leftToggle = document.getElementById('pvz-left-panel-toggle');
return;
var rightToggle = document.getElementById('pvz-right-panel-toggle');
}
var leftOpen = root.classList.contains('pvz-left-panel-open');
var rightOpen = root.classList.contains('pvz-right-panel-open');


if (leftToggle) {
if (parts.checkbox) {
leftToggle.setAttribute('aria-expanded', leftOpen ? 'true' : 'false');
parts.checkbox.checked = false;
leftToggle.setAttribute(
parts.checkbox.dispatchEvent(
'aria-label',
new Event('change', { bubbles: true })
leftOpen ? '왼쪽 보조창 닫기' : '왼쪽 보조창 열기'
);
leftToggle.setAttribute(
'title',
leftOpen ? '왼쪽 보조창 닫기' : '왼쪽 보조창 열기'
);
);
}
}


if (rightToggle) {
parts.menu.classList.remove(
rightToggle.setAttribute('aria-expanded', rightOpen ? 'true' : 'false');
'pvz-cactions-open',
rightToggle.setAttribute(
'vector-menu-dropdown-active'
'aria-label',
);
rightOpen ? '오른쪽 설정창 닫기' : '오른쪽 설정창 열기'
 
);
if (parts.label) {
rightToggle.setAttribute(
parts.label.setAttribute('aria-expanded', 'false');
'title',
}
rightOpen ? '오른쪽 설정창 닫기' : '오른쪽 설정창 열기'
 
);
if (parts.content) {
parts.content.setAttribute('aria-hidden', 'true');
}
}
}
}


function syncPanelTop() {
function handleCactionsClick(event) {
var content = document.querySelector('.skin-vector-legacy #content');
var parts = getCactionsParts();
var top;
var label;
 
if (!parts) {
return;
}
 
label = event.target.closest(
'#p-cactions-label, #p-cactions > .vector-menu-heading'
);


if (!content) {
if (label && isCactionsOpen(parts)) {
event.preventDefault();
event.stopImmediatePropagation();
closeCactions(parts);
return;
return;
}
}


top = content.getBoundingClientRect().top + window.scrollY;
if (
document.documentElement.style.setProperty('--pvz-content-top', top + 'px');
isCactionsOpen(parts) &&
!event.target.closest('#p-cactions')
) {
closeCactions(parts);
}
}
}


function syncSearchLeft() {
function syncV35Layout() {
var content = document.querySelector('.skin-vector-legacy #content');
var content = document.querySelector('#content');
var left;
var leftNavigation = document.getElementById('left-navigation');
var rightNavigation = document.getElementById('right-navigation');
var search = document.getElementById('pvz-content-search');
var rightGap;
var navigationTop;


if (!content) {
if (!content || !leftNavigation) {
return;
return;
}
}


left = content.getBoundingClientRect().left + window.scrollX;
rightGap = Math.max(
document.documentElement.style.setProperty('--pvz-content-left', left + 'px');
0,
}
window.innerWidth - content.getBoundingClientRect().right
);
 
navigationTop =
leftNavigation.getBoundingClientRect().top +
window.scrollY;
 
if (!Number.isFinite(navigationTop)) {
navigationTop = CONTENT_TOP;
}
 
document.documentElement.style.setProperty(
'--pvz-content-right-gap',
rightGap + 'px'
);


function installSidePanels() {
document.documentElement.style.setProperty(
var panel = document.querySelector('.skin-vector-legacy #mw-panel');
'--pvz-navigation-top',
navigationTop + 'px'
);


if (!panel || !document.body) {
if (rightNavigation) {
return;
rightNavigation.style.setProperty(
'position',
'absolute',
'important'
);
rightNavigation.style.setProperty(
'top',
navigationTop + 'px',
'important'
);
rightNavigation.style.setProperty(
'right',
(rightGap + ACTION_OFFSET) + 'px',
'important'
);
rightNavigation.style.setProperty(
'left',
'auto',
'important'
);
rightNavigation.style.setProperty(
'display',
'flex',
'important'
);
rightNavigation.style.setProperty(
'align-items',
'flex-end',
'important'
);
rightNavigation.style.setProperty(
'justify-content',
'flex-end',
'important'
);
rightNavigation.style.setProperty(
'width',
'max-content',
'important'
);
rightNavigation.style.setProperty(
'margin',
'0',
'important'
);
rightNavigation.style.setProperty(
'transform',
'none',
'important'
);
}
}


moveLogoOutsidePanel(panel);
if (search) {
buildRightPanel();
search.style.setProperty(
installPanelToggles();
'position',
syncPanelTop();
'absolute',
syncSearchLeft();
'important'
);
search.style.setProperty(
'top',
(navigationTop + SEARCH_DOWN_OFFSET) + 'px',
'important'
);
search.style.setProperty(
'right',
rightGap + 'px',
'important'
);
search.style.setProperty(
'left',
'auto',
'important'
);
search.style.setProperty(
'width',
SEARCH_WIDTH + 'px',
'important'
);
search.style.setProperty(
'max-width',
SEARCH_WIDTH + 'px',
'important'
);
}
}
}


function initSidePanels() {
function initV35Layout() {
installSidePanels();
var observer;
 
syncV35Layout();
 
document.addEventListener(
'click',
handleCactionsClick,
true
);


window.addEventListener('resize', function () {
window.addEventListener(
syncPanelTop();
'resize',
syncSearchLeft();
syncV35Layout,
}, { passive: true });
{ passive: true }
);
 
window.addEventListener(
'orientationchange',
syncV35Layout,
{ passive: true }
);
 
observer = new MutationObserver(function () {
window.requestAnimationFrame(syncV35Layout);
});


window.addEventListener('orientationchange', function () {
observer.observe(document.body, {
syncPanelTop();
childList: true,
syncSearchLeft();
subtree: true
}, { passive: true });
});
}
}
applyStoredPreferences();


if (document.readyState === 'loading') {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSidePanels, { once: true });
document.addEventListener(
'DOMContentLoaded',
initV35Layout,
{ once: true }
);
} else {
} else {
initSidePanels();
initV35Layout();
}
}
}());
}());

2026년 7월 30일 (목) 13:59 기준 최신판

(function () {
	'use strict';

	var SPIN_CLASS = 'pvz-watch-spinning';
	var WATCHED_CLASS = 'pvz-watch-watched';
	var NOT_WATCHED_CLASS = 'pvz-watch-not-watched';
	var SPIN_TIME = 360;
	var cleanupTimer = 0;

	function getContainer() {
		return document.querySelector(
			'#ca-watch, #ca-unwatch, li.mw-watchlink, a.mw-watchlink'
		);
	}

	function getLink(container) {
		if (!container) {
			return null;
		}

		return container.matches('a') ? container : container.querySelector('a');
	}

	function applyState(isWatched) {
		var container = getContainer();

		if (!container) {
			return;
		}

		container.classList.toggle(WATCHED_CLASS, !!isWatched);
		container.classList.toggle(NOT_WATCHED_CLASS, !isWatched);
	}

	function syncFromMarkup() {
		var container = getContainer();
		var link = getLink(container);
		var href;

		if (!container || !link) {
			return;
		}

		href = link.getAttribute('href') || '';

		applyState(
			container.id === 'ca-unwatch' ||
			href.indexOf('action=unwatch') !== -1
		);
	}

	function spin() {
		var container = getContainer();

		if (!container) {
			return;
		}

		window.clearTimeout(cleanupTimer);
		container.classList.remove(SPIN_CLASS);
		void container.offsetWidth;
		container.classList.add(SPIN_CLASS);

		cleanupTimer = window.setTimeout(function () {
			container.classList.remove(SPIN_CLASS);
		}, SPIN_TIME + 40);
	}

	function handleClick(event) {
		var link = event.target.closest(
			'#ca-watch > a, #ca-unwatch > a, li.mw-watchlink > a, a.mw-watchlink'
		);

		if (link) {
			spin();
		}
	}

	function shortenHistoryLabel() {
		var historyLink = document.querySelector('#ca-history > a');

		if (!historyLink) {
			return;
		}

		Array.prototype.forEach.call(historyLink.childNodes, function (node) {
			if (node.nodeType === Node.TEXT_NODE) {
				node.nodeValue = node.nodeValue.replace(/역사 보기/g, '역사');
			}
		});

		if (historyLink.textContent.trim() === '역사 보기') {
			historyLink.textContent = '역사';
		}

		historyLink.setAttribute('title', '역사');
	}

	function init() {
		var observer;

		shortenHistoryLabel();
		syncFromMarkup();
		document.addEventListener('click', handleClick, true);

		observer = new MutationObserver(function () {
			shortenHistoryLabel();
			syncFromMarkup();
		});

		observer.observe(document.body, {
			subtree: true,
			childList: true,
			attributes: true,
			attributeFilter: ['id', 'href']
		});

		if (window.mw && mw.hook) {
			mw.hook('wikipage.watchlistChange').add(function (isWatched) {
				applyState(isWatched);
				spin();
			});
		}
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', init, { once: true });
	} else {
		init();
	}
}());


(function () {
	'use strict';

	function installSearchButtonIcon(wrapper) {
		var simpleSearch;
		var searchButton;
		var icon;

		if (!wrapper) {
			return;
		}

		simpleSearch = wrapper.querySelector('#simpleSearch');

		if (!simpleSearch) {
			return;
		}

		searchButton =
			simpleSearch.querySelector('#searchButton') ||
			simpleSearch.querySelector('.searchButton:not(#mw-searchButton)');

		if (!searchButton) {
			return;
		}

		searchButton.classList.add('pvz-primary-search-button');

		icon = simpleSearch.querySelector('.pvz-search-button-icon');

		if (!icon) {
			icon = document.createElement('span');
			icon.className = 'pvz-search-button-icon';
			icon.setAttribute('aria-hidden', 'true');
			simpleSearch.appendChild(icon);
		}
	}

	function installTopSearch() {
		var content = document.querySelector('.skin-vector-legacy #content');
		var form = document.querySelector('#searchform');
		var wrapper;

		if (!content || !form || !document.body) {
			return;
		}

		wrapper = document.getElementById('pvz-content-search');

		if (!wrapper) {
			wrapper = document.createElement('div');
			wrapper.id = 'pvz-content-search';
			wrapper.setAttribute('role', 'search');
			wrapper.setAttribute('aria-label', '사이트 검색');
		}

		if (wrapper.parentNode !== document.body) {
			document.body.insertBefore(wrapper, content);
		}

		if (form.parentNode !== wrapper) {
			wrapper.appendChild(form);
		}

		installSearchButtonIcon(wrapper);
		document.documentElement.classList.add('pvz-content-search-ready');
	}

	function initTopSearch() {
		var observer;

		installTopSearch();

		observer = new MutationObserver(function () {
			installTopSearch();
		});

		observer.observe(document.body, {
			childList: true,
			subtree: true
		});
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', initTopSearch, { once: true });
	} else {
		initTopSearch();
	}
}());


(function () {
	'use strict';

	function syncSearchLeft() {
		var content = document.querySelector('.skin-vector-legacy #content');
		var left;

		if (!content) {
			return;
		}

		left = content.getBoundingClientRect().left + window.scrollX;
		document.documentElement.style.setProperty('--pvz-content-left', left + 'px');
	}

	function initSearchAlignment() {
		syncSearchLeft();
		window.addEventListener('resize', syncSearchLeft, { passive: true });
		window.addEventListener('orientationchange', syncSearchLeft, { passive: true });
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', initSearchAlignment, { once: true });
	} else {
		initSearchAlignment();
	}
}());


(function () {
	'use strict';

	function removeObsoleteInterface() {
		var ids = [
			'pvz-related-toggle',
			'pvz-related-menu',
			'pvz-right-panel',
			'pvz-left-panel-toggle',
			'pvz-right-panel-toggle'
		];

		ids.forEach(function (id) {
			var element = document.getElementById(id);

			if (element) {
				element.remove();
			}
		});
	}

	function restoreLogoToPanel(panel) {
		var wrapper = document.getElementById('pvz-sidebar-logo');
		var logo =
			(wrapper && wrapper.querySelector('#p-logo')) ||
			document.querySelector('#p-logo');

		if (!panel || !logo) {
			return;
		}

		if (logo.parentNode !== panel) {
			panel.insertBefore(logo, panel.firstChild);
		}

		if (wrapper) {
			wrapper.remove();
		}
	}

	function syncPanelTop() {
		var content = document.querySelector('.skin-vector-legacy #content');
		var top;

		if (!content) {
			return;
		}

		top = content.getBoundingClientRect().top + window.scrollY;
		document.documentElement.style.setProperty('--pvz-content-top', top + 'px');
	}

	function syncSearchLeft() {
		var content = document.querySelector('.skin-vector-legacy #content');
		var left;

		if (!content) {
			return;
		}

		left = content.getBoundingClientRect().left + window.scrollX;
		document.documentElement.style.setProperty('--pvz-content-left', left + 'px');
	}

	function installV27Interface() {
		var panel = document.querySelector('.skin-vector-legacy #mw-panel');

		removeObsoleteInterface();
		restoreLogoToPanel(panel);
		syncPanelTop();
		syncSearchLeft();
	}

	function initV27Interface() {
		installV27Interface();

		window.addEventListener('resize', function () {
			syncPanelTop();
			syncSearchLeft();
		}, { passive: true });

		window.addEventListener('orientationchange', function () {
			syncPanelTop();
			syncSearchLeft();
		}, { passive: true });
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', initV27Interface, { once: true });
	} else {
		initV27Interface();
	}
}());


(function () {
	'use strict';

	function installGrassDividers(root) {
		var scope = root || document;
		var wrappers;
		var legacyHeadings;

		wrappers = scope.querySelectorAll(
			'.skin-vector-legacy .mw-parser-output .mw-heading2'
		);

		Array.prototype.forEach.call(wrappers, function (wrapper) {
			var divider;

			wrapper.classList.add('pvz-grass-heading');

			divider = wrapper.querySelector(
				':scope > .pvz-grass-divider'
			);

			if (!divider) {
				divider = document.createElement('span');
				divider.className = 'pvz-grass-divider';
				divider.setAttribute('aria-hidden', 'true');
				wrapper.appendChild(divider);
			}
		});

		legacyHeadings = scope.querySelectorAll(
			'.skin-vector-legacy .mw-parser-output > h2'
		);

		Array.prototype.forEach.call(legacyHeadings, function (heading) {
			var divider;

			if (heading.closest('.mw-heading2')) {
				return;
			}

			heading.classList.add('pvz-grass-heading');

			divider = heading.querySelector(
				':scope > .pvz-grass-divider'
			);

			if (!divider) {
				divider = document.createElement('span');
				divider.className = 'pvz-grass-divider';
				divider.setAttribute('aria-hidden', 'true');
				heading.appendChild(divider);
			}
		});
	}

	function initGrassDividers() {
		var observer;

		installGrassDividers(document);

		observer = new MutationObserver(function (mutations) {
			mutations.forEach(function (mutation) {
				Array.prototype.forEach.call(
					mutation.addedNodes,
					function (node) {
						if (node.nodeType !== Node.ELEMENT_NODE) {
							return;
						}

						if (
							node.matches(
								'.mw-heading2, .mw-parser-output > h2'
							)
						) {
							installGrassDividers(node.parentNode);
							return;
						}

						installGrassDividers(node);
					}
				);
			});
		});

		observer.observe(document.body, {
			childList: true,
			subtree: true
		});
	}

	if (document.readyState === 'loading') {
		document.addEventListener(
			'DOMContentLoaded',
			initGrassDividers,
			{ once: true }
		);
	} else {
		initGrassDividers();
	}
}());


(function () {
	'use strict';

	var ACTION_OFFSET = 230;
	var SEARCH_WIDTH = 205;
	var SEARCH_DOWN_OFFSET = 5;
	var CONTENT_TOP = 24;

	function getCactionsParts() {
		var menu = document.getElementById('p-cactions');

		if (!menu) {
			return null;
		}

		return {
			menu: menu,
			label:
				document.getElementById('p-cactions-label') ||
				menu.querySelector('.vector-menu-heading'),
			checkbox: menu.querySelector(
				'input.vector-menu-checkbox, input[type="checkbox"]'
			),
			content: menu.querySelector('.vector-menu-content')
		};
	}

	function isCactionsOpen(parts) {
		if (!parts) {
			return false;
		}

		if (parts.checkbox && parts.checkbox.checked) {
			return true;
		}

		if (
			parts.menu.classList.contains('vector-menu-dropdown-active') ||
			parts.menu.classList.contains('pvz-cactions-open')
		) {
			return true;
		}

		if (parts.label) {
			return parts.label.getAttribute('aria-expanded') === 'true';
		}

		return false;
	}

	function closeCactions(parts) {
		if (!parts) {
			return;
		}

		if (parts.checkbox) {
			parts.checkbox.checked = false;
			parts.checkbox.dispatchEvent(
				new Event('change', { bubbles: true })
			);
		}

		parts.menu.classList.remove(
			'pvz-cactions-open',
			'vector-menu-dropdown-active'
		);

		if (parts.label) {
			parts.label.setAttribute('aria-expanded', 'false');
		}

		if (parts.content) {
			parts.content.setAttribute('aria-hidden', 'true');
		}
	}

	function handleCactionsClick(event) {
		var parts = getCactionsParts();
		var label;

		if (!parts) {
			return;
		}

		label = event.target.closest(
			'#p-cactions-label, #p-cactions > .vector-menu-heading'
		);

		if (label && isCactionsOpen(parts)) {
			event.preventDefault();
			event.stopImmediatePropagation();
			closeCactions(parts);
			return;
		}

		if (
			isCactionsOpen(parts) &&
			!event.target.closest('#p-cactions')
		) {
			closeCactions(parts);
		}
	}

	function syncV35Layout() {
		var content = document.querySelector('#content');
		var leftNavigation = document.getElementById('left-navigation');
		var rightNavigation = document.getElementById('right-navigation');
		var search = document.getElementById('pvz-content-search');
		var rightGap;
		var navigationTop;

		if (!content || !leftNavigation) {
			return;
		}

		rightGap = Math.max(
			0,
			window.innerWidth - content.getBoundingClientRect().right
		);

		navigationTop =
			leftNavigation.getBoundingClientRect().top +
			window.scrollY;

		if (!Number.isFinite(navigationTop)) {
			navigationTop = CONTENT_TOP;
		}

		document.documentElement.style.setProperty(
			'--pvz-content-right-gap',
			rightGap + 'px'
		);

		document.documentElement.style.setProperty(
			'--pvz-navigation-top',
			navigationTop + 'px'
		);

		if (rightNavigation) {
			rightNavigation.style.setProperty(
				'position',
				'absolute',
				'important'
			);
			rightNavigation.style.setProperty(
				'top',
				navigationTop + 'px',
				'important'
			);
			rightNavigation.style.setProperty(
				'right',
				(rightGap + ACTION_OFFSET) + 'px',
				'important'
			);
			rightNavigation.style.setProperty(
				'left',
				'auto',
				'important'
			);
			rightNavigation.style.setProperty(
				'display',
				'flex',
				'important'
			);
			rightNavigation.style.setProperty(
				'align-items',
				'flex-end',
				'important'
			);
			rightNavigation.style.setProperty(
				'justify-content',
				'flex-end',
				'important'
			);
			rightNavigation.style.setProperty(
				'width',
				'max-content',
				'important'
			);
			rightNavigation.style.setProperty(
				'margin',
				'0',
				'important'
			);
			rightNavigation.style.setProperty(
				'transform',
				'none',
				'important'
			);
		}

		if (search) {
			search.style.setProperty(
				'position',
				'absolute',
				'important'
			);
			search.style.setProperty(
				'top',
				(navigationTop + SEARCH_DOWN_OFFSET) + 'px',
				'important'
			);
			search.style.setProperty(
				'right',
				rightGap + 'px',
				'important'
			);
			search.style.setProperty(
				'left',
				'auto',
				'important'
			);
			search.style.setProperty(
				'width',
				SEARCH_WIDTH + 'px',
				'important'
			);
			search.style.setProperty(
				'max-width',
				SEARCH_WIDTH + 'px',
				'important'
			);
		}
	}

	function initV35Layout() {
		var observer;

		syncV35Layout();

		document.addEventListener(
			'click',
			handleCactionsClick,
			true
		);

		window.addEventListener(
			'resize',
			syncV35Layout,
			{ passive: true }
		);

		window.addEventListener(
			'orientationchange',
			syncV35Layout,
			{ passive: true }
		);

		observer = new MutationObserver(function () {
			window.requestAnimationFrame(syncV35Layout);
		});

		observer.observe(document.body, {
			childList: true,
			subtree: true
		});
	}

	if (document.readyState === 'loading') {
		document.addEventListener(
			'DOMContentLoaded',
			initV35Layout,
			{ once: true }
		);
	} else {
		initV35Layout();
	}
}());