~ubuntu-branches/ubuntu/oneiric/lightning-extension/oneiric-updates

« back to all changes in this revision

Viewing changes to mozilla/other-licenses/simplejson-2.1.1/docs/_static/searchtools.js

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2012-11-08 10:00:06 UTC
  • mfrom: (1.3.8)
  • Revision ID: package-import@ubuntu.com-20121108100006-xpf89hktfitzuqc3
Tags: 1.9+build1-0ubuntu0.11.10.1
* New upstream stable release to support Thunderbird 17 (CALENDAR_1_9_BUILD1)
  - see LP: #1080212 for USN information

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * helper function to return a node containing the
3
 
 * search summary for a given text. keywords is a list
4
 
 * of stemmed words, hlwords is the list of normal, unstemmed
5
 
 * words. the first one is used to find the occurance, the
6
 
 * latter for highlighting it.
7
 
 */
8
 
jQuery.makeSearchSummary = function(text, keywords, hlwords) {
9
 
    var textLower = text.toLowerCase();
10
 
    var start = 0;
11
 
    $.each(keywords, function() {
12
 
            var i = textLower.indexOf(this.toLowerCase());
13
 
            if (i > -1) {
14
 
                start = i;
15
 
            }
16
 
        });
17
 
    start = Math.max(start - 120, 0);
18
 
    var excerpt = ((start > 0) ? '...' : '') +
19
 
    $.trim(text.substr(start, 240)) +
20
 
    ((start + 240 - text.length) ? '...' : '');
21
 
    var rv = $('<div class="context"></div>').text(excerpt);
22
 
    $.each(hlwords, function() {
23
 
            rv = rv.highlightText(this, 'highlight');
24
 
        });
25
 
    return rv;
26
 
}
27
 
 
28
 
/**
29
 
 * Porter Stemmer
30
 
 */
31
 
