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

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


var MAX_RELATED = 5;
function removeObsoleteInterface() {
var loaded = false;
var loading = false;
 
function clearV24Interface() {
var ids = [
var ids = [
'pvz-related-toggle',
'pvz-related-menu',
'pvz-right-panel',
'pvz-right-panel',
'pvz-left-panel-toggle',
'pvz-left-panel-toggle',
273번째 줄: 271번째 줄:
}
}
});
});
document.documentElement.classList.remove(
'pvz-font-small',
'pvz-font-normal',
'pvz-font-large',
'pvz-width-narrow',
'pvz-width-normal',
'pvz-width-wide',
'pvz-left-panel-open',
'pvz-right-panel-open'
);
}
}


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


if (!logo || !document.body) {
if (!panel || !logo) {
return;
return;
}
}


if (!wrapper) {
if (logo.parentNode !== panel) {
wrapper = document.createElement('div');
panel.insertBefore(logo, panel.firstChild);
wrapper.id = 'pvz-sidebar-logo';
document.body.appendChild(wrapper);
}
}


if (logo.parentNode !== wrapper) {
if (wrapper) {
wrapper.appendChild(logo);
wrapper.remove();
}
}
}
}
317번째 줄: 304번째 줄:
}
}


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


if (!personal) {
if (!content) {
return;
return;
}
}


top = personal.getBoundingClientRect().bottom + window.scrollY + 5;
left = content.getBoundingClientRect().left + window.scrollX;
document.documentElement.style.setProperty('--pvz-search-top', top + 'px');
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 makeRelatedInterface() {
function initV27Interface() {
var button = document.getElementById('pvz-related-toggle');
installV27Interface();
var menu = document.getElementById('pvz-related-menu');
 
var lines;
window.addEventListener('resize', function () {
var title;
syncPanelTop();
var list;
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);
}
});


if (!document.body) {
legacyHeadings = scope.querySelectorAll(
return;
'.skin-vector-legacy .mw-parser-output > h2'
}
);


if (!button) {
Array.prototype.forEach.call(legacyHeadings, function (heading) {
button = document.createElement('button');
var divider;
button.id = 'pvz-related-toggle';
button.type = 'button';
button.setAttribute('aria-label', '관련 문서 열기');
button.setAttribute('title', '관련 문서');
button.setAttribute('aria-expanded', 'false');


lines = document.createElement('span');
if (heading.closest('.mw-heading2')) {
lines.className = 'pvz-related-toggle-lines';
return;
lines.setAttribute('aria-hidden', 'true');
}
button.appendChild(lines);


document.body.appendChild(button);
heading.classList.add('pvz-grass-heading');
}


if (!menu) {
divider = heading.querySelector(
menu = document.createElement('aside');
':scope > .pvz-grass-divider'
menu.id = 'pvz-related-menu';
);
menu.setAttribute('aria-label', '관련 문서');


title = document.createElement('h2');
if (!divider) {
title.className = 'pvz-related-title';
divider = document.createElement('span');
title.textContent = '관련 문서';
divider.className = 'pvz-grass-divider';
divider.setAttribute('aria-hidden', 'true');
heading.appendChild(divider);
}
});
}


list = document.createElement('ul');
function initGrassDividers() {
list.className = 'pvz-related-list';
var observer;


menu.appendChild(title);
installGrassDividers(document);
menu.appendChild(list);
document.body.appendChild(menu);
}


if (button.getAttribute('data-pvz-ready') !== 'true') {
observer = new MutationObserver(function (mutations) {
button.setAttribute('data-pvz-ready', 'true');
mutations.forEach(function (mutation) {
Array.prototype.forEach.call(
mutation.addedNodes,
function (node) {
if (node.nodeType !== Node.ELEMENT_NODE) {
return;
}


button.addEventListener('click', function () {
if (
var willOpen = !menu.classList.contains('is-open');
node.matches(
'.mw-heading2, .mw-parser-output > h2'
)
) {
installGrassDividers(node.parentNode);
return;
}


menu.classList.toggle('is-open', willOpen);
installGrassDividers(node);
button.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
}
button.setAttribute(
'aria-label',
willOpen ? '관련 문서 닫기' : '관련 문서 열기'
);
);
if (willOpen && !loaded && !loading) {
loadRelatedPages(menu);
}
});
});
});


document.addEventListener('click', function (event) {
observer.observe(document.body, {
if (
childList: true,
menu.classList.contains('is-open') &&
subtree: true
!menu.contains(event.target) &&
});
!button.contains(event.target)
) {
menu.classList.remove('is-open');
button.setAttribute('aria-expanded', 'false');
button.setAttribute('aria-label', '관련 문서 열기');
}
});
}
}
}


function setRelatedMessage(menu, message) {
if (document.readyState === 'loading') {
var list = menu.querySelector('.pvz-related-list');
document.addEventListener(
var item = document.createElement('li');
'DOMContentLoaded',
var text = document.createElement('span');
initGrassDividers,
 
{ once: true }
list.textContent = '';
);
text.className = 'pvz-related-empty';
} else {
text.textContent = message;
initGrassDividers();
item.appendChild(text);
list.appendChild(item);
}
}
}());


