1// Scrollbar Width function 2function getScrollBarWidth() { 3 var inner = document.createElement('p'); 4 inner.style.width = "100%"; 5 inner.style.height = "200px"; 6 7 var outer = document.createElement('div'); 8 outer.style.position = "absolute"; 9 outer.style.top = "0px"; 10 outer.style.left = "0px"; 11 outer.style.visibility = "hidden"; 12 outer.style.width = "200px"; 13 outer.style.height = "150px"; 14 outer.style.overflow = "hidden"; 15 outer.appendChild(inner); 16 17 document.body.appendChild(outer); 18 var w1 = inner.offsetWidth; 19 outer.style.overflow = 'scroll'; 20 var w2 = inner.offsetWidth; 21 if (w1 == w2) w2 = outer.clientWidth; 22 23 document.body.removeChild(outer); 24 25 return (w1 - w2); 26}; 27 28function setMenuHeight() { 29 $('#sidebar .highlightable').height($('#sidebar').innerHeight() - $('#header-wrapper').height() - 40); 30} 31 32function fallbackMessage(action) { 33 var actionMsg = ''; 34 var actionKey = (action === 'cut' ? 'X' : 'C'); 35 36 if (/iPhone|iPad/i.test(navigator.userAgent)) { 37 actionMsg = 'No support :('; 38 } 39 else if (/Mac/i.test(navigator.userAgent)) { 40 actionMsg = 'Press â-' + actionKey + ' to ' + action; 41 } 42 else { 43 actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action; 44 } 45 46 return actionMsg; 47} 48 49// for the window resize 50$(window).resize(function() { 51 setMenuHeight(); 52}); 53 54// debouncing function from John Hann 55// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ 56(function($, sr) { 57 58 var debounce = function(func, threshold, execAsap) { 59 var timeout; 60 61 return function debounced() { 62 var obj = this, args = arguments; 63 64 function delayed() { 65 if (!execAsap) 66 func.apply(obj, args); 67 timeout = null; 68 }; 69 70 if (timeout) 71 clearTimeout(timeout); 72 else if (execAsap) 73 func.apply(obj, args); 74 75 timeout = setTimeout(delayed, threshold || 100); 76 }; 77 } 78 // smartresize 79 jQuery.fn[sr] = function(fn) { return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); }; 80 81})(jQuery, 'smartresize'); 82 83 84jQuery(document).ready(function() { 85 var sidebarStatus = searchStatus = 'open'; 86 87 // set the menu height 88 setMenuHeight(); 89 90 jQuery('#overlay').on('click', function() { 91 jQuery(document.body).toggleClass('sidebar-hidden'); 92 sidebarStatus = (jQuery(document.body).hasClass('sidebar-hidden') ? 'closed' : 'open'); 93 94 return false; 95 }); 96 97 jQuery('.scrollbar-inner').scrollbar(); 98 99 jQuery('[data-sidebar-toggle]').on('click', function() { 100 jQuery(document.body).toggleClass('sidebar-hidden'); 101 sidebarStatus = (jQuery(document.body).hasClass('sidebar-hidden') ? 'closed' : 'open'); 102 103 return false; 104 }); 105 jQuery('[data-clear-history-toggle]').on('click', function() { 106 sessionStorage.clear(); 107 location.reload(); 108 return false; 109 }); 110 jQuery('[data-search-toggle]').on('click', function() { 111 if (sidebarStatus == 'closed') { 112 jQuery('[data-sidebar-toggle]').trigger('click'); 113 jQuery(document.body).removeClass('searchbox-hidden'); 114 searchStatus = 'open'; 115 116 return false; 117 } 118 119 jQuery(document.body).toggleClass('searchbox-hidden'); 120 searchStatus = (jQuery(document.body).hasClass('searchbox-hidden') ? 'closed' : 'open'); 121 122 return false; 123 }); 124 125 var ajax; 126 jQuery('[data-search-input]').on('input', function() { 127 var input = jQuery(this), 128 value = input.val(), 129 items = jQuery('[data-nav-id]'); 130 131 items.removeClass('search-match'); 132 if (!value.length) { 133 $('ul.topics').removeClass('searched'); 134 items.css('display', 'block'); 135 sessionStorage.removeItem('search-value'); 136 $(".highlightable").unhighlight({ element: 'mark' }) 137 return; 138 } 139 140 sessionStorage.setItem('search-value', value); 141 $(".highlightable").unhighlight({ element: 'mark' }).highlight(value, { element: 'mark' }); 142 143 if (ajax && ajax.abort) ajax.abort(); 144 ajax = jQuery.ajax({ 145 url: input.data('search-input') + ':' + value 146 }).done(function(data) { 147 if (data && data.results && data.results.length) { 148 items.css('display', 'none'); 149 $('ul.topics').addClass('searched');
150 data.results.forEach(function(navitem) { 151 jQuery('[data-nav-id="' + navitem + '"]').css('display', 'block').addClass('search-match'); 152 jQuery('[data-nav-id="' + navitem + '"]').parents('li').css('display', 'block'); 153 }); 154 } 155 ; 156 157 }); 158 jQuery('[data-search-clear]').on('click', function() { 159 jQuery('[data-search-input]').val('').trigger('input'); 160 sessionStorage.removeItem('search-input'); 161 $(".highlightable").unhighlight({ element: 'mark' }) 162 }); 163 }); 164 165 if (sessionStorage.getItem('search-value')) { 166 jQuery(document.body).removeClass('searchbox-hidden'); 167 jQuery('[data-search-input]').val(sessionStorage.getItem('search-value')); 168 jQuery('[data-search-input]').trigger('input'); 169 } 170 171 // clipboard 172 var clipInit = false; 173 $('code').each(function() { 174 var code = $(this), 175 text = code.text(); 176 177 if (text.length > 5) { 178 if (!clipInit) { 179 var text, clip = new Clipboard('.copy-to-clipboard', { 180 text: function(trigger) { 181 text = $(trigger).prev('code').text(); 182 return text.replace(/^\$\s/gm, ''); 183 } 184 }); 185 186 var inPre; 187 clip.on('success', function(e) { 188 e.clearSelection(); 189 inPre = $(e.trigger).parent().prop('tagName') == 'PRE'; 190 $(e.trigger).attr('aria-label', 'Copied to clipboard!').addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's')); 191 }); 192 193 clip.on('error', function(e) { 194 inPre = $(e.trigger).parent().prop('tagName') == 'PRE'; 195 $(e.trigger).attr('aria-label', fallbackMessage(e.action)).addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's')); 196 $(document).one('copy', function(){ 197 $(e.trigger).attr('aria-label', 'Copied to clipboard!').addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's')); 198 }); 199 }); 200 201 clipInit = true; 202 } 203
204 code.after('<span class="copy-to-clipboard" title="Copy to clipboard" />'); 205 code.next('.copy-to-clipboard').on('mouseleave', function() { 206 $(this).attr('aria-label', null).removeClass('tooltipped tooltipped-s tooltipped-w'); 207 }); 208 } 209 }); 210 211 // allow keyboard control for prev/next links 212 jQuery(function() { 213 jQuery('.nav-prev').click(function(){ 214 location.href = jQuery(this).attr('href'); 215 }); 216 jQuery('.nav-next').click(function() { 217 location.href = jQuery(this).attr('href'); 218 }); 219 }); 220 221 jQuery(document).keydown(function(e) { 222 // prev links - left arrow key 223 if(e.which == '37') { 224 jQuery('.nav.nav-prev').click(); 225 } 226 227 // next links - right arrow key 228 if(e.which == '39') { 229 jQuery('.nav.nav-next').click(); 230 } 231 }); 232 233}); 234 235jQuery(window).on('load', function() { 236 237 function adjustForScrollbar() { 238 if ((parseInt(jQuery('#body-inner').height()) + 83) >= jQuery('#body').height()) { 239 jQuery('.nav.nav-next').css({ 'margin-right': getScrollBarWidth() }); 240 } else { 241 jQuery('.nav.nav-next').css({ 'margin-right': 0 }); 242 } 243 } 244 245 // adjust sidebar for scrollbar 246 adjustForScrollbar(); 247 248 jQuery(window).smartresize(function() { 249 adjustForScrollbar(); 250 }); 251 252 // store this page in session 253 sessionStorage.setItem(jQuery('body').data('url'), 1); 254 255 // loop through the sessionStorage and see if something should be marked as visited 256 for (var url in sessionStorage) { 257 if (sessionStorage.getItem(url) == 1) jQuery('[data-nav-id="' + url + '"]').addClass('visited'); 258 } 259 260 261 $(".highlightable").highlight(sessionStorage.getItem('search-value'), { element: 'mark' }); 262}); 263 264$(function() { 265 $('a[rel="lightbox"]').featherlight({ 266 root: 'section#body' 267 }); 268}); 269 270jQuery.extend({ 271 highlight: function(node, re, nodeName, className) { 272 if (node.nodeType === 3) { 273 var match = node.data.match(re); 274 if (match) { 275 var highlight = document.createElement(nodeName || 'span'); 276 highlight.className = className || 'highlight'; 277 var wordNode = node.splitText(match.index); 278 wordNode.splitText(match[0].length); 279 var wordClone = wordNode.cloneNode(true); 280 highlight.appendChild(wordClone); 281 wordNode.parentNode.replaceChild(highlight, wordNode); 282 return 1; //skip added node in parent 283 } 284 } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 285 !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 286 !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 287 for (var i = 0; i < node.childNodes.length; i++) { 288 i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 289 } 290 } 291 return 0; 292 } 293}); 294 295jQuery.fn.unhighlight = function(options) { 296 var settings = { 297 className: 'highlight', 298 element: 'span' 299 }; 300 jQuery.extend(settings, options); 301 302 return this.find(settings.element + "." + settings.className).each(function() { 303 var parent = this.parentNode; 304 parent.replaceChild(this.firstChild, this); 305 parent.normalize(); 306 }).end(); 307}; 308 309jQuery.fn.highlight = function(words, options) { 310 var settings = { 311 className: 'highlight', 312 element: 'span', 313 caseSensitive: false, 314 wordsOnly: false 315 }; 316 jQuery.extend(settings, options); 317 318 if (!words) { return; } 319 320 if (words.constructor === String) { 321 words = [words]; 322 } 323 words = jQuery.grep(words, function(word, i) { 324 return word != ''; 325 }); 326 words = jQuery.map(words, function(word, i) { 327 return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 328 }); 329 if (words.length == 0) { return this; } 330 ; 331 332 var flag = settings.caseSensitive ? "" : "i"; 333 var pattern = "(" + words.join("|") + ")"; 334 if (settings.wordsOnly) { 335 pattern = "\\b" + pattern + "\\b"; 336 } 337 var re = new RegExp(pattern, flag); 338 339 return this.each(function() { 340 jQuery.highlight(this, re, settings.element, settings.className); 341 }); 342};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.