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