function renderRelatedPages(menu, titles) {
var list = menu.querySelector('.pvz-related-list');


list.textContent = '';
(function () {
'use strict';


titles.slice(0, MAX_RELATED).forEach(function (title) {
var ACTION_OFFSET = 230;
var item = document.createElement('li');
var SEARCH_WIDTH = 205;
var link = document.createElement('a');
var SEARCH_DOWN_OFFSET = 5;
var CONTENT_TOP = 24;


link.href = mw.util.getUrl(title);
function getCactionsParts() {
link.textContent = title;
var menu = document.getElementById('p-cactions');
item.appendChild(link);
list.appendChild(item);
});


if (!list.children.length) {
if (!menu) {
setRelatedMessage(menu, '관련 문서가 없습니다.');
return null;
}
}


loaded = true;
return {
loading = false;
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 extractLinkedTitles(data) {
function isCactionsOpen(parts) {
var pages = data && data.query && data.query.pages;
if (!parts) {
var currentTitle = mw.config.get('wgPageName').replace(/_/g, ' ');
return false;
var titles = [];
}
var seen = Object.create(null);


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


Object.keys(pages).some(function (pageId) {
if (
var links = pages[pageId].links || [];
parts.menu.classList.contains('vector-menu-dropdown-active') ||
parts.menu.classList.contains('pvz-cactions-open')
) {
return true;
}


links.forEach(function (link) {
if (parts.label) {
var title = link.title;
return parts.label.getAttribute('aria-expanded') === 'true';
}


if (
return false;
title &&
}
title !== currentTitle &&
!seen[title] &&
titles.length < MAX_RELATED
) {
seen[title] = true;
titles.push(title);
}
});


return titles.length >= MAX_RELATED;
function closeCactions(parts) {
});
if (!parts) {
return;
}


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


function searchFallback(menu) {
parts.menu.classList.remove(
var pageTitle = mw.config.get('wgTitle') || '';
'pvz-cactions-open',
'vector-menu-dropdown-active'
);


return new mw.Api().get({
if (parts.label) {
action: 'query',
parts.label.setAttribute('aria-expanded', 'false');
list: 'search',
}
srsearch: pageTitle,
srnamespace: 0,
srlimit: MAX_RELATED + 1,
formatversion: 2
}).then(function (data) {
var currentTitle = mw.config.get('wgPageName').replace(/_/g, ' ');
var results = data && data.query && data.query.search
? data.query.search
: [];
var titles = results
.map(function (result) {
return result.title;
})
.filter(function (title) {
return title && title !== currentTitle;
})
.slice(0, MAX_RELATED);


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


function loadRelatedPages(menu) {
function handleCactionsClick(event) {
var articleId = mw.config.get('wgArticleId');
var parts = getCactionsParts();
var label;


loading = true;
if (!parts) {
setRelatedMessage(menu, '관련 문서를 불러오는 중…');
return;
}


if (!window.mw || !mw.Api || !mw.util) {
label = event.target.closest(
setRelatedMessage(menu, '관련 문서를 불러올 수 없습니다.');
'#p-cactions-label, #p-cactions > .vector-menu-heading'
loading = false;
);
 
if (label && isCactionsOpen(parts)) {
event.preventDefault();
event.stopImmediatePropagation();
closeCactions(parts);
return;
return;
}
}


if (!articleId) {
if (
searchFallback(menu).catch(function () {
isCactionsOpen(parts) &&
setRelatedMessage(menu, '관련 문서가 없습니다.');
!event.target.closest('#p-cactions')
loading = false;
) {
});
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;
return;
}
}


new mw.Api().get({
rightGap = Math.max(
action: 'query',
0,
prop: 'links',
window.innerWidth - content.getBoundingClientRect().right
pageids: articleId,
);
plnamespace: 0,
pllimit: 20,
formatversion: 2
}).then(function (data) {
var titles = extractLinkedTitles(data);


if (titles.length) {
navigationTop =
renderRelatedPages(menu, titles);
leftNavigation.getBoundingClientRect().top +
return;
window.scrollY;
}


return searchFallback(menu);
if (!Number.isFinite(navigationTop)) {
}).catch(function () {
navigationTop = CONTENT_TOP;
return searchFallback(menu);
}
}).catch(function () {
setRelatedMessage(menu, '관련 문서를 불러올 수 없습니다.');
loading = false;
});
}


function installV25Interface() {
document.documentElement.style.setProperty(
var panel = document.querySelector('.skin-vector-legacy #mw-panel');
'--pvz-content-right-gap',
rightGap + 'px'
);


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


if (panel) {
if (rightNavigation) {
moveLogoOutsidePanel(panel);
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'
);
}
}


makeRelatedInterface();
if (search) {
syncPanelTop();
search.style.setProperty(
syncSearchTop();
'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 initV25Interface() {
function initV35Layout() {
installV25Interface();
var observer;
 
syncV35Layout();
 
document.addEventListener(
'click',
handleCactionsClick,
true
);
 
window.addEventListener(
'resize',
syncV35Layout,
{ passive: true }
);
 
window.addEventListener(
'orientationchange',
syncV35Layout,
{ passive: true }
);


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


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


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