Changeset 28181


Ignore:
Timestamp:
Apr 14, 2014, 11:08:27 PM (10 years ago)
Author:
rvelices
Message:

autocomplete js changes

Location:
extensions/rv_autocomplete
Files:
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • extensions/rv_autocomplete/res/suggest-core.js

    r27771 r28181  
    5757}
    5858
    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;
     59function ac_normalize(str) {
     60        return str.replace(RVAC.rSpaceLike, ' ').replace(/ {2,}/g, ' ').replace(/(^ | $)/g, '');
     61}
     62
     63function 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                }
    10671                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;
    15390                }
    15491                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
     147function 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" )
    171153                        , 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                }
    172159
    173160                // first pass - build matches
     
    178165                        var item = RVAC.dataSource[i];
    179166                        if ( (item._matchIdx = item.q.search(matcher)) > -1 ) {
    180                                 if (item.ctx && item._matchIdx>0)
    181                                         continue; // context searches only at beginning
    182167                                if (item.value !== -1) {
    183168                                        if (found.hasOwnProperty(item.value))
     
    195180                var foundWords=0, word;
    196181                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 );
    198183                        if (!found.hasOwnProperty(word)) {
    199184                                foundWords++;
     
    235220                }
    236221
    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
     228function 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
     240function 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
     253function 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
     259RVAC.rSpaceLike = /[&.,;!\?-]/g;
     260RVAC.noMatch = {};
     261
     262RVAC.start = function() {
     263var $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                                }
    274346                        }
    275347                }
  • extensions/rv_autocomplete/suggestions.php

    r22304 r28181  
    3333        stopLookingAfter: 80,
    3434        suggestions: 4,
    35         maxSuggestions: 8,
    36         minWeightForContextTrigger: 25
     35        maxSuggestions: 8
    3736});
    3837$.each(RVAC.dataSource, function(i,item) {
Note: See TracChangeset for help on using the changeset viewer.