xref: /dokuwiki/lib/scripts/qsearch.js (revision 9ee7fd095e8cb3c84ad95dd52c35630147333ecb)
1/*jslint sloppy: true, plusplus: true, continue: true */
2/*global jQuery, DOKU_BASE, window, document, substr_replace */
3
4/**
5 * AJAX functions for the pagename quicksearch
6 *
7 * @license  GPL2 (http://www.gnu.org/licenses/gpl.html)
8 * @author   Andreas Gohr <andi@splitbrain.org>
9 * @author   Adrian Lang <lang@cosmocode.de>
10 * @author   Michal Rezler <m.rezler@centrum.cz>
11 */
12
13var dw_qsearch = {
14
15    $inObj: null,
16    $outObj: null,
17    timer: null,
18
19    /**
20     * initialize the quick search
21     *
22     * Attaches the event handlers
23     *
24     * @param input element (JQuery selector/DOM obj)
25     * @param output element (JQuery selector/DOM obj)
26     */
27    init: function (input, output) {
28        var do_qsearch;
29
30        dw_qsearch.$inObj  = jQuery(input);
31        dw_qsearch.$outObj = jQuery(output);
32
33        // objects found?
34        if (dw_qsearch.$inObj.length === 0 ||
35            dw_qsearch.$outObj.length === 0) {
36            return;
37        }
38
39        // attach eventhandler to search field
40        do_qsearch = function () {
41            dw_qsearch.clear_results();
42            var value = dw_qsearch.$inObj.val();
43            if (value === '') {
44                return;
45            }
46            jQuery.post(
47                DOKU_BASE + 'lib/exe/ajax.php',
48                {
49                    call: 'qsearch',
50                    q: encodeURI(value)
51                },
52                dw_qsearch.onCompletion,
53                'html'
54            );
55        };
56
57        dw_qsearch.$inObj.keyup(
58            function() {
59                if(dw_qsearch.timer){
60                    window.clearTimeout(dw_qsearch.timer);
61                    dw_qsearch.timer = null;
62                }
63                dw_qsearch.clear_results();
64                dw_qsearch.timer = window.setTimeout(do_qsearch, 500);
65            }
66        );
67
68        // attach eventhandler to output field
69        dw_qsearch.$outObj.click(dw_qsearch.clear_results);
70    },
71
72    /**
73     * Empty and hide the output div
74     */
75    clear_results: function(){
76        dw_qsearch.$outObj.hide();
77        dw_qsearch.$outObj.text('');
78    },
79
80    /**
81     * Callback. Reformat and display the results.
82     *
83     * Namespaces are shortened here to keep the results from overflowing
84     * or wrapping
85     *
86     * @param data The result HTML
87     */
88    onCompletion: function(data) {
89        var max, $links, too_big;
90
91        if (data === '') { return; }
92
93        dw_qsearch.$outObj
94            .html(data)
95            .show()
96            .css('white-space', 'nowrap');
97
98        // shorten namespaces if too long
99        max = dw_qsearch.$outObj[0].clientWidth;
100        $links = dw_qsearch.$outObj.find('a');
101        too_big = (document.documentElement.dir === 'rtl')
102                  ? function (l) { return l.offsetLeft < 0; }
103                  : function (l) { return l.offsetWidth + l.offsetLeft > max; };
104
105        $links.each(function () {
106            var start, length, replace, nsL, nsR, eli, runaway;
107
108            if (!too_big(this)) {
109                return;
110            }
111
112            nsL = this.innerText.indexOf('(');
113            nsR = this.innerText.indexOf(')');
114            eli = 0;
115            runaway = 0;
116
117            while((nsR - nsL > 3) && too_big(this) && runaway++ < 500) {
118                if(eli !== 0){
119                    // elipsis already inserted
120                    if( (eli - nsL) > (nsR - eli) ){
121                        // cut left
122                        start = eli - 2;
123                        length = 2;
124                    }else{
125                        // cut right
126                        start = eli + 1;
127                        length = 1;
128                    }
129                    replace = '';
130                }else{
131                    // replace middle with ellipsis
132                    start = Math.floor( nsL + ((nsR-nsL)/2) );
133                    length = 1;
134                    replace = '…';
135                }
136                this.innerText = substr_replace(this.innerText,
137                                                replace, start, length);
138
139                eli = this.innerText.indexOf('…');
140                nsL = this.innerText.indexOf('(');
141                nsR = this.innerText.indexOf(')');
142            }
143        });
144    }
145};
146
147jQuery(function () {
148    dw_qsearch.init('#qsearch__in','#qsearch__out');
149});
150