利用者:Sigsign/vector.js

出典: 謎の百科事典もどき『エンペディア(Enpedia)』
< 利用者:Sigsign
2020-11-25T02:18:24時点におけるSigsign (トーク | 投稿記録)による版 (fixup)
ナビゲーションに移動 検索に移動

注意: 保存後、変更を確認するにはブラウザーのキャッシュを消去する必要がある場合があります。

  • Firefox / Safari: Shift を押しながら 再読み込み をクリックするか、Ctrl-F5 または Ctrl-R を押してください (Mac では ⌘-R)
  • Google Chrome: Ctrl-Shift-R を押してください (Mac では ⌘-Shift-R)
  • Internet Explorer / Microsoft Edge: Ctrl を押しながら 最新の情報に更新 をクリックするか、Ctrl-F5 を押してください
  • Opera: Ctrl-F5を押してください
/**
* Pathnav.js
*
* Author: [[User:Sigsign]]
* License: CC0
*/

( function () {
'use strict';

mw.loader.using( [ 'jquery', 'mediawiki.api', 'mediawiki.storage' ], function () {
	function makeTree( array, title ) {
		var promise;

		array = array.concat();

		if ( array.indexOf( title ) !== -1 ) {
			array.push( '…' );
			addPathnav( array );
			return;
		}

		array.push( title );
		promise = getParentCategories( title );
		promise.then( function ( parents ) {
			if ( parents.length === 0 ) {
				addPathnav( array );
				return;
			}
			parents.forEach( function ( t ) {
				return makeTree( array, t );
			} );
		} );
	}

	function addPathnav( array ) {
		var container = document.getElementById( 'pathnavContainer' );
		container.innerHTML += array.reverse().join( ' > ' ) + '<br>';
	}

	function fetchParentCategories( title ) {
		var promise;

		promise = new mw.Api().get( {
			action: 'categorytree',
			category: title,
			options: '{ "mode": 100, "hideprefix": 20, "showcount": false, "namespaces": false }',
			uselang: mw.config.get( 'wgUserLanguage' ),
			formatversion: 2
		} );
		return promise.then( function ( object ) {
			var doc, html = object.categorytree.html;

			// ParentCategories are not exist (root category)
			if ( html === '' ) {
				return [];
			}
			// ParentCategories are exist
			doc = new DOMParser().parseFromString( html, 'text/html' );
			return [].map.call( doc.querySelectorAll( '.CategoryTreeItem a' ), function ( e ) {
				return e.textContent;
			} );
		} );
	}

	function getParentCategories( title ) {
		var cache, key, promise;

		key = 'pathnav_cache_' + title;
		cache = mw.storage.getObject( key );

		// cache exists and not expired
		if ( cache && cache.expire > Date.now() ) {
			return wrappedPromise( cache.categories );
		}
		// cache not exists or expired
		promise = fetchParentCategories( title );
		return promise.then( function ( categories ) {
			// update cache
			mw.storage.setObject( key, {
				categories: categories,
				expire: Date.now() + ( 3600 * 1000 ) // expire: after 3600 sec
			} );
			return categories;
		} );
	}

	function wrappedPromise( categories ) {
		return $.Deferred().resolve( categories ).promise();
	}

	if ( mw.config.get( 'wgAction' ) === 'view' && mw.config.get( 'wgNamespaceNumber' ) === 14 ) {
		mw.hook( 'wikipage.content' ).add( function () {
			$( '<div>' ).attr( {
				id: 'pathnavContainer'
			} ).css( {
				backgroundColor: '#eef',
				border: '1px outset #eef',
				clear: 'both',
				fontSize: '80%',
				margin: '0 0 0.5em 0',
				padding: '0.3em 0.6em'
			} ).prependTo( '#mw-content-text' );
			makeTree( [], mw.config.get( 'wgTitle' ) );
		} );
	}

} );

}() );