- /**
- Adds accent-folding highlighters to `Y.Highlight`.
-
- @module highlight
- @submodule highlight-accentfold
- **/
-
- /**
- @class Highlight
- @static
- **/
-
- var AccentFold = Y.Text.AccentFold,
- Escape = Y.Escape,
-
- EMPTY_OBJECT = {},
-
- Highlight = Y.mix(Y.Highlight, {
- // -- Public Static Methods ------------------------------------------------
-
- /**
- Accent-folding version of `all()`.
-
- @method allFold
- @param {String} haystack String to apply highlighting to.
- @param {String|String[]} needles String or array of strings that should be
- highlighted.
- @param {Object} [options] Options object.
- @param {Boolean} [options.startsWith=false] If `true`, matches must be
- anchored to the beginning of the string.
- @return {String} Escaped and highlighted copy of _haystack_.
- @static
- **/
- allFold: function (haystack, needles, options) {
- var template = Highlight._TEMPLATE,
- results = [],
- startPos = 0,
- chunk, i, len, match, result;
-
- options = Y.merge({
- // This tells Highlight.all() not to escape HTML, in order to ensure
- // usable match offsets. The output of all() is discarded, and we
- // perform our own escaping before returning the highlighted string.
- escapeHTML: false,
-
- // While the highlight regex operates on the accent-folded strings,
- // this replacer will highlight the matched positions in the
- // original string.
- //
- // Note: this implementation doesn't handle multi-character folds,
- // like "æ" -> "ae". Doing so correctly would be prohibitively
- // expensive both in terms of code size and runtime performance, so
- // I've chosen to take the pragmatic route and just not do it at
- // all. This is one of many reasons why accent folding is best done
- // on the server.
- replacer: function (match, p1, foldedNeedle, pos) {
- var len;
-
- // Ignore matches inside HTML entities.
- if (p1 && !(/\s/).test(foldedNeedle)) {
- return match;
- }
-
- len = foldedNeedle.length;
-
- results.push([
- haystack.substring(startPos, pos), // substring between previous match and this match
- haystack.substr(pos, len) // match to be highlighted
- ]);
-
- startPos = pos + len;
- }
- }, options || EMPTY_OBJECT);
-
- // Run the highlighter on the folded strings. We don't care about the
- // output; our replacer function will build the canonical highlighted
- // string, with original accented characters.
- Highlight.all(AccentFold.fold(haystack), AccentFold.fold(needles), options);
-
- // Tack on the remainder of the haystack that wasn't highlighted, if
- // any.
- if (startPos < haystack.length) {
- results.push([haystack.substr(startPos)]);
- }
-
- // Highlight and escape the string.
- for (i = 0, len = results.length; i < len; ++i) {
- chunk = Escape.html(results[i][0]);
-
- if ((match = results[i][1])) {
- chunk += template.replace(/\{s\}/g, Escape.html(match));
- }
-
- results[i] = chunk;
- }
-
- return results.join('');
- },
-
- /**
- Accent-folding version of `start()`.
-
- @method startFold
- @param {String} haystack String to apply highlighting to.
- @param {String|String[]} needles String or array of strings that should be
- highlighted.
- @return {String} Escaped and highlighted copy of _haystack_.
- @static
- **/
- startFold: function (haystack, needles) {
- return Highlight.allFold(haystack, needles, {startsWith: true});
- },
-
- /**
- Accent-folding version of `words()`.
-
- @method wordsFold
- @param {String} haystack String to apply highlighting to.
- @param {String|String[]} needles String or array of strings containing words
- that should be highlighted. If a string is passed, it will be split
- into words; if an array is passed, it is assumed to have already been
- split.
- @return {String} Escaped and highlighted copy of _haystack_.
- @static
- **/
- wordsFold: function (haystack, needles) {
- var template = Highlight._TEMPLATE;
-
- return Highlight.words(haystack, AccentFold.fold(needles), {
- mapper: function (word, needles) {
- if (needles.hasOwnProperty(AccentFold.fold(word))) {
- return template.replace(/\{s\}/g, Escape.html(word));
- }
-
- return Escape.html(word);
- }
- });
- }
- });
-
-