src/cm/media/js/lib/yui/yui_3.10.3/build/highlight-base/highlight-base-debug.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 /*
       
     2 YUI 3.10.3 (build 2fb5187)
       
     3 Copyright 2013 Yahoo! Inc. All rights reserved.
       
     4 Licensed under the BSD License.
       
     5 http://yuilibrary.com/license/
       
     6 */
       
     7 
       
     8 YUI.add('highlight-base', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11 Provides methods for highlighting strings within other strings by wrapping
       
    12 them in HTML.
       
    13 
       
    14 @module highlight
       
    15 @submodule highlight-base
       
    16 @main
       
    17 @since 3.3.0
       
    18 **/
       
    19 
       
    20 /**
       
    21 Provides methods for highlighting strings within other strings by wrapping
       
    22 them in HTML.
       
    23 
       
    24 The highlight methods first escape any special HTML characters in the input
       
    25 strings and then highlight the appropriate substrings by wrapping them in a
       
    26 `<b class="yui3-highlight"></b>` element. The `<b>` element is used rather than
       
    27 `<strong>` in accordance with HTML5's definition of `<b>` as being purely
       
    28 presentational, which is exactly what highlighting is.
       
    29 
       
    30 @class Highlight
       
    31 @static
       
    32 **/
       
    33 
       
    34 var YArray    = Y.Array,
       
    35     Escape    = Y.Escape,
       
    36     WordBreak = Y.Text.WordBreak,
       
    37 
       
    38     isArray = Y.Lang.isArray,
       
    39 
       
    40     EMPTY_OBJECT = {},
       
    41 
       
    42     // Regex string that captures zero or one unclosed HTML entities. Used in
       
    43     // the static regex template properties below. The entity matching is
       
    44     // intentionally loose here, since there's a world of complexity involved in
       
    45     // doing strict matching for this use case.
       
    46     UNCLOSED_ENTITY = '(&[^;\\s]*)?',
       
    47 
       
    48 Highlight = {
       
    49     // -- Protected Static Properties ------------------------------------------
       
    50 
       
    51     /**
       
    52     Regular expression template for highlighting a match that occurs anywhere
       
    53     in a string. The placeholder `%needles` will be replaced with a list of
       
    54     needles to match, joined by `|` characters.
       
    55 
       
    56     This regex should have two capturing subpatterns:
       
    57 
       
    58       1. Zero or one unclosed HTML entity (e.g. "&amp" without a ";" at the
       
    59          end).
       
    60       2. The `%needles` placeholder.
       
    61 
       
    62     The first subpattern match is used to emulate a negative lookbehind
       
    63     assertion in order to prevent highlighting inside HTML entities.
       
    64 
       
    65     @property _REGEX
       
    66     @type String
       
    67     @protected
       
    68     @static
       
    69     @final
       
    70     **/
       
    71     _REGEX: UNCLOSED_ENTITY + '(%needles)',
       
    72 
       
    73     /**
       
    74     Regex replacer function or string for normal matches.
       
    75 
       
    76     @property _REPLACER
       
    77     @type Function|String
       
    78     @protected
       
    79     @static
       
    80     @final
       
    81     **/
       
    82     _REPLACER: function (match, p1, p2) {
       
    83          // Mimicking a negative lookbehind assertion to prevent matches inside
       
    84          // HTML entities. Hat tip to Steven Levithan for the technique:
       
    85          // http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
       
    86          return p1 && !(/\s/).test(p2) ? match :
       
    87                     Highlight._TEMPLATE.replace(/\{s\}/g, p2);
       
    88      },
       
    89 
       
    90     /**
       
    91     Regular expression template for highlighting start-of-string matches
       
    92     (i.e., only matches that occur at the beginning of a string). The
       
    93     placeholder `%needles` will be replaced with a list of needles to match,
       
    94     joined by `|` characters.
       
    95 
       
    96     See `_REGEX` for a description of the capturing subpatterns this regex
       
    97     string should contain.
       
    98 
       
    99     @property _START_REGEX
       
   100     @type String
       
   101     @protected
       
   102     @static
       
   103     @final
       
   104      */
       
   105     _START_REGEX: '^' + UNCLOSED_ENTITY + '(%needles)',
       
   106 
       
   107     /**
       
   108     Highlight template which will be used as a replacement for matched
       
   109     substrings. The placeholder `{s}` will be replaced with the matched
       
   110     substring.
       
   111 
       
   112     @property _TEMPLATE
       
   113     @type String
       
   114     @default '<b class="yui3-highlight">{s}</b>'
       
   115     @protected
       
   116     @static
       
   117     @final
       
   118     **/
       
   119     _TEMPLATE: '<b class="' + Y.ClassNameManager.getClassName('highlight') + '">{s}</b>',
       
   120 
       
   121     // -- Public Static Methods ------------------------------------------------
       
   122 
       
   123     /**
       
   124     Highlights all occurrences in the _haystack_ string of the items in the
       
   125     _needles_ array, regardless of where they occur. The returned string will
       
   126     have all HTML characters escaped except for the highlighting markup.
       
   127 
       
   128     @method all
       
   129     @param {String} haystack String to apply highlighting to.
       
   130     @param {String|String[]} needles String or array of strings that should be
       
   131         highlighted.
       
   132     @param {Object} [options] Options object.
       
   133     @param {Boolean} [options.caseSensitive=false] If `true`, matching will
       
   134         be case-sensitive.
       
   135     @param {Boolean} [options.startsWith=false] If `true`, matches must be
       
   136         anchored to the beginning of the string.
       
   137     @return {String} Escaped and highlighted copy of _haystack_.
       
   138     @static
       
   139     **/
       
   140     all: function (haystack, needles, options) {
       
   141         var validNeedles = [],
       
   142             esc, i, len, needle, regex, replacer;
       
   143 
       
   144         if (!options) {
       
   145             options = EMPTY_OBJECT;
       
   146         }
       
   147 
       
   148         // TODO: document options.replacer
       
   149         esc      = options.escapeHTML !== false;
       
   150         regex    = options.startsWith ? Highlight._START_REGEX : Highlight._REGEX;
       
   151         replacer = options.replacer || Highlight._REPLACER;
       
   152         needles  = isArray(needles) ? needles : [needles];
       
   153 
       
   154         // Escape HTML characters and special regular expression characters in
       
   155         // the needles so they can be used in a regex and matched against the
       
   156         // escaped haystack.
       
   157         for (i = 0, len = needles.length; i < len; ++i) {
       
   158             needle = needles[i];
       
   159 
       
   160             if (needle) {
       
   161                 validNeedles.push(Escape.regex(esc ? Escape.html(needle) : needle));
       
   162             }
       
   163         }
       
   164 
       
   165         // Escape HTML characters in the haystack to prevent HTML injection.
       
   166         if (esc) {
       
   167             haystack = Escape.html(haystack);
       
   168         }
       
   169 
       
   170         // No point continuing if there are no needles.
       
   171         if (!validNeedles.length) {
       
   172             return haystack;
       
   173         }
       
   174 
       
   175         return haystack.replace(
       
   176             new RegExp(
       
   177                 regex.replace('%needles', validNeedles.join('|')),
       
   178                 options.caseSensitive ? 'g' : 'gi'
       
   179             ),
       
   180             replacer
       
   181         );
       
   182     },
       
   183 
       
   184     /**
       
   185     Same as `all()`, but case-sensitive by default.
       
   186 
       
   187     @method allCase
       
   188     @param {String} haystack String to apply highlighting to.
       
   189     @param {String|String[]} needles String or array of strings that should be
       
   190       highlighted.
       
   191     @param {Object} [options] Options object. See `all()` for details.
       
   192     @return {String} Escaped and highlighted copy of _haystack_.
       
   193     @static
       
   194     **/
       
   195     allCase: function (haystack, needles, options) {
       
   196         return Highlight.all(haystack, needles,
       
   197                 Y.merge(options || EMPTY_OBJECT, {caseSensitive: true}));
       
   198     },
       
   199 
       
   200     /**
       
   201     Highlights _needles_ that occur at the start of _haystack_. The returned
       
   202     string will have all HTML characters escaped except for the highlighting
       
   203     markup.
       
   204 
       
   205     @method start
       
   206     @param {String} haystack String to apply highlighting to.
       
   207     @param {String|String[]} needles String or array of strings that should be
       
   208       highlighted.
       
   209     @param {Object} [options] Options object.
       
   210     @param {Boolean} [options.caseSensitive=false] If `true`, matching will
       
   211         be case-sensitive.
       
   212     @return {String} Escaped and highlighted copy of _haystack_.
       
   213     @static
       
   214     **/
       
   215     start: function (haystack, needles, options) {
       
   216         return Highlight.all(haystack, needles,
       
   217                 Y.merge(options || EMPTY_OBJECT, {startsWith: true}));
       
   218     },
       
   219 
       
   220     /**
       
   221     Same as `start()`, but case-sensitive by default.
       
   222 
       
   223     @method startCase
       
   224     @param {String} haystack String to apply highlighting to.
       
   225     @param {String|String[]} needles String or array of strings that should be
       
   226       highlighted.
       
   227     @return {String} Escaped and highlighted copy of _haystack_.
       
   228     @static
       
   229     **/
       
   230     startCase: function (haystack, needles) {
       
   231         // No options passthru for now, since it would be redundant. If start()
       
   232         // ever supports more options than caseSensitive, then we'll start
       
   233         // passing the options through.
       
   234         return Highlight.start(haystack, needles, {caseSensitive: true});
       
   235     },
       
   236 
       
   237     /**
       
   238     Highlights complete words in the _haystack_ string that are also in the
       
   239     _needles_ array. The returned string will have all HTML characters escaped
       
   240     except for the highlighting markup.
       
   241 
       
   242     @method words
       
   243     @param {String} haystack String to apply highlighting to.
       
   244     @param {String|String[]} needles String or array of strings containing words
       
   245       that should be highlighted. If a string is passed, it will be split
       
   246       into words; if an array is passed, it is assumed to have already been
       
   247       split.
       
   248     @param {Object} [options] Options object.
       
   249     @param {Boolean} [options.caseSensitive=false] If `true`, matching will
       
   250         be case-sensitive.
       
   251     @return {String} Escaped and highlighted copy of _haystack_.
       
   252     @static
       
   253     **/
       
   254     words: function (haystack, needles, options) {
       
   255         var caseSensitive,
       
   256             mapper,
       
   257             template = Highlight._TEMPLATE,
       
   258             words;
       
   259 
       
   260         if (!options) {
       
   261             options = EMPTY_OBJECT;
       
   262         }
       
   263 
       
   264         caseSensitive = !!options.caseSensitive;
       
   265 
       
   266         // Convert needles to a hash for faster lookups.
       
   267         needles = YArray.hash(
       
   268             isArray(needles) ? needles : WordBreak.getUniqueWords(needles, {
       
   269                 ignoreCase: !caseSensitive
       
   270             })
       
   271         );
       
   272 
       
   273         // The default word mapping function can be overridden with a custom
       
   274         // one. This is used to implement accent-folded highlighting in the
       
   275         // highlight-accentfold module.
       
   276         mapper = options.mapper || function (word, needles) {
       
   277             if (needles.hasOwnProperty(caseSensitive ? word : word.toLowerCase())) {
       
   278                 return template.replace(/\{s\}/g, Escape.html(word));
       
   279             }
       
   280 
       
   281             return Escape.html(word);
       
   282         };
       
   283 
       
   284         // Split the haystack into an array of words, including punctuation and
       
   285         // whitespace so we can rebuild the string later.
       
   286         words = WordBreak.getWords(haystack, {
       
   287             includePunctuation: true,
       
   288             includeWhitespace : true
       
   289         });
       
   290 
       
   291         return YArray.map(words, function (word) {
       
   292             return mapper(word, needles);
       
   293         }).join('');
       
   294     },
       
   295 
       
   296     /**
       
   297     Same as `words()`, but case-sensitive by default.
       
   298 
       
   299     @method wordsCase
       
   300     @param {String} haystack String to apply highlighting to.
       
   301     @param {String|String[]} needles String or array of strings containing words
       
   302       that should be highlighted. If a string is passed, it will be split
       
   303       into words; if an array is passed, it is assumed to have already been
       
   304       split.
       
   305     @return {String} Escaped and highlighted copy of _haystack_.
       
   306     @static
       
   307     **/
       
   308     wordsCase: function (haystack, needles) {
       
   309         // No options passthru for now, since it would be redundant. If words()
       
   310         // ever supports more options than caseSensitive, then we'll start
       
   311         // passing the options through.
       
   312         return Highlight.words(haystack, needles, {caseSensitive: true});
       
   313     }
       
   314 };
       
   315 
       
   316 Y.Highlight = Highlight;
       
   317 
       
   318 
       
   319 }, '3.10.3', {"requires": ["array-extras", "classnamemanager", "escape", "text-wordbreak"]});