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 */ 9jQuery.fn.dw_qsearch = function (overrides) { 10 11 var dw_qsearch = { 12 13 output: '#qsearch__out', 14 15 $inObj: this, 16 $outObj: null, 17 timer: null, 18 curRequest: null, 19 20 /** 21 * initialize the quick search 22 * 23 * Attaches the event handlers 24 * 25 */ 26 init: function () { 27 var do_qsearch; 28 29 dw_qsearch.$outObj = jQuery(dw_qsearch.output); 30 31 // objects found? 32 if (dw_qsearch.$inObj.length === 0 || 33 dw_qsearch.$outObj.length === 0) { 34 return; 35 } 36 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 }; 59 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 ); 69 70 // attach eventhandler to output field 71 dw_qsearch.$outObj.on('click', dw_qsearch.clear_results); 72 }, 73 74 /** 75 * Read search term from input 76 */ 77 getSearchterm: function() { 78 return dw_qsearch.$inObj.val(); 79 }, 80 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 }, 89 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'); 101 102 dw_qsearch.curRequest = null; 103 104 if (data === '') { 105 dw_qsearch.clear_results(); 106 return; 107 } 108 109 dw_qsearch.$outObj 110 .html(data) 111 .show() 112 .css('white-space', 'nowrap'); 113 114 // disable overflow during shortening 115 dw_qsearch.$outObj.find('li').css('overflow', 'visible'); 116 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 } 130 131 $links.each(function () { 132 var start, length, replace, nsL, nsR, eli, runaway; 133 134 if (!too_big(this)) { 135 return; 136 } 137 138 nsL = this.textContent.indexOf('('); 139 nsR = this.textContent.indexOf(')'); 140 eli = 0; 141 runaway = 0; 142 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); 164 165 eli = this.textContent.indexOf('…'); 166 nsL = this.textContent.indexOf('('); 167 nsR = this.textContent.indexOf(')'); 168 } 169 }); 170 171 // reenable overflow 172 dw_qsearch.$outObj.find('li').css('overflow', 'hidden').css('text-overflow', 'ellipsis'); 173 } 174 175 176 }; 177 178 jQuery.extend(dw_qsearch, overrides); 179 180 if (!overrides.deferInit) { 181 dw_qsearch.init(); 182 } 183 184 return dw_qsearch; 185}; 186 187jQuery(function () { 188 jQuery('#qsearch__in').dw_qsearch({ 189 output: '#qsearch__out' 190 }); 191}); 192