MediaWiki:Gadget-Global-ExcerptTree.js

From wikiNonStop
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**
 * ExcerptTree enables navigation of excerpt trees
 * Documentation: https://www.mediawiki.org/wiki/ExcerptTree
 * License: GNU General Public License (http://www.gnu.org/licenses/gpl.html)
 * Author: Sophivorus
 */
var ExcerptTree = {

	/**
	 * Initialization script
	 */
	init: function () {
		$( '.ExcerptTree' ).show();
		$( '.ExcerptTree li' ).each( ExcerptTree.addChildren );
	},

	addChildren: function () {
		var node = $( this ),
			title = $( node ).children( 'a' ).text();
		ExcerptTree.getContent( title ).done( function ( data ) {
			if ( data.query.pages[0].missing ) {
				return;
			}
			var content = data.query.pages[0].revisions[0].slots.main.content;
				names = mw.config.get( 'excerpt-templates' ) || [ 'Excerpt' ],
				regexp = new RegExp( '{{ *(?:' + names.join( '|' ) + ') *\\| *([^}]+) *}}', 'gi' ),
				matches = [ ...content.matchAll( regexp ) ];
			if ( matches.length ) {
				ExcerptTree.addButton( node );
				var list = $( '<ul>' ).hide().data( 'virgin', true );
				matches.forEach( function ( match ) {
					var params = match[1].split( '|' ).filter( function ( param ) {
						return /=/.test( param ) === false; // Remove all named params
					} );
					var title = params[0].split( '#' )[0];
					title = title.charAt(0).toUpperCase() + title.slice(1); // Capitalize the title
					var section = params[0].split( '#' )[1] || params[1];
					var text = section ? title + ' § ' + section : title;
					var href = mw.util.getUrl( ( section ? title + '#' + section : title ) );
					var link = $( '<a>', { 'href': href } ).text( text );
					var item = $( '<li>' ).html( link );
					list.append( item );
				} );
				node.append( list );
			}
		} );
	},

	/**
	 * Add a clickable right-arrow to the given node
	 */
	addButton: function ( node ) {
		var button = $( '<span>' ).text( '►' ).css( {
			'cursor': 'pointer',
			'position': 'absolute',
			'left': '-1em'
		} );
		node.css( {
			'list-style': 'none',
			'position': 'relative'
		} ).prepend( button );
		button.click( node, ExcerptTree.toggleChildren );
	},

	toggleChildren: function ( event ) {
		var node = event.data,
			button = $( node ).children( 'span' ),
			list = $( node ).children( 'ul' ),
			virgin = list.data( 'virgin' );

		list.toggle();
		if ( virgin ) {
			list.data( 'virgin', false );
			list.children( 'li' ).each( ExcerptTree.addChildren );
			button.text( '▼' );
		} else {
			if ( list.is( ':visible' ) ) {
				button.text( '▼' );
			} else {
				button.text( '►' );
			}
		}
	},

	getContent: function ( title ) {
		var api = new mw.Api();
		return api.get( {
			titles: title,
			action: 'query',
			formatversion: 2,
			prop: 'revisions',
			rvprop: 'content',
			rvslots: 'main',
			redirects: true
		} );
	}
};

mw.loader.using( 'mediawiki.api', ExcerptTree.init );