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

편집 요약 없음
편집 요약 없음
2번째 줄: 2번째 줄:
mw.hook('wikipage.content').add(function ($content) {
mw.hook('wikipage.content').add(function ($content) {


    /*
    * mw-customtoggle-* 하나마다 초기화
    */
     var initialized = {};
     var initialized = {};


20번째 줄: 17번째 줄:
                 return;
                 return;
             }
             }
             initialized[suffix] = true;
             initialized[suffix] = true;


25번째 줄: 23번째 줄:


             /*
             /*
             * 현재 HTML에는 같은 id가 2개 있으므로
             * 동일 id가 2개 존재하므로 #id를 쓰지 않고
             * #id selector를 사용하지 않음.
             * attribute selector로 모두 찾음.
             */
             */
             var $sameIds = $content.find('[id="' + targetId + '"]');
             var $sameIds = $content.find('[id="' + targetId + '"]');


             /*
             /*
             * 실제 펼쳐지는 패널:
             * wikitable이 들어 있는 쪽이 실제 펼쳐질 내용.
            * wikitable을 포함하고 있는 쪽.
             */
             */
             var $panel = $sameIds.filter(function () {
             var $panel = $sameIds.filter(function () {
43번째 줄: 40번째 줄:


             /*
             /*
             * 위쪽 버튼을 감싸고 있는 wrapper.
             * 나머지 하나는 상단 버튼 wrapper.
            *
            * 실제 패널이 아닌 동일 ID 요소를 찾는다.
             */
             */
             var $topWrapper = $sameIds.not($panel).filter(function () {
             var $topWrapper = $sameIds.not($panel).filter(function () {
59번째 줄: 54번째 줄:


             /*
             /*
             * 남성/여성 패널과 하단 "전직 아나운서" 표가
            * 중요:
             * 들어 있는 공통 영역
            * 패널을 다른 곳으로 append하지 않는다.
            *
            * DOM 원래 순서
            *
             * 남성 버튼
            * 남성 패널
            * 여성 버튼
            * 여성 패널
            *
             * 를 그대로 유지해야 다음 버튼이 아래로 밀린다.
             */
             */
            var $area = $panel.parent();
            /*
            * 펼쳐진 패널들을 쌓아놓을 공간 생성
            */
            var $stack = $area.children('.smooth-collapsible-stack');
            if (!$stack.length) {
                $stack = $('<div class="smooth-collapsible-stack"></div>');
                /*
                * 맨 아래의 "전직 아나운서" 표 바로 위에 배치
                */
                var $footer = $area.children('table').last();
                if ($footer.length) {
                    $stack.insertBefore($footer);
                } else {
                    $stack.appendTo($area);
                }
            }


            /*
             $panel.hide();
            * 최초 상태에서는 패널을 stack 안으로 이동.
            * 접힌 상태는 유지.
            */
             $panel
                .appendTo($stack)
                .hide();


             /*
             /*
             * MediaWiki 기본 클릭 핸들러가 slideToggle과
             * MediaWiki 기본 토글 이벤트 제거
            * 충돌하지 않도록 이 토글들의 기존 click 이벤트 제거.
             */
             */
             $topToggle.off('click');
             $topToggle.off('click');
101번째 줄: 77번째 줄:


             /*
             /*
             * ─────────────────────────────
             * ==========================
             * 위쪽 버튼 클릭 → 펼치기
             * 위쪽 버튼 → 펼치기
             * ─────────────────────────────
             * ==========================
             */
             */
             $topToggle.on('click.smoothSlide', function (e) {
             $topToggle.on('click.smoothSlide', function (e) {
                 e.preventDefault();
                 e.preventDefault();
                 e.stopPropagation();
                 e.stopImmediatePropagation();


                 if ($panel.is(':visible')) {
                 if ($panel.is(':visible')) {
114번째 줄: 90번째 줄:


                 /*
                 /*
                 * 위쪽 버튼은 자리 자체는 유지하면서
                 * 이번에는 visibility:hidden이 아니라
                 * 화면에서만 사라지게 한다.
                 * display:none을 사용한다.
                 *
                 *
                 * display:none을 사용하면 여성 버튼 등이
                 * 그래야 남성 버튼이 차지하던 공간까지 없어지고
                 * 왼쪽으로 이동하기 때문에 visibility 사용.
                 * 그 뒤의 여성 버튼이 남성 내용 아래로 이동한다.
                 */
                 */
                 $topWrapper.css('visibility', 'hidden');
                 $topWrapper.hide();


                 /*
                 /*
                 * 클릭한 순서대로 맨 아래에 쌓는다.
                 * 패널은 원래 DOM 위치에서 그대로 펼침.
                 */
                 */
                $panel.appendTo($stack);
                 $panel
                 $panel
                     .stop(true, true)
                     .stop(true, true)
148번째 줄: 122번째 줄:


             /*
             /*
             * ─────────────────────────────
             * ==========================
             * 아래쪽 버튼 클릭 → 접기
             * 펼쳐진 쪽 버튼 → 접기
             * ─────────────────────────────
             * ==========================
             */
             */
             $panelToggle.on('click.smoothSlide', function (e) {
             $panelToggle.on('click.smoothSlide', function (e) {
                 e.preventDefault();
                 e.preventDefault();
                 e.stopPropagation();
                 e.stopImmediatePropagation();


                 $panel
                 $panel
161번째 줄: 135번째 줄:


                         /*
                         /*
                         * 위쪽의 원래 버튼 복귀
                         * 패널이 다 접힌 뒤
                        * 원래 상단 버튼을 다시 표시.
                         */
                         */
                         $topWrapper.css('visibility', 'visible');
                         $topWrapper.show();


                         $(this).css({
                         $(this).css({
180번째 줄: 155번째 줄:
                 return false;
                 return false;
             });
             });
         });
         });
     });
     });
});
});

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

/* MediaWiki:Common.js */
mw.hook('wikipage.content').add(function ($content) {

    var initialized = {};

    $content.find('[class*="mw-customtoggle-"]').each(function () {
        var classList = (this.className || '').split(/\s+/);

        classList.forEach(function (cls) {
            if (cls.indexOf('mw-customtoggle-') !== 0) {
                return;
            }

            var suffix = cls.substring('mw-customtoggle-'.length);

            if (initialized[suffix]) {
                return;
            }

            initialized[suffix] = true;

            var targetId = 'mw-customcollapsible-' + suffix;

            /*
             * 동일 id가 2개 존재하므로 #id를 쓰지 않고
             * attribute selector로 모두 찾음.
             */
            var $sameIds = $content.find('[id="' + targetId + '"]');

            /*
             * wikitable이 들어 있는 쪽이 실제 펼쳐질 내용.
             */
            var $panel = $sameIds.filter(function () {
                return $(this).find('table.wikitable').length > 0;
            }).first();

            if (!$panel.length) {
                return;
            }

            /*
             * 나머지 하나는 상단 버튼 wrapper.
             */
            var $topWrapper = $sameIds.not($panel).filter(function () {
                return $(this).find('.' + cls).length > 0;
            }).first();

            var $topToggle = $topWrapper.find('.' + cls).first();
            var $panelToggle = $panel.find('.' + cls).first();

            if (!$topToggle.length || !$panelToggle.length) {
                return;
            }

            /*
             * 중요:
             * 패널을 다른 곳으로 append하지 않는다.
             *
             * DOM 원래 순서
             *
             * 남성 버튼
             * 남성 패널
             * 여성 버튼
             * 여성 패널
             *
             * 를 그대로 유지해야 다음 버튼이 아래로 밀린다.
             */

            $panel.hide();

            /*
             * MediaWiki 기본 토글 이벤트 제거
             */
            $topToggle.off('click');
            $panelToggle.off('click');


            /*
             * ==========================
             * 위쪽 버튼 → 펼치기
             * ==========================
             */
            $topToggle.on('click.smoothSlide', function (e) {
                e.preventDefault();
                e.stopImmediatePropagation();

                if ($panel.is(':visible')) {
                    return false;
                }

                /*
                 * 이번에는 visibility:hidden이 아니라
                 * display:none을 사용한다.
                 *
                 * 그래야 남성 버튼이 차지하던 공간까지 없어지고
                 * 그 뒤의 여성 버튼이 남성 내용 아래로 이동한다.
                 */
                $topWrapper.hide();

                /*
                 * 패널은 원래 DOM 위치에서 그대로 펼침.
                 */
                $panel
                    .stop(true, true)
                    .slideDown(200, function () {
                        $(this).css({
                            height: '',
                            overflow: '',
                            paddingTop: '',
                            paddingBottom: '',
                            marginTop: '',
                            marginBottom: ''
                        });
                    });

                $topToggle.attr('aria-expanded', 'true');
                $panelToggle.attr('aria-expanded', 'true');

                return false;
            });


            /*
             * ==========================
             * 펼쳐진 쪽 버튼 → 접기
             * ==========================
             */
            $panelToggle.on('click.smoothSlide', function (e) {
                e.preventDefault();
                e.stopImmediatePropagation();

                $panel
                    .stop(true, true)
                    .slideUp(200, function () {

                        /*
                         * 패널이 다 접힌 뒤
                         * 원래 상단 버튼을 다시 표시.
                         */
                        $topWrapper.show();

                        $(this).css({
                            height: '',
                            overflow: '',
                            paddingTop: '',
                            paddingBottom: '',
                            marginTop: '',
                            marginBottom: ''
                        });
                    });

                $topToggle.attr('aria-expanded', 'false');
                $panelToggle.attr('aria-expanded', 'false');

                return false;
            });

        });
    });

});