/* Printliminator v3.1.0 */ /* jshint expr:false */ /* global csstricksPrintliminatorVars */ ;( function() { 'use strict'; var pl = { version : '3.1.0', css : { hilite : '_printliminator_highlight', fullWidth : '_printliminator_full_width', hidden : '_printliminator_hidden', stylized : '_printliminator_stylized', // class name added to body noSelection: '_printliminator_noSelection', // class on body while dragging // printliminator stylesheet : '_print_controls_styles', // stylesheet ID controls : '_print_controls', icon : '_print_controls_icon', wrap : '_print_controls_wrap', noGraphics : '_print_controls_remove_graphics', stylize : '_print_controls_stylize', print : '_print_controls_print', close : '_print_controls_close', undo : '_print_controls_undo', drag : '_print_controls_icon_drag', keyboard : '_print_controls_keyboard' }, keys : { parent1 : 33, // pageUp parent2 : 38, // up arrow child1 : 34, // pageDown child2 : 40, // down arrow nextSib : 39, // right arrow prevSib : 37, // left arrow hide : 13, // enter undo : 8, // backspace fontUp : 107, // Numpad + fontDown : 109, // Numpad - fontReset : 106, // Numpad * print : 44, // PrtScn (keyup only) abort : 27, // Esc // use event key below opposite : 'altKey', // alt + click fullWidth : 'shiftKey' // shift + click }, // elements hidden when "remove graphics" is selected noGraphicsSelectors : 'img, iframe:not(._print_controls), object, embed, audio, video, input[type=image], svg', // elements to ignore while traversing ignoredElm : /^(br|meta|style|link|script)$/i, // iframe height with keyboard open/closed keyboardOpen : 630, keyboardClosed : 220, // dragging parameters stored here drag : { el : null, pos : [ 0, 0 ], elm : [ 0, 0 ] }, init : function() { var body = document.querySelector( 'body' ); // need a global variable to store history & flags if ( typeof window.csstricksPrintliminatorVars === 'undefined' ) { // use object separate from pl, otherwise these values get lost // upon javascript injection a second time (after uses presses Esc) window.csstricksPrintliminatorVars = { history : [], // flags to prevent multiple applications of same action flags : {} }; pl.addStyles(); } pl.addControls(); // highlighting elements & keyboard binding pl.addEvent( body, 'click', pl.bodyClick ); pl.addEvent( body, 'mouseover', pl.bodyMouseover ); pl.addEvent( body, 'mouseout', pl.removeHighlight ); pl.addEvent( document, 'keyup', pl.bodyKeyUp ); pl.addEvent( document, 'keydown', pl.bodyKeyDown ); // drag pl.addEvent( document, 'mouseup', pl.docMouseUp ); pl.addEvent( document, 'mousemove', pl.docMouseMove ); }, addStyles : function(){ var el, body = document.querySelector( 'body' ), prefix = 'body.' + pl.css.stylized + ' ', impt = '!important;', // programmically added stylesheets styles = '' + // hide printliminator controls from print '@media print{ .' + pl.css.wrap + '{ display: none; } }' + // print stylesheet '@media print, screen {' + prefix + '{ margin: 0; padding: 0; line-height: 1.4;' + 'word-spacing: 1.1pt; letter-spacing: 0.2pt; font-size: 12pt;' + 'font-family: Garamond, "Times New Roman", serif; color: #000; background: none; }' + prefix + 'h1,' + prefix + 'h2,' + prefix + 'h3,' + prefix + 'h4,' + prefix +'h5,' + prefix +'h6' + '{ font-family: Helvetica, Arial, sans-serif; }' + prefix + 'h1 { font-size: 19pt; }' + prefix + 'h2 { font-size: 17pt; }' + prefix + 'h3 { font-size: 15pt; }' + prefix + 'h4, ' + prefix +'h5,' + prefix + 'h6 { font-size: 12pt; }' + prefix + 'code { font: 10pt Courier, monospace; }' + prefix + 'blockquote { margin: 1.3em; padding: 1em; font-size: 10pt; }' + prefix + 'hr { background-color: #ccc; }' + prefix + 'img { float: left; margin: 1em 1.5em 1.5em 0; }' + prefix + 'a img { border: none; }' + prefix + 'table { margin: 1px; text-align:left; border-collapse: collapse; }' + prefix + 'th { border: 1px solid #333; font-weight: bold; }' + prefix + 'td { border: 1px solid #333; }' + prefix + 'th, ' + prefix +' td { padding: 4px 10px; }' + prefix + 'tfoot { font-style: italic; }' + prefix + 'caption { background: #fff; margin-bottom: 20px; text-align:left; }' + prefix + 'thead { display: table-header-group; }' + prefix + 'tr { page-break-inside: avoid; }' + // elements hidden by Printliminator '.' + pl.css.hidden + ' { display: none' + impt + '}' + // elements set to full width/no margins '.' + pl.css.fullWidth + ' { width: 100%' + impt + ' min-width: 100%' + impt + ' max-width: 100%' + impt + 'margin: 0' + impt + '}' + '} @media screen {' + prefix + '{ padding: 20px; }' + // printliminator controls '.' + pl.css.wrap + '{ width: 375px' + impt + ' height: ' + pl.keyboardClosed + 'px; position: fixed' + impt + 'top: 0; right: 0; z-index: 999999' + impt + ' border: #000 1px solid' + impt + '}' + '.' + pl.css.drag + '{ width: 28px' + impt + 'height: 20px' + impt + 'position: absolute' + impt + ' top: 0' + impt + ' left: 0' + impt + 'cursor: move' + impt + '}' + '.' + pl.css.wrap + ' iframe { width: 375px' + impt + ' height: ' + pl.keyboardClosed + 'px; border: 0' + impt + 'overflow-x: hidden' + impt + ' margin: 0' + impt + ' padding: 0' + impt + '}' + // prevent selection 'body.' + pl.css.noSelection + ',.' + pl.css.hilite + ',.' + pl.css.wrap + ',.' + pl.css.drag + ',.' + pl.css.wrap + ' iframe {' + '-webkit-user-select: none' + impt + '-moz-user-select: none' + impt + ' -ms-user-select: none' + impt + ' user-select: none' + impt + '}' + // box highlighting '.' + pl.css.hilite + '{ outline: 3px solid red' + impt + 'cursor: default' + impt + '}' + '.' + pl.css.hilite + '.' + pl.css.fullWidth + '{ outline-color: blue' + impt + '}'; // add print stylesheet el = document.createElement( 'style' ); el.id = pl.css.stylesheet; el.innerHTML = styles; document.querySelector( 'head' ).appendChild( el ); }, // create popup addControls : function(){ var frame, body = document.querySelector( 'body' ), el = document.createElement( 'div' ), controls = pl.css.controls, prefix = '.' + controls, button = '_print_controls_button', icon = pl.css.icon, sprite = 'data:image/png;base64,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'; body.appendChild( el ); pl.addClass( el, pl.css.wrap ); pl.addClass( el, controls ); el.innerHTML = '' + '
'; frame = el.querySelector( 'iframe.' + pl.css.controls ).contentWindow.document.body; frame.innerHTML = '
' + '
CLOSE
' + '
DRAG
' + '
' + '
' + '

The Printliminator

' + '

Click highlighted boxes to delete

' + '
' + '' + ''; pl.addEvent( frame.querySelector( '.' + pl.css.noGraphics ), 'click', pl.removeGraphics ); pl.addEvent( frame.querySelector( '.' + pl.css.print ), 'click', pl.print ); pl.addEvent( frame.querySelector( '.' + pl.css.undo ), 'click', pl.undo ); pl.addEvent( frame.querySelector( '.' + pl.css.stylize ), 'click', pl.stylize ); pl.addEvent( frame.querySelector( '.' + pl.css.close ), 'click', pl.abort ); pl.addEvent( frame.querySelector( '.' + pl.css.keyboard ), 'click', pl.keyboard ); // can't drag from within the iframe - the mouse coordinates would be within it pl.addEvent( document.querySelector( '.' + pl.css.drag ), 'mousedown', pl.dragInit ); // include mouseup inside frame to stop the drag pl.addEvent( frame, 'mouseup', pl.docMouseUp ); }, bodyClick : function( event ) { event.preventDefault(); event.stopImmediatePropagation(); if ( event.target.nodeName !== 'BODY' && !pl.hasClass( event.target, pl.css.controls ) ) { var done, sel, hilite = document.querySelector( '.' + pl.css.hilite ); // show opposite (Alt + click) if ( event[ pl.keys.opposite ] ) { done = pl.getOpposite( hilite ); sel = done.length; if ( !sel ) { // nothing left to remove return false; } } else { // hide clicked element done = [ hilite ]; } pl.hide( done ); csstricksPrintliminatorVars.history.push( done ); // remove any text selection pl.clearSelection(); } }, bodyMouseover : function( event ) { if ( !pl.hasClass( event.target, pl.css.controls ) ) { pl.addClass( event.target, pl.css.hilite ); } }, removeHighlight : function() { // remove all highlight class names, just in case var indx, // include body as it might also get the highlight class hilite = document.querySelectorAll( '.' + pl.css.hilite ), len = hilite.length; for ( indx = 0; indx < len; indx++ ) { pl.removeClass( hilite[ indx ], pl.css.hilite ); } }, bodyKeyUp : function( event ) { event.preventDefault(); // PrntScrn only works on keyup if ( event.which === pl.keys.print ) { pl.print(); } }, bodyKeyDown : function( event ) { event.preventDefault(); var n, suffix, elm, els, isBody, body = document.querySelectorAll( 'body' )[ 0 ], el = document.querySelectorAll( '.' + pl.css.hilite )[ 0 ], hidden = pl.css.hidden, highlight = pl.css.hilite; if ( el ) { isBody = el.nodeName === 'BODY'; switch ( event.which ) { case pl.keys.parent1 : // pageUp case pl.keys.parent2 : // up arrow if ( !isBody && el.parentNode ) { pl.removeClass( el, highlight ); pl.addClass( el.parentNode, highlight ); } break; case pl.keys.child1 : // pageDown case pl.keys.child2 : // down arrow els = Array.prototype.filter.call( el.children, pl.filterElements ); if ( els.length ) { pl.removeClass( el, highlight ); pl.addClass( els[0], highlight ); } break; case pl.keys.nextSib : // right arrow (siblings) elm = pl.getNext( el ); if ( !isBody && elm ) { pl.removeClass( el, highlight ); pl.addClass( elm, highlight ); } break; case pl.keys.prevSib : // left arrow (siblings) elm = pl.getPrev( el ); if ( !isBody && elm ) { pl.removeClass( el, highlight ); pl.addClass( elm, highlight ); } break; case pl.keys.hide : // enter if ( !isBody ) { pl.addClass( el, hidden ); pl.addClass( el.parentNode, highlight ); csstricksPrintliminatorVars.history.push( el ); } break; } } else { el = event.target; pl.addClass( el, highlight ); } n = window.getComputedStyle( body, null ).getPropertyValue( 'font-size' ); suffix = n.match( /[a-z]+/i )[0]; switch ( event.which ) { case pl.keys.fontUp : // Numpad + = Increase font size body.style.fontSize = ( parseFloat( n ) + 1 ) + suffix; break; case pl.keys.fontDown : // Numpad - = Decrease font size body.style.fontSize = ( parseFloat( n ) - 1 ) + suffix; break; case pl.keys.fontReset : // Numpad * = reset font-size body.style.fontSize = ''; break; case pl.keys.undo : // backspace pl.undo(); break; case pl.keys.abort : // Esc pl.abort(); break; } }, // drag code adapted from http://jsfiddle.net/tovic/Xcb8d/light/ dragInit : function() { var drag = pl.drag; drag.el = document.querySelector( '.' + pl.css.wrap ); drag.elm[0] = drag.pos[0] - drag.el.offsetLeft; drag.elm[1] = drag.pos[1] - drag.el.offsetTop; // prevent selecting content while dragging pl.toggleSelection( true ); }, docMouseMove : function( event ) { var drag = pl.drag; drag.pos[0] = document.all ? window.event.clientX : event.pageX; drag.pos[1] = document.all ? window.event.clientY : event.pageY; if ( pl.drag.el !== null ) { drag.el.style.left = ( drag.pos[0] - drag.elm[0] ) + 'px'; drag.el.style.top = ( drag.pos[1] - drag.elm[1] ) + 'px'; } }, docMouseUp : function() { pl.drag.el = null; pl.toggleSelection(); }, stopSelection : function() { return false; }, clearSelection : function() { // remove text selection - http://stackoverflow.com/a/3171348/145346 var sel = window.getSelection ? window.getSelection() : document.selection; if ( sel ) { if ( sel.removeAllRanges ) { sel.removeAllRanges(); } else if ( sel.empty ) { sel.empty(); } } }, toggleSelection : function( disable ) { var body = document.querySelector( 'body' ); if ( disable ) { // save current "unselectable" value pl.savedUnsel = body.getAttribute( 'unselectable' ); body.setAttribute( 'unselectable', 'on' ); pl.addClass( body, pl.css.noSelection ); pl.addEvent( body, 'onselectstart', pl.stopSelection ); } else { if ( pl.savedUnsel ) { body.setAttribute( 'unselectable', pl.savedUnsel ); } pl.removeClass( body, pl.css.noSelection ); pl.removeEvent( body, 'onselectstart', pl.stopSelection ); } // clear any selections pl.clearSelection(); }, removeGraphics : function() { if ( !csstricksPrintliminatorVars.flags.removeGraphics ) { var indx, bkgd, bkgds = [], body = document.querySelector( 'body' ), done = body.querySelectorAll( pl.noGraphicsSelectors ), items = body.querySelectorAll( '*:not(.' + pl.css.controls + ')' ), len = items.length; for ( indx = 0; indx < len; indx++ ) { bkgd = window.getComputedStyle( items[ indx ] ).getPropertyValue( 'background-image' ); if ( bkgd && bkgd !== 'none' ) { bkgds.push( [ items[ indx ], bkgd ] ); items[ indx ].style.backgroundImage = 'none'; } } pl.removeHighlight(); pl.hide( done ); csstricksPrintliminatorVars.flags.removeGraphics = true; csstricksPrintliminatorVars.history.push( function() { csstricksPrintliminatorVars.flags.removeGraphics = false; pl.show( done ); len = bkgds.length; for ( indx = 0; indx < len; indx++ ) { bkgds[ indx ][ 0 ].style.backgroundImage = bkgds[ indx ][ 1 ]; } }); } }, // Add print style stylize : function() { if ( !csstricksPrintliminatorVars.flags.stylize ) { var indx, inline = [], body = document.querySelector( 'body' ), links = document.querySelectorAll( 'link[rel="stylesheet"], style' ), visibleElms = document.querySelectorAll( 'body *:not(.' + pl.css.hidden + '):not(.' + pl.css.controls + ')' ), len = links.length; for ( indx = 0; indx < len; indx++ ) { if ( links[ indx ].id !== pl.css.stylesheet ) { links[ indx ].disabled = true; } } // cache and remove inline styles Array.prototype.filter.call( visibleElms, function( elm ) { var style = elm.getAttribute( 'style' ); if ( style !== null ) { elm.removeAttribute( 'style' ); inline.push({ el: elm, style: style }); } }); pl.addClass( body, pl.css.stylized ); pl.removeHighlight(); csstricksPrintliminatorVars.flags.stylize = true; csstricksPrintliminatorVars.history.push( function() { csstricksPrintliminatorVars.flags.stylize = false; pl.removeClass( body, pl.css.stylized ); var indx, len = links.length; for ( indx = 0; indx < len; indx++ ) { links[ indx ].disabled = false; } len = inline.length; for ( indx = 0; indx < len; indx++ ) { inline[ indx ].el.setAttribute( 'style', inline[ indx ].style ); } }); } }, print : function() { pl.removeHighlight(); window.print(); }, // Undo undo : function() { var last = csstricksPrintliminatorVars.history.pop(); if ( last ) { pl.removeHighlight(); if ( typeof last !== 'function' ) { pl.show( last ); } else { last.call(); } } }, keyboard : function() { var wrap = document.querySelector( '.' + pl.css.wrap ), iframe = wrap.querySelector( 'iframe.' + pl.css.controls ), ibody = iframe.contentWindow.document.body, kb = ibody.querySelector( '#' + pl.css.keyboard ), button = ibody.querySelector( '.' + pl.css.keyboard ), disply = kb.style.display, makeVisible = disply === 'none'; pl[ makeVisible ? 'addClass' : 'removeClass' ]( button, 'active' ); kb.style.display = makeVisible ? '' : 'none'; wrap.style.height = ( makeVisible ? pl.keyboardOpen : pl.keyboardClosed ) + 5 + 'px'; // iframe needs to be a tiny bit taller than the body inside iframe.style.height = ( makeVisible ? pl.keyboardOpen : pl.keyboardClosed ) + 5 + 'px'; ibody.style.height = ( makeVisible ? pl.keyboardOpen : pl.keyboardClosed ) + 'px'; }, abort : function() { var body = document.querySelector( 'body' ); pl.removeHighlight(); pl.removeEvent( body, 'click', pl.bodyClick ); pl.removeEvent( body, 'mouseover', pl.bodyMouseover ); pl.removeEvent( body, 'mouseout', pl.removeHighlight ); pl.removeEvent( document,'keyup', pl.bodyKeyUp ); pl.removeEvent( document, 'keydown', pl.bodyKeyDown ); // drag pl.removeEvent( document, 'mouseup', pl.docMouseUp ); pl.removeEvent( document, 'mousemove', pl.docMouseMove ); body.removeChild( document.querySelector( '.' + pl.css.wrap ) ); }, filterElements : function( elm ) { return elm && // element node elm.nodeType === 1 && // not an ignored element !pl.ignoredElm.test( elm.nodeName ) && // not controls !pl.hasClass( elm, pl.css.controls ) && // not hidden !( pl.hasClass( elm, pl.css.hidden ) || elm.style.display === 'none' ); }, getOpposite : function( el ) { var sibs, done = []; // method: start from highlighted element // get siblings & hide them; then go to parent, get siblings & hide them... // rinse & repeat until we hit the body element while ( el.nodeName !== 'BODY' ) { sibs = pl.getSiblings( el ); done = done.concat( sibs ); el = el.parentNode; } return done; }, // modified from // https://plainjs.com/javascript/traversing/get-siblings-of-an-element-40/ getSiblings : function ( el ) { var siblings = [], sibling = el.parentNode.firstChild; for ( ; sibling; sibling = sibling.nextSibling ) { if ( sibling !== el && pl.filterElements( sibling ) ) { siblings.push( sibling ); } } return siblings; }, // modified from // https://plainjs.com/javascript/traversing/get-siblings-of-an-element-40/ getNext : function ( el ) { while ( el = el.nextSibling ) { // jshint ignore:line if ( el && pl.filterElements( el ) ) { return el; } } return null; }, // modified from // https://plainjs.com/javascript/traversing/get-siblings-of-an-element-40/ getPrev : function( el ) { while ( el = el.previousSibling ) { // jshint ignore:line if ( el && pl.filterElements( el ) ) { return el; } } return null; }, hide : function ( els ) { if ( els ) { var indx, len = els.length; // single elements have undefined length if ( typeof len !== 'undefined' ) { for ( indx = 0; indx < len; indx++ ) { pl.addClass( els[ indx ], pl.css.hidden ); } } else { pl.addClass( els, pl.css.hidden ); } } }, show : function ( els ) { if ( els ) { var indx, len = els.length; if ( typeof len !== 'undefined' ) { for ( indx = 0; indx < len; indx++ ) { pl.removeClass( els[ indx ], pl.css.hidden ); } } else { pl.removeClass( els, pl.css.hidden ); } } }, addClass : function( el, name ) { if ( el.classList ) { el.classList.add( name ); } else if ( !pl.hasClass( el, name ) ) { el.className += ' ' + name; } }, removeClass : function( el, name ) { if ( el.classList ) { el.classList.remove( name ); } else { el.className = el.className.replace( new RegExp( '\\b' + name + '\\b', 'g' ), '' ); } }, hasClass : function( el, name ) { return el.classList ? el.classList.contains( name ) : new RegExp( '\\b' + name + '\\b' ).test( el.className ); }, addEvent : function( el, type, handler ) { if ( el.attachEvent ) { el.attachEvent( 'on' + type, handler ); } else { el.addEventListener( type, handler ); } }, removeEvent : function( el, type, handler ) { if ( el.detachEvent ) { el.detachEvent( 'on' + type, handler ); } else { el.removeEventListener( type, handler ); } } }; window.csstricksPrintliminator = function() { pl.init(); }; })();