Instantly share code, notes, and snippets.

Embed
What would you like to do?
Emulate print media in Firefox 62 (userscript work in progress)
// For Firefox's Web Console, creates the functions showAsPrint() and undoShowAsPrint()
// to roughly emulate print media and revert
function showAsPrint(){
var docSS = document.styleSheets, ss, oldMedia, newMedia, rules;
var p2s = function(media){
if (media.indexOf('all') > -1) return media; //no need to change
if (media == 'print') return 'all, wasprint'; //show on screen, too
if (media.indexOf('print') > -1 && media.indexOf('screen') > -1) return media; //no need to change
if (media == 'screen') return 'wasscreen'; //hide these rules
if (media.indexOf('screen') > -1) return media.replace('screen', 'wasscreen'); //hide these rules
if (media.trim().slice(0,1) == '(' && media.trim().slice(-1) == ')') return media; //too hard to parse
return media + ', WTF'; //for debugging only
}
for (var i=0; i<docSS.length; i++) {
ss = docSS[i];
if (!ss.disabled){
if (ss.ownerNode && ss.ownerNode.id.indexOf('stylus-') == -1 && ss.ownerNode.id.indexOf('stylish-') == -1){
// check link or style tag for media attribute and edit as needed
if (ss.ownerNode.hasAttribute('media') && ss.ownerNode.getAttribute('media') != 'all'){
oldMedia = ss.ownerNode.getAttribute('media');
newMedia = p2s(oldMedia);
if (newMedia != oldMedia){
//console.log('Updating: ' + ss.ownerNode.outerHTML + ' to ' + newMedia);
ss.ownerNode.setAttribute('media', newMedia);
}
}
// check content of style sheet for media rules
try {
rules = ss.cssRules;
} catch(err) {
console.log('Can\'t access cssRules for ' + ss.href + ' due to: ' + err );
rules = [];
}
for (var j=0; j<rules.length; j++){
if (rules[j].type == 4){
oldMedia = rules[j].conditionText;
newMedia = p2s(oldMedia);
if (newMedia != oldMedia){
//console.log('Updating CSSMediaRule from ' + oldMedia + ' to ' + newMedia);
rules[j].conditionText = newMedia;
}
}
}
} else if (!ss.ownerNode){
console.log('No .ownerNode on i=' + i);
}
}
}
}
function undoShowAsPrint(){
var docSS = document.styleSheets, ss, oldMedia, newMedia, rules;
var unp2s = function(media){
if (media == 'all, wasprint' || media == 'all,wasprint') return 'print'; //undo applying to screen
if (media == 'wasscreen') return 'screen'; //undo hiding
if (media.indexOf('wasscreen') > -1) return media.replace('wasscreen', 'screen'); //undo hiding
return media; // otherwise, we didn't mess with it
}
for (var i=0; i<docSS.length; i++) {
ss = docSS[i];
if (!ss.disabled){
if (ss.ownerNode && ss.ownerNode.id.indexOf('stylus-') == -1 && ss.ownerNode.id.indexOf('stylish-') == -1){
// check link or style tag for media attribute and edit as needed
if (ss.ownerNode.hasAttribute('media') && ss.ownerNode.getAttribute('media') != 'all'){
oldMedia = ss.ownerNode.getAttribute('media');
newMedia = unp2s(oldMedia);
if (newMedia != oldMedia){
//console.log('Restoring: ' + ss.ownerNode.outerHTML + ' to ' + newMedia);
ss.ownerNode.setAttribute('media', newMedia);
}
} else {
// check content of style sheet for media rules
try {
rules = ss.cssRules;
} catch(err) {
console.log('Can\'t access cssRules for ' + ss.href + ' due to: ' + err );
rules = [];
}
for (var j=0; j<rules.length; j++){
if (rules[j].type == 4){
oldMedia = rules[j].conditionText;
newMedia = unp2s(oldMedia);
if (newMedia != oldMedia){
//console.log('Restoring CSSMediaRule from ' + oldMedia + ' to ' + newMedia);
rules[j].conditionText = newMedia;
}
}
}
}
} else if (!ss.ownerNode){
console.log('No .ownerNode on i=' + i);
}
}
}
}
@jscher2000

This comment has been minimized.

Copy link
Owner

jscher2000 commented Sep 21, 2018

The above does not call a function, so add

showAsPrint();

to the end when pasting into the Web Console* to run that function. Until the page is reloaded, you don't need to reinject the script, just call either function.

BSD-3-clause license.

*https://developer.mozilla.org/docs/Tools/Web_Console

@SetTrend

This comment has been minimized.

Copy link

SetTrend commented Dec 11, 2018

Would you mind moving p2s() and unp2s() as nested functions into the bodies of showAsPrint() and undoShowAsPrint()? That would improve legibility and avoid confusion about whether they are public and may be called by users or not.

@SetTrend

This comment has been minimized.

Copy link

SetTrend commented Dec 11, 2018

unp2s() doesn't undo p2s(), line 8.

Example media query: @media screen, speech {}

@jscher2000

This comment has been minimized.

Copy link
Owner

jscher2000 commented Dec 11, 2018

Would you mind moving p2s() and unp2s() as nested functions into the bodies of showAsPrint() and undoShowAsPrint()? That would improve legibility and avoid confusion about whether they are public and may be called by users or not.

Yes, it should all be in one object. If I were a programmer, I'm sure I would have thought of that originally.

unp2s() doesn't undo p2s(), line 8.

Example media query: @media screen, speech {}

Hmm, yes, I missed that. An additional line is needed.

Maybe tonight.

@jscher2000

This comment has been minimized.

Copy link
Owner

jscher2000 commented Dec 12, 2018

Updated to address both of those issues, and also problems with halting on some cross-origin style sheets due to a security error (from https://support.mozilla.org/questions/1235041).

@LordPachelbel

This comment has been minimized.

Copy link

LordPachelbel commented Dec 18, 2018

This script was really really helpful for me today. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment