1 /* This file is part of NIT ( http://www.nitlanguage.org ).
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
7 http://www.apache.org/licenses/LICENSE-2.0
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
15 Documentation generator for the nit language.
16 Generate API documentation in HTML format from nit source code.
20 * Nitdoc QuickSearch widget
27 ], function($
, ui
, utils
) {
28 $
.widget("nitdoc.quicksearch", {
31 list
: {}, // List of raw results generated by nitdoc tool
35 tableID
: "nitdoc-qs-table",
37 "position": "absolute"
39 rowClass
: "nitdoc-qs-row",
40 rowCatClass
: "nitdoc-qs-cat",
41 rowSubClass
: "nitdoc-qs-sub",
42 rowActiveClass
: "nitdoc-qs-active",
43 rowOverflowClass
: "nitdoc-qs-overflow",
44 rowOverflowActive
: "nitdoc-qs-overflow-active",
45 rowNoResultClass
: "nitdoc-qs-noresult",
46 overflowUpHtml
: "▲",
47 overflowDownHtml
: "▼",
48 noresultText
: "Sorry, there is no match, best results are:",
49 infoClass
: "nitdoc-qs-info",
50 gotoPage
: "search.html",
56 .attr(this.options
.fieldAttrs
)
57 .keydown($
.proxy(this._doKeyDown
, this))
58 .keyup($
.proxy(this._doKeyUp
, this))
60 this._table
= $
("<table/>")
61 .attr("id", this.options
.tableID
)
62 .css(this.options
.tableCSS
)
63 .css("min-width", this.element
.outerWidth());
64 $
("body").append(this._table
);
66 $
(document
).click($
.proxy(this.closeTable
, this));
71 _doKeyDown
: function(event
) {
72 switch(event
.keyCode
) {
84 _doKeyUp
: function(event
) {
85 switch(event
.keyCode
) {
96 default: // Other keys
97 utils
.delayEvent($
.proxy(this.search
, this));
104 _getResults
: function(query
) {
106 results
.matches
= [];
107 for(var entry
in this.options
.list
) {
108 if(!entry
.startsWith(query
, true)) {
113 entries
: this.options
.list
[entry]
115 results
.matches
[results
.matches
.length
] = cat
;
119 } else if(entry
.toUpperCase() == query
.toUpperCase()) {
122 cat
.rank
= 1 + query
.dice(entry
);
125 results
.matches
.sort(this._rankSorter
);
126 results
.partials
= new Array();
127 if(results
.matches
.length
== 0) {
128 for(var entry
in this.options
.list
) {
131 entries
: this.options
.list
[entry]
133 cat
.rank
= query
.dice(entry
);
135 results
.partials
[results
.partials
.length
] = cat
;
138 results
.partials
.sort(this._rankSorter
);
143 _rankSorter
: function(a
, b
){
144 if(a
.rank
< b
.rank
) {
146 } else if(a
.rank
> b
.rank
) {
155 var query
= this.element
.val();
157 var results
= this._getResults(query
);
158 this.openTable(query
, results
);
162 openTable
: function(query
, results
) {
167 var resultSet
= results
.matches
;
168 if(resultSet
.length
== 0) {
169 resultSet
= results
.partials
172 for(var i
in resultSet
) {
173 var cat
= resultSet
[i];
174 var result
= cat
.entries
[0];
175 this.addRow(cat
.name
, result
.txt
, result
.url
, this.options
.rowCatClass
)
176 for(var j
= 1; j
< cat
.entries
.length
; j
++) {
177 var result
= cat
.entries
[j];
178 this.addRow(cat
.name
, result
.txt
, result
.url
, this.options
.rowSubClass
)
182 if(this._rows
.length
>= this.options
.maxSize
) {
183 this.addOverflowUp();
184 this.addOverflowDown();
186 if(results
.matches
.length
== 0) {
187 this.addNoResultRow();
190 if(resultSet
.length
> 0) {
194 this._autosizeTable();
197 closeTable
: function(target
) {
198 if(target
!= this.element
&& target
!= this._table
) {
203 addRow
: function(name
, txt
, url
, cls
) {
205 .addClass(this.options
.rowClass
)
206 .data("searchDetails", {name
: name
, url
: url
})
207 .data("index", this._rows
.length
)
215 .html(txt
+ " »")
216 .addClass(this.options
.infoClass
)
218 .mouseover($
.proxy(this._mouseOverRow
, this))
219 .click($
.proxy(this._clickRow
, this))
220 this._rows
.push(row
);
221 if(this._rows
.length
>= this.options
.maxSize
) {
224 this._table
.append(row
);
227 addOverflowUp
: function() {
230 .addClass(this.options
.rowOverflowClass
)
234 .html(this.options
.overflowUpHtml
)
236 .click($
.proxy(this._clickPrev
, this))
240 addOverflowDown
: function() {
243 .addClass(this.options
.rowOverflowClass
)
244 .addClass(this.options
.rowOverflowActive
)
248 .html(this.options
.overflowDownHtml
)
250 .click($
.proxy(this._clickNext
, this))
254 addNoResultRow
: function() {
257 .addClass(this.options
.rowNoResultClass
)
260 .attr("colspan", "2")
261 .text(this.options
.noresultText
)
266 _autosizeTable
: function() {
267 this._table
.position({
274 _hasIndex
: function(index
) {
275 return index
>= 0 && index
< this._rows
.length
;
278 _hasPrev
: function(index
) {
279 return index
- 1 >= 0;
282 _hasNext
: function(index
) {
283 return index
+ 1 < this._rows
.length
;
286 _setIndex
: function(index
) {
287 if(this._hasIndex(this._index
)) {
288 this._rows
[this._index
].removeClass(this.options
.rowActiveClass
);
291 if(this._hasIndex(this._index
)) {
292 this._rows
[this._index
].addClass(this.options
.rowActiveClass
);
296 _selectPrev
: function() {
297 if(this._hasPrev(this._index
)) {
298 this._setIndex(this._index
- 1);
299 if(!this._rows
[this._index
].is(":visible")) {
300 this._table
.find("tr." + this.options
.rowClass
+ ":visible").last().hide();
301 this._table
.find("tr." + this.options
.rowOverflowClass
).addClass(this.options
.rowOverflowActive
);
302 this._rows
[this._index
].show();
303 if(!this._hasPrev(this._index
)) {
304 this._table
.find("tr." + this.options
.rowOverflowClass
).removeClass(this.options
.rowOverflowActive
);
306 this._autosizeTable();
311 _selectNext
: function() {
312 if(this._hasNext(this._index
)) {
313 this._setIndex(this._index
+ 1);
314 if(!this._rows
[this._index
].is(":visible")) {
315 this._table
.find("tr." + this.options
.rowClass
+ ":visible").first().hide();
316 this._table
.find("tr." + this.options
.rowOverflowClass
).addClass(this.options
.rowOverflowActive
);
317 this._rows
[this._index
].show();
318 if(!this._hasNext(this._index
)) {
319 this._table
.find("tr." + this.options
.rowOverflowClass
).removeClass(this.options
.rowOverflowActive
);
321 this._autosizeTable();
326 // Load selected search result page
327 _loadResult
: function() {
328 if(this._index
> -1) {
329 window
.location
= this._rows
[this._index
].data("searchDetails").url
;
332 if(this.element
.val().length
== 0) { return; }
334 window
.location
= this.options
.gotoPage
+ "#q=" + this.element
.val();
335 if(window
.location
.href
.indexOf(this.options
.gotoPage
) > -1) {
342 _clickNext
: function(event
) {
343 event
.stopPropagation();
347 _clickPrev
: function(event
) {
348 event
.stopPropagation();
352 _clickRow
: function(event
) {
353 window
.location
= $
(event
.currentTarget
).data("searchDetails")["url"];
356 _mouseOverRow
: function(event
) {
357 this._setIndex($
(event
.currentTarget
).data("index"));
361 var searchField
= $
("<input/>")
362 .addClass("form-control input-sm")
364 id
: "nitdoc-qs-field",
366 placeholder
: "Search..."
369 $
("#topmenu-collapse").append(
371 .addClass("navbar-form navbar-right")
374 .addClass("form-group")
379 searchField
.quicksearch({
380 list
: this.nitdocQuickSearchRawList