[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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. "&" 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"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |