/* austlii.js
- * Bookmarklet to add annotation tools to AustLII cases.
- * Invoke with:
+ * Bookmarklet to add annotation tools to AustLII cases. Invoke with:
* javascript:var d=document;var s=d.createElement("script");s.src="http://splintax.ucc.asn.au/austlii/austlii.js";s.type="text/javascript";d.getElementsByTagName('head').item(0).appendChild(s); */
+// create a namespace for this tool
window.austlii = {
VERSION: '0.1',
load: function(url, cb) {
s.rel = "stylesheet"; s.type = "text/css"; s.href = url;
document.getElementsByTagName('head').item(0).appendChild(s); return;
},
- init: function() {
- if (window.location.host.slice(-14) != "austlii.edu.au" ||
- window.location.pathname.slice(0,10) != "/au/cases/" ||
- window.location.pathname.slice(-5) != ".html")
- console.log("You're not looking at a case on AustLII.");
- else
- austlii.main();
- },
- prune: function() {
- // Remove all but the newest script tag containing the queries passed in as arguments.
- for (var i = 0; i < arguments.length; i++) {
- var $els = $("head script[src*="+arguments[i]+"]");
- var toRemove = $els.slice(0,-1);
- if (toRemove.length > 0) {
- toRemove.remove();
- console.log("Removed "+toRemove.length+" stale scripts matching '"+arguments[i]+"'...");
- }
- }
- },
+ url: function(relative_path) {
+ // return url relative to the source of this file, eg. http://splintax.ucc.asn.au/austlii/
+ var prefix = $('script[src$="austlii.js"]').attr('src').replace(/austlii\.js/, "");
+ return prefix + relative_path;
+ }
};
+// Initialises once jQuery is loaded.
austlii.main = function() {
+ austlii.style(austlii.url("austlii.css")); // inject css
+ // set viewport width so iPad doesn't zoom out
+ $("head").append('<meta name="viewport" content="initial-scale=1.0" />');
+ $("a").slice(10,16).css({"margin-right": "1em"}); // space out "Database Search", ... links
- // grab austlii.css from the same directory as this JavaScript
- var cssUrl = $('script[src$="austlii.js"]').attr('src').replace(/austlii\.js/, "austlii.css");
- austlii.style(cssUrl);
+ austlii.markup();
+ austlii.menu();
+ $(window).scroll(austlii.scrollHandler).scroll();
- austlii.cleanup();
- austlii.addMarkup();
- austlii.paintMenu();
+ // enable smooth scrolling on anchors
+ // TODO: doing this synchronously makes for slow injection on mobile browsers
+ austlii.load(austlii.url("jquery.scrollTo-1.4.2-min.js"), function() {
+ austlii.load(austlii.url("jquery.localscroll-1.2.7-min.js"), function() {
+ $.localScroll({duration: '200'});
+ });
+ });
-};
+ // TODO: user annotations
+ $("#trigger-highlight").click(austlii.highlight);
+}
-austlii.cleanup = function() {
- // remove text nodes ([] surrounding "Download", etc)
- // var textNodes = $("body").contents().filter(function(){return this.nodeType == 3;}).remove();
- // remove unnecessary <br />s
+// Cleans up page and adds semantic markup.
+austlii.markup = function() {
+ // remove cruft
$("br").remove();
-};
-
-austlii.addMarkup = function() {
+ $('img[alt="AustLII"]').detach().prependTo("body");
+ $("table").remove();
- // add back to top around header
- $("h1").eq(1).wrap('<a name="top">');
-
- // highlight case title
- $("center i").first().parent().addClass("citation");
+ $("h1").wrap('<a class="section" name="top">'); // add back-to-top
+ $('a[name="fn1"]').addClass("section"); // mark beginning of footnotes
// find and markup judges
- // var judgeExp = /([A-Zc]+\s)([A-Zc,\s]+\sC?JJ?\.)/g;
- var judgeExp = /([A-Z]{3})((?:[A-Z\s,]| )+C?J?J\.)/g
- var replacementText = document.body.innerHTML.replace(judgeExp, '<a class="judge" name="$1">$1$2</a>');
+ var judgeExp = /([A-Zc]{3})((?:[A-Z\s,]| )+C?J?J\.)/g
+ /* This regex is confusing and I keep breaking it. Remember:
+ * [A-Zc] is used to match McHUGH J.
+ * Since we're matching innerHTML is not part of \s.
+ * The first 3 characters are captured, hopefully because they are ASCII non-whitespace
+ * suitable for use in the <a name>. */
+ var replacementText = document.body.innerHTML.replace(judgeExp, '<a class="section" name="$1">$1$2</a>');
document.body.innerHTML = replacementText;
-
};
-austlii.paintMenu = function() {
-
- // create menu
- var $menu = $('<div id="menu"><ol></ol></div>');
- $("body").append($menu);
-
- // add fixed link to headnote
- $("#menu ol").append('<li><a href="#top">Headnote</a></li>')
+// Updates responsive menu whenever the page is scrolled.
+austlii.scrollHandler = function() {
+ var currentPosition = $(window).scrollTop() + $(window).height()/2;
+
+ var $anchors = $("#container a.section");
+ var $links = $("#menu ol li a");
+ var $pars = $("#container ol li").not("ol ol li");
+
+ // remove existing section highlight and citation
+ $links.removeClass("current");
+ $("#menu .pinpoint").remove();
+
+ // find the current document section
+ var $anchor = $anchors.filter(function(){
+ // is this anchor above the fold?
+ return currentPosition > $(this).offset().top;
+ }).last(); // current section = last anchor above fold
+ // highlight the link to the current document section
+ $links.filter('[href="#' + $anchor.attr("name") + '"]').addClass("current");
+
+ // check whether we're in the judgment body
+ if ( currentPosition > $pars.first().offset().top &&
+ currentPosition < $pars.last().offset().top ) {
+ // we are, so find the current paragraph and add a pinpoint citation
+ var $par = $pars.filter(function(){
+ // is this paragraph above the fold?
+ return currentPosition > $(this).offset().top;
+ }).last(); // current paragraph = last paragraph above fold
+ if ( $par.val() != 0 ) { // don't add unofficial paragraph citations on old cases
+ // TODO: make it work anyway, but add a warning?
+ var $pinpoint = $('<span class="pinpoint"> at ['+ $par.val() +']</span>');
+ $("#menu a.current").after($pinpoint); // add citation
+ }
+ }
+};
- // add jumplinks for each judge
- $("a.judge").each(function(){
- var $li = $('<li><a href="#' + this.name + '">' + $(this).html() + '</a></li>');
- $("#menu ol").append($li);
+// Create the responsive menu.
+austlii.menu = function() {
+ // wrap the source body content in a container
+ $("body").children().wrapAll('<div id="container" />');
+
+ // create and prepend menu to the page
+ var $menu = $('<div id="menu"></div>');
+ $('<h2>'+ $("h2").first().html() +'</h2>').prependTo($menu); // add header
+ $('img[alt="AustLII"]').detach().prependTo($menu);
+ $menu.prependTo("body");
+
+ // create and insert links in the menu
+ var $links = $('<ol />');
+ // headnote
+ $links.append('<li><a href="#top">Headnote</a><span class="spacer">·</span></li>')
+ // judgments
+ var $judges = $("a.section").slice(1,-1);
+ $judges.each(function(i){
+ var li = '<li><a href="#' + this.name + '">' + $(this).html().slice(0,-1) + '</a>';
+ if ( i < $judges.length )
+ li += '<span class="spacer">·</span>'
+ li += '</li>';
+ $links.append(li);
});
-
- // add fixed link to footnotes
- $("#menu ol").append('<li><a href="#fn1">Footnotes</a></li>');
+ // footnotes
+ $links.append('<li><a href="#fn1">Footnotes</a></li>');
+ $menu.append($links);
// add annotation features
//$menu.append($('<a id="trigger-highlight" href="#">Highlight</a>'));
-
- // enable smooth scrolling on anchors
- austlii.load("http://splintax.ucc.asn.au/austlii/jquery.scrollTo-1.4.2-min.js", function() {
- austlii.load("http://splintax.ucc.asn.au/austlii/jquery.localscroll-1.2.7-min.js", function() {
- $.localScroll({duration: '200'});
- });
- });
-
- // update current judge on scroll
- $(window).scroll(function() {
- $("#menu ol li a").each(function(){
- // if the relevant link appearsmore than half way down the page
- var $anchor = $('a[name="'+$(this).attr("href").slice(1)+'"]');
- if ($(window).scrollTop() + $(window).height()/2 > $anchor.offset().top) {
- austlii.$currentSection = $(this);
- }
- });
- $("#menu ol li a").not(austlii.$currentSection).removeClass("current");
- austlii.$currentSection.addClass("current");
- }); $(window).scroll(); // and run it once
-
- $("#trigger-highlight").click(austlii.highlight);
-
};
+// FIXME Highlight the current selection.
austlii.highlight = function(event) {
event.preventDefault();
var sel = document.getSelection();
else {console.log("You haven't highlighted anything.")}
};
-if (document.getElementsByTagName("script").length == 1) {
- console.log("Loaded austlii.js v"+austlii.VERSION+".");
- austlii.load('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', austlii.init);
-} else {
- alert("austlii.js will not run when there are other scripts on the page.");
+// don't run on other sites
+if (window.location.host.slice(-14) != "austlii.edu.au" ||
+ window.location.pathname.slice(0,10) != "/au/cases/" ||
+ window.location.pathname.slice(-5) != ".html")
+ console.error("You're not looking at a case on AustLII.");
+
+else if (document.getElementsByTagName("script").length > 1)
+ console.error("austlii.js will not run when there are other scripts on the page.");
+
+else {
+ console.log("Loaded austlii.js.");
+ // load jQuery and initialise the bookmarklet
+ austlii.load('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', austlii.main);
}