daccd209dab05a75f5627390e37a6b764e93f547
5 * Sphinx JavaScript utilities for all documentation.
7 * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
8 * :license: BSD, see LICENSE for details.
13 * select a different prefix for underscore
18 * make the code below compatible with browsers without
19 * an installed firebug like debugger
20 if (!window.console || !console.firebug) {
21 var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
22 "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
23 "profile", "profileEnd"];
25 for (var i = 0; i < names.length; ++i)
26 window.console[names[i]] = function() {};
31 * small helper function to urldecode strings
33 jQuery
.urldecode = function(x
) {
34 return decodeURIComponent(x
).replace(/\+/g, ' ');
38 * small helper function to urlencode strings
40 jQuery
.urlencode
= encodeURIComponent
;
43 * This function returns the parsed url parameters of the
44 * current request. Multiple values per key are supported,
45 * it will always return arrays of strings for the value parts.
47 jQuery
.getQueryParameters = function(s
) {
48 if (typeof s
=== 'undefined')
49 s
= document
.location
.search
;
50 var parts
= s
.substr(s
.indexOf('?') + 1).split('&');
52 for (var i
= 0; i
< parts
.length
; i
++) {
53 var tmp
= parts
[i
].split('=', 2);
54 var key
= jQuery
.urldecode(tmp
[0]);
55 var value
= jQuery
.urldecode(tmp
[1]);
57 result
[key
].push(value
);
59 result
[key
] = [value
];
65 * highlight a given string on a jquery object by wrapping it in
66 * span elements with the given class name.
68 jQuery
.fn
.highlightText = function(text
, className
) {
69 function highlight(node
, addItems
) {
70 if (node
.nodeType
=== 3) {
71 var val
= node
.nodeValue
;
72 var pos
= val
.toLowerCase().indexOf(text
);
74 !jQuery(node
.parentNode
).hasClass(className
) &&
75 !jQuery(node
.parentNode
).hasClass("nohighlight")) {
77 var isInSVG
= jQuery(node
).closest("body, svg, foreignObject").is("svg");
79 span
= document
.createElementNS("http://www.w3.org/2000/svg", "tspan");
81 span
= document
.createElement("span");
82 span
.className
= className
;
84 span
.appendChild(document
.createTextNode(val
.substr(pos
, text
.length
)));
85 node
.parentNode
.insertBefore(span
, node
.parentNode
.insertBefore(
86 document
.createTextNode(val
.substr(pos
+ text
.length
)),
88 node
.nodeValue
= val
.substr(0, pos
);
90 var rect
= document
.createElementNS("http://www.w3.org/2000/svg", "rect");
91 var bbox
= node
.parentElement
.getBBox();
92 rect
.x
.baseVal
.value
= bbox
.x
;
93 rect
.y
.baseVal
.value
= bbox
.y
;
94 rect
.width
.baseVal
.value
= bbox
.width
;
95 rect
.height
.baseVal
.value
= bbox
.height
;
96 rect
.setAttribute('class', className
);
98 "parent": node
.parentNode
,
103 else if (!jQuery(node
).is("button, select, textarea")) {
104 jQuery
.each(node
.childNodes
, function() {
105 highlight(this, addItems
);
110 var result
= this.each(function() {
111 highlight(this, addItems
);
113 for (var i
= 0; i
< addItems
.length
; ++i
) {
114 jQuery(addItems
[i
].parent
).before(addItems
[i
].target
);
120 * backward compatibility for jQuery.browser
121 * This will be supported until firefox bug is fixed.
123 if (!jQuery
.browser
) {
124 jQuery
.uaMatch = function(ua
) {
125 ua
= ua
.toLowerCase();
127 var match
= /(chrome)[ \/]([\w.]+)/.exec(ua
) ||
128 /(webkit)[ \/]([\w.]+)/.exec(ua
) ||
129 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua
) ||
130 /(msie) ([\w.]+)/.exec(ua
) ||
131 ua
.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua
) ||
135 browser
: match
[ 1 ] || "",
136 version
: match
[ 2 ] || "0"
140 jQuery
.browser
[jQuery
.uaMatch(navigator
.userAgent
).browser
] = true;
144 * Small JavaScript module for the documentation.
146 var Documentation
= {
149 this.fixFirefoxAnchorBug();
150 this.highlightSearchWords();
151 this.initIndexTable();
152 if (DOCUMENTATION_OPTIONS
.NAVIGATION_WITH_KEYS
) {
153 this.initOnKeyListeners();
161 PLURAL_EXPR : function(n
) { return n
=== 1 ? 0 : 1; },
164 // gettext and ngettext don't access this so that the functions
165 // can safely bound to a different name (_ = Documentation.gettext)
166 gettext : function(string
) {
167 var translated
= Documentation
.TRANSLATIONS
[string
];
168 if (typeof translated
=== 'undefined')
170 return (typeof translated
=== 'string') ? translated
: translated
[0];
173 ngettext : function(singular
, plural
, n
) {
174 var translated
= Documentation
.TRANSLATIONS
[singular
];
175 if (typeof translated
=== 'undefined')
176 return (n
== 1) ? singular
: plural
;
177 return translated
[Documentation
.PLURALEXPR(n
)];
180 addTranslations : function(catalog
) {
181 for (var key
in catalog
.messages
)
182 this.TRANSLATIONS
[key
] = catalog
.messages
[key
];
183 this.PLURAL_EXPR
= new Function('n', 'return +(' + catalog
.plural_expr
+ ')');
184 this.LOCALE
= catalog
.locale
;
188 * add context elements like header anchor links
190 addContextElements : function() {
191 $('div[id] > :header:first').each(function() {
192 $('<a class="headerlink">\u00B6</a>').
193 attr('href', '#' + this.id
).
194 attr('title', _('Permalink to this headline')).
197 $('dt[id]').each(function() {
198 $('<a class="headerlink">\u00B6</a>').
199 attr('href', '#' + this.id
).
200 attr('title', _('Permalink to this definition')).
206 * workaround a firefox stupidity
207 * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
209 fixFirefoxAnchorBug : function() {
210 if (document
.location
.hash
&& $.browser
.mozilla
)
211 window
.setTimeout(function() {
212 document
.location
.href
+= '';
217 * highlight the search words provided in the url in the text
219 highlightSearchWords : function() {
220 var params
= $.getQueryParameters();
221 var terms
= (params
.highlight
) ? params
.highlight
[0].split(/\s+/) : [];
223 var body
= $('div.body');
227 window
.setTimeout(function() {
228 $.each(terms
, function() {
229 body
.highlightText(this.toLowerCase(), 'highlighted');
232 $('<p class="highlight-link"><a href="javascript:Documentation.' +
233 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
234 .appendTo($('#searchbox'));
239 * init the domain index toggle buttons
241 initIndexTable : function() {
242 var togglers
= $('img.toggler').click(function() {
243 var src
= $(this).attr('src');
244 var idnum
= $(this).attr('id').substr(7);
245 $('tr.cg-' + idnum
).toggle();
246 if (src
.substr(-9) === 'minus.png')
247 $(this).attr('src', src
.substr(0, src
.length
-9) + 'plus.png');
249 $(this).attr('src', src
.substr(0, src
.length
-8) + 'minus.png');
250 }).css('display', '');
251 if (DOCUMENTATION_OPTIONS
.COLLAPSE_INDEX
) {
257 * helper function to hide the search marks again
259 hideSearchWords : function() {
260 $('#searchbox .highlight-link').fadeOut(300);
261 $('span.highlighted').removeClass('highlighted');
265 * make the url absolute
267 makeURL : function(relativeURL
) {
268 return DOCUMENTATION_OPTIONS
.URL_ROOT
+ '/' + relativeURL
;
272 * get the current relative url
274 getCurrentURL : function() {
275 var path
= document
.location
.pathname
;
276 var parts
= path
.split(/\//);
277 $.each(DOCUMENTATION_OPTIONS
.URL_ROOT
.split(/\//), function() {
281 var url
= parts
.join('/');
282 return path
.substring(url
.lastIndexOf('/') + 1, path
.length
- 1);
285 initOnKeyListeners: function() {
286 $(document
).keydown(function(event
) {
287 var activeElementType
= document
.activeElement
.tagName
;
288 // don't navigate when in search box or textarea
289 if (activeElementType
!== 'TEXTAREA' && activeElementType
!== 'INPUT' && activeElementType
!== 'SELECT'
290 && !event
.altKey
&& !event
.ctrlKey
&& !event
.metaKey
&& !event
.shiftKey
) {
291 switch (event
.keyCode
) {
293 var prevHref
= $('link[rel="prev"]').prop('href');
295 window
.location
.href
= prevHref
;
299 var nextHref
= $('link[rel="next"]').prop('href');
301 window
.location
.href
= nextHref
;
310 // quick alias for translations
311 _
= Documentation
.gettext
;
313 $(document
).ready(function() {
314 Documentation
.init();