From 25cf7a8142dab5e612268a824a72be2236927943 Mon Sep 17 00:00:00 2001 From: Mottie Date: Tue, 1 Sep 2015 12:20:21 -0500 Subject: Remove jQuery dependency; add drag & keyboard I know, this is a bad all-in-one commit. I did try to test the heck out of it! --- Gruntfile.js | 10 +- README.md | 20 +- demo/images/screenshot.png | Bin 5870 -> 16101 bytes index.html | 11 +- package.json | 6 +- printliminator.min.js | 2 +- printliminator.png | Bin 9840 -> 0 bytes src/bookmarklet.js | 14 +- src/index.html | 7 +- src/printliminator.js | 921 ++++++++++++++++++++++++++++++++++++--------- src/printliminator.png | Bin 0 -> 1852 bytes 11 files changed, 773 insertions(+), 218 deletions(-) delete mode 100644 printliminator.png create mode 100644 src/printliminator.png diff --git a/Gruntfile.js b/Gruntfile.js index 9468751..e307ff9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -15,11 +15,9 @@ module.exports = function( grunt ) { // bookmarklet builder URLs indexHtml : 'index.html', production : { - jQuery : '//ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', printliminator : '//css-tricks.github.io/The-Printliminator/printliminator.min.js' }, dev : { - jQuery : 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js', printliminator : 'src/printliminator.js' }, @@ -46,10 +44,8 @@ module.exports = function( grunt ) { globals: { '<%= config.printliminatorFunctionName %>': false }, - 'loopfunc': true, - 'jquery': true, - 'browser': true, - 'undef': true + browser: true, + undef: true }, files: { src: [ @@ -102,8 +98,6 @@ module.exports = function( grunt ) { modFile = function( mode ) { var file = content - // replace URLs in javascript, depending on mode - .replace( /\{jQuery\}/, config[ mode ].jQuery ) .replace( /\{printliminator\}/, config[ mode ].printliminator ) .replace( /\"/g, "'" ) // not using encodeURI because it changes "{}" into "%7B%7D" diff --git a/README.md b/README.md index a3ae966..a05247c 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,34 @@ The Printliminator is a bookmarklet with some simple tools you can use to makes One click to activate, and then click to remove elements from the page, remove graphics, and apply better print styling. -![screenshot](https://cloud.githubusercontent.com/assets/136959/9445926/649cb622-4a54-11e5-9971-0782ae009a30.png) +![screenshot](//cloud.githubusercontent.com/assets/136959/9610695/cb3e4a4c-50a0-11e5-96cb-e3e54a9c88d5.png) [Get the Bookmarklet here](//css-tricks.github.io/The-Printliminator/) ### To Do -* [ ] Add keyboard commands to alter the targeted element. For example: +* [x] Add keyboard commands to alter the targeted element. For example: * pageUp to select parent of hovered element * pageDown to select child of hovered element (not sure what to do if the mouse moves though) * Enter to hide outlined element. * Esc to cancel. -* [ ] Make Printliminator window draggable. +* [x] Make Printliminator window draggable. +* [x] Remove jQuery dependency. * [ ] Add documentation to the wiki pages. -* [ ] Remove jQuery dependency. ### Recent Changes +#### Version 3.1.0 (9/1/2015) + +* Change design of popup (design by Chris Coyier); see screenshot! +* Removed jQuery dependency; lots of internal structural changes made. +* Add keyboard commands. See screenshot for the complete list. +* Make popup draggable. +* Note: + * This bookmarklet may still not work on some sites that have a strict Content Security directive. + * We are working on making this bookmarklet into a browser extension! + * It might be best to include both in this repository; use the bookmarklet for older browsers, or in browsers where an extension has not yet been made. + #### Version 3.0.0 (8/24/2015) * Reformat code (clean up mixed tabs & spaces). @@ -40,5 +51,6 @@ print styling. ### Credits * By [Chris Coyier](http://chriscoyier.net) and [Devon Govett](http://devongovett.wordpress.com/). +* Some contributions by [Rob Garrison](http://wowmotty.blogspot.com/). * Icons by [Function](http://wefunction.com/2008/07/function-free-icon-set/). * Print stylesheet based on [Hartija](http://code.google.com/p/hartija/). diff --git a/demo/images/screenshot.png b/demo/images/screenshot.png index a36e785..2797122 100644 Binary files a/demo/images/screenshot.png and b/demo/images/screenshot.png differ diff --git a/index.html b/index.html index 53327ce..b09b80c 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@ To make changes, modify the "src/index.html" Here is the bookmarklet:

- Printliminator + Printliminator drag to your bookmarks bar

@@ -48,9 +48,12 @@ To make changes, modify the "src/index.html"

Credits

-

By Chris Coyier and Devon Govett. +

+ By Chris Coyier and Devon Govett. + Some contributions by Rob Garrison. Icons by Function. - Print stylesheet based on Hartija.

+ Print stylesheet based on Hartija. +

@@ -59,7 +62,7 @@ To make changes, modify the "src/index.html" ( function() { if ( window.location.origin === 'file://' ) { var link = document.getElementById( 'bookmarklet' ); - link.href = "javascript:/*PRINTLIMINATOR*/!function(){function%20a(a,b){var%20c=document.createElement('script'),d=document.getElementsByTagName('head')[0],e=!1;c.type='text/javascript',c.src=a,c.onload=c.onreadystatechange=function(){e||this.readyState&&'loaded'!=this.readyState&&'complete'!=this.readyState||(e=!0,b())},d.appendChild(c)}a('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js',function(){var%20b=jQuery.noConflict();a('src/printliminator.js',function(){csstricksPrintliminator(b)})})}();"; + link.href = "javascript:/*PRINTLIMINATOR*/!function(){function%20a(a,b){var%20c=document.createElement('script'),d=document.getElementsByTagName('head')[0],e=!1;c.type='text/javascript',c.src=a,c.onload=c.onreadystatechange=function(){e||this.readyState&&'loaded'!=this.readyState&&'complete'!=this.readyState||(e=!0,b())},d.appendChild(c)}a('src/printliminator.js',function(){csstricksPrintliminator()})}();"; document.getElementById('dev-mode').textContent = '(Dev Mode)'; } })(); diff --git a/package.json b/package.json index d69657b..a836162 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "printliminator", "title": "Printliminator", - "version": "3.0.0", + "version": "3.1.0", "description": "The Printliminator is a bookmarklet with some simple tools you can use to makes websites print better. One click to activate, and then click to remove elements from the page, remove graphics, and apply better print styling.", "author": { "name": "Chris Coyier", @@ -23,9 +23,7 @@ "bugs": "https://github.com/CSS-Tricks/The-Printliminator/issues", "docs": "https://github.com/CSS-Tricks/The-Printliminator/wiki", "demo": "https://css-tricks.github.io/The-Printliminator", - "dependencies": { - "jquery": "1.3.2" - }, + "dependencies": {}, "keywords": [ "print", "" diff --git a/printliminator.min.js b/printliminator.min.js index 9c85bfd..feb5e23 100644 --- a/printliminator.min.js +++ b/printliminator.min.js @@ -1 +1 @@ -function csstricksPrintliminator(a){var b=a.noConflict(),c=[],d={},e=("file://"===window.location.origin?"":"//css-tricks.github.io/The-Printliminator/")+"printliminator.png",f="._print_controls { position: fixed; top: 25px; right: 25px; width: 162px; height: 182px; z-index: 10000;-moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;background: url("+e+") no-repeat; }._print_controls_close { position: absolute; top: -20px; right: -20px; width: 33px; height: 33px;background: url("+e+") -222px -3px no-repeat; }._print_controls_close:hover { background-position: -222px -39px; }._print_controls_remove_graphics, ._print_controls_print, ._print_controls_undo, ._print_controls_stylize {position: absolute; height: 74px; width: 74px;background: url("+e+") no-repeat; }._print_controls_remove_graphics { top: 6px; left: 6px; background-position: 0px -182px; }._print_controls_remove_graphics:hover { background-position: 0 -256px; }._print_controls_remove_graphics.active { background-position: 0 -330px; }._print_controls_print { top: 83px; left: 83px; background-position: -74px -182px; }._print_controls_print:hover { background-position: -74px -256px; }._print_controls_print.active { background-position: -74px -330px; }._print_controls_undo { top: 83px; left: 6px; background-position: -148px -182px; }._print_controls_undo:hover { background-position: -148px -256px; }._print_controls_undo.active { background-position: -148px -330px; }._print_controls_stylize { top: 6px; left: 83px; background-position: -222px -182px; }._print_controls_stylize:hover { background-position: -222px -256px; }._print_controls_stylize.active { background-position: -222px -330px; }._print_removed { display: none !important; }._printliminator_highlight { outline: 3px solid red; }@media print{ ._print_controls { display: none; } }",g='@media print, screen {body { margin:0; padding:0; line-height: 1.4; word-spacing: 1.1pt; letter-spacing: 0.2pt;font-family: Garamond, "Times New Roman", serif; color: #000; background: none; font-size: 12pt; }h1, h2, h3, h4, h5, h6 { font-family: Helvetica, Arial, sans-serif; }h1 { font-size: 19pt; }h2 { font-size: 17pt; }h3 { font-size: 15pt; }h4, h5, h6 { font-size: 12pt; }code { font: 10pt Courier, monospace; }blockquote { margin: 1.3em; padding: 1em; font-size: 10pt; }hr { background-color: #ccc; }img { float: left; margin: 1em 1.5em 1.5em 0; }a img { border: none; }table { margin: 1px; text-align: left; border-collapse: collapse; }th { border: 1px solid #333; font-weight: bold; }td { border: 1px solid #333; }th, td { padding: 4px 10px; }tfoot { font-style: italic; }caption { background: #fff; margin-bottom: 20px; text-align: left; }thead {display: table-header-group; }tr { page-break-inside: avoid; }} @media screen { body { padding: 20px; } }';b('",a.addEvent(b.querySelector("."+a.css.noGraphics),"click",a.removeGraphics),a.addEvent(b.querySelector("."+a.css.print),"click",a.print),a.addEvent(b.querySelector("."+a.css.undo),"click",a.undo),a.addEvent(b.querySelector("."+a.css.stylize),"click",a.stylize),a.addEvent(b.querySelector("."+a.css.close),"click",a.abort),a.addEvent(b.querySelector("."+a.css.keyboard),"click",a.keyboard),a.addEvent(document.querySelector("."+a.css.drag),"mousedown",a.dragInit),a.addEvent(b,"mouseup",a.docMouseUp)},bodyClick:function(b){if(b.preventDefault(),b.stopImmediatePropagation(),"BODY"!==b.target.nodeName&&!a.hasClass(b.target,a.css.controls)){var c,d,e=document.querySelector("."+a.css.hilite);if(b[a.keys.opposite]){if(c=a.getOpposite(e),d=c.length,!d)return!1}else c=[e];a.hide(c),csstricksPrintliminatorVars.history.push(c),a.clearSelection()}},bodyMouseover:function(b){a.hasClass(b.target,a.css.controls)||a.addClass(b.target,a.css.hilite)},removeHighlight:function(){var b,c=document.querySelectorAll("."+a.css.hilite),d=c.length;for(b=0;d>b;b++)a.removeClass(c[b],a.css.hilite)},bodyKeyUp:function(b){b.preventDefault(),b.which===a.keys.print&&a.print()},bodyKeyDown:function(b){b.preventDefault();var c,d,e,f,g,h=document.querySelectorAll("body")[0],i=document.querySelectorAll("."+a.css.hilite)[0],j=a.css.hidden,k=a.css.hilite;if(i)switch(g="BODY"===i.nodeName,b.which){case a.keys.parent1:case a.keys.parent2:!g&&i.parentNode&&(a.removeClass(i,k),a.addClass(i.parentNode,k));break;case a.keys.child1:case a.keys.child2:f=Array.prototype.filter.call(i.children,a.filterElements),f.length&&(a.removeClass(i,k),a.addClass(f[0],k));break;case a.keys.nextSib:e=a.getNext(i),!g&&e&&(a.removeClass(i,k),a.addClass(e,k));break;case a.keys.prevSib:e=a.getPrev(i),!g&&e&&(a.removeClass(i,k),a.addClass(e,k));break;case a.keys.hide:g||(a.addClass(i,j),a.addClass(i.parentNode,k),csstricksPrintliminatorVars.history.push(i))}else i=b.target,a.addClass(i,k);switch(c=window.getComputedStyle(h,null).getPropertyValue("font-size"),d=c.match(/[a-z]+/i)[0],b.which){case a.keys.fontUp:h.style.fontSize=parseFloat(c)+1+d;break;case a.keys.fontDown:h.style.fontSize=parseFloat(c)-1+d;break;case a.keys.fontReset:h.style.fontSize="";break;case a.keys.undo:a.undo();break;case a.keys.abort:a.abort()}},dragInit:function(){var b=a.drag;b.el=document.querySelector("."+a.css.wrap),b.elm[0]=b.pos[0]-b.el.offsetLeft,b.elm[1]=b.pos[1]-b.el.offsetTop,a.toggleSelection(!0)},docMouseMove:function(b){var c=a.drag;c.pos[0]=document.all?window.event.clientX:b.pageX,c.pos[1]=document.all?window.event.clientY:b.pageY,null!==a.drag.el&&(c.el.style.left=c.pos[0]-c.elm[0]+"px",c.el.style.top=c.pos[1]-c.elm[1]+"px")},docMouseUp:function(){a.drag.el=null,a.toggleSelection()},stopSelection:function(){return!1},clearSelection:function(){var a=window.getSelection?window.getSelection():document.selection;a&&(a.removeAllRanges?a.removeAllRanges():a.empty&&a.empty())},toggleSelection:function(b){var c=document.querySelector("body");b?(a.savedUnsel=c.getAttribute("unselectable"),c.setAttribute("unselectable","on"),a.addClass(c,a.css.noSelection),a.addEvent(c,"onselectstart",a.stopSelection)):(a.savedUnsel&&c.setAttribute("unselectable",a.savedUnsel),a.removeClass(c,a.css.noSelection),a.removeEvent(c,"onselectstart",a.stopSelection)),a.clearSelection()},removeGraphics:function(){if(!csstricksPrintliminatorVars.flags.removeGraphics){var b,c,d=[],e=document.querySelector("body"),f=e.querySelectorAll(a.noGraphicsSelectors),g=e.querySelectorAll("*:not(."+a.css.controls+")"),h=g.length;for(b=0;h>b;b++)c=window.getComputedStyle(g[b]).getPropertyValue("background-image"),c&&"none"!==c&&(d.push([g[b],c]),g[b].style.backgroundImage="none");a.removeHighlight(),a.hide(f),csstricksPrintliminatorVars.flags.removeGraphics=!0,csstricksPrintliminatorVars.history.push(function(){for(csstricksPrintliminatorVars.flags.removeGraphics=!1,a.show(f),h=d.length,b=0;h>b;b++)d[b][0].style.backgroundImage=d[b][1]})}},stylize:function(){if(!csstricksPrintliminatorVars.flags.stylize){var b,c=[],d=document.querySelector("body"),e=document.querySelectorAll('link[rel="stylesheet"], style'),f=document.querySelectorAll("body *:not(."+a.css.hidden+"):not(."+a.css.controls+")"),g=e.length;for(b=0;g>b;b++)e[b].id!==a.css.stylesheet&&(e[b].disabled=!0);Array.prototype.filter.call(f,function(a){var b=a.getAttribute("style");null!==b&&(a.removeAttribute("style"),c.push({el:a,style:b}))}),a.addClass(d,a.css.stylized),a.removeHighlight(),csstricksPrintliminatorVars.flags.stylize=!0,csstricksPrintliminatorVars.history.push(function(){csstricksPrintliminatorVars.flags.stylize=!1,a.removeClass(d,a.css.stylized);var b,f=e.length;for(b=0;f>b;b++)e[b].disabled=!1;for(f=c.length,b=0;f>b;b++)c[b].el.setAttribute("style",c[b].style)})}},print:function(){a.removeHighlight(),window.print()},undo:function(){var b=csstricksPrintliminatorVars.history.pop();b&&(a.removeHighlight(),"function"!=typeof b?a.show(b):b.call())},keyboard:function(){var b=document.querySelector("."+a.css.wrap),c=b.querySelector("iframe."+a.css.controls),d=c.contentWindow.document.body,e=d.querySelector("#"+a.css.keyboard),f=d.querySelector("."+a.css.keyboard),g=e.style.display,h="none"===g;a[h?"addClass":"removeClass"](f,"active"),e.style.display=h?"":"none",b.style.height=(h?a.keyboardOpen:a.keyboardClosed)+5+"px",c.style.height=(h?a.keyboardOpen:a.keyboardClosed)+5+"px",d.style.height=(h?a.keyboardOpen:a.keyboardClosed)+"px"},abort:function(){var b=document.querySelector("body");a.removeHighlight(),a.removeEvent(b,"click",a.bodyClick),a.removeEvent(b,"mouseover",a.bodyMouseover),a.removeEvent(b,"mouseout",a.removeHighlight),a.removeEvent(document,"keyup",a.bodyKeyUp),a.removeEvent(document,"keydown",a.bodyKeyDown),a.removeEvent(document,"mouseup",a.docMouseUp),a.removeEvent(document,"mousemove",a.docMouseMove),b.removeChild(document.querySelector("."+a.css.wrap))},filterElements:function(b){return b&&1===b.nodeType&&!a.ignoredElm.test(b.nodeName)&&!a.hasClass(b,a.css.controls)&&!(a.hasClass(b,a.css.hidden)||"none"===b.style.display)},getOpposite:function(b){for(var c,d=[];"BODY"!==b.nodeName;)c=a.getSiblings(b),d=d.concat(c),b=b.parentNode;return d},getSiblings:function(b){for(var c=[],d=b.parentNode.firstChild;d;d=d.nextSibling)d!==b&&a.filterElements(d)&&c.push(d);return c},getNext:function(b){for(;b=b.nextSibling;)if(b&&a.filterElements(b))return b;return null},getPrev:function(b){for(;b=b.previousSibling;)if(b&&a.filterElements(b))return b;return null},hide:function(b){if(b){var c,d=b.length;if("undefined"!=typeof d)for(c=0;d>c;c++)a.addClass(b[c],a.css.hidden);else a.addClass(b,a.css.hidden)}},show:function(b){if(b){var c,d=b.length;if("undefined"!=typeof d)for(c=0;d>c;c++)a.removeClass(b[c],a.css.hidden);else a.removeClass(b,a.css.hidden)}},addClass:function(b,c){b.classList?b.classList.add(c):a.hasClass(b,c)||(b.className+=" "+c)},removeClass:function(a,b){a.classList?a.classList.remove(b):a.className=a.className.replace(new RegExp("\\b"+b+"\\b","g"),"")},hasClass:function(a,b){return a.classList?a.classList.contains(b):new RegExp("\\b"+b+"\\b").test(a.className)},addEvent:function(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener(b,c)},removeEvent:function(a,b,c){a.detachEvent?a.detachEvent("on"+b,c):a.removeEventListener(b,c)}};window.csstricksPrintliminator=function(){a.init()}}(); \ No newline at end of file diff --git a/printliminator.png b/printliminator.png deleted file mode 100644 index d117275..0000000 Binary files a/printliminator.png and /dev/null differ diff --git a/src/bookmarklet.js b/src/bookmarklet.js index 7185f8c..08ff42d 100644 --- a/src/bookmarklet.js +++ b/src/bookmarklet.js @@ -14,14 +14,10 @@ }; head.appendChild(script); } - // dev = http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js - // production = //ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js - loadScript('{jQuery}', function() { - var jQ132 = jQuery.noConflict(); - // dev = src/printliminator.js - // production = //css-tricks.github.io/The-Printliminator/printliminator.min.js - loadScript('{printliminator}', function() { - csstricksPrintliminator( jQ132 ); - }); + // dev = src/printliminator.js + // production = //css-tricks.github.io/The-Printliminator/printliminator.min.js + loadScript('{printliminator}', function() { + csstricksPrintliminator(); }); + })(); diff --git a/src/index.html b/src/index.html index abcc8e3..913e53e 100644 --- a/src/index.html +++ b/src/index.html @@ -41,9 +41,12 @@

Credits

-

By Chris Coyier and Devon Govett. +

+ By Chris Coyier and Devon Govett. + Some contributions by Rob Garrison. Icons by Function. - Print stylesheet based on Hartija.

+ Print stylesheet based on Hartija. +

diff --git a/src/printliminator.js b/src/printliminator.js index 91403fb..5d7f201 100644 --- a/src/printliminator.js +++ b/src/printliminator.js @@ -1,199 +1,748 @@ -/* Printliminator */ -function csstricksPrintliminator( jQ ) { - // remove conflicts with other javascript libraries - var $ = jQ.noConflict(), - history = [], - flags = {}, - // if local, load local sprite image - sprite = ( window.location.origin === 'file://' ? '' : '//css-tricks.github.io/The-Printliminator/' ) + - 'printliminator.png', - // programmically added stylesheets - styles = '' + - '._print_controls { position: fixed; top: 25px; right: 25px; width: 162px; height: 182px; z-index: 10000;' + - '-moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;' + - 'background: url(' + sprite + ') no-repeat; }' + - '._print_controls_close { position: absolute; top: -20px; right: -20px; width: 33px; height: 33px;' + - 'background: url(' + sprite + ') -222px -3px no-repeat; }' + - '._print_controls_close:hover { background-position: -222px -39px; }' + - '._print_controls_remove_graphics, ._print_controls_print, ._print_controls_undo, ._print_controls_stylize {' + - 'position: absolute; height: 74px; width: 74px;' + - 'background: url(' + sprite + ') no-repeat; }' + - '._print_controls_remove_graphics { top: 6px; left: 6px; background-position: 0px -182px; }' + - '._print_controls_remove_graphics:hover { background-position: 0 -256px; }' + - '._print_controls_remove_graphics.active { background-position: 0 -330px; }' + - '._print_controls_print { top: 83px; left: 83px; background-position: -74px -182px; }' + - '._print_controls_print:hover { background-position: -74px -256px; }' + - '._print_controls_print.active { background-position: -74px -330px; }' + - '._print_controls_undo { top: 83px; left: 6px; background-position: -148px -182px; }' + - '._print_controls_undo:hover { background-position: -148px -256px; }' + - '._print_controls_undo.active { background-position: -148px -330px; }' + - '._print_controls_stylize { top: 6px; left: 83px; background-position: -222px -182px; }' + - '._print_controls_stylize:hover { background-position: -222px -256px; }' + - '._print_controls_stylize.active { background-position: -222px -330px; }' + - '._print_removed { display: none !important; }' + - '._printliminator_highlight { outline: 3px solid red; }' + - '@media print{ ._print_controls { display: none; } }', - - printstylesheet = '@media print, screen {' + - 'body { margin:0; padding:0; line-height: 1.4; word-spacing: 1.1pt; letter-spacing: 0.2pt;' + - 'font-family: Garamond, "Times New Roman", serif; color: #000; background: none; font-size: 12pt; }' + - 'h1, h2, h3, h4, h5, h6 { font-family: Helvetica, Arial, sans-serif; }' + - 'h1 { font-size: 19pt; }' + - 'h2 { font-size: 17pt; }' + - 'h3 { font-size: 15pt; }' + - 'h4, h5, h6 { font-size: 12pt; }' + - 'code { font: 10pt Courier, monospace; }' + - 'blockquote { margin: 1.3em; padding: 1em; font-size: 10pt; }' + - 'hr { background-color: #ccc; }' + - 'img { float: left; margin: 1em 1.5em 1.5em 0; }' + - 'a img { border: none; }' + - 'table { margin: 1px; text-align: left; border-collapse: collapse; }' + - 'th { border: 1px solid #333; font-weight: bold; }' + - 'td { border: 1px solid #333; }' + - 'th, td { padding: 4px 10px; }' + - 'tfoot { font-style: italic; }' + - 'caption { background: #fff; margin-bottom: 20px; text-align: left; }' + - 'thead {display: table-header-group; }' + - 'tr { page-break-inside: avoid; }' + - '} @media screen { body { padding: 20px; } }'; - - $( ''; + + 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 { - $done = $this; + // hide clicked element + done = [ hilite ]; } - $done.addClass( '_print_removed' ); - history.push( $done ); - }) - .live( 'mouseover', function() { - $(this).addClass( '_printliminator_highlight' ); - }) - .live( 'mouseout', function() { - $(this).removeClass( '_printliminator_highlight' ); - }); - - var $controls = $( '
' ) - .appendTo( 'body' ); - - // fix IE6, which doesn't support position: fixed - if ( $controls.css( 'position' ) !== 'fixed' ) { - $controls.css( 'position', 'absolute' ); - } - // Remove Graphics - $( '
' ) - .click( function() { - if ( !flags.removeGraphics ) { - var indx, $el, bkgd, - bkgds = [], - $done = $( 'img, iframe, object, embed, input[type=image], ins' ), - $item = $( 'body *:not(._print_controls, ._print_controls *)' ), - len = $item.length; - for ( indx = 0; indx < len; indx++ ) { - $el = $item.eq( indx ); - bkgd = $el.css( 'background-image' ); - if ( bkgd !== 'none' ) { - bkgds.push( [ $el, bkgd ] ); - $el.css( 'background-image', 'none' ); + 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 ); } - } - $done.addClass( '_print_removed' ); - flags.removeGraphics = true; - - history.push( function() { - flags.removeGraphics = false; - $done.removeClass( '_print_removed' ); - var $el, - len = bkgds.length; - for ( indx = 0; indx < len; indx++ ) { - $el = bkgds[ indx ][ 0 ]; - $el.css( 'background-image', bkgds[ indx ][ 1 ] ); + 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; + } - }) - .appendTo( $controls ); - - // Print Stylize - $( '
' ) - .click( function() { - window.print(); - }) - .appendTo( $controls ); - - // Print - $( '
' ) - .click( function() { - if ( !flags.stylize ) { - var links = $( 'link[rel="stylesheet"], style:not(#_print_controls_styles)' ).remove(), - // cache and remove inline styles - inline = $( 'body *:not(._print_controls, ._print_controls > *, ._print_removed)' ).map( function() { - var $this = $( this ), - style = $this.attr( 'style' ); - $this.attr( 'style', '' ); - return { - el: this, + } 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 - }; - }), - print = $( '