Вход Регистрация
Файл: CodeIgniter-3.0.3/user_guide/_static/searchtools.js
Строк: 424
<?php
/*
 * searchtools.js_t
 * ~~~~~~~~~~~~~~~~
 *
 * Sphinx JavaScript utilties for the full-text search.
 *
 * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
 * :license: BSD, see LICENSE for details.
 *
 */


/**
 * Porter Stemmer
 */
var Stemmer = function() {

  var 
step2list = {
    
ational: 'ate',
    
tional: 'tion',
    
enci: 'ence',
    
anci: 'ance',
    
izer: 'ize',
    
bli: 'ble',
    
alli: 'al',
    
entli: 'ent',
    
eli: 'e',
    
ousli: 'ous',
    
ization: 'ize',
    
ation: 'ate',
    
ator: 'ate',
    
alism: 'al',
    
iveness: 'ive',
    
fulness: 'ful',
    
ousness: 'ous',
    
aliti: 'al',
    
iviti: 'ive',
    
biliti: 'ble',
    
logi: 'log'
  
};

  var 
step3list = {
    
icate: 'ic',
    
ative: '',
    
alize: 'al',
    
iciti: 'ic',
    
ical: 'ic',
    
ful: '',
    
ness: ''
  
};

  var 
c = "[^aeiou]";          // consonant
  
var v = "[aeiouy]";          // vowel
  
var C = c + "[^aeiouy]*";    // consonant sequence
  
var V = v + "[aeiou]*";      // vowel sequence

  
var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
  
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
  
var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
  
var s_v   = "^(" + C + ")?" + v;                         // vowel in stem

  
this.stemWord = function (w) {
    var 
stem;
    var 
suffix;
    var 
firstch;
    var 
origword = w;

    if (
w.length < 3)
      return 
w;

    var 
re;
    var 
re2;
    var 
re3;
    var 
re4;

    
firstch = w.substr(0,1);
    if (
firstch == "y")
      
w = firstch.toUpperCase() + w.substr(1);

    
// Step 1a
    
re = /^(.+?)(ss|i)es$/;
    
re2 = /^(.+?)([^s])s$/;

    if (
re.test(w))
      
w = w.replace(re,"$1$2");
    else if (
re2.test(w))
      
w = w.replace(re2,"$1$2");

    
// Step 1b
    
re = /^(.+?)eed$/;
    
re2 = /^(.+?)(ed|ing)$/;
    if (
re.test(w)) {
      var 
fp = re.exec(w);
      
re = new RegExp(mgr0);
      if (
re.test(fp[1])) {
        
re = /.$/;
        
w = w.replace(re,"");
      }
    }
    else if (
re2.test(w)) {
      var 
fp = re2.exec(w);
      
stem = fp[1];
      
re2 = new RegExp(s_v);
      if (
re2.test(stem)) {
        
w = stem;
        
re2 = /(at|bl|iz)$/;
        
re3 = new RegExp("([^aeiouylsz])\1$");
        
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
        if (
re2.test(w))
          
w = w + "e";
        else if (
re3.test(w)) {
          
re = /.$/;
          
w = w.replace(re,"");
        }
        else if (
re4.test(w))
          
w = w + "e";
      }
    }

    
// Step 1c
    
re = /^(.+?)y$/;
    if (
re.test(w)) {
      var 
fp = re.exec(w);
      
stem = fp[1];
      
re = new RegExp(s_v);
      if (
re.test(stem))
        
w = stem + "i";
    }

    
// Step 2
    
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
    if (
re.test(w)) {
      var 
fp = re.exec(w);
      
stem = fp[1];
      
suffix = fp[2];
      
re = new RegExp(mgr0);
      if (
re.test(stem))
        
w = stem + step2list[suffix];
    }

    
// Step 3
    
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
    if (
re.test(w)) {
      var 
fp = re.exec(w);
      
stem = fp[1];
      
suffix = fp[2];
      
re = new RegExp(mgr0);
      if (
re.test(stem))
        
w = stem + step3list[suffix];
    }

    
// Step 4
    
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
    
re2 = /^(.+?)(s|t)(ion)$/;
    if (
re.test(w)) {
      var 
fp = re.exec(w);
      
stem = fp[1];
      
re = new RegExp(mgr1);
      if (
re.test(stem))
        
w = stem;
    }
    else if (
re2.test(w)) {
      var 
fp = re2.exec(w);
      
stem = fp[1] + fp[2];
      
re2 = new RegExp(mgr1);
      if (
re2.test(stem))
        
w = stem;
    }

    
// Step 5
    
re = /^(.+?)e$/;
    if (
re.test(w)) {
      var 
fp = re.exec(w);
      
stem = fp[1];
      
re = new RegExp(mgr1);
      
re2 = new RegExp(meq1);
      
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
      if (
re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
        
w = stem;
    }
    
re = /ll$/;
    
re2 = new RegExp(mgr1);
    if (
re.test(w) && re2.test(w)) {
      
re = /.$/;
      
w = w.replace(re,"");
    }

    
// and turn initial Y back to y
    
if (firstch == "y")
      
w = firstch.toLowerCase() + w.substr(1);
    return 
w;
  }
}



/**
 * Simple result scoring code.
 */
var Scorer = {
  
// Implement the following function to further tweak the score for each result
  // The function takes a result array [filename, title, anchor, descr, score]
  // and returns the new score.
  /*
  score: function(result) {
    return result[4];
  },
  */

  // query matches the full name of an object
  
objNameMatch: 11,
  
// or matches in the last dotted part of the object name
  
objPartialMatch: 6,
  
// Additive scores depending on the priority of the object
  
objPrio: {0:  15,   // used to be importantResults
            
1:  5,   // used to be objectResults
            
2: -5},  // used to be unimportantResults
  //  Used when the priority is not in the mapping.
  
objPrioDefault: 0,

  
// query found in title
  
title: 15,
  
// query found in terms
  
term: 5
};


/**
 * Search Module
 */
var Search = {

  
_index : null,
  
_queued_query : null,
  
_pulse_status : -1,

  
init : function() {
      var 
params = $.getQueryParameters();
      if (
params.q) {
          var 
query = params.q[0];
          $(
'input[name="q"]')[0].value = query;
          
this.performSearch(query);
      }
  },

  
loadIndex : function(url) {
    $.
ajax({type: "GET", url: url, data: null,
            
dataType: "script", cache: true,
            
complete: function(jqxhr, textstatus) {
              if (
textstatus != "success") {
                
document.getElementById("searchindexloader").src = url;
              }
            }});
  },

  
setIndex : function(index) {
    var 
q;
    
this._index = index;
    if ((
q = this._queued_query) !== null) {
      
this._queued_query = null;
      
Search.query(q);
    }
  },

  
hasIndex : function() {
      return 
this._index !== null;
  },

  
deferQuery : function(query) {
      
this._queued_query = query;
  },

  
stopPulse : function() {
      
this._pulse_status = 0;
  },

  
startPulse : function() {
    if (
this._pulse_status >= 0)
        return;
    function 
pulse() {
      var 
i;
      
Search._pulse_status = (Search._pulse_status + 1) % 4;
      var 
dotString = '';
      for (
i = 0; i < Search._pulse_status; i++)
        
dotString += '.';
      
Search.dots.text(dotString);
      if (
Search._pulse_status > -1)
        
window.setTimeout(pulse, 500);
    }
    
pulse();
  },

  
/**
   * perform a search for something (or wait until index is loaded)
   */
  
performSearch : function(query) {
    
// create the required interface elements
    
this.out = $('#search-results');
    
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
    
this.dots = $('<span></span>').appendTo(this.title);
    
this.status = $('<p style="display: none"></p>').appendTo(this.out);
    
this.output = $('<ul class="search"/>').appendTo(this.out);

    $(
'#search-progress').text(_('Preparing search...'));
    
this.startPulse();

    
// index already loaded, the browser was quick!
    
if (this.hasIndex())
      
this.query(query);
    else
      
this.deferQuery(query);
  },

  
/**
   * execute search (requires search index to be loaded)
   */
  
query : function(query) {
    var 
i;
    var 
stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];

    
// stem the searchterms and add them to the correct list
    
var stemmer = new Stemmer();
    var 
searchterms = [];
    var 
excluded = [];
    var 
hlterms = [];
    var 
tmp = query.split(/s+/);
    var 
objectterms = [];
    for (
i = 0; i < tmp.length; i++) {
      if (
tmp[i] !== "") {
          
objectterms.push(tmp[i].toLowerCase());
      }

      if (
$u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^d+$/) ||
          
tmp[i] === "") {
        
// skip this "word"
        
continue;
      }
      
// stem the word
      
var word = stemmer.stemWord(tmp[i].toLowerCase());
      var 
toAppend;
      
// select the correct list
      
if (word[0] == '-') {
        
toAppend = excluded;
        
word = word.substr(1);
      }
      else {
        
toAppend = searchterms;
        
hlterms.push(tmp[i].toLowerCase());
      }
      
// only add if not already in the list
      
if (!$u.contains(toAppend, word))
        
toAppend.push(word);
    }
    var 
highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));

    
// console.debug('SEARCH: searching for:');
    // console.info('required: ', searchterms);
    // console.info('excluded: ', excluded);

    // prepare search
    
