문서 편집 권한이 없습니다. 다음 이유를 확인해주세요: 이 문서는 이 위키의 소프트웨어 인터페이스에 쓰이는 문서로, 부정 행위를 막기 위해 보호되어 있습니다. 모든 위키에 대한 번역을 추가하거나 바꾸려면 미디어위키 지역화 프로젝트인 translatewiki.net에 참여하시기 바랍니다.모든 방문자에게 영향을 미칠 수 있기 때문에 이 자바스크립트 문서의 편집 권한이 없습니다. 문서의 원본을 보거나 복사할 수 있습니다. /* All JavaScript here will be loaded for users of the MinervaNeue skin */ /* 가온 위키 Minerva Neue 전용 커스텀 메뉴 * - PC/모바일 공통 * - Minerva 기본 메뉴와 같은 구조/클래스 사용 * (toggle-list__list / toggle-list-item / toggle-list-item__anchor / * minerva-icon / toggle-list-item__label) * - 상위 그룹(게시판, 버그/기능 개선, 도구, 도움말)은 접고 펼칠 수 있음 * - "파일 올리기" 아래에 3단계 메뉴 포함 */ ( function ( mw, $ ) { 'use strict'; // Minerva 스킨이 아닐 때는 아무 것도 하지 않는다. if ( mw.config.get( 'skin' ) !== 'minerva' ) { return; } /* ------------------------------------------------- * 1. 메뉴 설정 (질문에서 주신 내용을 JS 객체로 변환) * ------------------------------------------------- */ // icon 필드에는 Minerva 메뉴에서 사용하는 // `minerva-icon minerva-icon--XXX` 의 XXX 부분만 넣는다. // 예: icon: 'minerva-icon--speechBubbles' var gaonMenuConfig = [ { // 게시판 그룹 label: '게시판', icon: 'minerva-icon--speechBubbles', children: [ { label: '위키방', href: 'https://bbs.gaonwiki.com', title: 'https://bbs.gaonwiki.com', icon: 'minerva-icon--speechBubbles' }, { label: '저작권 처리 게시판', href: 'https://bbs.gaonwiki.com/copyrights', title: 'https://bbs.gaonwiki.com/copyrights', icon: 'minerva-icon--speechBubbles' }, { label: '자유게시판', href: 'https://bbs.gaonwiki.com/free', title: 'https://bbs.gaonwiki.com/free', icon: 'minerva-icon--speechBubbles' } ] }, { // 버그/기능 개선 그룹 label: '버그/기능 개선', icon: 'minerva-icon--die', children: [ { label: '이슈 등록', href: 'https://bbs.gaonwiki.com/issue', title: 'https://bbs.gaonwiki.com/issue', icon: 'minerva-icon--die' }, { label: '기능 구현 도움', href: 'https://www.gaonwiki.com/w/%EA%B0%80%EC%98%A8_%EC%9C%84%ED%82%A4:%EA%B8%B0%EB%8A%A5_%EA%B5%AC%ED%98%84_%EB%B6%88%EA%B0%80-%EB%88%84%EA%B0%80_%ED%95%B4%EA%B2%B0%EC%B1%85%EC%9D%84_%EC%95%8C%EB%A0%A4%EC%A3%BC%EC%84%B8%EC%9A%94!', title: 'https://www.gaonwiki.com/w/가온_위키:기능_구현_불가-누가_해결책을_알려주세요!', icon: 'minerva-icon--speechBubbles' }, { label: '알려진 문제들', href: 'https://www.gaonwiki.com/w/%EA%B0%80%EC%98%A8_%EC%9C%84%ED%82%A4/%EC%95%8C%EB%A0%A4%EC%A7%84_%EB%AC%B8%EC%A0%9C%EB%93%A4', title: 'https://www.gaonwiki.com/w/가온_위키/알려진_문제들', icon: 'minerva-icon--recentChanges' } ] }, { // 도구 그룹 label: '도구', icon: 'minerva-icon--specialPages', children: [ { label: '특수 문서 목록', href: mw.util.getUrl( '특수:특수문서' ), title: '특수:특수문서', icon: 'minerva-icon--specialPages' }, { // "파일 올리기" (3단계 메뉴를 가진 항목) label: '파일 올리기', href: '#', // 드롭다운 전용이므로 실제 링크는 없음 title: '파일 올리기', icon: 'minerva-icon--specialPages', children: [ { label: '(기존) 업로드', href: mw.util.getUrl( '특수:올리기' ), title: '특수:올리기', icon: 'minerva-icon--specialPages' }, { label: '(신규) 업로드 마법사', href: mw.util.getUrl( '특수:UploadWizard' ), title: '특수:UploadWizard', icon: 'minerva-icon--specialPages' } ] }, { label: '이슈 트래커', href: 'https://bbs.gaonwiki.com/issue/', title: 'https://bbs.gaonwiki.com/issue/', icon: 'minerva-icon--die' }, { label: '가온 위키 베타', href: 'https://beta.gaonwiki.com', title: 'https://beta.gaonwiki.com', icon: 'minerva-icon--specialPages' } ] }, { // 도움말 그룹 label: '도움말', icon: 'minerva-icon--specialPages', children: [ { label: '위키 문법', href: mw.util.getUrl( '도움말:위키_문법' ), title: '도움말:위키_문법', icon: 'minerva-icon--specialPages' }, { label: '설명서', href: mw.util.getUrl( '도움말:설명서' ), title: '도움말:설명서', icon: 'minerva-icon--specialPages' } ] } ]; /* ------------------------------------------------- * 2. DOM 생성 유틸리티 * ------------------------------------------------- */ /** * Minerva 스타일의 아이콘 <span> 요소를 생성한다. * * @param {string} iconClass "minerva-icon--XXX" 형식의 클래스 * @return {jQuery} */ function buildIcon( iconClass ) { var $icon = $( '<span>' ).addClass( 'minerva-icon' ); if ( iconClass ) { $icon.addClass( iconClass ); } return $icon; } /** * 메뉴 라벨 <span> 요소를 생성한다. * * @param {string} text 화면에 보일 텍스트 * @return {jQuery} */ function buildLabel( text ) { return $( '<span>' ) .addClass( 'toggle-list-item__label' ) .text( text || '' ); } /** * Minerva 스타일의 <a> 요소를 생성한다. * * @param {string} href 링크 URL (없으면 '#') * @param {string} title title 속성 * @return {jQuery} */ function buildAnchor( href, title ) { return $( '<a>' ) .addClass( 'toggle-list-item__anchor gaon-menu-link' ) .attr( 'href', href || '#' ) .attr( 'title', title || '' ); } /** * 하위 메뉴 항목(레벨 2, 3)을 재귀적으로 생성하여 <ul> 안에 추가한다. * * @param {jQuery} $ul 현재 레벨의 <ul> * @param {Object} item 메뉴 정의 객체 * @param {number} level 레벨 번호(2, 3, ...) */ function appendGaonMenuItem( $ul, item, level ) { var hasChildren = Array.isArray( item.children ) && item.children.length > 0; // <li> 생성 var $li = $( '<li>' ) .addClass( 'toggle-list-item gaon-menu-item gaon-menu-item-level' + level ); if ( hasChildren ) { $li.addClass( 'gaon-menu-item--has-children gaon-menu-item--collapsed' ); } // <a> 생성 var $a = buildAnchor( item.href, item.title || item.label ); $a.append( buildIcon( item.icon ) ); $a.append( buildLabel( item.label ) ); $li.append( $a ); $ul.append( $li ); // 하위 레벨이 있으면 <ul> 을 만들어 재귀 호출 if ( hasChildren ) { var nextLevel = level + 1; var $subUl = $( '<ul>' ) .addClass( 'gaon-menu gaon-menu-level' + nextLevel ); item.children.forEach( function ( child ) { appendGaonMenuItem( $subUl, child, nextLevel ); } ); // 이 부분이 중요: // 하위 <ul> 은 반드시 <li> 안에 들어가야 한다. $li.append( $subUl ); } } /** * 한 개의 상위 그룹(게시판 / 버그/기능 개선 / 도구 / 도움말)을 * Minerva 스타일의 <ul> 블록으로 생성한다. * * @param {Object} group 그룹 정의 * @param {number} index 그룹 index * @return {jQuery} 완성된 <ul> 요소 */ function buildGroup( group, index ) { // Minerva 기본 메뉴와 같은 class 사용 var $level1 = $( '<ul>' ) .addClass( 'toggle-list__list gaon-menu gaon-menu-level1' ) .attr( 'data-gaon-group-index', index ); var hasChildren = Array.isArray( group.children ) && group.children.length > 0; // 헤더 <li> var $headerLi = $( '<li>' ) .addClass( 'toggle-list-item gaon-menu-header gaon-menu-header--collapsed' ); var $headerA = buildAnchor( '#', group.label ); $headerA .addClass( 'gaon-menu-header__anchor' ) .append( buildIcon( group.icon ) ) .append( buildLabel( group.label ) ); $headerLi.append( $headerA ); // 그룹에 하위 항목이 있으면 level2 <ul> 생성 if ( hasChildren ) { var $level2 = $( '<ul>' ) .addClass( 'gaon-menu gaon-menu-level2' ); group.children.forEach( function ( item ) { appendGaonMenuItem( $level2, item, 2 ); } ); // 헤더 <li> 안에 하위 <ul> 을 넣는다. $headerLi.append( $level2 ); } $level1.append( $headerLi ); return $level1; } /* ------------------------------------------------- * 3. 메뉴를 실제 Minerva 햄버거 메뉴 안에 삽입 * ------------------------------------------------- */ /** * 가온 메뉴를 Minerva 왼쪽 메뉴에 삽입한다. */ function insertGaonMenuIntoMinerva() { // 기본 내비게이션 블록(대문/임의의 문서로)이 들어 있는 첫 번째 toggle-list__list 를 찾는다. var $firstList = $( '#p-navigation.toggle-list__list' ).first(); // 혹시 id 가 다르다면 fallback: 메뉴 안의 첫 toggle-list__list if ( !$firstList.length ) { $firstList = $( '#mw-mf-page-left .toggle-list__list' ).first(); } if ( !$firstList.length ) { return; } // 중복 삽입 방지 if ( $firstList.data( 'gaonMenuInjected' ) ) { return; } $firstList.data( 'gaonMenuInjected', true ); // 여러 그룹을 한 번에 생성하여 첫 번째 리스트 뒤에 삽입 var $allGroups = $( [] ); gaonMenuConfig.forEach( function ( group, index ) { $allGroups = $allGroups.add( buildGroup( group, index ) ); } ); $firstList.after( $allGroups ); // 모든 하위 레벨을 기본적으로 숨긴다. $( '.gaon-menu-level2, .gaon-menu-level3' ).hide(); // 상위 그룹 헤더 클릭 시 level2 토글 $( '.gaon-menu-header__anchor' ).on( 'click', function ( e ) { e.preventDefault(); var $headerLi = $( this ).closest( '.gaon-menu-header' ); var $sub = $headerLi.children( '.gaon-menu-level2' ); if ( !$sub.length ) { return; } $headerLi.toggleClass( 'gaon-menu-header--collapsed' ); $sub.slideToggle( 150 ); } ); // "파일 올리기"처럼 children 이 있는 2단계 항목 클릭 시 level3 토글 $( '.gaon-menu-item--has-children > .gaon-menu-link' ).on( 'click', function ( e ) { e.preventDefault(); var $li = $( this ).closest( '.gaon-menu-item--has-children' ); var $sub = $li.children( '.gaon-menu-level3' ); if ( !$sub.length ) { return; } $li.toggleClass( 'gaon-menu-item--collapsed' ); $sub.slideToggle( 150 ); } ); } /* ------------------------------------------------- * 4. 메뉴 HTML 로드 완료를 기다렸다가 삽입 * ------------------------------------------------- */ var maxAttempts = 50; // 최대 50번(약 5초 정도) 시도 var attemptCount = 0; function waitForMinervaMenu() { var $firstList = $( '#mw-mf-page-left .toggle-list__list' ).first(); if ( $firstList.length ) { insertGaonMenuIntoMinerva(); } else if ( attemptCount < maxAttempts ) { attemptCount += 1; setTimeout( waitForMinervaMenu, 100 ); } } $( waitForMinervaMenu ); }( mediaWiki, jQuery ) ); 미디어위키:Minerva.js 문서로 돌아갑니다.