Ruby on Rails API/wiki integration

By Henrik N Last update May 4, 2006 — Installed 363 times.
// ==UserScript==
// @name           Ruby on Rails API/wiki integration
// @namespace      http://henrik.nyh.se
// @description    Provides links (that open iframes) in the Rails API, to suitably named pages of the Rails wiki. The idea is to integrate the two better, somewhat like the PHP.net manual. Obviously, this script becomes a lot more useful if it (or at least its wiki page naming convention) is widely adopted.
// @include        http://api.rubyonrails.tld/*
// @include        http://wiki.rubyonrails.tld/*
// ==/UserScript==

// TODO: Integrate into API better, rather than using an iframe. Show # of revisions? HEAD request to see if page exists? How to get 301 status what with GM's redirect?
// TODO: Not only wiki pages for methods, but also "sectiontitles"? And one per class/module?
// TODO: Link to open in new window, link to enlarge iframe

function xp(query) { return document.evaluate(query, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); }

// API config

var title = /(?:Module|Class): (.+)/;
var methods = xp("//div[@class='title']//b");
var wikibase = "http://wiki.rubyonrails.com/rails/pages/";
var wiki_link_show_text = "show wiki page";
var wiki_link_hide_text = "hide wiki page";


// Someone set us up the gatekeeper

if (location.href.indexOf("http://api.") == 0)
	api();
else
	wiki();


// API pages

function api() {
	
	var lookupTable = {};

	var m = title.exec(document.title);
	if (m == null) return;  // There is no class/module here, so bail
	
	var klass = m[1];
	var methods_count = methods.snapshotLength;
	if (!methods_count) return;  // There are no methods here, so bail
	
	for (var i = 0; i < methods_count; i++) {
		var method = methods.snapshotItem(i);
		var method_uri = method.innerHTML.replace('?', '_');
		var fq_method = klass + '.' + method_uri;
		
		var method_id = /name="([M\d]+)"/.exec(method.parentNode.innerHTML)[1];
		
		var source_link = document.getElementById("l_" + method_id + "_source");
		if (!source_link) continue;  // Method aliases will not have a source link - so skip ahead
		
		var delim = document.createTextNode(" | ");
		var a = document.createElement("a");
		a.innerHTML = wiki_link_show_text;
		a.href = wikibase + fq_method;
		lookupTable[a.href] = method_id;
		
		a.addEventListener('click', show_wiki_page, false);
	
		// Juggle into place
		source_link.parentNode.insertBefore(delim, source_link);
		source_link.parentNode.insertBefore(source_link, delim);
		source_link.parentNode.insertBefore(a, delim);
		source_link.parentNode.insertBefore(delim, a);
		
	}
	
	function show_wiki_page(event) {
			event.preventDefault();  // Don't follow the link
			var url = this.href, id = lookupTable[this.href];  // There must be a nicer solution?
			var iframe_id = id + "_iframe";
			var iframe = document.getElementById(iframe_id);
			
			if (!iframe) {
				// Create iframe
				iframe = document.createElement("iframe");
				iframe.id = iframe_id;
				iframe.src = url; // + '#pageName';
				iframe.style.width = '100%';
				iframe.style.height = '350px';	
				this.parentNode.parentNode.appendChild(iframe);
				this.innerHTML = wiki_link_hide_text;
			} else if (iframe.style.display == 'none') {
				// Show iframe
				iframe.style.display = 'block';
				this.innerHTML = wiki_link_hide_text;
			} else {
				// Hide iframe
				iframe.style.display = 'none';
				this.innerHTML = wiki_link_show_text;
			}
	
	}

}


// Wiki pages

function wiki() {

	h = document.getElementById('pageName');
	h.innerHTML = h.innerHTML.replace(/(::|\.)/g, '$1<span style="font-size:0"> </span>');  // Allow long titles to wrap

	if (window.top == self) return;  // Don't bother if we're not in an (i)frame
	
	c = document.getElementById('Container');
	c.style.margin = '5px';
	
}