var terms = this._index.terms;
    var 
titleterms = this._index.titleterms;

    
// array of [filename, title, anchor, descr, score]
    
var results = [];
    $(
'#search-progress').empty();

    
// lookup as object
    
for (i = 0; i < objectterms.length; i++) {
      var 
others = [].concat(objectterms.slice(0, i),
                             
objectterms.slice(i+1, objectterms.length));
      
results = results.concat(this.performObjectSearch(objectterms[i], others));
    }

    
// lookup as search terms in fulltext
    
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, Scorer.term))
                     .
concat(this.performTermsSearch(searchterms, excluded, titleterms, Scorer.title));

    
// let the scorer override scores with a custom scoring function
    
if (Scorer.score) {
      for (
i = 0; i < results.length; i++)
        
results[i][4] = Scorer.score(results[i]);
    }

    
// now sort the results by score (in opposite order of appearance, since the
    // display function below uses pop() to retrieve items) and then
    // alphabetically
    
results.sort(function(a, b) {
      var 
left = a[4];
      var 
right = b[4];
      if (
left > right) {
        return 
1;
      } else if (
left < right) {
        return -
1;
      } else {
        
// same score: sort alphabetically
        
left = a[1].toLowerCase();
        
right = b[1].toLowerCase();
        return (
left > right) ? -1 : ((left < right) ? 1 : 0);
      }
    });

    
