1/*
2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26var noResult = {l: "No results found"};
27var catModules = "Modules";
28var catPackages = "Packages";
29var catTypes = "Types";
30var catMembers = "Members";
31var catSearchTags = "SearchTags";
32var highlight = "<span class=\"resultHighlight\">$&</span>";
33var camelCaseRegexp = "";
34var secondaryMatcher = "";
35function getHighlightedText(item) {
36    var ccMatcher = new RegExp(camelCaseRegexp);
37    var label = item.replace(ccMatcher, highlight);
38    if (label === item) {
39        label = item.replace(secondaryMatcher, highlight);
40    }
41    return label;
42}
43function getURLPrefix(ui) {
44    var urlPrefix="";
45    if (useModuleDirectories) {
46        var slash = "/";
47        if (ui.item.category === catModules) {
48            return ui.item.l + slash;
49        } else if (ui.item.category === catPackages && ui.item.m) {
50            return ui.item.m + slash;
51        } else if ((ui.item.category === catTypes && ui.item.p) || ui.item.category === catMembers) {
52            $.each(packageSearchIndex, function(index, item) {
53                if (ui.item.p == item.l) {
54                    urlPrefix = item.m + slash;
55                }
56            });
57            return urlPrefix;
58        } else {
59            return urlPrefix;
60        }
61    }
62    return urlPrefix;
63}
64var watermark = 'Search';
65$(function() {
66    $("#search").val('');
67    $("#search").prop("disabled", false);
68    $("#reset").prop("disabled", false);
69    $("#search").val(watermark).addClass('watermark');
70    $("#search").blur(function() {
71        if ($(this).val().length == 0) {
72            $(this).val(watermark).addClass('watermark');
73        }
74    });
75    $("#search").on('click keydown', function() {
76        if ($(this).val() == watermark) {
77            $(this).val('').removeClass('watermark');
78        }
79    });
80    $("#reset").click(function() {
81        $("#search").val('');
82        $("#search").focus();
83    });
84    $("#search").focus();
85    $("#search")[0].setSelectionRange(0, 0);
86});
87$.widget("custom.catcomplete", $.ui.autocomplete, {
88    _create: function() {
89        this._super();
90        this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
91    },
92    _renderMenu: function(ul, items) {
93        var rMenu = this,
94                currentCategory = "";
95        rMenu.menu.bindings = $();
96        $.each(items, function(index, item) {
97            var li;
98            if (item.l !== noResult.l && item.category !== currentCategory) {
99                ul.append("<li class=\"ui-autocomplete-category\">" + item.category + "</li>");
100                currentCategory = item.category;
101            }
102            li = rMenu._renderItemData(ul, item);
103            if (item.category) {
104                li.attr("aria-label", item.category + " : " + item.l);
105                li.attr("class", "resultItem");
106            } else {
107                li.attr("aria-label", item.l);
108                li.attr("class", "resultItem");
109            }
110        });
111    },
112    _renderItem: function(ul, item) {
113        var label = "";
114        if (item.category === catModules) {
115            label = getHighlightedText(item.l);
116        } else if (item.category === catPackages) {
117            label = (item.m)
118                    ? getHighlightedText(item.m + "/" + item.l)
119                    : getHighlightedText(item.l);
120        } else if (item.category === catTypes) {
121            label = (item.p)
122                    ? getHighlightedText(item.p + "." + item.l)
123                    : getHighlightedText(item.l);
124        } else if (item.category === catMembers) {
125            label = getHighlightedText(item.p + "." + (item.c + "." + item.l));
126        } else if (item.category === catSearchTags) {
127            label = getHighlightedText(item.l);
128        } else {
129            label = item.l;
130        }
131        var li = $("<li/>").appendTo(ul);
132        var div = $("<div/>").appendTo(li);
133        if (item.category === catSearchTags) {
134            if (item.d) {
135                div.html(label + "<span class=\"searchTagHolderResult\"> (" + item.h + ")</span><br><span class=\"searchTagDescResult\">"
136                                + item.d + "</span><br>");
137            } else {
138                div.html(label + "<span class=\"searchTagHolderResult\"> (" + item.h + ")</span>");
139            }
140        } else {
141            div.html(label);
142        }
143        return li;
144    }
145});
146$(function() {
147    $("#search").catcomplete({
148        minLength: 1,
149        delay: 100,
150        source: function(request, response) {
151            var result = new Array();
152            var presult = new Array();
153            var tresult = new Array();
154            var mresult = new Array();
155            var tgresult = new Array();
156            var secondaryresult = new Array();
157            var displayCount = 0;
158            var exactMatcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term) + "$", "i");
159            camelCaseRegexp = ($.ui.autocomplete.escapeRegex(request.term)).split(/(?=[A-Z])/).join("([a-z0-9_$]*?)");
160            var camelCaseMatcher = new RegExp("^" + camelCaseRegexp);
161            secondaryMatcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
162
163            // Return the nested innermost name from the specified object
164            function nestedName(e) {
165                return e.l.substring(e.l.lastIndexOf(".") + 1);
166            }
167
168            function concatResults(a1, a2) {
169                a1 = a1.concat(a2);
170                a2.length = 0;
171                return a1;
172            }
173
174            if (moduleSearchIndex) {
175                var mdleCount = 0;
176                $.each(moduleSearchIndex, function(index, item) {
177                    item.category = catModules;
178                    if (exactMatcher.test(item.l)) {
179                        result.push(item);
180                        mdleCount++;
181                    } else if (camelCaseMatcher.test(item.l)) {
182                        result.push(item);
183                    } else if (secondaryMatcher.test(item.l)) {
184                        secondaryresult.push(item);
185                    }
186                });
187                displayCount = mdleCount;
188                result = concatResults(result, secondaryresult);
189            }
190            if (packageSearchIndex) {
191                var pCount = 0;
192                var pkg = "";
193                $.each(packageSearchIndex, function(index, item) {
194                    item.category = catPackages;
195                    pkg = (item.m)
196                            ? (item.m + "/" + item.l)
197                            : item.l;
198                    if (exactMatcher.test(item.l)) {
199                        presult.push(item);
200                        pCount++;
201                    } else if (camelCaseMatcher.test(pkg)) {
202                        presult.push(item);
203                    } else if (secondaryMatcher.test(pkg)) {
204                        secondaryresult.push(item);
205                    }
206                });
207                result = result.concat(concatResults(presult, secondaryresult));
208                displayCount = (pCount > displayCount) ? pCount : displayCount;
209            }
210            if (typeSearchIndex) {
211                var tCount = 0;
212                $.each(typeSearchIndex, function(index, item) {
213                    item.category = catTypes;
214                    var s = nestedName(item);
215                    if (exactMatcher.test(s)) {
216                        tresult.push(item);
217                        tCount++;
218                    } else if (camelCaseMatcher.test(s)) {
219                        tresult.push(item);
220                    } else if (secondaryMatcher.test(item.p + "." + item.l)) {
221                        secondaryresult.push(item);
222                    }
223                });
224                result = result.concat(concatResults(tresult, secondaryresult));
225                displayCount = (tCount > displayCount) ? tCount : displayCount;
226            }
227            if (memberSearchIndex) {
228                var mCount = 0;
229                $.each(memberSearchIndex, function(index, item) {
230                    item.category = catMembers;
231                    var s = nestedName(item);
232                    if (exactMatcher.test(s)) {
233                        mresult.push(item);
234                        mCount++;
235                    } else if (camelCaseMatcher.test(s)) {
236                        mresult.push(item);
237                    } else if (secondaryMatcher.test(item.c + "." + item.l)) {
238                        secondaryresult.push(item);
239                    }
240                });
241                result = result.concat(concatResults(mresult, secondaryresult));
242                displayCount = (mCount > displayCount) ? mCount : displayCount;
243            }
244            if (tagSearchIndex) {
245                var tgCount = 0;
246                $.each(tagSearchIndex, function(index, item) {
247                    item.category = catSearchTags;
248                    if (exactMatcher.test(item.l)) {
249                        tgresult.push(item);
250                        tgCount++;
251                    } else if (secondaryMatcher.test(item.l)) {
252                        secondaryresult.push(item);
253                    }
254                });
255                result = result.concat(concatResults(tgresult, secondaryresult));
256                displayCount = (tgCount > displayCount) ? tgCount : displayCount;
257            }
258            displayCount = (displayCount > 500) ? displayCount : 500;
259            var counter = function() {
260                var count = {Modules: 0, Packages: 0, Types: 0, Members: 0, SearchTags: 0};
261                var f = function(item) {
262                    count[item.category] += 1;
263                    return (count[item.category] <= displayCount);
264                };
265                return f;
266            }();
267            response(result.filter(counter));
268        },
269        response: function(event, ui) {
270            if (!ui.content.length) {
271                ui.content.push(noResult);
272            } else {
273                $("#search").empty();
274            }
275        },
276        autoFocus: true,
277        position: {
278            collision: "flip"
279        },
280        select: function(event, ui) {
281            if (ui.item.l !== noResult.l) {
282                var url = getURLPrefix(ui);
283                if (ui.item.category === catModules) {
284                    if (useModuleDirectories) {
285                        url += "module-summary.html";
286                    } else {
287                        url = ui.item.l + "-summary.html";
288                    }
289                } else if (ui.item.category === catPackages) {
290                    if (ui.item.url) {
291                        url = ui.item.url;
292                    } else {
293                    url += ui.item.l.replace(/\./g, '/') + "/package-summary.html";
294                    }
295                } else if (ui.item.category === catTypes) {
296                    if (ui.item.url) {
297                        url = ui.item.url;
298                    } else if (ui.item.p === "<Unnamed>") {
299                        url += ui.item.l + ".html";
300                    } else {
301                        url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html";
302                    }
303                } else if (ui.item.category === catMembers) {
304                    if (ui.item.p === "<Unnamed>") {
305                        url += ui.item.c + ".html" + "#";
306                    } else {
307                        url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#";
308                    }
309                    if (ui.item.url) {
310                        url += ui.item.url;
311                    } else {
312                        url += ui.item.l;
313                    }
314                } else if (ui.item.category === catSearchTags) {
315                    url += ui.item.u;
316                }
317                if (top !== window) {
318                    parent.classFrame.location = pathtoroot + url;
319                } else {
320                    window.location.href = pathtoroot + url;
321                }
322                $("#search").focus();
323            }
324        }
325    });
326});
327