Changeset 28181 for extensions
- Timestamp:
- Apr 14, 2014, 11:08:27 PM (11 years ago)
- Location:
- extensions/rv_autocomplete
- Files:
-
- 1 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/rv_autocomplete/res/suggest-core.js
r27771 r28181 57 57 } 58 58 59 function ac_normalize(q) { 60 var ret = remove_accents( q.toLowerCase() ); 61 return ret.replace(/[&.,-]/g, ' ').replace(/ {2,}/g, ' '); 62 } 63 64 function ac_match_word(item, q) { 65 var i = item._matchIdx + q.length; 66 while (i<item.q.length && item.q[i] != ' ') 67 i++; 68 if ( i-item._matchIdx < 4 && i<item.q.length) { 69 i++; 70 while (i<item.q.length && item.q[i] != ' ') 71 i++; 72 } 73 return item.q.substr(item._matchIdx, i-item._matchIdx) 74 } 75 76 function ac_highlight(item, q){ 77 if (item._matchIdx) { 78 while (item._matchIdx+q.length <= item.label.length 79 && item.label[item._matchIdx].toLowerCase() != q[0]) 80 item._matchIdx++; 81 if (item.label[item._matchIdx].toLowerCase() != q[0]) 82 return item.label; 83 } 84 return item.label.substr(0, item._matchIdx) 85 + '<b style="text-decoration:underline">' + item.label.substr(item._matchIdx, q.length) + '</b>' 86 + item.label.substr(item._matchIdx + q.length) 87 } 88 89 function ac_url(item) { 90 if (item.value[0] == '$') 91 return RVAC.roots[item.value[1]] + item.value.substr(3); 92 return item.value; 93 } 94 95 RVAC.requestedContexts = {}; 96 RVAC.requestingContexts = 0; 97 98 RVAC.mergeData = function(data) { 99 RVAC.requestingContexts--; 100 var ctxq = data.ctxq + " " 101 , ctxl = data.ctxl + " "; 102 data = data.dataSource; 103 $.each(data, function(i,item) { 104 if (item.q) 105 item.q = ctxq + item.q; 59 function ac_normalize(str) { 60 return str.replace(RVAC.rSpaceLike, ' ').replace(/ {2,}/g, ' ').replace(/(^ | $)/g, ''); 61 } 62 63 function ac_analyze(input, lastFocusStr) { 64 var intent="", quoted=0, brackets=0, is_complex=0, scope="", i=0; 65 66 if (lastFocusStr.length) { 67 if (input.indexOf(lastFocusStr) == 0) { 68 i = lastFocusStr.length; 69 is_complex = 1; 70 } 106 71 else 107 item.q = ctxq + item.label.toLowerCase(); 108 item.label = ctxl + item.label; 109 item.ctx = 1; 110 }); 111 112 var ids=0, inew=0; 113 114 while (inew < data.length) { 115 while (RVAC.dataSource[ids].w > data[inew].w) 116 ids++; 117 RVAC.dataSource.splice(ids, 0, data[inew]); 118 RVAC.dataSourceAltLangIndex++; 119 inew++; 120 } 121 122 var inp = $("#qsearchInput"); 123 if (data.length && inp.is(":focus")) { 124 inp.autocomplete("search"); 125 } 126 }; 127 128 RVAC.start = function() { 129 var $input = $("#qsearchInput"); 130 $input.autocomplete({ 131 rv:{}, minLength: 1, 132 133 focus: function(event,ui) { 134 this.value = ui.item.label; 135 return false; 136 }, 137 138 change: function(event,ui) { 139 var term; 140 if (!ui.item && (term=$(this).data("ui-autocomplete").term)) 141 this.value = term; 142 }, 143 144 select: function(event,ui) { 145 var term = $(this).data("ui-autocomplete").term; 146 147 if (ui.item.value === -1 || /^q=/.test(ui.item.value) ) { 148 var usedq = ui.item.value === -1 ? ui.item.label : ui.item.value.substr(2); 149 this.value = usedq.indexOf(' ')>=0 ? '"' + usedq + '"' : usedq; 150 var form = $(this).parents("form"); 151 form.append( $("<input type='hidden' name='acs' />").val(term) ); 152 form.submit(); 72 lastFocusStr = ""; 73 } 74 75 var reset = function() { 76 if (ac_normalize(intent).length) 77 is_complex = 1; 78 intent = ""; 79 quoted = 0; 80 scope = ""; 81 } 82 83 for (; i<input.length; i++) { 84 var ch = input[i]; 85 if (quoted) { 86 if (ch == '"') 87 reset(); 88 else 89 intent += ch; 153 90 } 154 91 else { 155 var url = ac_url(ui.item); 156 event.preventDefault(); 157 window.location = (url + (/\?/.test(url) ? "&" : "?") + "acs=" + term); 158 } 159 160 return false; 161 }, 162 163 source: function(request, response) { 164 this.options.rv.term = request.term; 165 this.options.rv.q = ac_normalize(request.term); 166 request.qEsc = $.ui.autocomplete.escapeRegex( this.options.rv.q ); 167 var extraWChars=""; 168 if (this.options.rv.q.length<4) 169 extraWChars = "[\\w]{" + (4-this.options.rv.q.length) + ",}"; 170 var matcher = new RegExp( "(^"+request.qEsc+")|(\\b"+request.qEsc+extraWChars+ ")", "i" ) 92 switch (ch) { 93 case '(': 94 reset(); 95 brackets++; 96 break; 97 case ')': 98 if (brackets>0) 99 brackets--; 100 reset(); 101 break; 102 case '"': 103 reset(); 104 quoted = 1; 105 break; 106 case ':': 107 var matches = intent.match( /(tags?|photos?)$/ ); 108 if (matches != null) { 109 reset(); 110 scope = matches[0].replace( /s$/, ''); 111 } 112 else 113 intent += ch; 114 break; 115 case ' ': 116 if (/(^| )(not|or|and)/i.test(intent)) 117 reset(); 118 else { 119 if (intent.length && intent[0] == '-') 120 reset(); 121 else if (intent.length) 122 intent += " "; 123 } 124 break; 125 default: 126 intent += ch; 127 } 128 } 129 } 130 131 if (intent.length && intent[0] == '-' && !quoted) { 132 intent = intent.substr(1); 133 is_complex = 1; 134 } 135 136 return { 137 q: remove_accents( ac_normalize(intent.toLowerCase()) ), 138 raw_q: intent, 139 is_quoted: quoted, 140 is_complex: is_complex, 141 scope: scope, 142 lastFocusStr: lastFocusStr, 143 input: input 144 } 145 } 146 147 function ac_search(state) { 148 var qEsc = $.ui.autocomplete.escapeRegex( state.q ), 149 extraWChars=""; 150 if (state.q.length<4) 151 extraWChars = "[\\w]{" + (4-state.q.length) + ",}"; 152 var matcher = new RegExp( "(^"+qEsc+")|(\\b"+qEsc+extraWChars+ ")", "i" ) 171 153 , i, j, found={}, res=[]; 154 155 if (state.q.length==0 || 156 RVAC.noMatch.hasOwnProperty(state.q) || RVAC.noMatch.hasOwnProperty(state.q.substr(0,-1)) ) { 157 return res; 158 } 172 159 173 160 // first pass - build matches … … 178 165 var item = RVAC.dataSource[i]; 179 166 if ( (item._matchIdx = item.q.search(matcher)) > -1 ) { 180 if (item.ctx && item._matchIdx>0)181 continue; // context searches only at beginning182 167 if (item.value !== -1) { 183 168 if (found.hasOwnProperty(item.value)) … … 195 180 var foundWords=0, word; 196 181 for (i=0; i<res.length; i++) { 197 word = res[i]._matchWord = ac_match_word( res[i], this.options.rv.q );182 word = res[i]._matchWord = ac_match_word( res[i], state.q ); 198 183 if (!found.hasOwnProperty(word)) { 199 184 foundWords++; … … 235 220 } 236 221 237 // check for multi tags 238 if (!RVAC.requestingContexts && this.options.rv.q.length > 1) { 239 var eligible = $.grep( res, function(item) { 240 if (item._matchIdx > 0 241 || item.w <= RVAC.minWeightForContextTrigger 242 || item.value === -1 243 || item.value[0]!="$" || item.value[1]!="t") 244 return 0; 245 if (RVAC.requestedContexts.hasOwnProperty(item.value)) 246 return 0; 247 return 1; 248 } ); 249 250 if (eligible.length==1) { 251 if (res.length > RVAC.suggestions || foundWords>1) { 252 if (this.options.rv.q.length <= eligible[0].q.length/2 ) 253 eligible.length = 0; 254 } 255 } 256 else { 257 for (i=0; i<eligible.length; i++) 258 if (this.options.rv.q.length == eligible[i].q.length) { 259 eligible = [ eligible[i] ]; 260 break; 261 } 262 263 if (eligible.length > 1) 264 eligible.length = 0; 265 } 266 267 if (eligible.length) { 268 item = eligible[0]; 269 RVAC.requestedContexts[item.value] = 1; 270 RVAC.requestingContexts++; 271 var s=document.createElement("script");s.type="text/javascript";s.async=true; 272 s.src=RVAC.root+"context_suggest.php?context="+encodeURIComponent(item.value)+"&ctxq="+encodeURIComponent(item.q)+"&ctxl="+encodeURIComponent(item.label); 273 document.body.appendChild(s); 222 if (res.length == 0 && state.q.length >= 4 && !state.scope.length) 223 RVAC.noMatch[state.q] = 1; 224 225 return res; 226 } 227 228 function ac_match_word(item, q) { 229 var i = item._matchIdx + q.length; 230 while (i<item.q.length && item.q[i] != ' ') 231 i++; 232 if ( i-item._matchIdx < 4 && i<item.q.length) { 233 i++; 234 while (i<item.q.length && item.q[i] != ' ') 235 i++; 236 } 237 return item.q.substr(item._matchIdx, i-item._matchIdx) 238 } 239 240 function ac_highlight(item, q){ 241 if (item._matchIdx && item.label.length != item.q.length) { 242 while (item._matchIdx+q.length <= item.label.length 243 && item.label[item._matchIdx].toLowerCase() != q[0]) 244 item._matchIdx++; 245 if (item.label[item._matchIdx].toLowerCase() != q[0]) 246 return item.label; 247 } 248 return item.label.substr(0, item._matchIdx) 249 + '<b style="text-decoration:underline">' + item.label.substr(item._matchIdx, q.length) + '</b>' 250 + item.label.substr(item._matchIdx + q.length) 251 } 252 253 function ac_url(item) { 254 if (item.value[0] == '$') 255 return RVAC.roots[item.value[1]] + item.value.substr(3); 256 return item.value; 257 } 258 259 RVAC.rSpaceLike = /[&.,;!\?-]/g; 260 RVAC.noMatch = {}; 261 262 RVAC.start = function() { 263 var $input = $("#qsearchInput"); 264 $input.autocomplete({ 265 rv:{lastFocusStr: ""}, minLength: 1, 266 267 focus: function(event,ui) { 268 var ac = $(this).data("ui-autocomplete"), 269 expr = ac.options.rv, idx; 270 271 if (/^q=/.test(ui.item.value)) { 272 var shown = ui.item.value.substr(2) + ' '; 273 if (expr.is_complex) { 274 if ( (idx=expr.input.lastIndexOf(expr.raw_q)) !== -1) { 275 if (expr.is_quoted) 276 idx--; 277 this.value = expr.input.substr(0, idx) + shown; 278 } 279 } 280 else 281 this.value = shown; 282 } 283 else { 284 var shown = ac_normalize(ui.item.label) + ' '; 285 if (expr.is_complex) { 286 if ( (idx=expr.input.lastIndexOf(expr.raw_q)) !== -1) { 287 this.value = expr.input.substr(0, idx) + shown; 288 } 289 } 290 else 291 this.value = shown; 292 } 293 294 if (this.setSelectionRange) 295 this.setSelectionRange(999, 999); 296 297 expr.lastFocusStr = this.value; 298 return false; 299 }, 300 301 change: function(event,ui) { 302 var term; 303 if (!ui.item && (term=$(this).data("ui-autocomplete").term)) 304 this.value = term; 305 }, 306 307 select: function(event,ui) { 308 var ac = $(this).data("ui-autocomplete"), 309 expr = ac.options.rv; 310 311 if (!expr.is_complex && ui.item.value !== -1 && ! /^q=/.test(ui.item.value)) { 312 var url = ac_url(ui.item); 313 event.preventDefault(); 314 window.location = (url + (/\?/.test(url) ? "&" : "?") + "acs=" + ac.term); 315 } 316 else { 317 this.value = this.value.replace( / $/, ''); 318 var form = $(this).parents("form"); 319 form.append( $("<input type='hidden' name='acs' />").val(ac.term) ); 320 form.submit(); 321 } 322 323 return false; 324 }, 325 326 source: function(request, response) { 327 this.options.rv = ac_analyze(request.term, this.options.rv.lastFocusStr); 328 329 var res = ac_search(this.options.rv); 330 331 if (!res.length && !this.options.rv.is_quoted) { 332 var matches, 333 raw_q = this.options.rv.raw_q, 334 current = $.extend( {}, this.options.rv); 335 current.is_complex = 1; 336 337 while ( (matches = raw_q.match(/^[ &.,;!\?-]*[^ &.,;!\?-]+[ &.,;!\?-]+/)) != null ) { 338 current.lastFocusStr += raw_q.substr(0, matches[0].length); 339 raw_q = raw_q.substr(matches[0].length); 340 current.q = remove_accents( ac_normalize( current.raw_q.toLowerCase() ) ); 341 res = ac_search(current); 342 if (res.length) { 343 this.options.rv = current; 344 break; 345 } 274 346 } 275 347 } -
extensions/rv_autocomplete/suggestions.php
r22304 r28181 33 33 stopLookingAfter: 80, 34 34 suggestions: 4, 35 maxSuggestions: 8, 36 minWeightForContextTrigger: 25 35 maxSuggestions: 8 37 36 }); 38 37 $.each(RVAC.dataSource, function(i,item) {
Note: See TracChangeset
for help on using the changeset viewer.