[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/highlight-base/ -> highlight-base.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 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.17.2', {"requires": ["array-extras", "classnamemanager", "escape", "text-wordbreak"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1