Skip to content

Instantly share code, notes, and snippets.

@jscher2000
Last active March 26, 2024 10:50
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save jscher2000/f29d5d12713fa9afb40029bdb55e9c99 to your computer and use it in GitHub Desktop.
Save jscher2000/f29d5d12713fa9afb40029bdb55e9c99 to your computer and use it in GitHub Desktop.
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
Copy link
Author

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
Copy link

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
Copy link

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

Example media query: @media screen, speech {}

@jscher2000
Copy link
Author

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
Copy link
Author

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
Copy link

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

@TyDraniu
Copy link

Once again thanks! 👍

@jl91
Copy link

jl91 commented Jul 19, 2019

THX <3

@jscher2000
Copy link
Author

jscher2000 commented Dec 27, 2019

Firefox 70 has a button for this now in the Page Inspector, small document icon on the same bar as "Filter Styles" in the Rules pane.

Fx71-page-inspector-print-media-simulation

@shula
Copy link

shula commented Mar 26, 2024

(2024-03-26, 5 years after last comment)

  1. the function doesn't work (chromium 122, firefox 123).
    Calling the function doesn't give any error.
    It's just ends immediately, silently, without any visible change to the page.

(p.s. i was hoping to convert it to a bookmarklet.)

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