미디어위키:Common.js: 두 판 사이의 차이

편집 요약 없음
편집 요약 없음
1번째 줄: 1번째 줄:
/**
(function ($) {
* 식별자에 대응하는 실제 collapsible 대상 찾기
    'use strict';
*
* 동일한 id가 여러 번 사용되는 나무위키식/리브레위키식
* 둘러보기 틀 구조도 지원.
*
* 예:
*
* 1. 상단 버튼용
* <div class="mw-collapsible"
*      id="mw-customcollapsible-XXX">
*    <div class="mw-customtoggle-XXX">...</div>
* </div>
*
* 2. 실제 펼침 영역
* <div class="mw-collapsible mw-collapsed"
*      id="mw-customcollapsible-XXX">
*    <div class="mw-customtoggle-XXX">...</div>
*    <table>...</table>
* </div>
*
* → 2번을 선택
*/
function getTarget( name ) {
if ( !name ) {
return null;
}


var id =
    var DURATION = 300;
'mw-customcollapsible-' + name;


/*
    function getToggleName(toggle) {
* getElementById()를 사용하지 않는다.
        var prefix = 'mw-customtoggle-';
*
        var classes = toggle.classList;
* 같은 ID가 여러 개 존재하는 위키 문법을
        var i;
* 지원하기 위해 attribute selector로 전부 가져온다.
*/
var candidates =
document.querySelectorAll(
'[id="' +
escapeAttribute( id ) +
'"], .mw-customcollapsible-' +
escapeSelector( name )
);


if ( !candidates.length ) {
        for (i = 0; i < classes.length; i++) {
return null;
            if (classes[i].indexOf(prefix) === 0) {
}
                return classes[i].substring(prefix.length);
            }
        }


if ( candidates.length === 1 ) {
        return null;
return candidates[ 0 ];
    }
}


var bestTarget = null;
var bestScore = -1;
var i;


for ( i = 0; i < candidates.length; i++ ) {
    function findTarget(name) {
var candidate = candidates[ i ];
        var id = 'mw-customcollapsible-' + name;
var score = 0;
        var targets = document.querySelectorAll(
            '[id="' + id + '"]'
        );


/*
        if (!targets.length) {
* 실제 펼침 영역은 보통 mw-collapsed를 가지고 시작
            return null;
*/
        }
if (
candidate.classList.contains(
'mw-collapsed'
)
) {
score += 1000;
}


/*
        /*
* MediaWiki가 생성한 실제 콘텐츠
        * 실제 mw-collapsible-content를 가진 요소 우선
*/
        */
if (
        var i;
candidate.querySelector(
'.mw-collapsible-content'
)
) {
score += 500;
}


/*
        for (i = 0; i < targets.length; i++) {
* 실제 내용에 표가 존재하는 경우
            if (
*/
                getDirectContent(targets[i])
if (
            ) {
candidate.querySelector(
                return targets[i];
'table'
            }
)
        }
) {
score += 200;
}


/*
        return targets[0];
* wikitable
    }
*/
if (
candidate.querySelector(
'.wikitable'
)
) {
score += 200;
}


/*
* 내부 요소가 많을수록 실제 내용 영역일 가능성이 높음
*/
score +=
candidate.querySelectorAll( '*' ).length;


if ( score > bestScore ) {
    function getDirectContent(target) {
bestScore = score;
        var children = target.children;
bestTarget = candidate;
        var i;
}
}


