| /* | 
 |  * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. | 
 |  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
 |  * | 
 |  * This code is free software; you can redistribute it and/or modify it | 
 |  * under the terms of the GNU General Public License version 2 only, as | 
 |  * published by the Free Software Foundation.  Oracle designates this | 
 |  * particular file as subject to the "Classpath" exception as provided | 
 |  * by Oracle in the LICENSE file that accompanied this code. | 
 |  * | 
 |  * This code is distributed in the hope that it will be useful, but WITHOUT | 
 |  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
 |  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
 |  * version 2 for more details (a copy is included in the LICENSE file that | 
 |  * accompanied this code). | 
 |  * | 
 |  * You should have received a copy of the GNU General Public License version | 
 |  * 2 along with this work; if not, write to the Free Software Foundation, | 
 |  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
 |  * | 
 |  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
 |  * or visit www.oracle.com if you need additional information or have any | 
 |  * questions. | 
 |  */ | 
 |  | 
 | var noResult = {l: "No results found"}; | 
 | var loading = {l: "Loading search index..."}; | 
 | var catModules = "Modules"; | 
 | var catPackages = "Packages"; | 
 | var catTypes = "Classes and Interfaces"; | 
 | var catMembers = "Members"; | 
 | var catSearchTags = "Search Tags"; | 
 | var highlight = "<span class=\"result-highlight\">$&</span>"; | 
 | var searchPattern = ""; | 
 | var fallbackPattern = ""; | 
 | var RANKING_THRESHOLD = 2; | 
 | var NO_MATCH = 0xffff; | 
 | var MIN_RESULTS = 3; | 
 | var MAX_RESULTS = 500; | 
 | var UNNAMED = "<Unnamed>"; | 
 | function escapeHtml(str) { | 
 |     return str.replace(/</g, "<").replace(/>/g, ">"); | 
 | } | 
 | function getHighlightedText(item, matcher, fallbackMatcher) { | 
 |     var escapedItem = escapeHtml(item); | 
 |     var highlighted = escapedItem.replace(matcher, highlight); | 
 |     if (highlighted === escapedItem) { | 
 |         highlighted = escapedItem.replace(fallbackMatcher, highlight) | 
 |     } | 
 |     return highlighted; | 
 | } | 
 | function getURLPrefix(ui) { | 
 |     var urlPrefix=""; | 
 |     var slash = "/"; | 
 |     if (ui.item.category === catModules) { | 
 |         return ui.item.l + slash; | 
 |     } else if (ui.item.category === catPackages && ui.item.m) { | 
 |         return ui.item.m + slash; | 
 |     } else if (ui.item.category === catTypes || ui.item.category === catMembers) { | 
 |         if (ui.item.m) { | 
 |             urlPrefix = ui.item.m + slash; | 
 |         } else { | 
 |             $.each(packageSearchIndex, function(index, item) { | 
 |                 if (item.m && ui.item.p === item.l) { | 
 |                     urlPrefix = item.m + slash; | 
 |                 } | 
 |             }); | 
 |         } | 
 |     } | 
 |     return urlPrefix; | 
 | } | 
 | function createSearchPattern(term) { | 
 |     var pattern = ""; | 
 |     var isWordToken = false; | 
 |     term.replace(/,\s*/g, ", ").trim().split(/\s+/).forEach(function(w, index) { | 
 |         if (index > 0) { | 
 |             // whitespace between identifiers is significant | 
 |             pattern += (isWordToken && /^\w/.test(w)) ? "\\s+" : "\\s*"; | 
 |         } | 
 |         var tokens = w.split(/(?=[A-Z,.()<>[\/])/); | 
 |         for (var i = 0; i < tokens.length; i++) { | 
 |             var s = tokens[i]; | 
 |             if (s === "") { | 
 |                 continue; | 
 |             } | 
 |             pattern += $.ui.autocomplete.escapeRegex(s); | 
 |             isWordToken =  /\w$/.test(s); | 
 |             if (isWordToken) { | 
 |                 pattern += "([a-z0-9_$<>\\[\\]]*?)"; | 
 |             } | 
 |         } | 
 |     }); | 
 |     return pattern; | 
 | } | 
 | function createMatcher(pattern, flags) { | 
 |     var isCamelCase = /[A-Z]/.test(pattern); | 
 |     return new RegExp(pattern, flags + (isCamelCase ? "" : "i")); | 
 | } | 
 | var watermark = 'Search'; | 
 | $(function() { | 
 |     var search = $("#search-input"); | 
 |     var reset = $("#reset-button"); | 
 |     search.val(''); | 
 |     search.prop("disabled", false); | 
 |     reset.prop("disabled", false); | 
 |     search.val(watermark).addClass('watermark'); | 
 |     search.blur(function() { | 
 |         if ($(this).val().length === 0) { | 
 |             $(this).val(watermark).addClass('watermark'); | 
 |         } | 
 |     }); | 
 |     search.on('click keydown paste', function() { | 
 |         if ($(this).val() === watermark) { | 
 |             $(this).val('').removeClass('watermark'); | 
 |         } | 
 |     }); | 
 |     reset.click(function() { | 
 |         search.val('').focus(); | 
 |     }); | 
 |     search.focus()[0].setSelectionRange(0, 0); | 
 | }); | 
 | $.widget("custom.catcomplete", $.ui.autocomplete, { | 
 |     _create: function() { | 
 |         this._super(); | 
 |         this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)"); | 
 |     }, | 
 |     _renderMenu: function(ul, items) { | 
 |         var rMenu = this; | 
 |         var currentCategory = ""; | 
 |         rMenu.menu.bindings = $(); | 
 |         $.each(items, function(index, item) { | 
 |             var li; | 
 |             if (item.category && item.category !== currentCategory) { | 
 |                 ul.append("<li class=\"ui-autocomplete-category\">" + item.category + "</li>"); | 
 |                 currentCategory = item.category; | 
 |             } | 
 |             li = rMenu._renderItemData(ul, item); | 
 |             if (item.category) { | 
 |                 li.attr("aria-label", item.category + " : " + item.l); | 
 |                 li.attr("class", "result-item"); | 
 |             } else { | 
 |                 li.attr("aria-label", item.l); | 
 |                 li.attr("class", "result-item"); | 
 |             } | 
 |         }); | 
 |     }, | 
 |     _renderItem: function(ul, item) { | 
 |         var label = ""; | 
 |         var matcher = createMatcher(escapeHtml(searchPattern), "g"); | 
 |         var fallbackMatcher = new RegExp(fallbackPattern, "gi") | 
 |         if (item.category === catModules) { | 
 |             label = getHighlightedText(item.l, matcher, fallbackMatcher); | 
 |         } else if (item.category === catPackages) { | 
 |             label = getHighlightedText(item.l, matcher, fallbackMatcher); | 
 |         } else if (item.category === catTypes) { | 
 |             label = (item.p && item.p !== UNNAMED) | 
 |                     ? getHighlightedText(item.p + "." + item.l, matcher, fallbackMatcher) | 
 |                     : getHighlightedText(item.l, matcher, fallbackMatcher); | 
 |         } else if (item.category === catMembers) { | 
 |             label = (item.p && item.p !== UNNAMED) | 
 |                     ? getHighlightedText(item.p + "." + item.c + "." + item.l, matcher, fallbackMatcher) | 
 |                     : getHighlightedText(item.c + "." + item.l, matcher, fallbackMatcher); | 
 |         } else if (item.category === catSearchTags) { | 
 |             label = getHighlightedText(item.l, matcher, fallbackMatcher); | 
 |         } else { | 
 |             label = item.l; | 
 |         } | 
 |         var li = $("<li/>").appendTo(ul); | 
 |         var div = $("<div/>").appendTo(li); | 
 |         if (item.category === catSearchTags && item.h) { | 
 |             if (item.d) { | 
 |                 div.html(label + "<span class=\"search-tag-holder-result\"> (" + item.h + ")</span><br><span class=\"search-tag-desc-result\">" | 
 |                                 + item.d + "</span><br>"); | 
 |             } else { | 
 |                 div.html(label + "<span class=\"search-tag-holder-result\"> (" + item.h + ")</span>"); | 
 |             } | 
 |         } else { | 
 |             if (item.m) { | 
 |                 div.html(item.m + "/" + label); | 
 |             } else { | 
 |                 div.html(label); | 
 |             } | 
 |         } | 
 |         return li; | 
 |     } | 
 | }); | 
 | function rankMatch(match, category) { | 
 |     if (!match) { | 
 |         return NO_MATCH; | 
 |     } | 
 |     var index = match.index; | 
 |     var input = match.input; | 
 |     var leftBoundaryMatch = 2; | 
 |     var periferalMatch = 0; | 
 |     // make sure match is anchored on a left word boundary | 
 |     if (index === 0 || /\W/.test(input[index - 1]) || "_" === input[index]) { | 
 |         leftBoundaryMatch = 0; | 
 |     } else if ("_" === input[index - 1] || (input[index] === input[index].toUpperCase() && !/^[A-Z0-9_$]+$/.test(input))) { | 
 |         leftBoundaryMatch = 1; | 
 |     } | 
 |     var matchEnd = index + match[0].length; | 
 |     var leftParen = input.indexOf("("); | 
 |     var endOfName = leftParen > -1 ? leftParen : input.length; | 
 |     // exclude peripheral matches | 
 |     if (category !== catModules && category !== catSearchTags) { | 
 |         var delim = category === catPackages ? "/" : "."; | 
 |         if (leftParen > -1 && leftParen < index) { | 
 |             periferalMatch += 2; | 
 |         } else if (input.lastIndexOf(delim, endOfName) >= matchEnd) { | 
 |             periferalMatch += 2; | 
 |         } | 
 |     } | 
 |     var delta = match[0].length === endOfName ? 0 : 1; // rank full match higher than partial match | 
 |     for (var i = 1; i < match.length; i++) { | 
 |         // lower ranking if parts of the name are missing | 
 |         if (match[i]) | 
 |             delta += match[i].length; | 
 |     } | 
 |     if (category === catTypes) { | 
 |         // lower ranking if a type name contains unmatched camel-case parts | 
 |         if (/[A-Z]/.test(input.substring(matchEnd))) | 
 |             delta += 5; | 
 |         if (/[A-Z]/.test(input.substring(0, index))) | 
 |             delta += 5; | 
 |     } | 
 |     return leftBoundaryMatch + periferalMatch + (delta / 200); | 
 |  | 
 | } | 
 | function doSearch(request, response) { | 
 |     var result = []; | 
 |     searchPattern = createSearchPattern(request.term); | 
 |     fallbackPattern = createSearchPattern(request.term.toLowerCase()); | 
 |     if (searchPattern === "") { | 
 |         return this.close(); | 
 |     } | 
 |     var camelCaseMatcher = createMatcher(searchPattern, ""); | 
 |     var fallbackMatcher = new RegExp(fallbackPattern, "i"); | 
 |  | 
 |     function searchIndexWithMatcher(indexArray, matcher, category, nameFunc) { | 
 |         if (indexArray) { | 
 |             var newResults = []; | 
 |             $.each(indexArray, function (i, item) { | 
 |                 item.category = category; | 
 |                 var ranking = rankMatch(matcher.exec(nameFunc(item)), category); | 
 |                 if (ranking < RANKING_THRESHOLD) { | 
 |                     newResults.push({ranking: ranking, item: item}); | 
 |                 } | 
 |                 return newResults.length <= MAX_RESULTS; | 
 |             }); | 
 |             return newResults.sort(function(e1, e2) { | 
 |                 return e1.ranking - e2.ranking; | 
 |             }).map(function(e) { | 
 |                 return e.item; | 
 |             }); | 
 |         } | 
 |         return []; | 
 |     } | 
 |     function searchIndex(indexArray, category, nameFunc) { | 
 |         var primaryResults = searchIndexWithMatcher(indexArray, camelCaseMatcher, category, nameFunc); | 
 |         result = result.concat(primaryResults); | 
 |         if (primaryResults.length <= MIN_RESULTS && !camelCaseMatcher.ignoreCase) { | 
 |             var secondaryResults = searchIndexWithMatcher(indexArray, fallbackMatcher, category, nameFunc); | 
 |             result = result.concat(secondaryResults.filter(function (item) { | 
 |                 return primaryResults.indexOf(item) === -1; | 
 |             })); | 
 |         } | 
 |     } | 
 |  | 
 |     searchIndex(moduleSearchIndex, catModules, function(item) { return item.l; }); | 
 |     searchIndex(packageSearchIndex, catPackages, function(item) { | 
 |         return (item.m && request.term.indexOf("/") > -1) | 
 |             ? (item.m + "/" + item.l) : item.l; | 
 |     }); | 
 |     searchIndex(typeSearchIndex, catTypes, function(item) { | 
 |         return request.term.indexOf(".") > -1 ? item.p + "." + item.l : item.l; | 
 |     }); | 
 |     searchIndex(memberSearchIndex, catMembers, function(item) { | 
 |         return request.term.indexOf(".") > -1 | 
 |             ? item.p + "." + item.c + "." + item.l : item.l; | 
 |     }); | 
 |     searchIndex(tagSearchIndex, catSearchTags, function(item) { return item.l; }); | 
 |  | 
 |     if (!indexFilesLoaded()) { | 
 |         updateSearchResults = function() { | 
 |             doSearch(request, response); | 
 |         } | 
 |         result.unshift(loading); | 
 |     } else { | 
 |         updateSearchResults = function() {}; | 
 |     } | 
 |     response(result); | 
 | } | 
 | $(function() { | 
 |     $("#search-input").catcomplete({ | 
 |         minLength: 1, | 
 |         delay: 300, | 
 |         source: doSearch, | 
 |         response: function(event, ui) { | 
 |             if (!ui.content.length) { | 
 |                 ui.content.push(noResult); | 
 |             } else { | 
 |                 $("#search-input").empty(); | 
 |             } | 
 |         }, | 
 |         autoFocus: true, | 
 |         focus: function(event, ui) { | 
 |             return false; | 
 |         }, | 
 |         position: { | 
 |             collision: "flip" | 
 |         }, | 
 |         select: function(event, ui) { | 
 |             if (ui.item.category) { | 
 |                 var url = getURLPrefix(ui); | 
 |                 if (ui.item.category === catModules) { | 
 |                     url += "module-summary.html"; | 
 |                 } else if (ui.item.category === catPackages) { | 
 |                     if (ui.item.u) { | 
 |                         url = ui.item.u; | 
 |                     } else { | 
 |                         url += ui.item.l.replace(/\./g, '/') + "/package-summary.html"; | 
 |                     } | 
 |                 } else if (ui.item.category === catTypes) { | 
 |                     if (ui.item.u) { | 
 |                         url = ui.item.u; | 
 |                     } else if (ui.item.p === UNNAMED) { | 
 |                         url += ui.item.l + ".html"; | 
 |                     } else { | 
 |                         url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html"; | 
 |                     } | 
 |                 } else if (ui.item.category === catMembers) { | 
 |                     if (ui.item.p === UNNAMED) { | 
 |                         url += ui.item.c + ".html" + "#"; | 
 |                     } else { | 
 |                         url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#"; | 
 |                     } | 
 |                     if (ui.item.u) { | 
 |                         url += ui.item.u; | 
 |                     } else { | 
 |                         url += ui.item.l; | 
 |                     } | 
 |                 } else if (ui.item.category === catSearchTags) { | 
 |                     url += ui.item.u; | 
 |                 } | 
 |                 if (top !== window) { | 
 |                     parent.classFrame.location = pathtoroot + url; | 
 |                 } else { | 
 |                     window.location.href = pathtoroot + url; | 
 |                 } | 
 |                 $("#search-input").focus(); | 
 |             } | 
 |         } | 
 |     }); | 
 | }); |