1$(document).on('search.ready', function () { 2 initFuseSearch(); 3}); 4 5$(document).ajaxComplete(function() { 6 initFuseSearch(); 7}); 8 9function initFuseSearch(){ 10 //Stop arrow keys from default behaviour of moving before or after text so result selection can be done below 11 $('form .search-field').on('keydown', function (e) { 12 var _this = $(this); 13 if(e.keyCode == '13' && enterKey === 'search'){ 14 search(e, _this); 15 return false; 16 } 17 else if (e.keyCode == '38') { 18 return false; 19 } else if (e.keyCode == '40') { 20 return false; 21 } 22 }); 23 24 if(enterKey === 'search'){ 25 var searchfield = $('form .search-field'); 26 $(".portal-search .btn").click(function (e) { 27 search(e, searchfield.filter(':visible')); 28 return false; 29 }); 30 } 31 else{ 32 //Disable, only keyup used 33 $(".portal-search .btn").prop("disabled", true); 34 } 35 36 37 addSearch(); 38 39 var timeout; 40 var delay = 200; 41 42 if(enterKey !== 'search'){ 43 //Unbind the keyup and focus events so we can select a new index for fuse for portal page: 44 $('input#search').off('keyup focus'); 45 46 //on keydown, clear the countdown for the keypress search delay 47 $('input#search').on('keydown', function () { 48 clearTimeout(timeout); 49 }); 50 51 $('input#search').on('keyup focus', function (e) { 52 var _this = $(this); 53 clearTimeout(timeout); 54 timeout = setTimeout(function () { 55 if(enterKey === 'select'){ 56 //If the user is only using arrow keys to browse results, return false: 57 var isSearch = selectResults(e); 58 if (isSearch === false) { 59 return false; 60 } 61 } 62 search(e, _this); 63 }, 64 delay); 65 }); 66 } 67} 68 69var searchHighlighter; 70 71var $resultcontainer; 72 73var fuse; 74 75function addSearch() { 76 77 //For legacy HTML5: 78 if ($('ul#page-tools').length) { 79 $('ul#page-tools > li:first').html('<input placeholder="Search" type="text" class="form-control" id="search">'); 80 } else { 81 //For new HTML5: Only adds to the search field actually used in the current page 82 $('.portal-search .search-field, .navbar-form .search-field, .site-sidebar-search .search-field, .tool-search-form .search-field').attr('id', 'search'); 83 } 84 85 //For legacy, where the search container is not already there 86 if ($('.search-container').length == 0) {
87 $resultcontainer = $('<div id="search-container"><h2>Search results</h2><ul class="searchresults"></ul></div>'); 88 $resultcontainer.appendTo($('#content-wrapper, .content-wrapper')); 89 } else { 90 if ($("*[data-portal-language]").length) { 91 $resultcontainer = $("*[data-portal-language='" + portalLanguage + "'] .portal-search-result"); 92 } else { 93 $resultcontainer = $('.search-container'); 94 } 95 } 96 97 //Make sure it has the id, even if it's for 'preloaded' variant 98 $resultcontainer.attr('id', 'search-container'); 99 100 searchHighlighter = new Mark("ul.searchresults"); 101 102 $resultcontainer.click(function () { 103 hideSearch($resultcontainer); 104 }); 105 106 $('.portal-content, .site-content').click(function (e) { 107 if($(e.target).closest('.toolbar').length === 0){ 108 hideSearch($resultcontainer); 109 } 110 }); 111 112 hideSearch($resultcontainer); 113 114 var options = { 115 shouldSort: true, 116 threshold: fuse_threshold, 117 location: 10, 118 distance: 100000, 119 maxPatternLength: 32, 120 minMatchCharLength: 4, 121 keys:[ { 122 name: 'title', 123 weight: 0.7 124 }, { 125 name: 'body', 126 weight: 0.3 127 }] 128 }; 129 130 //The index variable is created by xslt in the fuzzydata.js file. 131 if (typeof index == "undefined") { 132 fuse = new Fuse(indexDict[portalLanguage], options) 133 } else { 134 fuse = new Fuse(index, options) 135 } 136} 137 138function search(e, searchfield) { 139 // Get query 140 var query = searchfield.val(); 141 // Search for it 142 var result = fuse.search(query); 143 144 var $ul = $('ul.searchresults', $resultcontainer); 145 146 // Output it 147 if (query === '') { 148 $ul.empty(); 149 hideSearch($resultcontainer); 150 } else if (result.length === 0) { 151 $ul.empty(); 152 $('.noresults').show(); 153 showSearch($resultcontainer); 154 } else { 155 // Show results 156 $ul.empty(); 157 $('.noresults').hide(); 158 if ($('.portal-search-result').length) { 159 $('footer[data-portal-language="' + portalLanguage + '"]').hide(); 160 } 161 162 for (var item in result) { 163 //For permalinks: data-topic-level will only be set if produce.permalink = 1 in XSLT 164 var topiclevel = $('section[data-topic-level]').first().attr('data-topic-level'); 165 var up = ''; 166 167 if (topiclevel != '') { 168 for (i = 1; i < parseInt(topiclevel); 169 i++) { 170 up += '../'; 171 } 172 } 173 174 var url = up + result[item].url; 175 176 //If this is the portal/index page: 177 if ($('.portal-search-result').length) { 178 url = portalLanguage + '/' + result[item].url; 179 } 180 181 var pathdisplay = ''; 182 var breadcrumbs = result[item].breadcrumbs; 183 if (typeof breadcrumbs !== "undefined") { 184 pathdisplay = '<p class="search-result-breadcrumbs">' + result[item].breadcrumbs + '</p>'; 185 } else { 186 pathdisplay = '<p class="search-result-url">' + url + '</p>'; 187 } 188 189 //If there's a video in the topic it has the string [video]: 190 var checkvideo = result[item].body.substring(0,7); 191 var videosearchicon = ''; 192 if(checkvideo == '[video]'){ 193 //console.log('video'); 194 videosearchicon = '<span class="video-search-icon" style="margin-left: 0.5em"><i class="fa fa-film" aria-hidden="true"></i></span>' 195 } 196 197 if (result[item].snippet !== '') { 198 var $li = $('<li></li>') 199 .addClass('searchresultitem'); 200 201 var $a = $('<a></a>') 202 .attr('href', url); 203 204 var $h3 = $('<h3></h3>') 205 .addClass('searchresulttitle') 206 .html(result[item].title + videosearchicon); 207 208 var $p = $('<p></p>') 209 .addClass('searchresultsnippet') 210 .text(result[item].snippet); 211 212 $a 213 .append($h3) 214 .append($p) 215 .append(pathdisplay) 216 .appendTo($li); 217 } else { 218 var $li = $('<li></li>') 219 .addClass('searchresultitem-nosnippet'); 220 221 var $a = $('<a></a>') 222 .attr('href', url) 223 .text(result[item].title); 224 225 $li.append($a); 226 } 227 228 $ul.append($li); 229 } 230 231 showSearch($resultcontainer); 232 233 searchHighlighter.mark(query, { 234 "className": "search-highlight" 235 }); 236 } 237 } 238 239function showSearch($resultcontainer) { 240 $resultcontainer.show(); 241 if(enterKey === 'select'){ 242 $('.searchresults .searchresultitem:first').addClass('selected-searchresultitem'); 243 } 244 $('#topic-content').hide(); 245} 246 247function hideSearch($resultcontainer) { 248 var input = $('form .search-field:visible'); 249 //Do not hide results if the input has focus and is not empty 250 if (input.is(":focus") && input.val() !== '') { 251 return; 252 } 253 $resultcontainer.hide(); 254 if ($('.portal-search-result').length) { 255 $('footer[data-portal-language="' + portalLanguage + '"]').show(); 256 } 257 $('.noresults').hide(); 258 259 $('#topic-content').show(); 260} 261 262function selectResults(e) { 263 //Let the user browse search results by arrow keys and select by Enter (handled in html5-2-mp-common.js). 264 if (e.keyCode == '38') { 265 if ($('.selected-searchresultitem').is(':first-child')) { 266 return false;
267 } else { 268 var _this = $('.selected-searchresultitem'); 269 _this.removeClass('selected-searchresultitem'); 270 _this.prev().addClass('selected-searchresultitem'); 271 var _new = $('.selected-searchresultitem'); 272 if (_new.index() <= 1) { 273 $(window).scrollTop(0); 274 } else { 275 _new[0].scrollIntoView(); 276 window.scrollBy(0, -80); 277 } 278 return false; 279 } 280 } else if (e.keyCode == '40') { 281 if ($('.selected-searchresultitem').is(':last-child')) { 282 return false; 283 } else { 284 var _this = $('.selected-searchresultitem'); 285 _this.removeClass('selected-searchresultitem'); 286 _this.next().addClass('selected-searchresultitem'); 287 var _new = $('.selected-searchresultitem'); 288 if (_new.index() > 1) { 289 _new[0].scrollIntoView(); 290 window.scrollBy(0, -80); 291 } 292 293 return false; 294 } 295 } 296 return true; 297}
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.