Skip to content

Instantly share code, notes, and snippets.

@mikelikespie
Created October 27, 2010 18:31
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mikelikespie/649650 to your computer and use it in GitHub Desktop.
Save mikelikespie/649650 to your computer and use it in GitHub Desktop.
This refreshes all the css on a page by changing the query string
/*
Add a bookmark to this
javascript:(function(){var c=document.getElementsByTagName("link");for(var d=0;d<c.length;d++){var a=c[d];if(a.rel=='stylesheet'||a.type=="text/css"){var e="css_buster_"+Math.floor(Math.random()*1000000000);var g=a.href.split("?",2);var f;if(g.length>1){var b=g[1].indexOf("&")==-1;if(b){f=e}else{f=g[1]+"&"+e}}else{f=e}a.href=g[0]+"?"+f}}})();
*/
(function() {
var links = document.getElementsByTagName('link');
for (var i = 0; i < links.length; i++) {
var l = links[i];
if (l.rel == 'stylesheet' || l.type == 'text/css') {
var rand_n = 'css_buster_' + Math.floor(Math.random() * 1000000000);
var splitted = l.href.split('?', 2);
var new_query_string;
// Does it already have a query string?
if (splitted.length > 1) {
// does it have params or just a cache buster
var has_amp = splitted[1].indexOf('&') == -1; // is it a query string?
// if it's just a cache buster, swap it out
if (has_amp) {
new_query_string = rand_n;
} else {
new_query_string = splitted[1] + '&' + rand_n;
}
} else {
new_query_string = rand_n;
}
l.href = splitted[0] + '?' + new_query_string;
}
}
})()
@kornelski
Copy link

type attribute is optional and not authoritative. You should be finding stylesheets by rel=stylesheet, not type.

@mikelikespie
Copy link
Author

@pornel good call. Made change

@justinperkins
Copy link

Check out ReCSS, basically the same but uses the current date (down to millisecond) instead of random numbers and doesn't get as complicated with the query string detection.

@eligrey
Copy link

eligrey commented Oct 28, 2010

@pornel Type is optional, but it is also authoritative. If a type of foo/bar is encountered, it should be ignored. In the future, everyone might be using CSSX (fictional), which uses XPath selectors instead of weak CSS selectors, and it would go in a rel=stylesheet link but might have a type of application/cssx. The if statement should be changed to l.rel === 'stylesheet' && (l.type === 'text/css' || !l.type).

Edit: Just realized that this code is stylesheet language-agnostic. Keep it as-is ;)

@kornelski
Copy link

@eligrey No, only rel matters. I can have:

<link rel=prefetch type=text/css href=x>

which is not a visible stylesheet, and there's no point forcing this to reload.

Type in HTML is only a hint. HTTP always overrides it. Besides, since HTML theoretically allows other stylesheet types than CSS, why take extra care to break that?

If check for rel=stylesheet seems unbelievably simple, then you might add check for rel="alternate stylesheet" (taking into account it's a space-separated token list) and link.disabled.

@eligrey
Copy link

eligrey commented Oct 28, 2010

@pornel I never said type=text/css alone signifies a stylesheet. I said "Type is optional, but it is also authoritative. If a type of foo/bar is encountered, it should be ignored". That means that "type isn't pointless", as you may have <link rel=stylesheet type=foo/bar href=x>, which should be ignored by a browser unless it actually supports a foo/bar stylesheet language. Also, if you read my if condition replacement, you'd see that I didn't drop requiring a rel=stylesheet. Though the thing is, you can't tell what types a browser supports, so the best way to check if a link is an active stylesheet would be l.sheet && !l.disabled.

@jney
Copy link

jney commented Oct 28, 2010

var splitted = l.href.split('?', 1); : splitted array limit is 1, so this condition can never happen : splitted.length > 1. or i am missing something ?

@tyler
Copy link

tyler commented Oct 28, 2010

The second parameter to split specifies the limit of the number splits, not the limit of the returned array. (In other words, the returned array is one greater than the number of splits.)

@jney
Copy link

jney commented Oct 28, 2010

I'm not sure i understand what you say. Actually i never used that parameter before. but here is what i got with Rhino :

js> "/style.css?foo".split('?', 0).length 
0
js> "/style.css?foo".split('?', 1).length
1
js> "/style.css?foo".split('?', 2).length
2
js> "/style.css?foo".split('?', 3).length
2

@mikelikespie
Copy link
Author

@jney Oh dang, you are indeed correct. I assumed the behavior was similar to python's .split. I guess JavaScript, Java, and Ruby is the number of elements max, whereas python is the number of splits max. Fixing code.

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