/* 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 = '' +
'' +
'
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();
};
})();