MediaWiki:Gadget-PrintOptions.js

/** * Print options is a Gadget writen by Derk-Jan Hartman / User:TheDJ * For more information see User:TheDJ/Print_options * * Licensed MIT and/or CC-by-SA 4.0 * * Copyright (c) 2010-2017 Derk-Jan Hartman / User:TheDJ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */

( function {	'use strict';	var windowManager;	var printDialog;

var printOptions = { install: function { var $printLink = $( '#t-print a' ); if ( $printLink.length === 0 ) { return; }			$printLink .text( 'Print page' ) .off( 'click' ) .get( 0 ).addEventListener( 'click', function ( e ) {					mw.loader.using( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] ).done( printOptions.createWindow );					e.stopPropagation;					e.preventDefault;				}, true ); // Use capturing phase, to beat the other click handler

// Late pre-loading mw.loader.load( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] ); },

createWindow: function { function PrintDialog( config ) { PrintDialog.super.call( this, config ); }			OO.inheritClass( PrintDialog, OO.ui.ProcessDialog );

PrintDialog.static.name = 'printdialog'; PrintDialog.static.title = 'Print this page'; PrintDialog.static.actions = [ { action: 'print', label: 'Print', flags: 'primary' }, { label: 'Cancel', flags: 'safe' } ];

PrintDialog.prototype.initialize = function { var checkbox, fieldset = []; PrintDialog.super.prototype.initialize.apply( this, arguments ); this.panel = new OO.ui.PanelLayout( { padded: true, expanded: false } ); this.content = new OO.ui.FieldsetLayout;

for ( var i = 0; i < printOptions.questions.length; i++ ) { if ( printOptions.questions[ i ].type === 'checkbox' ) { checkbox = new OO.ui.CheckboxInputWidget( {							selected: printOptions.questions[ i ].checked						} ); printOptions.questions[ i ].widget = checkbox; fieldset.push( new OO.ui.FieldLayout( checkbox, { label: printOptions.questions[ i ].label, align: 'inline' } ) ); }				}				this.content.addItems( fieldset );

this.panel.$element.append( this.content.$element ); this.$body.append( this.panel.$element ); };

PrintDialog.prototype.getActionProcess = function ( action ) { var dialog = this; if ( action === 'print' ) { return new OO.ui.Process( function {						// Get values of checkboxes						var question;						for ( var i = 0; i < printOptions.questions.length; i++ ) {							question = printOptions.questions[ i ];							if ( question.type === 'checkbox' && question.widget ) {								printOptions[ question.returnvalue ] = question.widget.isSelected;							}						}						dialog.close( { action: action } ).done( function  { printOptions.changePrintCSS; printOptions.otherEnhancements; window.print; window.location = window.location; } );					} );				}				return PrintDialog.super.prototype.getActionProcess.call( this, action ); };

if ( !windowManager ) { windowManager = new OO.ui.WindowManager; $( 'body' ).append( windowManager.$element ); }			if ( !printDialog ) { printDialog = new PrintDialog( {					size: 'medium'				} );

windowManager.addWindows( [ printDialog ] ); }			windowManager.openWindow( printDialog ); },

changePrintCSS: function { /* Here we: - disable stylesheets that are print specific - make screen specific stylesheets also enabled for print medium - remove print specific stylerules - make screen specific stylerules also enabled for print medium */			var printStyle = ''; if ( this.enhanced === false ) { var i, j, k,					rule, hasPrint, hasScreen, rules, stylesheet, stylesheets = document.styleSheets;

for ( i = 0; i < stylesheets.length; i++ ) { stylesheet = stylesheets[ i ]; if ( !stylesheet.media ) { continue; }					if ( stylesheet.media.mediaText && stylesheet.media.mediaText.indexOf( 'print' ) !== -1 ) { if ( stylesheet.media.mediaText.indexOf( 'screen' ) === -1 ) { stylesheet.disabled = true; }					} else if ( stylesheet.media.mediaText && stylesheet.media.mediaText.indexOf( 'screen' ) !== -1 ) { if ( stylesheet.media.mediaText.indexOf( 'print' ) === -1 ) { try { stylesheet.media.appendMedium( 'print' ); } catch ( e ) { stylesheet.media.mediaText += ',print'; }						}					}

/* now test individual stylesheet rules */ try { rules = stylesheet.cssRules || stylesheet.rules; } catch ( e ) { /* Cross domain issue. */						mw.log.warn( 'Not possible to correct stylesheet due to cross origin restrictions.' ); continue; }					stylesheet.compatdelete = stylesheet.deleteRule || stylesheet.removeRule; for ( j = 0; rules && j < rules.length; j++ ) { rule = rules[ j ]; hasPrint = false; hasScreen = false; if ( rule.type === CSSRule.MEDIA_RULE && rule.media ) { for ( k = 0; k < rule.media.length; k++ ) { if ( rule.media[ k ] === 'print' ) { hasPrint = true; } else if ( rule.media[ k ] === 'screen' ) { hasScreen = true; }							}						} else { continue; }						if ( hasPrint && !hasScreen ) { stylesheet.compatdelete( j ); j--; } else if ( hasScreen && !hasPrint ) { try { rule.media.appendMedium( 'print' ); } catch ( e ) { rule.media.mediaText += ',print'; }						}					}				}			}			/* Add css to hide images */ if ( this.noimages ) { printStyle += 'img, .thumb {display:none;}\n'; }			/* Add css to hide references markers and the references lists */ if ( this.norefs ) { printStyle += '.mw-heading:has(#References), ol.references, .reference {display:none;}\n'; }			if ( this.notoc ) { printStyle += '#toc, .toc {display:none;}\n'; }			if ( this.nobackground ) { printStyle += '* {background:none !important;}\n'; }			if ( this.blacktext ) { printStyle += '* {color:black !important;}\n'; }

if ( printStyle ) { $( 'head' ).append( '' + printStyle + ' ' ); }		},

/* Rewrite the "retrieved from" url to be readable */ otherEnhancements: function { var link = $( 'div.printfooter a' ); link.text( decodeURI( link.text ) ); },

questions: [ {				label: 'Hide interface elements', type: 'checkbox', checked: true, returnvalue: 'enhanced' },			{				label: 'Hide images', type: 'checkbox', checked: false, returnvalue: 'noimages' },			{				label: 'Hide references', type: 'checkbox', checked: false, returnvalue: 'norefs' },			{				label: 'Hide Table of Contents', type: 'checkbox', checked: false, returnvalue: 'notoc' },			{				label: 'Remove backgrounds (Your browser might or might not override this)', type: 'checkbox', checked: false, returnvalue: 'nobackground' },			{				label: 'Force all text to black', type: 'checkbox', checked: true, returnvalue: 'blacktext' }		]	};

if ( mw.config.get( 'wgNamespaceNumber' ) >= 0 ) { $( function {			// This can be before the click handler by MW is installed. Instead,			// re-add ourselves to the back of the document.ready list			// use async timeoute to do this			setTimeout( function  { $( printOptions.install ); } );		} );	} } );