// for debugging
    //Search.lastresults = results.slice();  // a copy
    //console.info('search results:', Search.lastresults);

    // print the results
    
var resultCount = results.length;
    function 
displayNextItem() {
      
// results left, load the summary and display it
      
if (results.length) {
        var 
item = results.pop();
        var 
listItem = $('<li style="display:none"></li>');
        if (
DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
          
// dirhtml builder
          
var dirname = item[0] + '/';
          if (
dirname.match(//index/$/)) {
            
dirname = dirname.substring(0, dirname.length-6);
          } else if (
dirname == 'index/') {
            
dirname = '';
          }
          
listItem.append($('<a/>').attr('href',
            
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
            
highlightstring + item[2]).html(item[1]));
        } else {
          
// normal html builders
          
listItem.append($('<a/>').attr('href',
            
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
            
highlightstring + item[2]).html(item[1]));
        }
        if (
item[3]) {
          
listItem.append($('<span> (' + item[3] + ')</span>'));
          
Search.output.append(listItem);
          
listItem.slideDown(5, function() {
            
displayNextItem();
          });
        } else if (
DOCUMENTATION_OPTIONS.HAS_SOURCE) {
          $.
ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
                  
dataType: "text",
                  
complete: function(jqxhr, textstatus) {
                    var 
data = jqxhr.responseText;
                    if (
data !== '') {
                      
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
                    }
                    
Search.output.append(listItem);
                    
listItem.slideDown(5, function() {
                      
displayNextItem();
                    });
                  }});
        } else {
          
// no source available, just display title
          
Search.output.append(listItem);
          
listItem.slideDown(5, function() {
            
displayNextItem();
          });
        }
      }
      
// search finished, update title and status message
      
