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)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/**
* This script interacts with [[Template:Menu]]
* [[Category:Template script pages]]
*/
var TemplateMenu = {
init: function () {
$content = $( '#mw-content-text' );
$content.find( '.menu-header' ).on( 'click', TemplateMenu.toggle );
$content.find( '.menu-progress-buttons' ).each( TemplateMenu.makeProgressButtons );
$content.find( '.menu-progress-bar' ).each( TemplateMenu.makeProgressBar );
$content.find( '.menu-book .mw-ui-button' ).on( 'click', TemplateMenu.makeBook );
$content.find( '.menu-list' ).each( TemplateMenu.trimList );
},
toggle: function ( event ) {
if ( event.target.tagName === 'A' ) {
return;
}
$( this ).next( '.menu-content' ).toggle();
},
/**
* Trim lists of more than 10 items
* Example: [[Template:NREMT menu]]
*/
trimList: function ( event ) {
var $button = $( '<span>more</span>' ).css( 'cursor', 'pointer' ).on( 'click', function () {
$( this ).hide().siblings().show();
} );
$( this ).find( 'li' ).eq( 10 ).nextAll().hide().last().after( $button );
},
makeProgressButtons: function () {
var $menu = $( this ).closest( '.menu' );
var prev, next, index;
var links = $menu.find( 'a' );
links.each( function ( i ) {
if ( $( this ).hasClass( 'selflink' ) ) {
index = i;
prev = links[ index - 1 ];
next = links[ index + 1 ];
return;
}
} );
if ( index === undefined ) {
return;
}
var prevButton = $( prev ).clone().addClass( 'mw-ui-button' ).text( '< Previous' );
var nextButton;
if ( next ) {
nextButton = $( next ).clone().addClass( 'mw-ui-button' ).text( 'Next >' );
}
if ( !prev ) {
nextButton.addClass( 'mw-ui-progressive' ).text( 'Start' );
}
$menu.find( '.menu-progress-buttons' ).append( prevButton, nextButton );
},
makeProgressBar: function () {
var $menu = $( this ).closest( '.menu' );
var index;
var links = $menu.find( 'a' );
links.each( function ( i ) {
if ( $( this ).hasClass( 'selflink' ) ) {
index = i;
return;
}
} );
if ( index === undefined ) {
return;
}
var percentage = Math.round( index * 100 / links.length ) + '%';
$menu.find( '.menu-progress' ).text( percentage ).css( 'width', percentage );
if ( percentage === '0%' ) {
$menu.find( '.menu-progress' ).addClass( 'menu-no-progress' );
}
},
makeBook: function ( event ) {
// Show loading dialog to hint the user that something is happening
var messageDialog = new OO.ui.MessageDialog();
var windowManager = new OO.ui.WindowManager();
TemplateMenu.windowManager = windowManager;
$( 'body' ).append( windowManager.$element );
windowManager.addWindows( [ messageDialog ] );
var progressBar = new OO.ui.ProgressBarWidget( {
progress: false
} );
windowManager.openWindow( messageDialog, {
title: 'Generating PDF',
message: progressBar.$element,
escapable: false,
actions: []
} );
// Get book data
var $menu = $( this ).closest( '.menu' );
var $book = $menu.find( '.menu-book' );
var bookLogo = $book.data( 'book-logo' ) ? '[' + '[File:' + $book.data( 'book-logo' ) + '|link=]]' : '';
var bookTitle = $book.data( 'book-title' );
var bookSubtitle = $book.data( 'book-subtitle' );
var bookImage = $book.data( 'book-image' ) ? '[' + '[File:' + $book.data( 'book-image' ) + '|300px|link=]]' : '';
var bookAuthors = $book.data( 'book-authors' );
// Make book cover
var $cover = $( '<div class="book-cover"></div>' );
var $coverContent = $( '<div class="book-cover-content"></div>' );
var $coverLogo = $( '<div class="book-cover-logo">' + bookLogo + '</div>' );
var $coverTitle = $( '<div class="book-cover-title">' + bookTitle + '</div>' );
var $coverSubtitle = $( '<div class="book-cover-subtitle">' + bookSubtitle + '</div>' );
var $coverImage = $( '<div class="book-cover-image">' + bookImage + '</div>' );
var $coverAuthors = $( '<div class="book-cover-authors">' + bookAuthors + '</div>' );
$coverContent.append( $coverLogo, $coverTitle, $coverSubtitle, $coverImage, $coverAuthors );
$cover.append( $coverContent );
// Cover CSS
$cover.css( {
'font-family': 'Garamond',
'page-break-after': 'always',
'display': 'flex',
'align-items': 'center',
'justify-content': 'center',
'text-align': 'center',
'width': '100vw',
'height': '99vh',
} );
$coverContent.css( {
'border': '10px double #202122',
'padding': '30px',
} );
$coverTitle.css( {
'font-size': '2em',
} );
$coverSubtitle.css( {
'font-size': '1.5em',
} );
$coverAuthors.css( {
'font-size': '1.5em',
} );
$coverContent.find( 'div' ).css( {
'margin': '30px',
} );
// Make book wikitext
var wikitext = $cover.prop( 'outerHTML' );
$menu.find( 'a' ).each( function () {
var link = $( this );
if ( link.hasClass( 'external' ) ) {
return; // Skip external pages
}
if ( link.hasClass( 'new' ) ) {
return; // Skip non-existent pages
}
if ( link.hasClass( 'mw-ui-button' ) ) {
return; // Skip Previous and Next buttons
}
var chapterName = link.text();
var chapterPage = link.hasClass( 'selflink' ) ? mw.config.get( 'wgPageName' ) : link.attr( 'title' );
wikitext += '\n<h1>' + chapterName + '</h1>';
wikitext += '\n{' + '{#invoke:Transcluder|main|' + chapterPage;
wikitext += '| noBehaviorSwitches = 1';
wikitext += '| templates = - Video, .* data, .* menu, .* header';
wikitext += '}}';
} );
// Get book HTML
new mw.Api().parse( wikitext ).then( function ( html ) {
// Save original HTML to restore it later
var $firstHeading = $( '#firstHeading' );
var $pageContent = $( '#mw-content-text .mw-parser-output' );
var originalContent = $pageContent.html();
// Append chapters HTML
$pageContent.html( html );
// Use imagesLoaded plugin to wait for images to load
mw.loader.getScript( 'https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js' ).then( function () {
$pageContent.imagesLoaded( function () {
// Hide elements we don't want to print
TemplateMenu.windowManager.destroy();
$firstHeading.hide();
$pageContent.find( '.map' ).hide(); // Maps don't load well so we hide them
// Finally, print
window.print();
// Restore original page
//$firstHeading.show();
//$pageContent.html( originalContent );
} );
} );
} );
}
};
$( TemplateMenu.init );