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