~ubuntu-branches/ubuntu/precise/maas/precise-updates

« back to all changes in this revision

Viewing changes to src/maasserver/static/jslibs/yui/3.4.1/build/text-wordbreak/text-wordbreak.js

Tags: 1.2+bzr1373+dfsg-0ubuntu1~12.04.4
* SECURITY UPDATE: failure to authenticate downloaded content (LP: #1039513)
  - debian/patches/CVE-2013-1058.patch: Authenticate downloaded files with
    GnuPG and MD5SUM files. Thanks to Julian Edwards.
  - CVE-2013-1058
* SECURITY UPDATE: configuration options may be loaded from current working
  directory (LP: #1158425)
  - debian/patches/CVE-2013-1057-1-2.patch: Do not load configuration
    options from the current working directory. Thanks to Julian Edwards.
  - CVE-2013-1057

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
YUI 3.4.1 (build 4118)
3
 
Copyright 2011 Yahoo! Inc. All rights reserved.
4
 
Licensed under the BSD License.
5
 
http://yuilibrary.com/license/
6
 
*/
7
 
YUI.add('text-wordbreak', function(Y) {
8
 
 
9
 
/**
10
 
 * Provides utility methods for splitting strings on word breaks and determining
11
 
 * whether a character index represents a word boundary.
12
 
 *
13
 
 * @module text
14
 
 * @submodule text-wordbreak
15
 
 */
16
 
 
17
 
/**
18
 
 * <p>
19
 
 * Provides utility methods for splitting strings on word breaks and determining
20
 
 * whether a character index represents a word boundary, using the generic word
21
 
 * breaking algorithm defined in the Unicode Text Segmentation guidelines
22
 
 * (<a href="http://unicode.org/reports/tr29/#Word_Boundaries">Unicode Standard
23
 
 * Annex #29</a>).
24
 
 * </p>
25
 
 *
26
 
 * <p>
27
 
 * This algorithm provides a reasonable default for many languages. However, it
28
 
 * does not cover language or context specific requirements, and it does not
29
 
 * provide meaningful results at all for languages that don't use spaces between
30
 
 * words, such as Chinese, Japanese, Thai, Lao, Khmer, and others. Server-based
31
 
 * word breaking services usually provide significantly better results with
32
 
 * better performance.
33
 
 * </p>
34
 
 *
35
 
 * @class Text.WordBreak
36
 
 * @static
37
 
 */
38
 
 
39
 
var Text   = Y.Text,
40
 
    WBData = Text.Data.WordBreak,
41
 
 
42
 
// Constants representing code point classifications.
43
 
ALETTER      = 0,
44
 
MIDNUMLET    = 1,
45
 
MIDLETTER    = 2,
46
 
MIDNUM       = 3,
47
 
NUMERIC      = 4,
48
 
CR           = 5,
49
 
LF           = 6,
50
 
NEWLINE      = 7,
51
 
EXTEND       = 8,
52
 
FORMAT       = 9,
53
 
KATAKANA     = 10,
54
 
EXTENDNUMLET = 11,
55
 
OTHER        = 12,
56
 
 
57
 
// RegExp objects generated from code point data. Each regex matches a single
58
 
// character against a set of Unicode code points. The index of each item in
59
 
// this array must match its corresponding code point constant value defined
60
 
// above.
61
 
SETS = [
62
 
    new RegExp(WBData.aletter),
63
 
    new RegExp(WBData.midnumlet),
64
 
    new RegExp(WBData.midletter),
65
 
    new RegExp(WBData.midnum),
66
 
    new RegExp(WBData.numeric),
67
 
    new RegExp(WBData.cr),
68
 
    new RegExp(WBData.lf),
69
 
    new RegExp(WBData.newline),
70
 
    new RegExp(WBData.extend),
71
 
    new RegExp(WBData.format),
72
 
    new RegExp(WBData.katakana),
73
 
    new RegExp(WBData.extendnumlet)
74
 
],
75
 
 
76
 
EMPTY_STRING = '',
77
 
PUNCTUATION  = new RegExp('^' + WBData.punctuation + '$'),
78
 
WHITESPACE   = /\s/,
79
 
 
80
 
WordBreak = {
81
 
    // -- Public Static Methods ------------------------------------------------
82
 
 
83
 
    /**
84
 
     * Splits the specified string into an array of individual words.
85
 
     *
86
 
     * @method getWords
87
 
     * @param {String} string String to split.
88
 
     * @param {Object} options (optional) Options object containing zero or more
89
 
     *   of the following properties:
90
 
     *
91
 
     * <dl>
92
 
     *   <dt>ignoreCase (Boolean)</dt>
93
 
     *   <dd>
94
 
     *     If <code>true</code>, the string will be converted to lowercase
95
 
     *     before being split. Default is <code>false</code>.
96
 
     *   </dd>
97
 
     *
98
 
     *   <dt>includePunctuation (Boolean)</dt>
99
 
     *   <dd>
100
 
     *     If <code>true</code>, the returned array will include punctuation
101
 
     *     characters. Default is <code>false</code>.
102
 
     *   </dd>
103
 
     *
104
 
     *   <dt>includeWhitespace (Boolean)</dt>
105
 
     *   <dd>
106
 
     *     If <code>true</code>, the returned array will include whitespace
107
 
     *     characters. Default is <code>false</code>.
108
 
     *   </dd>
109
 
     * </dl>
110
 
     * @return {Array} Array of words.
111
 
     * @static
112
 
     */
113
 
    getWords: function (string, options) {
114
 
        var i     = 0,
115
 
            map   = WordBreak._classify(string),
116
 
            len   = map.length,
117
 
            word  = [],
118
 
            words = [],
119
 
            chr,
120
 
            includePunctuation,
121
 
            includeWhitespace;
122
 
 
123
 
        if (!options) {
124
 
            options = {};
125
 
        }
126
 
 
127
 
        if (options.ignoreCase) {
128
 
            string = string.toLowerCase();
129
 
        }
130
 
 
131
 
        includePunctuation = options.includePunctuation;
132
 
        includeWhitespace  = options.includeWhitespace;
133
 
 
134
 
        // Loop through each character in the classification map and determine
135
 
        // whether it precedes a word boundary, building an array of distinct
136
 
        // words as we go.
137
 
        for (; i < len; ++i) {
138
 
            chr = string.charAt(i);
139
 
 
140
 
            // Append this character to the current word.
141
 
            word.push(chr);
142
 
 
143
 
            // If there's a word boundary between the current character and the
144
 
            // next character, append the current word to the words array and
145
 
            // start building a new word. 
146
 
            if (WordBreak._isWordBoundary(map, i)) {
147
 
                word = word.join(EMPTY_STRING);
148
 
 
149
 
                if (word &&
150
 
                        (includeWhitespace  || !WHITESPACE.test(word)) &&
151
 
                        (includePunctuation || !PUNCTUATION.test(word))) {
152
 
                    words.push(word);
153
 
                }
154
 
 
155
 
                word = [];
156
 
            }
157
 
        }
158
 
 
159
 
        return words;
160
 
    },
161
 
 
162
 
    /**
163
 
     * Returns an array containing only unique words from the specified string.
164
 
     * For example, the string <code>'foo bar baz foo'</code> would result in
165
 
     * the array <code>['foo', 'bar', 'baz']</code>.
166
 
     *
167
 
     * @method getUniqueWords
168
 
     * @param {String} string String to split.
169
 
     * @param {Object} options (optional) Options (see <code>getWords()</code>
170
 
     *   for details).
171
 
     * @return {Array} Array of unique words.
172
 
     * @static
173
 
     */
174
 
    getUniqueWords: function (string, options) {
175
 
        return Y.Array.unique(WordBreak.getWords(string, options));
176
 
    },
177
 
 
178
 
    /**
179
 
     * <p>
180
 
     * Returns <code>true</code> if there is a word boundary between the
181
 
     * specified character index and the next character index (or the end of the
182
 
     * string).
183
 
     * </p>
184
 
     *
185
 
     * <p>
186
 
     * Note that there are always word breaks at the beginning and end of a
187
 
     * string, so <code>isWordBoundary('', 0)</code> and
188
 
     * <code>isWordBoundary('a', 0)</code> will both return <code>true</code>.
189
 
     * </p>
190
 
     *
191
 
     * @method isWordBoundary
192
 
     * @param {String} string String to test.
193
 
     * @param {Number} index Character index to test within the string.
194
 
     * @return {Boolean} <code>true</code> for a word boundary,
195
 
     *   <code>false</code> otherwise.
196
 
     * @static
197
 
     */
198
 
    isWordBoundary: function (string, index) {
199
 
        return WordBreak._isWordBoundary(WordBreak._classify(string), index);
200
 
    },
201
 
 
202
 
    // -- Protected Static Methods ---------------------------------------------
203
 
 
204
 
    /**
205
 
     * Returns a character classification map for the specified string.
206
 
     *
207
 
     * @method _classify
208
 
     * @param {String} string String to classify.
209
 
     * @return {Array} Classification map.
210
 
     * @protected
211
 
     * @static
212
 
     */
213
 
    _classify: function (string) {
214
 
        var chr,
215
 
            map          = [],
216
 
            i            = 0,
217
 
            j,
218
 
            set,
219
 
            stringLength = string.length,
220
 
            setsLength   = SETS.length,
221
 
            type;
222
 
 
223
 
        for (; i < stringLength; ++i) {
224
 
            chr  = string.charAt(i);
225
 
            type = OTHER;
226
 
 
227
 
            for (j = 0; j < setsLength; ++j) {
228
 
                set = SETS[j];
229
 
 
230
 
                if (set && set.test(chr)) {
231
 
                    type = j;
232
 
                    break;
233
 
                }
234
 
            }
235
 
 
236
 
            map.push(type);
237
 
        }
238
 
 
239
 
        return map;
240
 
    },
241
 
 
242
 
    /**
243
 
     * <p>
244
 
     * Returns <code>true</code> if there is a word boundary between the
245
 
     * specified character index and the next character index (or the end of the
246
 
     * string).
247
 
     * </p>
248
 
     *
249
 
     * <p>
250
 
     * Note that there are always word breaks at the beginning and end of a
251
 
     * string, so <code>_isWordBoundary('', 0)</code> and
252
 
     * <code>_isWordBoundary('a', 0)</code> will both return <code>true</code>.
253
 
     * </p>
254
 
     *
255
 
     * @method _isWordBoundary
256
 
     * @param {Array} map Character classification map generated by
257
 
     *   <code>_classify</code>.
258
 
     * @param {Number} index Character index to test.
259
 
     * @return {Boolean}
260
 
     * @protected
261
 
     * @static
262
 
     */
263
 
    _isWordBoundary: function (map, index) {
264
 
        var prevType,
265
 
            type     = map[index],
266
 
            nextType = map[index + 1],
267
 
            nextNextType;
268
 
 
269
 
        if (index < 0 || (index > map.length - 1 && index !== 0)) {
270
 
            return false;
271
 
        }
272
 
 
273
 
        // WB5. Don't break between most letters.
274
 
        if (type === ALETTER && nextType === ALETTER) {
275
 
            return false;
276
 
        }
277
 
 
278
 
        nextNextType = map[index + 2];
279
 
 
280
 
        // WB6. Don't break letters across certain punctuation.
281
 
        if (type === ALETTER &&
282
 
                (nextType === MIDLETTER || nextType === MIDNUMLET) &&
283
 
                nextNextType === ALETTER) {
284
 
            return false;
285
 
        }
286
 
 
287
 
        prevType = map[index - 1];
288
 
 
289
 
        // WB7. Don't break letters across certain punctuation.
290
 
        if ((type === MIDLETTER || type === MIDNUMLET) &&
291
 
                nextType === ALETTER &&
292
 
                prevType === ALETTER) {
293
 
            return false;
294
 
        }
295
 
 
296
 
        // WB8/WB9/WB10. Don't break inside sequences of digits or digits
297
 
        // adjacent to letters.
298
 
        if ((type === NUMERIC || type === ALETTER) &&
299
 
                (nextType === NUMERIC || nextType === ALETTER)) {
300
 
            return false;
301
 
        }
302
 
 
303
 
        // WB11. Don't break inside numeric sequences like "3.2" or
304
 
        // "3,456.789".
305
 
        if ((type === MIDNUM || type === MIDNUMLET) &&
306
 
                nextType === NUMERIC &&
307
 
                prevType === NUMERIC) {
308
 
            return false;
309
 
        }
310
 
 
311
 
        // WB12. Don't break inside numeric sequences like "3.2" or
312
 
        // "3,456.789".
313
 
        if (type === NUMERIC &&
314
 
                (nextType === MIDNUM || nextType === MIDNUMLET) &&
315
 
                nextNextType === NUMERIC) {
316
 
            return false;
317
 
        }
318
 
 
319
 
        // WB4. Ignore format and extend characters.
320
 
        if (type === EXTEND || type === FORMAT ||
321
 
                prevType === EXTEND || prevType === FORMAT ||
322
 
                nextType === EXTEND || nextType === FORMAT) {
323
 
            return false;
324
 
        }
325
 
 
326
 
        // WB3. Don't break inside CRLF.
327
 
        if (type === CR && nextType === LF) {
328
 
            return false;
329
 
        }
330
 
 
331
 
        // WB3a. Break before newlines (including CR and LF).
332
 
        if (type === NEWLINE || type === CR || type === LF) {
333
 
            return true;
334
 
        }
335
 
 
336
 
        // WB3b. Break after newlines (including CR and LF).
337
 
        if (nextType === NEWLINE || nextType === CR || nextType === LF) {
338
 
            return true;
339
 
        }
340
 
 
341
 
        // WB13. Don't break between Katakana characters.
342
 
        if (type === KATAKANA && nextType === KATAKANA) {
343
 
            return false;
344
 
        }
345
 
 
346
 
        // WB13a. Don't break from extenders.
347
 
        if (nextType === EXTENDNUMLET &&
348
 
                (type === ALETTER || type === NUMERIC || type === KATAKANA ||
349
 
                type === EXTENDNUMLET)) {
350
 
            return false;
351
 
        }
352
 
 
353
 
        // WB13b. Don't break from extenders.
354
 
        if (type === EXTENDNUMLET &&
355
 
                (nextType === ALETTER || nextType === NUMERIC ||
356
 
                nextType === KATAKANA)) {
357
 
            return false;
358
 
        }
359
 
 
360
 
        // Break after any character not covered by the rules above.
361
 
        return true;
362
 
    }
363
 
};
364
 
 
365
 
Text.WordBreak = WordBreak;
366
 
 
367
 
 
368
 
}, '3.4.1' ,{requires:['array-extras', 'text-data-wordbreak']});