1var section; 2$(document).ready(function() { 3 4 var _this = this; 5 var rootDir = window.location.origin + "/"; 6 if( window.location.pathname.lastIndexOf( window.docsRoot + '/' ) >= 0 ){ 7 rootDir = window.location.pathname.substr(0, window.location.pathname.lastIndexOf( window.docsRoot + '/' ) + ( window.docsRoot.length + 1 ) ); 8 } 9 var windowHeight = window.innerHeight; 10 var input = document.querySelector( '#search-input' ); 11 12 var cinderJs = { 13 14 init: function(){ 15 this.selectNamspace( window.selectedNamespace ); 16 this.showContent( hash ); 17 this.adjustClassInfoLinks(); 18 $( input ).focus(); 19 }, 20 21 /* 22 * ---------------------------------------------------------------------- 23 * Selects the correct namepsace nav iten 24 * ---------------------------------------------------------------------- 25 */ 26 selectNamspace: function( namespace ){ 27 var selectedNs = $('#namespace-nav').find('[data-namespace="' + namespace + '"]'); 28 if( selectedNs ){ 29 selectedNs.addClass('active'); 30 } 31 }, 32 33 /* 34 * ---------------------------------------------------------------------- 35 * Unhides a piece of content if it contains a anchor tag with a 36 * specific hash 37 * @param {[type]} hash Hash name of the link 38 * ---------------------------------------------------------------------- 39 */ 40 showContent: function( hash ){ 41 if( !hash ) 42 return; 43 // find section with this hash 44 var linkTag = $('a[name='+hash+']')[0] || $('a[id='+hash+']')[0]; 45 if( linkTag != undefined ) { 46 // find parent 47 var linkParent = $(linkTag.parentNode); 48 // toggle show for this section 49 linkParent.removeClass("hidden"); 50 }; 51 }, 52 53 /* 54 * ---------------------------------------------------------------------- 55 * Scroll to anchor on link anchor click 56 * ---------------------------------------------------------------------- 57 */ 58 scrollToAnchor: function(){ 59 // return false; 60 // from https://css-tricks.com/snippets/jquery/smooth-scrolling/ 61 if( location.pathname.replace(/^\//,'') == this.pathname.replace( /^\//,'' ) && location.hostname == this.hostname ) { 62 var hash = this.hash; 63 var target = $( hash ); 64 target = target.length ? target : ($( '[name=' + this.hash.slice(1) +']' ) || $( '[id=' + this.hash.slice(1) +']' ) ); 65 66 if( target.length ) { 67 var limit = Math.max( document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight ) - window.innerHeight; 68 var top = Math.min( target.offset().top, limit ); 69 var diff = top - $( this ).scrollTop(); 70 var time = Math.max( Math.min( diff * 0.5, 1200 ), 500 ); 71 72 // animate to anchor 73 $( 'html,body' ).animate( { 74 scrollTop: top, 75 easing: "easeInOutCubic" 76 }, time ); 77 78 // open content at anchor 79 setTimeout(function() { 80 cinderJs.showContent( hash.split('#')[1] ); 81 }, time); 82 return false; 83 } 84 } 85 }, 86 87 /* 88 * ---------------------------------------------------------------------- 89 * Adjust column width for class info links based on the amount of 90 * columns that exist. 91 * ---------------------------------------------------------------------- 92 */ 93 adjustClassInfoLinks: function(){ 94 if( window.sectionType == 'classes' ){ 95 var infoColumns = $( '#container .info-links .columns' ); 96 var colAmt = infoColumns.length; 97 var colClass = 'max-' + ( 12 / colAmt ); 98 _.each( infoColumns, function( col ){ 99 $(col).addClass( colClass ); 100 } ); 101 } 102 103 } 104 }; 105 106 107 /* 108 * -------------------------------------------------------------------------- 109 * Side Nav 110 * -------------------------------------------------------------------------- 111 */ 112 var sideNav = { 113 main: null, 114 sections: [], 115 init: function(){ 116 117 // find all sideNav sections 118 this.main = $( '#side-nav' ); 119 this.sections = this.main.find( 'section' ); 120 121 // list depth of side nav 122 var baseDepth = this.main.parent('ul').length; 123 124 // Find the depth of each nested list and apply a class based on 125 // the depth value. This is used to style the lists. 126 _.each( this.sections, function( section ){ 127 var lists = $(section).find( 'ul' ); 128 129 _.each(lists, function( list ) { 130 // depth of list 131 var $list = $( list ); 132 var listDepth = $list.parents('ul').length - baseDepth; 133 $list.addClass( 'depth-' + listDepth ); 134 135 // For each list item, add a class if they have nested lists 136 var listItems = $list.find( 'li' ); 137 _.each( listItems, function( li ) { 138 $li = $( li ); 139 if( $li.find( 'ul' ).length > 0 ) { 140 $li.addClass( 'list-parent' ); 141 } 142 } ); 143 }); 144 145 // For each anchor, add magellan arival data 146 var anchorLinks = $(section).find( 'a' ); 147 _.each( anchorLinks, function( aLink ) { 148 $aLink = $( aLink ); 149 var hash = aLink.hash.split('#')[1]; 150 if( hash ){ 151 var magArrival = $('<span data-magellan-arrival="' + hash + '"></span>'); 152 $aLink.wrap( magArrival ); 153 } 154 155 // if the link is the same as the current page, make it active 156 if( aLink.href == window.location.href.split("#")[0] ) { 157 $aLink.parent('li').addClass('active'); 158 } 159 } ); 160 }); 161
162 // for each anchor in the content, wrap the anchor in magellan destination data 163 // For each anchor, add magellan arival data 164 $( '.content a[href*=#]:not([href=#])' ).click( function() { 165 cinderJs.scrollToAnchor.apply(this); 166 }); 167 168 // find all anchors with name or id 169 var anchorTags = $( '.content a[id], .content a[name]' ); 170 _.each( anchorTags, function( aTag ) { 171 $aTag = $( aTag ); 172 var hash = aTag['name'] || aTag['id']; 173 var magDestination = $('<span data-magellan-destination="' + hash + '"></span>'); 174 $aTag.wrap( magDestination ); 175 } ); 176 177 178 // table of contents 179 var tableSection = $( 'section.table label' ); 180 tableSection.on('click', function(){ 181 $(this).parent('section').toggleClass('active'); 182 }) 183 184 this.resize(); 185 }, 186 187 resize: function(){ 188 // change the max side nav height in relation to the window inner height 189 if( this.sections.length === 1 ) { 190 $( $( this.sections[0] ).find( 'ul' )[0] ).css( "max-height", window.innerHeight - 100 ); 191 } 192 } 193 }; 194 195 // look for all dom items with class 196 197 // find all expandable sections 198 var expandableSections = $( '.expandable' ); 199 expandableSections.each( function() { 200 201 var $this = $(this); 202 var content = $( $this.find('.content')[0] ); 203 var maxHeight = content.innerHeight(); 204 205 // set height to max height 206 content.css('height', maxHeight + 'px'); 207 208 // add a button 209 var button = $('<button class="expand"></button>'); 210 $this.prepend( button ); 211 212 // button.on('click', function(){ 213 $this.on('click', function(){ 214 $this.toggleClass('hidden'); 215 }); 216 217 // Hide all of the definition tags 218 if( $this.find( ".functionDef, .enumDef, .definitionCol" ).length > 0 ){ 219 $this.addClass("hidden"); 220 } 221 }); 222 223 224 // --- Open all and Close all --- 225 var showAll = function(){ 226 $( '.reference-lists .expandable' ).each( function(){ 227 var $this = $(this); 228 $this.removeClass("hidden"); 229 }); 230 }; 231 232 var hideAll = function(){ 233 $( '.reference-lists .expandable' ).each( function(){ 234 var $this = $(this); 235 $this.addClass("hidden"); 236 }); 237 }; 238 239 // attach show/hide all functionality 240 var show = $( '#show-hide a.show-all' ); 241 var hide = $( '#show-hide a.hide-all' ); 242 if( $( '.reference-lists .expandable' ).length > 1 ) { 243 $( '#show-hide' ).removeClass( 'hide' ); 244 $( '#show-hide a.show-all' ).on( 'click', showAll ); 245 $( '#show-hide a.hide-all' ).on( 'click', hideAll ); 246 } 247 248 249 // get anchor tag if there is one 250 var hash = window.location.hash.substring(1); 251 252 // --- Search stuff --- // 253 window.search = function (term) { 254 255 256 var resultsDiv = $( '#search-results' ); 257 // the search term must be at least 2 characters 258 if( term.length < 2 ){ 259 resultsDiv.hide(); 260 return; 261 } 262 263 var searchTerm = term.replace(":", " "); 264 var maxResults = 15; 265 var results = search_index.search( searchTerm ); 266 267 var classResults = $('#search-results-class'),
268 guideResults = $('#search-results-guide'), 269 nsResults = $('#search-results-namespace'), 270 refResults = $('#search-results-reference'), 271 moduleResults = $('#search-results-module'); 272 273 var classResultsUl = classResults.find('ul'), 274 guideResultsUl = guideResults.find('ul'); 275 nsResultsUl = nsResults.find('ul'); 276 refResultsUl = refResults.find('ul'); 277 moduleResultsUl = moduleResults.find('ul'); 278 279 var uls = [classResultsUl, guideResultsUl, nsResultsUl, refResultsUl, moduleResultsUl]; 280 var amtList = _.range( uls.length ).map(function () { return 0; }); 281 282 var appendResult = function(ul, li){ 283 var index = uls.indexOf(ul); 284 amtList[index]++; 285 ul.append(li); 286 }; 287 288 // empty out the uls 289 _.each( uls, function(ul) { 290 ul.empty(); 291 }); 292 293 if( results.length > 0 ){ 294 resultsDiv.show(); 295 } else { 296 resultsDiv.hide(); 297 return false; 298 } 299 300 // console.log ( 'results', results.length ); 301 302 // resultsDiv.append( resultsUl ); 303 for( var i in results ){ 304 var li = $("<li>"); 305 var result = results[i]; 306 var data = search_index_data.data[result.ref]; 307 var link = rootDir + data.link; 308 var type = data.type; 309 var a = $("<a href=" + link + "> " + data.title + "</a>" ); 310 li.append(a); 311 312 313 switch( type ){ 314 case 'class': 315 case 'struct': 316 appendResult( classResultsUl, li ); 317 break; 318 319 case 'guide': 320 appendResult( guideResultsUl, li ); 321 break; 322 323 case 'namespace': 324 appendResult( nsResultsUl, li ); 325 break; 326 327 case 'reference': 328 appendResult( refResultsUl, li ); 329 break; 330 331 case 'module': 332 appendResult( moduleResultsUl, li ); 333 break; 334 } 335 } 336 337 // remove empty values 338 amtList = _.filter(amtList, function(val){ return val > 0; }); 339 340 // find the max amount per category based on the number of results and the amount of populated categories 341 var categoryMax = maxResults; 342 if( results.length > maxResults ){ 343 categoryMax = Math.floor(Math.min(maxResults, results.length) / amtList.length); 344 } 345 346 // for each list in the array, only show if they have content 347 _.each( uls, function( ul ) { 348 var liArr = ul.find('li'); 349 var listLen = liArr.length; 350 if( listLen === 0) { 351 ul.parent().hide(); 352 }else{ 353 // remove extras 354 ul.find('li').slice(categoryMax, listLen).remove(); 355 ul.parent().show(); 356 } 357 }); 358 }; 359 360 $( '#search-results-view-all, #search-button' ).on( 'click', function(){ 361 var searchTerm = escape( input.value ); 362 window.location = rootDir + 'search.html?' + searchTerm; 363 } ); 364 365 /** 366 * Search keydown functionality 367 */ 368 $( input ).keydown( function( e ) { 369 var selected = $( $( '#search-results li.selected' )[0] ), // selected list item 370 parentContainer = selected.parents( 'div' ), // selected parent container 371 liList = $( '#search-results li' ); // list of all list items in search results 372 373 // press enter 374 if( e.keyCode == 13 ) { 375 if( selected.length ) { 376 window.location = selected.find('a')[0].href; 377 } 378 } 379 // press up 380 if (e.keyCode == 38) { 381 if( selected.length ){ 382 selected.removeClass("selected"); 383 384 // if no previous list item 385 if( selected.prev().length === 0 ){ 386 387 // find previous container 388 var prevContainer = parentContainer.prev().first(); 389 390 // the container has to exist and have list items 391 while( prevContainer.length > 0 && prevContainer.find( 'ul li' ).length === 0 ){ 392 prevContainer = prevContainer.prev().first(); 393 } 394 395 if( prevContainer.length > 0 ){ 396 // select the last item in the previous valid list 397 prevContainer.find('li').last().addClass('selected'); 398 } else{ 399 // last list item 400 liList.last().addClass("selected"); 401 } 402 } else { 403 selected.prev( '#search-results li' ).addClass("selected"); 404 } 405 } else { 406 // if nothing is selected, select the last search result 407 selected = $( '#search-results li' ).last(); 408 selected.addClass("selected"); 409 } 410 } 411 412 // press down 413 if (e.keyCode == 40) { 414 if( selected.length ){ 415 selected.removeClass("selected"); 416 417 // if no next list item 418 if( selected.next().length == 0) { 419 // find next container 420 var nextContainer = parentContainer.next().first(); 421 422 // the container has to exist and have list items 423 while( nextContainer.length > 0 && nextContainer.find( 'ul li' ).length === 0 ){ 424 nextContainer = nextContainer.next().first(); 425 } 426 427 if( nextContainer.length > 0 ){ 428 // select the last item in the next valid list 429 $(nextContainer.find('li')[0]).addClass('selected'); 430 } else{ 431 // first list item 432 liList.first().addClass("selected"); 433 } 434 } else { 435 selected.next().addClass("selected"); 436 } 437 } else { 438 // if nothing is selected, select the first search result 439 selected = $( '#search-results li' ).first(); 440 selected.addClass("selected"); 441 } 442 } 443 444 // esc 445 if (e.keyCode == 27) { 446 // clear input and clear search 447 input.value = ''; 448 search(''); 449 } 450 } ); 451 452 453 if( input ){ 454 input.addEventListener('input', function() 455 { 456 search(input.value); 457 }); 458 } 459 460 461 window.search_index = lunr(function () { 462 this.field('title', {boost: 5}); 463 this.field('tags', {boost: 10}
463); 464 this.field('body'); 465 this.ref('id'); 466 }); 467 468 function initSearch(){ 469 for(var item in search_index_data.data){ 470 var searchItem = search_index_data.data[item]; 471 // console.log(searchItem.tags); 472 search_index.add({ 473 id: searchItem.id, 474 title: searchItem.title, 475 body: searchItem.body, 476 tags: searchItem.tags 477 }); 478 } 479 } 480 481 482 /* 483 * ----------------------------------------------------- 484 * Scroll to anchor on link anchor click 485 * ----------------------------------------------------- 486 */ 487 $( function() { 488 $( 'a[href*=#]:not([href=#])' ).click( function() { 489 cinderJs.scrollToAnchor.apply(this); 490 }); 491 } ); 492 493 494 // initialization 495 cinderJs.init(); 496 sideNav.init(); 497 if( search_index_data ) 498 initSearch(); 499 500 // disable history pushState for local files, otherwise, magellan throws an error 501 if( location.protocol == "file:" ) { 502 history.pushState = false; 503 } 504 505 // set up magellan stuff 506 $(document).foundation({ 507 "magellan-expedition": { 508 // active_class: 'active', // specify the class used for active sections 509 // threshold: 40, // how many pixels until the magellan bar sticks, 0 = auto 510 destination_threshold: 35, // pixels from the top of destination for it to be considered active 511 // throttle_delay: 50, // calculation throttling to increase framerate 512 // fixed_top: 0, // top distance in pixels assigend to the fixed element on scroll 513 offset_by_height: false // whether to offset the destination by the expedition height. Usually you want this to be true, unless your expedition is on the side. 514 } 515 }); 516 $(document).foundation('magellan', 'offcanvas', 'reflow'); 517 518 519 // listen for resize 520 $( window ).on( 'resize', function(){ 521 windowHeight = window.innerHeight; 522 sideNav.resize(); 523 $('#search-results').css('max-height', windowHeight - 100); 524 } ); 525 return cinderJs; 526 } );
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.