편집 요약 없음 태그: 되돌려진 기여 |
편집 요약 없음 태그: 되돌려진 기여 |
||
| 1번째 줄: | 1번째 줄: | ||
/** | /** | ||
* MediaWiki 커스텀 펼치기/접기 애니메이션 | * MediaWiki 커스텀 펼치기/접기 슬라이드 애니메이션 | ||
* | * | ||
* | * 지원 구조: | ||
* | * | ||
* | * 1) | ||
* <div id="mw-customcollapsible-XXX"> | |||
* <div id="mw-customcollapsible-XXX | * <div class="mw-customtoggle-XXX mw-customtoggle">버튼</div> | ||
* <table>내용</table> | |||
* <div class="mw-customtoggle-XXX mw-customtoggle"> | * </div> | ||
* | |||
* | |||
* | * | ||
* 2) | |||
* <div id="mw-customcollapsible-XXX"> | |||
* <div class="mw-customtoggle-XXX mw-customtoggle">버튼</div> | |||
* </div> | * </div> | ||
* <table>내용</table> | |||
* | * | ||
* | * 둘 다 자동 처리 | ||
*/ | */ | ||
| 25번째 줄: | 24번째 줄: | ||
var DURATION = 300; | var DURATION = 300; | ||
var | var READY_CLASS = 'custom-collapse-ready'; | ||
var | var OPEN_CLASS = 'custom-collapse-open'; | ||
var | var ANIMATING_CLASS = 'custom-collapse-animating'; | ||
var | var CONTENT_CLASS = 'custom-collapse-content'; | ||
/* | /* ============================== | ||
toggle 이름 추출 | |||
============================== */ | |||
function getToggleName( toggle ) { | function getToggleName( toggle ) { | ||
var prefix = 'mw-customtoggle-'; | var prefix = 'mw-customtoggle-'; | ||
| 55번째 줄: | 51번째 줄: | ||
/* | /* ============================== | ||
연결된 collapsible 찾기 | |||
============================== */ | |||
function getTarget( toggle ) { | function getTarget( toggle ) { | ||
var name = getToggleName( toggle ); | var name = getToggleName( toggle ); | ||
| 65번째 줄: | 62번째 줄: | ||
} | } | ||
return document.getElementById( | |||
'mw-customcollapsible-' + name | |||
' | |||
); | ); | ||
} | |||
/* ============================== | |||
다음 custom collapsible인지 검사 | |||
============================== */ | |||
if ( | function isNextCollapsible( element ) { | ||
if ( !element || !element.id ) { | |||
return false; | |||
return | |||
} | } | ||
return ( | |||
element.id.indexOf( | |||
'mw-customcollapsible-' | |||
) === 0 | |||
); | ); | ||
} | } | ||
/* | /* ============================== | ||
실제 내용 wrapper 만들기 | |||
============================== */ | |||
function createContentWrapper( target, toggle ) { | |||
function | /* | ||
var existing = target.querySelector( | * 이미 만들었으면 재사용 | ||
*/ | |||
var existing = | |||
target.querySelector( | |||
':scope > .' + CONTENT_CLASS | |||
); | |||
if ( existing ) { | if ( existing ) { | ||
| 105번째 줄: | 103번째 줄: | ||
} | } | ||
/* -------------------------------- | |||
경우 1: | |||
내용이 target 내부에 있음 | |||
-------------------------------- */ | |||
var internalNodes = []; | |||
var node = toggle.nextSibling; | var node = toggle.nextSibling; | ||
while ( node ) { | while ( node ) { | ||
internalNodes.push( node ); | |||
node = node.nextSibling; | node = node.nextSibling; | ||
} | } | ||
if ( internalNodes.length ) { | |||
var internalWrapper = | |||
document.createElement( 'div' ); | |||
internalWrapper.className = | |||
CONTENT_CLASS; | |||
internalNodes.forEach( | |||
function ( child ) { | |||
internalWrapper.appendChild( | |||
child | |||
); | |||
} | |||
); | |||
target.appendChild( | |||
internalWrapper | |||
); | |||
return internalWrapper; | |||
} | |||
/* -------------------------------- | |||
경우 2: | |||
내용이 target 다음 형제에 있음 | |||
-------------------------------- */ | |||
var parent = target.parentNode; | |||
if ( !parent ) { | |||
return null; | |||
if ( | |||
return | |||
} | } | ||
/* | var externalWrapper = | ||
document.createElement( 'div' ); | |||
externalWrapper.className = | |||
CONTENT_CLASS; | |||
var sibling = | |||
target.nextSibling; | |||
var foundContent = false; | |||
while ( sibling ) { | |||
var nextSibling = | |||
sibling.nextSibling; | |||
/* | |||
* 다음 customcollapsible을 만나면 | |||
* 현재 영역 종료 | |||
*/ | |||
if ( | |||
sibling.nodeType === 1 && | |||
isNextCollapsible( sibling ) | |||
) { | |||
break; | |||
} | |||
/* | |||
* 공백 텍스트는 무시 | |||
*/ | |||
if ( | |||
sibling.nodeType === 3 && | |||
!sibling.textContent.trim() | |||
) { | |||
sibling = nextSibling; | |||
continue; | |||
} | |||
/* | |||
* script / style은 건드리지 않음 | |||
*/ | |||
if ( | |||
sibling.nodeType === 1 && | |||
( | |||
sibling.tagName === 'SCRIPT' || | |||
sibling.tagName === 'STYLE' | |||
) | |||
) { | |||
break; | |||
} | |||
externalWrapper.appendChild( | |||
sibling | |||
); | |||
foundContent = true; | |||
sibling = nextSibling; | |||
} | } | ||
if ( !foundContent ) { | |||
return null; | |||
if ( | |||
return | |||
} | } | ||
return true; | parent.insertBefore( | ||
externalWrapper, | |||
sibling | |||
); | |||
return externalWrapper; | |||
} | |||
/* ============================== | |||
즉시 펼쳐진 상태 설정 | |||
============================== */ | |||
function setOpenImmediately( | |||
target, | |||
toggle, | |||
content | |||
) { | |||
target.classList.remove( | |||
'mw-collapsed' | |||
); | |||
target.classList.add( | |||
OPEN_CLASS | |||
); | |||
content.style.display = ''; | |||
content.style.height = ''; | |||
content.style.overflow = ''; | |||
toggle.setAttribute( | |||
'aria-expanded', | |||
'true' | |||
); | |||
} | |||
/* ============================== | |||
즉시 접힌 상태 설정 | |||
============================== */ | |||
function setClosedImmediately( | |||
target, | |||
toggle, | |||
content | |||
) { | |||
target.classList.add( | |||
'mw-collapsed' | |||
); | |||
target.classList.remove( | |||
OPEN_CLASS | |||
); | |||
content.style.display = 'none'; | |||
content.style.height = ''; | |||
content.style.overflow = ''; | |||
toggle.setAttribute( | |||
'aria-expanded', | |||
'false' | |||
); | |||
} | } | ||
/* | /* ============================== | ||
펼치기 애니메이션 | |||
============================== */ | |||
function | |||
function openContent( | |||
target, | |||
toggle, | |||
content | |||
) { | |||
if ( | if ( | ||
content.classList.contains( | |||
ANIMATING_CLASS | ANIMATING_CLASS | ||
) | ) | ||
| 178번째 줄: | 298번째 줄: | ||
} | } | ||
content.classList.add( | |||
ANIMATING_CLASS | ANIMATING_CLASS | ||
); | ); | ||
| 186번째 줄: | 306번째 줄: | ||
); | ); | ||
content.style.display = 'block'; | |||
content.style.overflow = 'hidden'; | |||
content.style.height = '0px'; | |||
/* | /* | ||
* | * 브라우저가 0px 상태를 먼저 | ||
* 그리도록 한 프레임 기다림 | |||
*/ | */ | ||
window.requestAnimationFrame( | |||
function () { | |||
var endHeight = | |||
content.scrollHeight; | |||
content.style.transition = | |||
'height ' + | |||
DURATION + | |||
'ms ease'; | |||
/* | |||
* 한 프레임을 더 나누어 | |||
* height transition이 확실하게 실행되게 함 | |||
*/ | |||
window.requestAnimationFrame( | |||
function () { | |||
content.style.height = | |||
endHeight + 'px'; | |||
} | |||
); | |||
} | } | ||
); | ); | ||
window.setTimeout( | |||
function () { | |||
content.classList.remove( | |||
ANIMATING_CLASS | |||
); | |||
target.classList.add( | |||
OPEN_CLASS | |||
); | |||
content.style.transition = ''; | |||
content.style.height = ''; | |||
content.style.overflow = ''; | |||
content.style.display = ''; | |||
toggle.setAttribute( | |||
'aria-expanded', | |||
'true' | |||
); | |||
}, | |||
DURATION + 40 | |||
); | |||
} | } | ||
/* | /* ============================== | ||
접기 애니메이션 | |||
============================== */ | |||
function | |||
function closeContent( | |||
target, | |||
toggle, | |||
content | |||
) { | |||
if ( | if ( | ||
content.classList.contains( | |||
ANIMATING_CLASS | ANIMATING_CLASS | ||
) | ) | ||
| 257번째 줄: | 382번째 줄: | ||
} | } | ||
content.classList.add( | |||
ANIMATING_CLASS | ANIMATING_CLASS | ||
); | ); | ||
var startHeight = | var startHeight = | ||
content.getBoundingClientRect() | |||
.height; | |||
if ( startHeight <= 0 ) { | if ( startHeight <= 0 ) { | ||
content.classList.remove( | |||
ANIMATING_CLASS | ANIMATING_CLASS | ||
); | |||
setClosedImmediately( | |||
target, | |||
toggle, | |||
content | |||
); | ); | ||
| 275번째 줄: | 404번째 줄: | ||
} | } | ||
content.style.overflow = 'hidden'; | |||
content.style.height = | |||
startHeight + 'px'; | startHeight + 'px'; | ||
content.style.transition = | |||
' | 'height ' + | ||
DURATION + | |||
'ms ease'; | |||
/* | /* | ||
* | * 현재 높이를 브라우저에 먼저 반영 | ||
*/ | */ | ||
content.offsetHeight; | |||
window.requestAnimationFrame( | |||
function () { | |||
content.style.height = | |||
'0px'; | |||
} | } | ||
); | ); | ||
window.setTimeout( | |||
function () { | |||
content.classList.remove( | |||
ANIMATING_CLASS | |||
); | |||
target.classList.remove( | |||
OPEN_CLASS | |||
); | |||
target.classList.add( | |||
'mw-collapsed' | |||
); | |||
content.style.display = | |||
'none'; | |||
content.style.transition = | |||
''; | |||
content.style.height = ''; | |||
content.style.overflow = ''; | |||
toggle.setAttribute( | |||
'aria-expanded', | |||
'false' | |||
); | |||
}, | |||
DURATION + 40 | |||
); | |||
} | } | ||
/* | /* ============================== | ||
토글 실행 | |||
============================== */ | |||
function | |||
var target = getTarget( toggle ); | function toggleContent( toggle ) { | ||
var target = | |||
getTarget( toggle ); | |||
if ( !target ) { | if ( !target ) { | ||
return | return; | ||
} | } | ||
var | var content = | ||
target._customCollapseContent; | |||
if ( !content ) { | |||
content = | |||
createContentWrapper( | |||
target, | |||
toggle | |||
); | |||
target._customCollapseContent = | |||
content; | |||
} | } | ||
if ( ! | if ( !content ) { | ||
return | return; | ||
} | } | ||
| 358번째 줄: | 493번째 줄: | ||
toggle.getAttribute( | toggle.getAttribute( | ||
'aria-expanded' | 'aria-expanded' | ||
) | ) !== 'false' && | ||
!target.classList.contains( | !target.classList.contains( | ||
'mw-collapsed' | 'mw-collapsed' | ||
| 364번째 줄: | 499번째 줄: | ||
if ( isOpen ) { | if ( isOpen ) { | ||
closeContent( | |||
target, | target, | ||
toggle, | toggle, | ||
content | |||
); | ); | ||
} else { | } else { | ||
openContent( | |||
target, | target, | ||
toggle, | toggle, | ||
content | |||
); | ); | ||
} | } | ||
} | |||
/* ============================== | |||
초기화 | |||
============================== */ | |||
function initializeToggle( toggle ) { | |||
var target = | |||
getTarget( toggle ); | |||
function | |||
var target = getTarget( toggle ); | |||
if ( !target ) { | if ( !target ) { | ||
| 399번째 줄: | 534번째 줄: | ||
} | } | ||
var | var content = | ||
createContentWrapper( | |||
target, | |||
toggle | |||
); | |||
if ( ! | if ( !content ) { | ||
return; | return; | ||
} | } | ||
target._customCollapseContent = | |||
content; | |||
target.classList.add( | target.classList.add( | ||
| 412번째 줄: | 551번째 줄: | ||
); | ); | ||
var | /* | ||
* 최초 상태 판별 | |||
toggle | */ | ||
var initiallyClosed = | |||
target.classList.contains( | |||
'mw-collapsed' | |||
) || | |||
toggle.getAttribute( | |||
'aria-expanded' | |||
) === 'false'; | |||
if ( | if ( initiallyClosed ) { | ||
target | setClosedImmediately( | ||
target, | |||
toggle, | |||
content | |||
); | ); | ||
} else { | } else { | ||
target | setOpenImmediately( | ||
target, | |||
toggle, | |||
content | |||
); | ); | ||
} | } | ||
} | } | ||
function initializeAll() { | function initializeAll() { | ||
var toggles = document.querySelectorAll( | var toggles = | ||
document.querySelectorAll( | |||
'.mw-customtoggle' | |||
); | |||
toggles.forEach( | toggles.forEach( | ||
function ( toggle ) { | function ( toggle ) { | ||
if ( getToggleName( toggle ) ) { | |||
if ( | |||
getToggleName( | |||
toggle | |||
) | |||
) { | |||
initializeToggle( | |||
toggle | toggle | ||
); | ); | ||
} | } | ||
} | } | ||
); | ); | ||
| 472번째 줄: | 606번째 줄: | ||
/* | /* ============================== | ||
클릭 이벤트 | |||
============================== */ | |||
document.addEventListener( | document.addEventListener( | ||
'click', | 'click', | ||
function ( event ) { | function ( event ) { | ||
var toggle = | var toggle = | ||
event.target.closest( | event.target.closest( | ||
| 491번째 줄: | 624번째 줄: | ||
if ( | if ( | ||
!getToggleName( toggle ) | !getToggleName( | ||
toggle | |||
) | |||
) { | ) { | ||
return; | return; | ||
} | } | ||
/* | |||
* MediaWiki 기본 즉시 토글 차단 | |||
*/ | |||
event.preventDefault(); | event.preventDefault(); | ||
event.stopPropagation(); | event.stopPropagation(); | ||
event.stopImmediatePropagation(); | event.stopImmediatePropagation(); | ||
toggleContent( | |||
toggle | toggle | ||
); | ); | ||
}, | }, | ||
true | true | ||
| 508번째 줄: | 647번째 줄: | ||
/* | /* ============================== | ||
키보드 | |||
============================== */ | |||
document.addEventListener( | document.addEventListener( | ||
'keydown', | 'keydown', | ||
function ( event ) { | function ( event ) { | ||
if ( | if ( | ||
event.key !== 'Enter' && | event.key !== 'Enter' && | ||
| 531번째 줄: | 672번째 줄: | ||
if ( | if ( | ||
!getToggleName( toggle ) | !getToggleName( | ||
toggle | |||
) | |||
) { | ) { | ||
return; | return; | ||
| 540번째 줄: | 683번째 줄: | ||
event.stopImmediatePropagation(); | event.stopImmediatePropagation(); | ||
toggleContent( | |||
toggle | toggle | ||
); | ); | ||
}, | }, | ||
true | true | ||
| 548번째 줄: | 692번째 줄: | ||
/* | /* ============================== | ||
페이지 로드 | |||
============================== */ | |||
if ( | if ( | ||
document.readyState === | document.readyState === | ||
'loading' | 'loading' | ||
) { | ) { | ||
document.addEventListener( | document.addEventListener( | ||
'DOMContentLoaded', | 'DOMContentLoaded', | ||
initializeAll | initializeAll | ||
); | ); | ||
} else { | } else { | ||
initializeAll(); | initializeAll(); | ||
} | } | ||
/ | /* | ||
* MediaWiki | * MediaWiki 동적 콘텐츠 대응 | ||
*/ | */ | ||
if ( | if ( | ||
| 571번째 줄: | 720번째 줄: | ||
mw.hook | mw.hook | ||
) { | ) { | ||
mw.hook( | mw.hook( | ||
'wikipage.content' | 'wikipage.content' | ||
| 578번째 줄: | 728번째 줄: | ||
} | } | ||
); | ); | ||
} | } | ||
}() ); | }() ); | ||
2026년 8월 20일 (목) 13:24 판
/**
* MediaWiki 커스텀 펼치기/접기 슬라이드 애니메이션
*
* 지원 구조:
*
* 1)
* <div id="mw-customcollapsible-XXX">
* <div class="mw-customtoggle-XXX mw-customtoggle">버튼</div>
* <table>내용</table>
* </div>
*
* 2)
* <div id="mw-customcollapsible-XXX">
* <div class="mw-customtoggle-XXX mw-customtoggle">버튼</div>
* </div>
* <table>내용</table>
*
* 둘 다 자동 처리
*/
( function () {
'use strict';
var DURATION = 300;
var READY_CLASS = 'custom-collapse-ready';
var OPEN_CLASS = 'custom-collapse-open';
var ANIMATING_CLASS = 'custom-collapse-animating';
var CONTENT_CLASS = 'custom-collapse-content';
/* ==============================
toggle 이름 추출
============================== */
function getToggleName( toggle ) {
var prefix = 'mw-customtoggle-';
var classes = toggle.classList;
var i;
for ( i = 0; i < classes.length; i++ ) {
if ( classes[ i ].indexOf( prefix ) === 0 ) {
return classes[ i ].substring(
prefix.length
);
}
}
return null;
}
/* ==============================
연결된 collapsible 찾기
============================== */
function getTarget( toggle ) {
var name = getToggleName( toggle );
if ( !name ) {
return null;
}
return document.getElementById(
'mw-customcollapsible-' + name
);
}
/* ==============================
다음 custom collapsible인지 검사
============================== */
function isNextCollapsible( element ) {
if ( !element || !element.id ) {
return false;
}
return (
element.id.indexOf(
'mw-customcollapsible-'
) === 0
);
}
/* ==============================
실제 내용 wrapper 만들기
============================== */
function createContentWrapper( target, toggle ) {
/*
* 이미 만들었으면 재사용
*/
var existing =
target.querySelector(
':scope > .' + CONTENT_CLASS
);
if ( existing ) {
return existing;
}
/* --------------------------------
경우 1:
내용이 target 내부에 있음
-------------------------------- */
var internalNodes = [];
var node = toggle.nextSibling;
while ( node ) {
internalNodes.push( node );
node = node.nextSibling;
}
if ( internalNodes.length ) {
var internalWrapper =
document.createElement( 'div' );
internalWrapper.className =
CONTENT_CLASS;
internalNodes.forEach(
function ( child ) {
internalWrapper.appendChild(
child
);
}
);
target.appendChild(
internalWrapper
);
return internalWrapper;
}
/* --------------------------------
경우 2:
내용이 target 다음 형제에 있음
-------------------------------- */
var parent = target.parentNode;
if ( !parent ) {
return null;
}
var externalWrapper =
document.createElement( 'div' );
externalWrapper.className =
CONTENT_CLASS;
var sibling =
target.nextSibling;
var foundContent = false;
while ( sibling ) {
var nextSibling =
sibling.nextSibling;
/*
* 다음 customcollapsible을 만나면
* 현재 영역 종료
*/
if (
sibling.nodeType === 1 &&
isNextCollapsible( sibling )
) {
break;
}
/*
* 공백 텍스트는 무시
*/
if (
sibling.nodeType === 3 &&
!sibling.textContent.trim()
) {
sibling = nextSibling;
continue;
}
/*
* script / style은 건드리지 않음
*/
if (
sibling.nodeType === 1 &&
(
sibling.tagName === 'SCRIPT' ||
sibling.tagName === 'STYLE'
)
) {
break;
}
externalWrapper.appendChild(
sibling
);
foundContent = true;
sibling = nextSibling;
}
if ( !foundContent ) {
return null;
}
parent.insertBefore(
externalWrapper,
sibling
);
return externalWrapper;
}
/* ==============================
즉시 펼쳐진 상태 설정
============================== */
function setOpenImmediately(
target,
toggle,
content
) {
target.classList.remove(
'mw-collapsed'
);
target.classList.add(
OPEN_CLASS
);
content.style.display = '';
content.style.height = '';
content.style.overflow = '';
toggle.setAttribute(
'aria-expanded',
'true'
);
}
/* ==============================
즉시 접힌 상태 설정
============================== */
function setClosedImmediately(
target,
toggle,
content
) {
target.classList.add(
'mw-collapsed'
);
target.classList.remove(
OPEN_CLASS
);
content.style.display = 'none';
content.style.height = '';
content.style.overflow = '';
toggle.setAttribute(
'aria-expanded',
'false'
);
}
/* ==============================
펼치기 애니메이션
============================== */
function openContent(
target,
toggle,
content
) {
if (
content.classList.contains(
ANIMATING_CLASS
)
) {
return;
}
content.classList.add(
ANIMATING_CLASS
);
target.classList.remove(
'mw-collapsed'
);
content.style.display = 'block';
content.style.overflow = 'hidden';
content.style.height = '0px';
/*
* 브라우저가 0px 상태를 먼저
* 그리도록 한 프레임 기다림
*/
window.requestAnimationFrame(
function () {
var endHeight =
content.scrollHeight;
content.style.transition =
'height ' +
DURATION +
'ms ease';
/*
* 한 프레임을 더 나누어
* height transition이 확실하게 실행되게 함
*/
window.requestAnimationFrame(
function () {
content.style.height =
endHeight + 'px';
}
);
}
);
window.setTimeout(
function () {
content.classList.remove(
ANIMATING_CLASS
);
target.classList.add(
OPEN_CLASS
);
content.style.transition = '';
content.style.height = '';
content.style.overflow = '';
content.style.display = '';
toggle.setAttribute(
'aria-expanded',
'true'
);
},
DURATION + 40
);
}
/* ==============================
접기 애니메이션
============================== */
function closeContent(
target,
toggle,
content
) {
if (
content.classList.contains(
ANIMATING_CLASS
)
) {
return;
}
content.classList.add(
ANIMATING_CLASS
);
var startHeight =
content.getBoundingClientRect()
.height;
if ( startHeight <= 0 ) {
content.classList.remove(
ANIMATING_CLASS
);
setClosedImmediately(
target,
toggle,
content
);
return;
}
content.style.overflow = 'hidden';
content.style.height =
startHeight + 'px';
content.style.transition =
'height ' +
DURATION +
'ms ease';
/*
* 현재 높이를 브라우저에 먼저 반영
*/
content.offsetHeight;
window.requestAnimationFrame(
function () {
content.style.height =
'0px';
}
);
window.setTimeout(
function () {
content.classList.remove(
ANIMATING_CLASS
);
target.classList.remove(
OPEN_CLASS
);
target.classList.add(
'mw-collapsed'
);
content.style.display =
'none';
content.style.transition =
'';
content.style.height = '';
content.style.overflow = '';
toggle.setAttribute(
'aria-expanded',
'false'
);
},
DURATION + 40
);
}
/* ==============================
토글 실행
============================== */
function toggleContent( toggle ) {
var target =
getTarget( toggle );
if ( !target ) {
return;
}
var content =
target._customCollapseContent;
if ( !content ) {
content =
createContentWrapper(
target,
toggle
);
target._customCollapseContent =
content;
}
if ( !content ) {
return;
}
var isOpen =
toggle.getAttribute(
'aria-expanded'
) !== 'false' &&
!target.classList.contains(
'mw-collapsed'
);
if ( isOpen ) {
closeContent(
target,
toggle,
content
);
} else {
openContent(
target,
toggle,
content
);
}
}
/* ==============================
초기화
============================== */
function initializeToggle( toggle ) {
var target =
getTarget( toggle );
if ( !target ) {
return;
}
if (
target.classList.contains(
READY_CLASS
)
) {
return;
}
var content =
createContentWrapper(
target,
toggle
);
if ( !content ) {
return;
}
target._customCollapseContent =
content;
target.classList.add(
READY_CLASS
);
/*
* 최초 상태 판별
*/
var initiallyClosed =
target.classList.contains(
'mw-collapsed'
) ||
toggle.getAttribute(
'aria-expanded'
) === 'false';
if ( initiallyClosed ) {
setClosedImmediately(
target,
toggle,
content
);
} else {
setOpenImmediately(
target,
toggle,
content
);
}
}
function initializeAll() {
var toggles =
document.querySelectorAll(
'.mw-customtoggle'
);
toggles.forEach(
function ( toggle ) {
if (
getToggleName(
toggle
)
) {
initializeToggle(
toggle
);
}
}
);
}
/* ==============================
클릭 이벤트
============================== */
document.addEventListener(
'click',
function ( event ) {
var toggle =
event.target.closest(
'.mw-customtoggle'
);
if ( !toggle ) {
return;
}
if (
!getToggleName(
toggle
)
) {
return;
}
/*
* MediaWiki 기본 즉시 토글 차단
*/
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
toggleContent(
toggle
);
},
true
);
/* ==============================
키보드
============================== */
document.addEventListener(
'keydown',
function ( event ) {
if (
event.key !== 'Enter' &&
event.key !== ' '
) {
return;
}
var toggle =
event.target.closest(
'.mw-customtoggle'
);
if ( !toggle ) {
return;
}
if (
!getToggleName(
toggle
)
) {
return;
}
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
toggleContent(
toggle
);
},
true
);
/* ==============================
페이지 로드
============================== */
if (
document.readyState ===
'loading'
) {
document.addEventListener(
'DOMContentLoaded',
initializeAll
);
} else {
initializeAll();
}
/*
* MediaWiki 동적 콘텐츠 대응
*/
if (
window.mw &&
mw.hook
) {
mw.hook(
'wikipage.content'
).add(
function () {
initializeAll();
}
);
}
}() );