var PorterStemmer = function() {
32
 
 
33
 
    var step2list = {
34
 
        ational: 'ate',
35
 
        tional: 'tion',
36
 
        enci: 'ence',
37
 
        anci: 'ance',
38
 
        izer: 'ize',
39
 
        bli: 'ble',
40
 
        alli: 'al',
41
 
        entli: 'ent',
42
 
        eli: 'e',
43
 
        ousli: 'ous',
44
 
        ization: 'ize',
45
 
        ation: 'ate',
46
 
        ator: 'ate',
47
 
        alism: 'al',
48
 
        iveness: 'ive',
49
 
        fulness: 'ful',
50
 
        ousness: 'ous',
51
 
        aliti: 'al',
52
 
        iviti: 'ive',
53
 
        biliti: 'ble',
54
 
        logi: 'log'
55
 
    };
56
 
 
57
 
    var step3list = {
58
 
        icate: 'ic',
59
 
        ative: '',
60
 
        alize: 'al',
61
 
        iciti: 'ic',
62
 
        ical: 'ic',
63
 
        ful: '',
64
 
        ness: ''
65
 
    };
66
 
 
67
 
    var c = "[^aeiou]";          // consonant
68
 
    var v = "[aeiouy]";          // vowel
69
 
    var C = c + "[^aeiouy]*";    // consonant sequence
70
 
    var V = v + "[aeiou]*";      // vowel sequence
71
 
 
72
 
    var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
73
 
    var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
74
 
    var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
75
 
    var s_v   = "^(" + C + ")?" + v;                        // vowel in stem
76
 
 
77
 
    this.stemWord = function (w) {
78
 
        var stem;
79
 
        var suffix;
80
 
        var firstch;
81
 
        var origword = w;
82
 
 
83
 
        if (w.length < 3) {
84
 
            return w;
85
 
        }
86
 
 
87
 
        var re;
88
 
        var re2;
89
 
        var re3;
90
 
        var re4;
91
 
 
92
 
        firstch = w.substr(0,1);
93
 
        if (firstch == "y") {
94
 
            w = firstch.toUpperCase() + w.substr(1);
95
 
        }
96
 
 
97
 
        // Step 1a
98
 
        re = /^(.+?)(ss|i)es$/;
99
 
        re2 = /^(.+?)([^s])s$/;
100
 
 
101
 
        if (re.test(w)) {
102
 
            w = w.replace(re,"$1$2");
103
 
        }
104
 
        else if (re2.test(w)) {
105
 
            w = w.replace(re2,"$1$2");
106
 
        }
107
 
 
108
 
        // Step 1b
109
 
        re = /^(.+?)eed$/;
110
 
        re2 = /^(.+?)(ed|ing)$/;
111
 
        if (re.test(w)) {
112
 
            var fp = re.exec(w);
113
 
            re = new RegExp(mgr0);
114
 
            if (re.test(fp[1])) {
115
 
                re = /.$/;
116
 
                w = w.replace(re,"");
117
 
            }
118
 
        }
119
 
        else if (re2.test(w)) {
120
 
            var fp = re2.exec(w);
121
 
            stem = fp[1];
122
 
            re2 = new RegExp(s_v);
123
 
            if (re2.test(stem)) {
124
 
                w = stem;
125
 
                re2 = /(at|bl|iz)$/;
126
 
                re3 = new RegExp("([^aeiouylsz])\\1$");
127
 
                re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
128
 
                if (re2.test(w)) {
129
 
                    w = w + "e";
130
 
                }
131
 
                else if (re3.test(w)) {
132
 
                    re = /.$/; w = w.replace(re,"");
133
 
                }
134
 
                else if (re4.test(w)) {
135
 
                    w = w + "e";
136
 
                }
137
 
            }
138
 
        }
139
 
 
140
 
        // Step 1c
141
 
        re = /^(.+?)y$/;
142
 
        if (re.test(w)) {
143
 
            var fp = re.exec(w);
144
 
            stem = fp[1];
145
 
            re = new RegExp(s_v);
146
 
            if (re.test(stem)) { w = stem + "i"; }
147
 
        }
148
 
 
149
 
        // Step 2
150
 
        re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
151
 
        if (re.test(w)) {
152
 
            var fp = re.exec(w);
153
 
            stem = fp[1];
154
 
            suffix = fp[2];
155
 
            re = new RegExp(mgr0);
156
 
            if (re.test(stem)) {
157
 
                w = stem + step2list[suffix];
158
 
            }
159
 
        }
160
 
 
161
 
        // Step 3
162
 
        re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
163
 
        if (re.test(w)) {
164
 
            var fp = re.exec(w);
165
 
            stem = fp[1];
166
 
            suffix = fp[2];
167
 
            re = new RegExp(mgr0);
168
 
            if (re.test(stem)) {
169
 
                w = stem + step3list[suffix];
170
 
            }
171
 
        }
172
 
 
173
 
        // Step 4
174
 
        re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
175
 
        re2 = /^(.+?)(s|t)(ion)$/;
176
 
        if (re.test(w)) {
177
 
            var fp = re.exec(w);
178
 
            stem = fp[1];
179
 
            re = new RegExp(mgr1);
180
 
            if (re.test(stem)) {
181
 
                w = stem;
182
 
            }
183
 
        }
184
 
        else if (re2.test(w)) {
185
 
            var fp = re2.exec(w);
186
 
            stem = fp[1] + fp[2];
187
 
            re2 = new RegExp(mgr1);
188
 
            if (re2.test(stem)) {
189
 
                w = stem;
190
 
            }
191
 
        }
192
 
 
193
 
        // Step 5
194
 
        re = /^(.+?)e$/;
195
 
        if (re.test(w)) {
196
 
            var fp = re.exec(w);
197
 
            stem = fp[1];
198
 
            re = new RegExp(mgr1);
199
 
            re2 = new RegExp(meq1);
200
 
            re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
201
 
            if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {
202
 
                w = stem;
203
 
            }
204
 
        }
205
 
        re = /ll$/;
206
 
        re2 = new RegExp(mgr1);
207
 
        if (re.test(w) && re2.test(w)) {
208
 
            re = /.$/;
209
 
            w = w.replace(re,"");
210
 
        }
211
 
 
212
 
        // and turn initial Y back to y
213
 
        if (firstch == "y") {
214
 
            w = firstch.toLowerCase() + w.substr(1);
215
 
        }
216
 
        return w;
217
 
    }
218
 
}
219
 
 
220
 
 
221
 
 
222
 
/**
223
 
 * Search Module
224
 
 */
225
 
