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

편집 요약 없음
편집 요약 없음
1번째 줄: 1번째 줄:
/* MediaWiki:Common.js */
/* MediaWiki:Common.js */
mw.hook('wikipage.content').add(function ($content) {
mw.hook('wikipage.content').add(function ($content) {
    /*
    * mw-customtoggle-* 하나마다 초기화
    */
    var initialized = {};
     $content.find('[class*="mw-customtoggle-"]').each(function () {
     $content.find('[class*="mw-customtoggle-"]').each(function () {
         var $toggle = $(this);
         var classList = (this.className || '').split(/\s+/);
        var classList = ($toggle.attr('class') || '').split(/\s+/);


         classList.forEach(function (cls) {
         classList.forEach(function (cls) {
10번째 줄: 15번째 줄:
             }
             }


             var suffix = cls.replace('mw-customtoggle-', '');
             var suffix = cls.substring('mw-customtoggle-'.length);
 
            if (initialized[suffix]) {
                return;
            }
            initialized[suffix] = true;
 
             var targetId = 'mw-customcollapsible-' + suffix;
             var targetId = 'mw-customcollapsible-' + suffix;


             /*
             /*
             * #id를 사용하지 않는 이유:
            * 현재 HTML에는 같은 id가 2개 있으므로
             * 현재 문서에 같은 id가 2개 존재하므로
             * #id selector를 사용하지 않음.
             * 실제 접히는 영역을 정확히 찾아야 함.
             */
            var $sameIds = $content.find('[id="' + targetId + '"]');
 
            /*
             * 실제 펼쳐지는 패널:
            * wikitable을 포함하고 있는 쪽.
             */
             */
             var $targets = $content.find('[id="' + targetId + '"]');
             var $panel = $sameIds.filter(function () {
                return $(this).find('table.wikitable').length > 0;
            }).first();
 
            if (!$panel.length) {
                return;
            }


             // 실제 내용이 들어 있는 collapsible 영역 선택
             /*
             var $target = $targets.filter(function () {
            * 위쪽 버튼을 감싸고 있는 wrapper.
                 return $(this).find('table').length > 0 ||
            *
                      $(this).hasClass('mw-collapsed') ||
            * 실제 패널이 아닌 동일 ID 요소를 찾는다.
                      $(this).css('display') === 'none';
            */
             var $topWrapper = $sameIds.not($panel).filter(function () {
                 return $(this).find('.' + cls).length > 0;
             }).first();
             }).first();


             if (!$target.length) {
            var $topToggle = $topWrapper.find('.' + cls).first();
            var $panelToggle = $panel.find('.' + cls).first();
 
             if (!$topToggle.length || !$panelToggle.length) {
                 return;
                 return;
             }
             }


             $toggle
             /*
                .off('click.smoothSlide')
            * 남성/여성 패널과 하단 "전직 아나운서" 표가
                .on('click.smoothSlide', function (e) {
            * 들어 있는 공통 영역
                    /*
            */
                    * MediaWiki 기본 mw-collapsible 핸들러와
            var $area = $panel.parent();
                    * slideToggle이 동시에 실행되는 것을 방지
 
                    */
            /*
                    e.preventDefault();
            * 펼쳐진 패널들을 쌓아놓을 공간 생성
                    e.stopImmediatePropagation();
            */
            var $stack = $area.children('.smooth-collapsible-stack');
 
            if (!$stack.length) {
                $stack = $('<div class="smooth-collapsible-stack"></div>');


                    var $contentTarget = $target.children('.mw-collapsible-content');
                /*
                    var $animTarget = $contentTarget.length
                * 맨 아래의 "전직 아나운서" 표 바로 위에 배치
                        ? $contentTarget
                */
                        : $target;
                var $footer = $area.children('table').last();


                     var isOpening = !$animTarget.is(':visible');
                if ($footer.length) {
                    $stack.insertBefore($footer);
                } else {
                     $stack.appendTo($area);
                }
            }


                    $animTarget
            /*
                        .stop(true, true)
            * 최초 상태에서는 패널을 stack 안으로 이동.
                        .slideToggle(200, function () {
            * 접힌 상태는 유지.
                            if ($(this).is(':visible')) {
            */
                                /*
            $panel
                                * slideToggle이 남기는 height, padding 등의
                .appendTo($stack)
                                * 임시 스타일 정리.
                .hide();
                                *
 
                                * display는 현재 구조에서는 지우지 않는 편이 안전함.
            /*
                                */
            * MediaWiki 기본 클릭 핸들러가 slideToggle과
                                $(this).css({
            * 충돌하지 않도록 이 토글들의 기존 click 이벤트 제거.
                                    height: '',
            */
                                    overflow: '',
            $topToggle.off('click');
                                    paddingTop: '',
            $panelToggle.off('click');
                                    paddingBottom: '',
 
                                    marginTop: '',
 
                                    marginBottom: ''
            /*
                                });
            * ─────────────────────────────
                            }
            * 위쪽 버튼 클릭 → 펼치기
            * ─────────────────────────────
            */
            $topToggle.on('click.smoothSlide', function (e) {
                e.preventDefault();
                e.stopPropagation();
 
                if ($panel.is(':visible')) {
                    return false;
                }
 
                /*
                * 위쪽 버튼은 자리 자체는 유지하면서
                * 화면에서만 사라지게 한다.
                *
                * display:none을 사용하면 여성 버튼 등이
                * 왼쪽으로 이동하기 때문에 visibility 사용.
                */
                $topWrapper.css('visibility', 'hidden');
 
                /*
                * 클릭한 순서대로 맨 아래에 쌓는다.
                */
                $panel.appendTo($stack);
 
                $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.stopPropagation();
                $panel
                    .stop(true, true)
                    .slideUp(200, function () {
                        /*
                        * 위쪽의 원래 버튼 복귀
                        */
                        $topWrapper.css('visibility', 'visible');
                        $(this).css({
                            height: '',
                            overflow: '',
                            paddingTop: '',
                            paddingBottom: '',
                            marginTop: '',
                            marginBottom: ''
                        });
                    });
                $topToggle.attr('aria-expanded', 'false');
                $panelToggle.attr('aria-expanded', 'false');


                    // 접근성 상태도 같이 갱신
                return false;
                    $('[class~="' + cls + '"]').attr(
            });
                        'aria-expanded',
                        isOpening ? 'true' : 'false'
                    );
                });
         });
         });
     });
     });
});
});

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

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

    /*
     * mw-customtoggle-* 하나마다 초기화
     */
    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;

            /*
             * 현재 HTML에는 같은 id가 2개 있으므로
             * #id 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.
             *
             * 실제 패널이 아닌 동일 ID 요소를 찾는다.
             */
            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;
            }

            /*
             * 남성/여성 패널과 하단 "전직 아나운서" 표가
             * 들어 있는 공통 영역
             */
            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);
                }
            }

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

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


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

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

                /*
                 * 위쪽 버튼은 자리 자체는 유지하면서
                 * 화면에서만 사라지게 한다.
                 *
                 * display:none을 사용하면 여성 버튼 등이
                 * 왼쪽으로 이동하기 때문에 visibility 사용.
                 */
                $topWrapper.css('visibility', 'hidden');

                /*
                 * 클릭한 순서대로 맨 아래에 쌓는다.
                 */
                $panel.appendTo($stack);

                $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.stopPropagation();

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

                        /*
                         * 위쪽의 원래 버튼 복귀
                         */
                        $topWrapper.css('visibility', 'visible');

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

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

                return false;
            });
        });
    });
});