미디어위키:Common.js

신사 (토론 | 기여)님의 2026년 8월 20일 (목) 13:45 판

참고: 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.

  • 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
  • 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
  • 인터넷 익스플로러 / 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
  • 오페라: Ctrl-F5를 입력.
/**
 * 이 스크립트는 위키백과 전체에 적용됩니다. 고칠 때는 주의해주세요.
 * [[위키백과:위키프로젝트 시스템]] 참고
 *
 * 스크립트를 넣을 때는 충분한 설명, 출처를 넣어주세요! 이후 관리가 어려워집니다.
 **/

mw.loader.using( ['mediawiki.util', 'mediawiki.notify', 'jquery.client'], function () {
/* Begin of mw.loader.using callback */

/**
 * Map addPortletLink to mw.util
 *
 * @deprecated: Use mw.util.addPortletLink instead.
 */
mw.log.deprecate(
	window,
	'addPortletLink',
	mw.util.addPortletLink,
	'Use mw.util.addPortletLink instead'
);

/**
 * Extract a URL parameter from the current URL
 *
 * @deprecated: Use mw.util.getParamValue with proper escaping
 */
mw.log.deprecate(
	window,
	'getURLParamValue',
	mw.util.getParamValue,
	'Use mw.util.getParamValue instead'
);

/**
 * Test if an element has a certain class
 *
 * @deprecated: Use $(element).hasClass() instead.
 */
mw.log.deprecate(
	window,
	'hasClass',
	function ( element, className ) {
		return $( element ).hasClass( className );
	},
	'Use jQuery.hasClass() instead'
);

/**
 * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
 * @rev 5
 */

// CSS
var extraCSS = mw.util.getParamValue( 'withCSS' );

if ( extraCSS ) {
	if ( extraCSS.match( /^MediaWiki:[^&<>=%#]*\.css$/ ) ) {
		importStylesheet( extraCSS );
	} else {
		mw.notify(
			'Only pages from the MediaWiki namespace are allowed.',
			{
				title: 'Invalid withCSS value'
			}
		);
	}
}

// JS
var extraJS = mw.util.getParamValue( 'withJS' );

if ( extraJS ) {
	if ( extraJS.match( /^MediaWiki:[^&<>=%#]*\.js$/ ) ) {
		importScript( extraJS );
	} else {
		mw.notify(
			'Only pages from the MediaWiki namespace are allowed.',
			{
				title: 'Invalid withJS value'
			}
		);
	}
}

/**
 * Import more specific scripts if necessary
 */

if ( mw.config.get( 'wgNamespaceNumber' ) === 6 ) {
	/* file description page scripts */
	importScript( 'MediaWiki:Common.js/file.js' );
}

/* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */
/** Collapsible tables *******************************************************
 *
 * Description: Allows tables to be collapsed, showing only the header. See
 *              [[:en:Wikipedia:NavFrame]].
 * Maintainers: [[:en:User:R. Koot]]
 */

var autoCollapse = 2;
var collapseCaption = '숨기기';
var expandCaption = '보이기';

window.collapseTable = function ( tableIndex ) {
	var Button = document.getElementById(
		'collapseButton' + tableIndex
	);

	var Table = document.getElementById(
		'collapsibleTable' + tableIndex
	);

	if ( !Table || !Button ) {
		return false;
	}

	var Rows = Table.rows;
	var i;

	if ( Button.firstChild.data === collapseCaption ) {

		for ( i = 1; i < Rows.length; i++ ) {
			Rows[ i ].style.display = 'none';
		}

		Button.firstChild.data = expandCaption;

	} else {

		for ( i = 1; i < Rows.length; i++ ) {
			Rows[ i ].style.display =
				Rows[ 0 ].style.display;
		}

		Button.firstChild.data = collapseCaption;
	}
};

function createCollapseButtons() {
	var tableIndex = 0;
	var NavigationBoxes = {};
	var Tables = document.getElementsByTagName( 'table' );
	var i;

	function handleButtonLink( index, e ) {
		window.collapseTable( index );
		e.preventDefault();
	}

	for ( i = 0; i < Tables.length; i++ ) {

		if ( $( Tables[ i ] ).hasClass( 'collapsible' ) ) {

			/*
			 * only add button and increment count
			 * if there is a header row to work with
			 */
			var HeaderRow =
				Tables[ i ].getElementsByTagName( 'tr' )[ 0 ];

			if ( !HeaderRow ) {
				continue;
			}

			var Header =
				HeaderRow.getElementsByTagName( 'th' )[ 0 ];

			if ( !Header ) {
				continue;
			}

			NavigationBoxes[ tableIndex ] = Tables[ i ];

			Tables[ i ].setAttribute(
				'id',
				'collapsibleTable' + tableIndex
			);

			var Button =
				document.createElement( 'span' );

			var ButtonLink =
				document.createElement( 'a' );

			var ButtonText =
				document.createTextNode(
					collapseCaption
				);

			/*
			 * Styles are declared in Common.css
			 */
			Button.className = 'collapseButton';

			ButtonLink.style.color =
				Header.style.color;

			ButtonLink.setAttribute(
				'id',
				'collapseButton' + tableIndex
			);

			ButtonLink.setAttribute(
				'href',
				'#'
			);

			$( ButtonLink ).on(
				'click',
				$.proxy(
					handleButtonLink,
					ButtonLink,
					tableIndex
				)
			);

			ButtonLink.appendChild(
				ButtonText
			);

			Button.appendChild(
				document.createTextNode( '[' )
			);

			Button.appendChild(
				ButtonLink
			);

			Button.appendChild(
				document.createTextNode( ']' )
			);

			Header.insertBefore(
				Button,
				Header.firstChild
			);

			tableIndex++;
		}
	}

	for ( i = 0; i < tableIndex; i++ ) {

		if (
			$( NavigationBoxes[ i ] ).hasClass( 'collapsed' ) ||
			(
				tableIndex >= autoCollapse &&
				$( NavigationBoxes[ i ] ).hasClass( 'autocollapse' )
			)
		) {

			window.collapseTable( i );

		} else if (
			$( NavigationBoxes[ i ] ).hasClass( 'innercollapse' )
		) {

			var element =
				NavigationBoxes[ i ];

			while (
				( element = element.parentNode )
			) {

				if (
					$( element ).hasClass( 'outercollapse' )
				) {

					window.collapseTable( i );
					break;
				}
			}
		}
	}
}

mw.hook( 'wikipage.content' ).add(
	createCollapseButtons
);

/* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */
/** Dynamic Navigation Bars (experimental) **********************************
 *
 * Description: See [[:en:Wikipedia:NavFrame]].
 * Maintainers: UNMAINTAINED
 */

/* set up the words in your language */
var NavigationBarHide =
	'[' + collapseCaption + ']';

var NavigationBarShow =
	'[' + expandCaption + ']';

/**
 * Shows and hides content and picture
 * (if available) of navigation bars
 *
 * Parameters:
 * indexNavigationBar:
 * the index of navigation bar to be toggled
 */
window.toggleNavigationBar =
	function ( indexNavigationBar, event ) {

		var NavToggle =
			document.getElementById(
				'NavToggle' + indexNavigationBar
			);

		var NavFrame =
			document.getElementById(
				'NavFrame' + indexNavigationBar
			);

		var NavChild;

		if ( !NavFrame || !NavToggle ) {
			return false;
		}

		/*
		 * if shown now
		 */
		if (
			NavToggle.firstChild.data ===
			NavigationBarHide
		) {

			for (
				NavChild = NavFrame.firstChild;
				NavChild !== null;
				NavChild = NavChild.nextSibling
			) {

				if (
					$( NavChild ).hasClass( 'NavContent' ) ||
					$( NavChild ).hasClass( 'NavPic' )
				) {

					NavChild.style.display =
						'none';
				}
			}

			NavToggle.firstChild.data =
				NavigationBarShow;

		/*
		 * if hidden now
		 */
		} else if (
			NavToggle.firstChild.data ===
			NavigationBarShow
		) {

			for (
				NavChild = NavFrame.firstChild;
				NavChild !== null;
				NavChild = NavChild.nextSibling
			) {

				if (
					$( NavChild ).hasClass( 'NavContent' ) ||
					$( NavChild ).hasClass( 'NavPic' )
				) {

					NavChild.style.display =
						'block';
				}
			}

			NavToggle.firstChild.data =
				NavigationBarHide;
		}

		event.preventDefault();
	};

/*
 * adds show/hide-button
 * to navigation bars
 */
function createNavigationBarToggleButton() {
	var indexNavigationBar = 0;
	var NavFrame;
	var NavChild;

	/*
	 * iterate over all div-elements
	 */
	var divs =
		document.getElementsByTagName( 'div' );

	for (
		var i = 0;
		( NavFrame = divs[ i ] );
		i++
	) {

		/*
		 * if found a navigation bar
		 */
		if (
			$( NavFrame ).hasClass( 'NavFrame' )
		) {

			indexNavigationBar++;

			var NavToggle =
				document.createElement( 'a' );

			NavToggle.className =
				'NavToggle';

			NavToggle.setAttribute(
				'id',
				'NavToggle' + indexNavigationBar
			);

			NavToggle.setAttribute(
				'href',
				'#'
			);

			$( NavToggle ).on(
				'click',
				$.proxy(
					window.toggleNavigationBar,
					window,
					indexNavigationBar
				)
			);

			var isCollapsed =
				$( NavFrame ).hasClass(
					'collapsed'
				);

			/**
			 * Check if any children are already hidden.
			 * This loop is here for backwards compatibility.
			 */
			for (
				NavChild = NavFrame.firstChild;
				NavChild != null &&
				!isCollapsed;
				NavChild = NavChild.nextSibling
			) {

				if (
					$( NavChild ).hasClass( 'NavPic' ) ||
					$( NavChild ).hasClass( 'NavContent' )
				) {

					if (
						NavChild.style.display ===
						'none'
					) {

						isCollapsed = true;
					}
				}
			}

			if ( isCollapsed ) {

				for (
					NavChild = NavFrame.firstChild;
					NavChild != null;
					NavChild =
						NavChild.nextSibling
				) {

					if (
						$( NavChild ).hasClass( 'NavPic' ) ||
						$( NavChild ).hasClass( 'NavContent' )
					) {

						NavChild.style.display =
							'none';
					}
				}
			}

			var NavToggleText =
				document.createTextNode(
					isCollapsed ?
						NavigationBarShow :
						NavigationBarHide
				);

			NavToggle.appendChild(
				NavToggleText
			);

			/*
			 * Find the NavHead and
			 * attach the toggle link
			 */
			for (
				var j = 0;
				j < NavFrame.childNodes.length;
				j++
			) {

				if (
					$( NavFrame.childNodes[ j ] )
						.hasClass( 'NavHead' )
				) {

					NavToggle.style.color =
						NavFrame
							.childNodes[ j ]
							.style.color;

					NavFrame
						.childNodes[ j ]
						.appendChild(
							NavToggle
						);
				}
			}

			NavFrame.setAttribute(
				'id',
				'NavFrame' +
				indexNavigationBar
			);
		}
	}
}

mw.hook( 'wikipage.content' ).add(
	createNavigationBarToggleButton
);

/***** 그림 정보 틀을 자동으로 불러옴 ********
 * Adds a link to subpages of current page
 * from commons.wikimedia.org
 * Maintainers: [[User:Yonidebest]], [[User:Dschwen]]
 * [[사용자:Kwj2772]]가 수정
 * JSconfig items: bool 'loadAutoInformationTemplate'
 *                    (true=enabled (default), false=disabled)
 * JSConfig를 사용하지 않도록 수정함.
 * --[[사용자:Klutzy|Klutzy]]
 ********************************************/

if (
	mw.config.get(
		'wgCanonicalSpecialPageName'
	) == 'Upload'
) {

	importScript(
		'MediaWiki:Upload.js'
	);
}

/*
 * 인터랙티브 지도.
 * 영어 위키백과에서 가져옴.
 */

/**
 * WikiMiniAtlas
 *
 * Description:
 * WikiMiniAtlas is a popup click and drag
 * world map.
 *
 * Maintainers: [[User:Dschwen]]
 */
( function () {

	var require_wikiminiatlas = false;
	var coord_filter = /geohack/;

	$( function () {

		$( 'a.external.text' ).each(
			function ( key, link ) {

				if (
					link.href &&
					coord_filter.exec(
						link.href
					)
				) {

					require_wikiminiatlas =
						true;

					return false;
				}
			}
		);

		if (
			$( 'div.kmldata' ).length
		) {

			require_wikiminiatlas =
				true;
		}

		if ( require_wikiminiatlas ) {

			mw.loader.load(
				'//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript'
			);
		}
	} );

}() );

/**
 * Fix for Windows XP Unicode font rendering
 */
if (
	navigator.appVersion.search(
		/windows nt 5/i
	) !== -1
) {

	mw.util.addCSS(
		'.IPA {' +
			'font-family:' +
			'"Lucida Sans Unicode",' +
			'"Arial Unicode MS";' +
		'} ' +

		'.Unicode {' +
			'font-family:' +
			'"Arial Unicode MS",' +
			'"Lucida Sans Unicode";' +
		'} '
	);
}

/**
 * 편집 안내
 *
 * 생존 인물에 대한 편집 안내.
 * 영어 위키백과에서 가져옴
 */
function addEditIntro( name ) {

	$( '.mw-editsection, #ca-edit' )
		.find( 'a' )
		.each(
			function () {

				this.href =
					$( this ).attr(
						'href'
					) +
					'&editintro=' +
					name;
			}
		);
}

if (
	mw.config.get(
		'wgNamespaceNumber'
	) === 0
) {

	$( function () {

		var cats =
			mw.config.get(
				'wgCategories'
			);

		if ( !cats ) {
			return;
		}

		if (
			$.inArray(
				'살아있는 사람',
				cats
			) !== -1 ||

			$.inArray(
				'생사 불명',
				cats
			) !== -1
		) {

			addEditIntro(
				'틀:BLP_편집_안내'
			);
		}
	} );
}


/* =========================================================
 * 사용자 정의 펼치기 · 접기
 *
 * 예:
 *
 * id="toggleCompany"
 *          ↓
 * id="collapsibleCompany"
 *
 * 선택적으로:
 * id="toggleTextCompany"
 *
 * 투명도 효과 없이 높이만 300ms 동안 애니메이션
 * =========================================================
 */

function initializeCustomToggle( $root ) {

	$root.find( '.toggleBtn' )
		.addBack( '.toggleBtn' )
		.each( function () {

			var $toggle =
				$( this );

			/*
			 * 동일 요소 중복 초기화 방지
			 */
			if (
				$toggle.data(
					'custom-toggle-initialized'
				)
			) {
				return;
			}

			var toggleId =
				$toggle.attr( 'id' );

			if ( !toggleId ) {
				return;
			}

			/*
			 * toggleXXX
			 * → collapsibleXXX
			 */
			var contentId =
				toggleId.replace(
					'toggle',
					'collapsible'
				);

			/*
			 * toggleXXX
			 * → toggleTextXXX
			 */
			var textId =
				toggleId.replace(
					'toggle',
					'toggleText'
				);

			var $content =
				$( '#' + contentId );

			var $text =
				$( '#' + textId );

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

			$toggle.data(
				'custom-toggle-initialized',
				true
			);

			/*
			 * 최초 상태는 접힘
			 */
			$content.hide();

			$toggle.attr( {
				'aria-expanded':
					'false',
				'tabindex':
					$toggle.attr(
						'tabindex'
					) || '0'
			} );

			/*
			 * 펼치기/접기 실행
			 */
			function toggleContent() {

				/*
				 * 진행 중인 애니메이션의
				 * 끝 상태로 강제 이동하지 않고
				 * 현재 상태에서 정리
				 */
				$content.stop(
					true,
					false
				);

				if (
					$content.is(
						':visible'
					)
				) {

					/*
					 * 접기
					 */
					$toggle.attr(
						'aria-expanded',
						'false'
					);

					$content.slideUp(
						300,
						function () {

							/*
							 * jQuery가 애니메이션 과정에서
							 * 넣은 높이 관련 스타일 정리.
							 *
							 * display:none은 slideUp이 유지.
							 */
							$content.css( {
								height: '',
								paddingTop: '',
								paddingBottom: '',
								marginTop: '',
								marginBottom: '',
								overflow: ''
							} );
						}
					);

				} else {

					/*
					 * 펼치기
					 */
					$toggle.attr(
						'aria-expanded',
						'true'
					);

					$content.slideDown(
						300,
						function () {

							/*
							 * 펼친 뒤에는 원래 CSS가
							 * 크기와 여백을 다시 결정.
							 */
							$content.css( {
								height: '',
								paddingTop: '',
								paddingBottom: '',
								marginTop: '',
								marginBottom: '',
								overflow: '',
								display: ''
							} );
						}
					);
				}

				/*
				 * 토글 문구가 따로 있는 경우
				 */
				if ( $text.length ) {

					$text.text(
						'[ 펼치기 · 접기 ]'
					);
				}
			}

			/*
			 * 마우스 클릭
			 */
			$toggle.on(
				'click.customToggle',
				function ( event ) {

					event.preventDefault();

					toggleContent();
				}
			);

			/*
			 * 키보드
			 * Enter / Space
			 */
			$toggle.on(
				'keydown.customToggle',
				function ( event ) {

					if (
						event.key === 'Enter' ||
						event.key === ' '
					) {

						event.preventDefault();

						toggleContent();
					}
				}
			);
		} );
}


/*
 * 일반 문서 최초 로딩
 */
$( function () {

	initializeCustomToggle(
		$( document )
	);
} );


/*
 * AJAX / VisualEditor / 동적 콘텐츠 등으로
 * 문서 내용이 다시 삽입되는 경우에도 초기화
 */
mw.hook( 'wikipage.content' ).add(
	function ( $content ) {

		initializeCustomToggle(
			$content
		);
	}
);


/* End of mw.loader.using callback */
} );

/* DO NOT ADD CODE BELOW THIS LINE */