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 var value = dw_qsearch.$inObj.val(); 39 if (value === '') { 40 return; 41 } 42 jQuery.post( 43 DOKU_BASE + 'lib/exe/ajax.php', 44 { 45 call: 'qsearch', 46 q: encodeURI(value) 47 }, 48 dw_qsearch.onCompletion, 49 'html' 50 ); 51 }; 52 53 dw_qsearch.$inObj.keyup( 54 function() { 55 if(dw_qsearch.timer){ 56 window.clearTimeout(dw_qsearch.timer); 57 dw_qsearch.timer = null; 58 } 59 dw_qsearch.timer = 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 // disable overflow during shortening 94 dw_qsearch.$outObj.find('li').css('overflow', 'visible'); 95 96 $links = dw_qsearch.$outObj.find('a'); 97 max = dw_qsearch.$outObj[0].clientWidth; // maximum width allowed (but take away paddings below) 98 if(document.documentElement.dir === 'rtl'){ 99 max -= parseInt(dw_qsearch.$outObj.css('padding-left')); 100 too_big = function (l) { return l.offsetLeft < 0; }; 101 }else{ 102 max -= parseInt(dw_qsearch.$outObj.css('padding-right')); 103 too_big = function (l) { return l.offsetWidth + l.offsetLeft > max; }; 104 } 105 106 $links.each(function () { 107 var start, length, replace, nsL, nsR, eli, runaway; 108 109 if (!too_big(this)) { 110 return; 111 } 112 113 // make IE's innerText available to W3C conform browsers 114 if(this.textContent){ 115 this.__defineGetter__('innerText', function(){ return this.textContent }); 116 this.__defineSetter__('innerText', function(val){ this.textContent = val }); 117 } 118 119 nsL = this.innerText.indexOf('('); 120 nsR = this.innerText.indexOf(')'); 121 eli = 0; 122 runaway = 0; 123 124 while((nsR - nsL > 3) && too_big(this) && runaway++ < 500) { 125 if(eli !== 0){ 126 // elipsis already inserted 127 if( (eli - nsL) > (nsR - eli) ){ 128 // cut left 129 start = eli - 2; 130 length = 2; 131 }else{ 132 // cut right 133 start = eli + 1; 134 length = 1; 135 } 136 replace = ''; 137 }else{ 138 // replace middle with ellipsis 139 start = Math.floor( nsL + ((nsR-nsL)/2) ); 140 length = 1; 141 replace = '…'; 142 } 143 this.innerText = substr_replace(this.innerText, 144 replace, start, length); 145 146 eli = this.innerText.indexOf('…'); 147 nsL = this.innerText.indexOf('('); 148 nsR = this.innerText.indexOf(')'); 149 } 150 }); 151 152 // reenable overflow 153 dw_qsearch.$outObj.find('li').css('overflow', 'hidden').css('text-overflow','ellipsis'); 154 } 155}; 156 157jQuery(function () { 158 dw_qsearch.init('#qsearch__in','#qsearch__out'); 159}); 160