else {
        
Search.stopPulse();
        
Search.title.text(_('Search Results'));
        if (!
resultCount)
          
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.'));
        else
            Search.status.text(_('
Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
        Search.status.fadeIn(500);
      }
    }
    displayNextItem();
  },

  /**
   * search for object names
   */
  performObjectSearch : function(object, otherterms) {
    var filenames = this._index.filenames;
    var objects = this._index.objects;
    var objnames = this._index.objnames;
    var titles = this._index.titles;

    var i;
    var results = [];

    for (var prefix in objects) {
      for (var name in objects[prefix]) {
        var fullname = (prefix ? prefix + '
.' : '') + name;
        if (fullname.toLowerCase().indexOf(object) > -1) {
          var score = 0;
          var parts = fullname.split('
.');
          // check for different match types: exact matches of full name or
          // "last name" (i.e. last dotted part)
          if (fullname == object || parts[parts.length - 1] == object) {
            score += Scorer.objNameMatch;
          // matches in last name
          } else if (parts[parts.length - 1].indexOf(object) > -1) {
            score += Scorer.objPartialMatch;
          }
          var match = objects[prefix][name];
          var objname = objnames[match[1]][2];
          var title = titles[match[0]];
          // If more than one term searched for, we require other words to be
          // found in the name/title/description
          if (otherterms.length > 0) {
            var haystack = (prefix + ' ' + name + ' ' +
                            objname + ' ' + title).toLowerCase();
            var allfound = true;
            for (i = 0; i < otherterms.length; i++) {
              if (haystack.indexOf(otherterms[i]) == -1) {
                allfound = false;
                break;
              }
            }
            if (!allfound) {
              continue;
            }
          }
          var descr = objname + _('
, in ') + title;

          var anchor = match[3];
          if (anchor === '')
            anchor = fullname;
          else if (anchor == '
-')
            anchor = objnames[match[1]][1] + '
-' + fullname;
          // add custom score for some objects according to scorer
          if (Scorer.objPrio.hasOwnProperty(match[2])) {
            score += Scorer.objPrio[match[2]];
          } else {
            score += Scorer.objPrioDefault;
          }
          results.push([filenames[match[0]], fullname, '
#'+anchor, descr, score]);
        
}
      }
    }

    return 
results;
  },

  
/**
   * search for full-text terms in the index
   */
  
performTermsSearch : function(searchterms, excluded, terms, score) {
    var 
filenames = this._index.filenames;
    var 
titles = this._index.titles;

    var 
i, j, file, files;
    var 
fileMap = {};
    var 
results = [];

    
// perform the search on the required terms
    
for (i = 0; i < searchterms.length; i++) {
      var 
word = searchterms[i];
      
// no match but word was a required one
      
if ((files = terms[word]) === undefined)
        break;
      if (
files.length === undefined) {
        
files = [files];
      }
      
// create the mapping
      
for (j = 0; j < files.length; j++) {
        
file = files[j];
        if (
file in fileMap)
          
fileMap[file].push(word);
        else
          
fileMap[file] = [word];
      }
    }

    
// now check if the files don't contain excluded terms
    
for (file in fileMap) {
      var 
valid = true;

      
// check if all requirements are matched
      
if (fileMap[file].length != searchterms.length)
          continue;

      
// ensure that none of the excluded terms is in the search result
      
for (i = 0; i < excluded.length; i++) {
        if (
terms[excluded[i]] == file ||
          
$u.contains(terms[excluded[i]] || [], file)) {
          
valid = false;
          break;
        }
      }

      
// if we have still a valid result we can add it to the result list
      
if (valid) {
        
results.push([filenames[file], titles[file], '', null, score]);
      }
    }
    return 
results;
  },

  
/**
   * helper function to return a node containing the
   * search summary for a given text. keywords is a list
   * of stemmed words, hlwords is the list of normal, unstemmed
   * words. the first one is used to find the occurance, the
   * latter for highlighting it.
   */
  
makeSearchSummary : function(text, keywords, hlwords) {
    var 
textLower = text.toLowerCase();
    var 
start = 0;
    $.
each(keywords, function() {
      var 
i = textLower.indexOf(this.toLowerCase());
      if (
i > -1)
        
start = i;
    });
    
start = Math.max(start - 120, 0);
    var 
excerpt = ((start > 0) ? '...' : '') +
      $.
trim(text.substr(start, 240)) +
      ((
start + 240 - text.length) ? '...' : '');
    var 
rv = $('<div class="context"></div>').text(excerpt);
    $.
each(hlwords, function() {
      
rv = rv.highlightText(this, 'highlighted');
    });
    return 
rv;
  }
};

$(
document).ready(function() {
  
Search.init();
});
?>
Онлайн: 0
Реклама