fix typo
[dokuwiki.git] / lib / scripts / qsearch.js
blobf95515b93760d13a81ac6b8440f66003d7e59c6e
1 /**
2  * AJAX functions for the pagename quicksearch
3  *
4  * @license  GPL2 (http://www.gnu.org/licenses/gpl.html)
5  * @author   Andreas Gohr <andi@splitbrain.org>
6  * @author   Adrian Lang <lang@cosmocode.de>
7  * @author   Michal Rezler <m.rezler@centrum.cz>
8  */
9 jQuery.fn.dw_qsearch = function (overrides) {
11     var dw_qsearch = {
13         output: '#qsearch__out',
15         $inObj: this,
16         $outObj: null,
17         timer: null,
18         curRequest: null,
20         /**
21          * initialize the quick search
22          *
23          * Attaches the event handlers
24          *
25          */
26         init: function () {
27             var do_qsearch;
29             dw_qsearch.$outObj = jQuery(dw_qsearch.output);
31             // objects found?
32             if (dw_qsearch.$inObj.length === 0 ||
33                 dw_qsearch.$outObj.length === 0) {
34                 return;
35             }
37             // attach eventhandler to search field
38             do_qsearch = function () {
39                 // abort any previous request
40                 if (dw_qsearch.curRequest != null) {
41                     dw_qsearch.curRequest.abort();
42                 }
43                 var value = dw_qsearch.getSearchterm();
44                 if (value === '') {
45                     dw_qsearch.clear_results();
46                     return;
47                 }
48                 dw_qsearch.$inObj.parents('form').addClass('searching');
49                 dw_qsearch.curRequest = jQuery.post(
50                     DOKU_BASE + 'lib/exe/ajax.php',
51                     {
52                         call: 'qsearch',
53                         q: encodeURI(value)
54                     },
55                     dw_qsearch.onCompletion,
56                     'html'
57                 );
58             };
60             dw_qsearch.$inObj.on('keyup',
61                 function () {
62                     if (dw_qsearch.timer) {
63                         window.clearTimeout(dw_qsearch.timer);
64                         dw_qsearch.timer = null;
65                     }
66                     dw_qsearch.timer = window.setTimeout(do_qsearch, 500);
67                 }
68             );
70             // attach eventhandler to output field
71             dw_qsearch.$outObj.on('click', dw_qsearch.clear_results);
72         },
74         /**
75          * Read search term from input
76          */
77         getSearchterm: function() {
78             return dw_qsearch.$inObj.val();
79         },
81         /**
82          * Empty and hide the output div
83          */
84         clear_results: function () {
85             dw_qsearch.$inObj.parents('form').removeClass('searching');
86             dw_qsearch.$outObj.hide();
87             dw_qsearch.$outObj.text('');
88         },
90         /**
91          * Callback. Reformat and display the results.
92          *
93          * Namespaces are shortened here to keep the results from overflowing
94          * or wrapping
95          *
96          * @param data The result HTML
97          */
98         onCompletion: function (data) {
99             var max, $links, too_big;
100             dw_qsearch.$inObj.parents('form').removeClass('searching');
102             dw_qsearch.curRequest = null;
104             if (data === '') {
105                 dw_qsearch.clear_results();
106                 return;
107             }
109             dw_qsearch.$outObj
110                 .html(data)
111                 .show()
112                 .css('white-space', 'nowrap');
114             // disable overflow during shortening
115             dw_qsearch.$outObj.find('li').css('overflow', 'visible');
117             $links = dw_qsearch.$outObj.find('a');
118             max = dw_qsearch.$outObj[0].clientWidth; // maximum width allowed (but take away paddings below)
119             if (document.documentElement.dir === 'rtl') {
120                 max -= parseInt(dw_qsearch.$outObj.css('padding-left'));
121                 too_big = function (l) {
122                     return l.offsetLeft < 0;
123                 };
124             } else {
125                 max -= parseInt(dw_qsearch.$outObj.css('padding-right'));
126                 too_big = function (l) {
127                     return l.offsetWidth + l.offsetLeft > max;
128                 };
129             }
131             $links.each(function () {
132                 var start, length, replace, nsL, nsR, eli, runaway;
134                 if (!too_big(this)) {
135                     return;
136                 }
138                 nsL = this.textContent.indexOf('(');
139                 nsR = this.textContent.indexOf(')');
140                 eli = 0;
141                 runaway = 0;
143                 while ((nsR - nsL > 3) && too_big(this) && runaway++ < 500) {
144                     if (eli !== 0) {
145                         // elipsis already inserted
146                         if ((eli - nsL) > (nsR - eli)) {
147                             // cut left
148                             start = eli - 2;
149                             length = 2;
150                         } else {
151                             // cut right
152                             start = eli + 1;
153                             length = 1;
154                         }
155                         replace = '';
156                     } else {
157                         // replace middle with ellipsis
158                         start = Math.floor(nsL + ((nsR - nsL) / 2));
159                         length = 1;
160                         replace = '…';
161                     }
162                     this.textContent = substr_replace(this.textContent,
163                         replace, start, length);
165                     eli = this.textContent.indexOf('…');
166                     nsL = this.textContent.indexOf('(');
167                     nsR = this.textContent.indexOf(')');
168                 }
169             });
171             // reenable overflow
172             dw_qsearch.$outObj.find('li').css('overflow', 'hidden').css('text-overflow', 'ellipsis');
173         }
176     };
178     jQuery.extend(dw_qsearch, overrides);
180     if (!overrides.deferInit) {
181         dw_qsearch.init();
182     }
184     return dw_qsearch;
187 jQuery(function () {
188     jQuery('#qsearch__in').dw_qsearch({
189         output: '#qsearch__out'
190     });