PageSourceSearch

https://libcinder.org/docs/_assets/js/cinder.js

js libcinder.org collected 2026-10-01 10:35:04 UTC 15,754 bytes, 526 lines download raw bytes

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.