michael@0: /* michael@0: * doctools.js michael@0: * ~~~~~~~~~~~ michael@0: * michael@0: * Sphinx JavaScript utilities for all documentation. michael@0: * michael@0: * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. michael@0: * :license: BSD, see LICENSE for details. michael@0: * michael@0: */ michael@0: michael@0: /** michael@0: * select a different prefix for underscore michael@0: */ michael@0: $u = _.noConflict(); michael@0: michael@0: /** michael@0: * make the code below compatible with browsers without michael@0: * an installed firebug like debugger michael@0: if (!window.console || !console.firebug) { michael@0: var names = ["log", "debug", "info", "warn", "error", "assert", "dir", michael@0: "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", michael@0: "profile", "profileEnd"]; michael@0: window.console = {}; michael@0: for (var i = 0; i < names.length; ++i) michael@0: window.console[names[i]] = function() {}; michael@0: } michael@0: */ michael@0: michael@0: /** michael@0: * small helper function to urldecode strings michael@0: */ michael@0: jQuery.urldecode = function(x) { michael@0: return decodeURIComponent(x).replace(/\+/g, ' '); michael@0: } michael@0: michael@0: /** michael@0: * small helper function to urlencode strings michael@0: */ michael@0: jQuery.urlencode = encodeURIComponent; michael@0: michael@0: /** michael@0: * This function returns the parsed url parameters of the michael@0: * current request. Multiple values per key are supported, michael@0: * it will always return arrays of strings for the value parts. michael@0: */ michael@0: jQuery.getQueryParameters = function(s) { michael@0: if (typeof s == 'undefined') michael@0: s = document.location.search; michael@0: var parts = s.substr(s.indexOf('?') + 1).split('&'); michael@0: var result = {}; michael@0: for (var i = 0; i < parts.length; i++) { michael@0: var tmp = parts[i].split('=', 2); michael@0: var key = jQuery.urldecode(tmp[0]); michael@0: var value = jQuery.urldecode(tmp[1]); michael@0: if (key in result) michael@0: result[key].push(value); michael@0: else michael@0: result[key] = [value]; michael@0: } michael@0: return result; michael@0: }; michael@0: michael@0: /** michael@0: * small function to check if an array contains michael@0: * a given item. michael@0: */ michael@0: jQuery.contains = function(arr, item) { michael@0: for (var i = 0; i < arr.length; i++) { michael@0: if (arr[i] == item) michael@0: return true; michael@0: } michael@0: return false; michael@0: }; michael@0: michael@0: /** michael@0: * highlight a given string on a jquery object by wrapping it in michael@0: * span elements with the given class name. michael@0: */ michael@0: jQuery.fn.highlightText = function(text, className) { michael@0: function highlight(node) { michael@0: if (node.nodeType == 3) { michael@0: var val = node.nodeValue; michael@0: var pos = val.toLowerCase().indexOf(text); michael@0: if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { michael@0: var span = document.createElement("span"); michael@0: span.className = className; michael@0: span.appendChild(document.createTextNode(val.substr(pos, text.length))); michael@0: node.parentNode.insertBefore(span, node.parentNode.insertBefore( michael@0: document.createTextNode(val.substr(pos + text.length)), michael@0: node.nextSibling)); michael@0: node.nodeValue = val.substr(0, pos); michael@0: } michael@0: } michael@0: else if (!jQuery(node).is("button, select, textarea")) { michael@0: jQuery.each(node.childNodes, function() { michael@0: highlight(this); michael@0: }); michael@0: } michael@0: } michael@0: return this.each(function() { michael@0: highlight(this); michael@0: }); michael@0: }; michael@0: michael@0: /** michael@0: * Small JavaScript module for the documentation. michael@0: */ michael@0: var Documentation = { michael@0: michael@0: init : function() { michael@0: this.fixFirefoxAnchorBug(); michael@0: this.highlightSearchWords(); michael@0: this.initIndexTable(); michael@0: }, michael@0: michael@0: /** michael@0: * i18n support michael@0: */ michael@0: TRANSLATIONS : {}, michael@0: PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, michael@0: LOCALE : 'unknown', michael@0: michael@0: // gettext and ngettext don't access this so that the functions michael@0: // can safely bound to a different name (_ = Documentation.gettext) michael@0: gettext : function(string) { michael@0: var translated = Documentation.TRANSLATIONS[string]; michael@0: if (typeof translated == 'undefined') michael@0: return string; michael@0: return (typeof translated == 'string') ? translated : translated[0]; michael@0: }, michael@0: michael@0: ngettext : function(singular, plural, n) { michael@0: var translated = Documentation.TRANSLATIONS[singular]; michael@0: if (typeof translated == 'undefined') michael@0: return (n == 1) ? singular : plural; michael@0: return translated[Documentation.PLURALEXPR(n)]; michael@0: }, michael@0: michael@0: addTranslations : function(catalog) { michael@0: for (var key in catalog.messages) michael@0: this.TRANSLATIONS[key] = catalog.messages[key]; michael@0: this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); michael@0: this.LOCALE = catalog.locale; michael@0: }, michael@0: michael@0: /** michael@0: * add context elements like header anchor links michael@0: */ michael@0: addContextElements : function() { michael@0: $('div[id] > :header:first').each(function() { michael@0: $('\u00B6'). michael@0: attr('href', '#' + this.id). michael@0: attr('title', _('Permalink to this headline')). michael@0: appendTo(this); michael@0: }); michael@0: $('dt[id]').each(function() { michael@0: $('\u00B6'). michael@0: attr('href', '#' + this.id). michael@0: attr('title', _('Permalink to this definition')). michael@0: appendTo(this); michael@0: }); michael@0: }, michael@0: michael@0: /** michael@0: * workaround a firefox stupidity michael@0: */ michael@0: fixFirefoxAnchorBug : function() { michael@0: if (document.location.hash && $.browser.mozilla) michael@0: window.setTimeout(function() { michael@0: document.location.href += ''; michael@0: }, 10); michael@0: }, michael@0: michael@0: /** michael@0: * highlight the search words provided in the url in the text michael@0: */ michael@0: highlightSearchWords : function() { michael@0: var params = $.getQueryParameters(); michael@0: var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; michael@0: if (terms.length) { michael@0: var body = $('div.body'); michael@0: window.setTimeout(function() { michael@0: $.each(terms, function() { michael@0: body.highlightText(this.toLowerCase(), 'highlighted'); michael@0: }); michael@0: }, 10); michael@0: $('
') michael@0: .appendTo($('#searchbox')); michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * init the domain index toggle buttons michael@0: */ michael@0: initIndexTable : function() { michael@0: var togglers = $('img.toggler').click(function() { michael@0: var src = $(this).attr('src'); michael@0: var idnum = $(this).attr('id').substr(7); michael@0: $('tr.cg-' + idnum).toggle(); michael@0: if (src.substr(-9) == 'minus.png') michael@0: $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); michael@0: else michael@0: $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); michael@0: }).css('display', ''); michael@0: if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { michael@0: togglers.click(); michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * helper function to hide the search marks again michael@0: */ michael@0: hideSearchWords : function() { michael@0: $('#searchbox .highlight-link').fadeOut(300); michael@0: $('span.highlighted').removeClass('highlighted'); michael@0: }, michael@0: michael@0: /** michael@0: * make the url absolute michael@0: */ michael@0: makeURL : function(relativeURL) { michael@0: return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; michael@0: }, michael@0: michael@0: /** michael@0: * get the current relative url michael@0: */ michael@0: getCurrentURL : function() { michael@0: var path = document.location.pathname; michael@0: var parts = path.split(/\//); michael@0: $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { michael@0: if (this == '..') michael@0: parts.pop(); michael@0: }); michael@0: var url = parts.join('/'); michael@0: return path.substring(url.lastIndexOf('/') + 1, path.length - 1); michael@0: } michael@0: }; michael@0: michael@0: // quick alias for translations michael@0: _ = Documentation.gettext; michael@0: michael@0: $(document).ready(function() { michael@0: Documentation.init(); michael@0: });