Playing with user scripts

March 6th, 2010 § 0

I’m taking a rather fun algorithms course with a website that reddit loves but I do not. I decided to turn this dire, lolcat-overloaded, situation into an opportunity to practice some javascript (without jQuery) and to write my first userscript.

User scripts are javascript files with the extension ‘.user.js’ that are executed client-side to add functionality to a web page. They are natively supported by chrome and opera and are supported via extensions in most other browsers of any note. (Some include Greasemonkey for Firefox, GreaseKit for Safari and Trixie for IE).

I succeeded in reskinning the whole website which was pretty fun. There seems to be a limit to the usefulness of userscripts in that support for the ‘@run-at document-start’ flag which I believe should make the script run before any scripts on the page do, is not supported by most browsers. It’s not all that useful a flag anyway as I imagine you’d often want the script to run after the DOM has been written so that you can work with the content expected to be on the page. In this case however it would be useful as I attempt to strip out a script on the course page that redirects 1% of all hits to a rickroll (sigh). As such the script still runs before the userscript and so the rickrolling still happens.

I might also put some more time into the replacement style sheet some time soon.

CS16 course site

OriginalCS16 course site with userscript and restyle

Reshaped and restyled

Code after the break.

Final Code:

// ==UserScript==
// @name           !cs16chan
// @namespace      http://zethrae.us
// @description    Strips mematic content from the cs16 course website
// @include        http://cs.brown.edu/courses/cs016/*
// @include        http://www.cs.brown.edu/courses/cs016/*
// @run-at document-start
// ==/UserScript==

(function() {
 //the following function is from http://snipplr.com/view/1696/get-elements-by-class-name/
 //the internet claims that document.getElementsByClassName() is supported in firefox 3.
 //this doesn't seem to be the case on the CIT machines, so I guess this will have to do.
 //and yes. if i was writing this again, I'd just include and use jquery.
 function getElementsByClassName(classname, node) {
 if(!node) node = document.getElementsByTagName("body")[0];
 var a = [];
 var re = new RegExp('\\b' + classname + '\\b');
 var els = node.getElementsByTagName("*");
 for(var i=0,j=els.length; i<j; i++)
 if(re.test(els[i].className))a.push(els[i]);
 return a;
 }

function insertAfter(parent, node, referenceNode) {
 parent.insertBefore(node, referenceNode.nextSibling);
}

function strip_css_js(){
 var jsToRemove = document.getElementsByTagName("script");
 for (var i=jsToRemove.length; i>=0; i--){
 if (jsToRemove[i] && jsToRemove[i].getAttribute("src")!=null){
 jsToRemove[i].parentNode.removeChild(jsToRemove[i]);
 }
 }
 var cssToRemove = document.getElementsByTagName("link")
 for (var i=cssToRemove.length; i>=0; i--){
 if (cssToRemove[i] && cssToRemove[i].getAttribute("href")!=null){
 cssToRemove[i].parentNode.removeChild(cssToRemove[i]);
 }
 }
 }

function import_css(source) {
 var link = document.createElement("link");
 link.href = source;
 link.rel = "stylesheet";
 link.type = "text/css";
 document.getElementsByTagName("head")[0].appendChild(link);
}

//removes memes that won't be wiped by the fix_markup function
function strip_inline_memes(){
 var tagline = document.getElementById('tagline');
 tagline.parentNode.removeChild(tagline);

 var footer = document.getElementById('footer');
 footer.parentNode.removeChild(footer);

 var images = document.getElementsByTagName("img")
 for (var i=images.length; i>=0; i--){
 if (images[i]){
 images[i].parentNode.removeChild(images[i]);
 }
 }

var memesbyclass = getElementsByClassName('preH1').concat(getElementsByClassName('postH1'))
 for (var i=memesbyclass.length; i>=0; i--){
 if (memesbyclass[i]){
 memesbyclass[i].parentNode.removeChild(memesbyclass[i]);
 }
 }

}
function fix_markup(){
 var header = document.getElementById('header');
 header.parentNode.removeChild(header);

 var head1 = getElementsByClassName('h1')
 for (var i=head1.length; i>=0; i--){
 if (head1[i]){
 var newheader = document.createElement("div");
 newheader.innerHTML = "<h1>CS16 / "+ head1[i].innerHTML +"</h1>";
 head1[i].parentNode.replaceChild(newheader,head1[i]);
 }
 }

 var nav = document.getElementById('nav');
 var navcontent = nav.innerHTML;
 var newnav = document.createElement("div");
 newnav.id = "navigation";
 newnav.innerHTML = navcontent;
 nav.parentNode.removeChild(nav);

 var content = document.getElementById('content');
 content.insertBefore(newnav, content.firstChild.nextSibling.nextSibling.nextSibling.nextSibling);

}

strip_css_js();
strip_inline_memes();
fix_markup();
import_css("http://zethrae.us/work/bangCS16chan/style.css");
})();

This was all intended to be tongue in cheek. But yes, memes from ’06 are rather annoying to see every day. And there wasn’t even longcat.

Tagged: , , , ,

§ Leave a Reply

What's this?

You are currently reading Playing with user scripts at zethrae.us/blog.

meta