var Search = {
226
 
 
227
 
    init : function() {
228
 
        var params = $.getQueryParameters();
229
 
        if (params.q) {
230
 
            var query = params.q[0];
231
 
            $('input[@name="q"]')[0].value = query;
232
 
            this.performSearch(query);
233
 
        }
234
 
    },
235
 
 
236
 
    /**
237
 
     * perform a search for something
238
 
     */
239
 
    performSearch : function(query) {
240
 
        // create the required interface elements
241
 
        var out = $('#search-results');
242
 
        var title = $('<h2>Searching</h2>').appendTo(out);
243
 
        var dots = $('<span></span>').appendTo(title);
244
 
        var status = $('<p style="display: none"></p>').appendTo(out);
245
 
        var output = $('<ul class="search"/>').appendTo(out);
246
 
 
247
 
        // spawn a background runner for updating the dots
248
 
        // until the search has finished
249
 
        var pulseStatus = 0;
250
 
        function pulse() {
251
 
            pulseStatus = (pulseStatus + 1) % 4;
252
 
            var dotString = '';
253
 
            for (var i = 0; i < pulseStatus; i++) {
254
 
                dotString += '.';
255
 
            }
256
 
            dots.text(dotString);
257
 
            if (pulseStatus > -1) {
258
 
                window.setTimeout(pulse, 500);
259
 
            }
260
 
        };
261
 
        pulse();
262
 
 
263
 
        // stem the searchwords and add them to the
264
 
        // correct list
265
 
        var stemmer = new PorterStemmer();
266
 
        var searchwords = [];
267
 
        var excluded = [];
268
 
        var hlwords = [];
269
 
        var tmp = query.split(/\s+/);
270
 
        for (var i = 0; i < tmp.length; i++) {
271
 
            // stem the word
272
 
            var word = stemmer.stemWord(tmp[i]).toLowerCase();
273
 
            // select the correct list
274
 
            if (word[0] == '-') {
275
 
                var toAppend = excluded;
276
 
                word = word.substr(1);
277
 
            }
278
 
            else {
279
 
                var toAppend = searchwords;
280
 
                hlwords.push(tmp[i].toLowerCase());
281
 
            }
282
 
            // only add if not already in the list
283
 
            if (!$.contains(toAppend, word)) {
284
 
                toAppend.push(word);
285
 
            }
286
 
        };
287
 
        var highlightstring = '?highlight=' + $.urlencode(hlwords.join(" "));
288
 
 
289
 
        console.debug('SEARCH: searching for:');
290
 
        console.info('required: ', searchwords);
291
 
        console.info('excluded: ', excluded);
292
 
 
293
 
        // fetch searchindex and perform search
294
 
        $.getJSON('searchindex.json', function(data) {
295
 
 
296
 
                // prepare search
297
 
                var filenames = data[0];
298
 
                var titles = data[1]
299
 
                var words = data[2];
300
 
                var fileMap = {};
301
 
                var files = null;
302
 
 
303
 
                // perform the search on the required words
304
 
                for (var i = 0; i < searchwords.length; i++) {
305
 
                    var word = searchwords[i];
306
 
                    // no match but word was a required one
307
 
                    if ((files = words[word]) == null) {
308
 
                        break;
309
 
                    }
310
 
                    // create the mapping
311
 
                    for (var j = 0; j < files.length; j++) {
312
 
                        var file = files[j];
313
 
                        if (file in fileMap) {
314
 
                            fileMap[file].push(word);
315
 
                        }
316
 
                        else {
317
 
                            fileMap[file] = [word];
318
 
                        }
319
 
                    }
320
 
                }
321
 
 
322
 
                // now check if the files are in the correct
323
 
                // areas and if the don't contain excluded words
324
 
                var results = [];
325
 
                for (var file in fileMap) {
326
 
                    var valid = true;
327
 
 
328
 
                    // check if all requirements are matched
329
 
                    if (fileMap[file].length != searchwords.length) {
330
 
                        continue;
331
 
                    }
332
 
                    // ensure that none of the excluded words is in the
333
 
                    // search result.
334
 
                    for (var i = 0; i < excluded.length; i++) {
335
 
                        if ($.contains(words[excluded[i]] || [], file)) {
336
 
                            valid = false;
337
 
                            break;
338
 
                        }
339
 
                    }
340
 
 
341
 
                    // if we have still a valid result we can add it
342
 
                    // to the result list
343
 
                    if (valid) {
344
 
                        results.push([filenames[file], titles[file]]);
345
 
                    }
346
 
                }
347
 
 
348
 
                // delete unused variables in order to not waste
349
 
                // memory until list is retrieved completely
350
 
                delete filenames, titles, words, data;
351
 
 
352
 
                // now sort the results by title
353
 
                results.sort(function(a, b) {
354
 
                        var left = a[1].toLowerCase();
355
 
                        var right = b[1].toLowerCase();
356
 
                        return (left > right) ? -1 : ((left < right) ? 1 : 0);
357
 
                    });
358
 
 
359
 
                // print the results
360
 
                var resultCount = results.length;
361
 
                function displayNextItem() {
362
 
                    // results left, load the summary and display it
363
 
                    if (results.length) {
364
 
                        var item = results.pop();
365
 
                        var listItem = $('<li style="display:none"></li>');
366
 
                        listItem.append($('<a/>').attr(
367
 
                            'href',
368
 
                            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
369
 
                            highlightstring).html(item[1]));
370
 
                        $.get('_sources/' + item[0] + '.txt', function(data) {
371
 
                                listItem.append($.makeSearchSummary(data, searchwords, hlwords));
372
 
                                output.append(listItem);
373
 
                                listItem.slideDown(10, function() {
374
 
                                        displayNextItem();
375
 
                                    });
376
 
                            });
377
 
                    }
378
 
                    // search finished, update title and status message
379
 
                    else {
380
 
                        pulseStatus = -1;
381
 
                        title.text('Search Results');
382
 
                        if (!resultCount) {
383
 
                            status.text('Your search did not match any documents. ' +
384
 
                                        'Please make sure that all words are spelled ' +
385
 
                                        'correctly and that you\'ve selected enough ' +
386
 
                                        'categories.');
387
 
                        }
388
 
                        else {
389
 
                            status.text('Search finished, found ' + resultCount +
390
 
                                        ' page' + (resultCount != 1 ? 's' : '') +
391
 
                                        ' matching the search query.');
392
 
                        }
393
 
                        status.fadeIn(500);
394
 
                    }
395
 
                }
396
 
                displayNextItem();
397
 
            });
398
 
    }
399
 
 
400
 
}
401
 
 
402
 
$(document).ready(function() {
403
 
        Search.init();
404
 
    });