return bestTarget;
        for (i = 0; i < children.length; i++) {
}
            if (
                children[i].classList.contains(
                    'mw-collapsible-content'
                )
            ) {
                return children[i];
            }
        }
 
        return null;
    }
 
 
    function toggle(toggle) {
        var name = getToggleName(toggle);
 
        if (!name) {
            return;
        }
 
        var target = findTarget(name);
 
        if (!target) {
            return;
        }
 
        var content = getDirectContent(target);
 
        if (!content) {
            return;
        }
 
        var $content = $(content);
 
        /*
        * 중복 애니메이션 방지
        */
        $content.stop(true, true);
 
        var collapsed =
            target.classList.contains('mw-collapsed') ||
            $content.css('display') === 'none';
 
 
        if (collapsed) {
 
            /*
            * 펼치기
            */
            target.classList.remove('mw-collapsed');
 
            $content
                .hide()
                .slideDown(DURATION);
 
            toggle.setAttribute(
                'aria-expanded',
                'true'
            );
 
        } else {
 
            /*
            * 접기
            */
            $content.slideUp(
                DURATION,
                function () {
                    target.classList.add(
                        'mw-collapsed'
                    );
                }
            );
 
            toggle.setAttribute(
                'aria-expanded',
                'false'
            );
        }
    }
 
 
    document.addEventListener(
        'click',
        function (event) {
            var toggleElement =
                event.target.closest(
                    '.mw-customtoggle'
                );
 
            if (!toggleElement) {
                return;
            }
 
            if (!getToggleName(toggleElement)) {
                return;
            }
 
            /*
            * MediaWiki 기본 클릭 동작 차단
            */
            event.preventDefault();
            event.stopPropagation();
            event.stopImmediatePropagation();
 
            toggle(toggleElement);
        },
        true
    );
 
 
    document.addEventListener(
        'keydown',
        function (event) {
            if (
                event.key !== 'Enter' &&
                event.key !== ' '
            ) {
                return;
            }
 
            var toggleElement =
                event.target.closest(
                    '.mw-customtoggle'
                );
 
            if (!toggleElement) {
                return;
            }
 
            if (!getToggleName(toggleElement)) {
                return;
            }
 
            event.preventDefault();
            event.stopPropagation();
            event.stopImmediatePropagation();
 
            toggle(toggleElement);
        },
        true
    );
 
}(jQuery));

2026년 8월 20일 (목) 14:04 판

(function ($) {
    'use strict';

    var DURATION = 300;

    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;
    }


    function findTarget(name) {
        var id = 'mw-customcollapsible-' + name;
        var targets = document.querySelectorAll(
            '[id="' + id + '"]'
        );

        if (!targets.length) {
            return null;
        }

        /*
         * 실제 mw-collapsible-content를 가진 요소 우선
         */
        var i;

        for (i = 0; i < targets.length; i++) {
            if (
                getDirectContent(targets[i])
            ) {
                return targets[i];
            }
        }

        return targets[0];
    }


    function getDirectContent(target) {
        var children = target.children;
        var i;

        for (i = 0; i < children.length; i++) {
            if (
                children[i].classList.contains(
                    'mw-collapsible-content'
                )
            ) {
                return children[i];
            }
        }

        return null;
    }


    function toggle(toggle) {
        var name = getToggleName(toggle);

        if (!name) {
            return;
        }

        var target = findTarget(name);

        if (!target) {
            return;
        }

        var content = getDirectContent(target);

        if (!content) {
            return;
        }

        var $content = $(content);

        /*
         * 중복 애니메이션 방지
         */
        $content.stop(true, true);

        var collapsed =
            target.classList.contains('mw-collapsed') ||
            $content.css('display') === 'none';


        if (collapsed) {

            /*
             * 펼치기
             */
            target.classList.remove('mw-collapsed');

            $content
                .hide()
                .slideDown(DURATION);

            toggle.setAttribute(
                'aria-expanded',
                'true'
            );

        } else {

            /*
             * 접기
             */
            $content.slideUp(
                DURATION,
                function () {
                    target.classList.add(
                        'mw-collapsed'
                    );
                }
            );

            toggle.setAttribute(
                'aria-expanded',
                'false'
            );
        }
    }


    document.addEventListener(
        'click',
        function (event) {
            var toggleElement =
                event.target.closest(
                    '.mw-customtoggle'
                );

            if (!toggleElement) {
                return;
            }

            if (!getToggleName(toggleElement)) {
                return;
            }

            /*
             * MediaWiki 기본 클릭 동작 차단
             */
            event.preventDefault();
            event.stopPropagation();
            event.stopImmediatePropagation();

            toggle(toggleElement);
        },
        true
    );


    document.addEventListener(
        'keydown',
        function (event) {
            if (
                event.key !== 'Enter' &&
                event.key !== ' '
            ) {
                return;
            }

            var toggleElement =
                event.target.closest(
                    '.mw-customtoggle'
                );

            if (!toggleElement) {
                return;
            }

            if (!getToggleName(toggleElement)) {
                return;
            }

            event.preventDefault();
            event.stopPropagation();
            event.stopImmediatePropagation();

            toggle(toggleElement);
        },
        true
    );

}(jQuery));