API Docs for: 3.18.1
Show:

File: highlight/js/highlight-accentfold.js

  1. /**
  2. Adds accent-folding highlighters to `Y.Highlight`.
  3.  
  4. @module highlight
  5. @submodule highlight-accentfold
  6. **/
  7.  
  8. /**
  9. @class Highlight
  10. @static
  11. **/
  12.  
  13. var AccentFold = Y.Text.AccentFold,
  14. Escape = Y.Escape,
  15.  
  16. EMPTY_OBJECT = {},
  17.  
  18. Highlight = Y.mix(Y.Highlight, {
  19. // -- Public Static Methods ------------------------------------------------
  20.  
  21. /**
  22. Accent-folding version of `all()`.
  23.  
  24. @method allFold
  25. @param {String} haystack String to apply highlighting to.
  26. @param {String|String[]} needles String or array of strings that should be
  27. highlighted.
  28. @param {Object} [options] Options object.
  29. @param {Boolean} [options.startsWith=false] If `true`, matches must be
  30. anchored to the beginning of the string.
  31. @return {String} Escaped and highlighted copy of _haystack_.
  32. @static
  33. **/
  34. allFold: function (haystack, needles, options) {
  35. var template = Highlight._TEMPLATE,
  36. results = [],
  37. startPos = 0,
  38. chunk, i, len, match, result;
  39.  
  40. options = Y.merge({
  41. // This tells Highlight.all() not to escape HTML, in order to ensure
  42. // usable match offsets. The output of all() is discarded, and we
  43. // perform our own escaping before returning the highlighted string.
  44. escapeHTML: false,
  45.  
  46. // While the highlight regex operates on the accent-folded strings,
  47. // this replacer will highlight the matched positions in the
  48. // original string.
  49. //
  50. // Note: this implementation doesn't handle multi-character folds,
  51. // like "æ" -> "ae". Doing so correctly would be prohibitively
  52. // expensive both in terms of code size and runtime performance, so
  53. // I've chosen to take the pragmatic route and just not do it at
  54. // all. This is one of many reasons why accent folding is best done
  55. // on the server.
  56. replacer: function (match, p1, foldedNeedle, pos) {
  57. var len;
  58.  
  59. // Ignore matches inside HTML entities.
  60. if (p1 && !(/\s/).test(foldedNeedle)) {
  61. return match;
  62. }
  63.  
  64. len = foldedNeedle.length;
  65.  
  66. results.push([
  67. haystack.substring(startPos, pos), // substring between previous match and this match
  68. haystack.substr(pos, len) // match to be highlighted
  69. ]);
  70.  
  71. startPos = pos + len;
  72. }
  73. }, options || EMPTY_OBJECT);
  74.  
  75. // Run the highlighter on the folded strings. We don't care about the
  76. // output; our replacer function will build the canonical highlighted
  77. // string, with original accented characters.
  78. Highlight.all(AccentFold.fold(haystack), AccentFold.fold(needles), options);
  79.  
  80. // Tack on the remainder of the haystack that wasn't highlighted, if
  81. // any.
  82. if (startPos < haystack.length) {
  83. results.push([haystack.substr(startPos)]);
  84. }
  85.  
  86. // Highlight and escape the string.
  87. for (i = 0, len = results.length; i < len; ++i) {
  88. chunk = Escape.html(results[i][0]);
  89.  
  90. if ((match = results[i][1])) {
  91. chunk += template.replace(/\{s\}/g, Escape.html(match));
  92. }
  93.  
  94. results[i] = chunk;
  95. }
  96.  
  97. return results.join('');
  98. },
  99.  
  100. /**
  101. Accent-folding version of `start()`.
  102.  
  103. @method startFold
  104. @param {String} haystack String to apply highlighting to.
  105. @param {String|String[]} needles String or array of strings that should be
  106. highlighted.
  107. @return {String} Escaped and highlighted copy of _haystack_.
  108. @static
  109. **/
  110. startFold: function (haystack, needles) {
  111. return Highlight.allFold(haystack, needles, {startsWith: true});
  112. },
  113.  
  114. /**
  115. Accent-folding version of `words()`.
  116.  
  117. @method wordsFold
  118. @param {String} haystack String to apply highlighting to.
  119. @param {String|String[]} needles String or array of strings containing words
  120. that should be highlighted. If a string is passed, it will be split
  121. into words; if an array is passed, it is assumed to have already been
  122. split.
  123. @return {String} Escaped and highlighted copy of _haystack_.
  124. @static
  125. **/
  126. wordsFold: function (haystack, needles) {
  127. var template = Highlight._TEMPLATE;
  128.  
  129. return Highlight.words(haystack, AccentFold.fold(needles), {
  130. mapper: function (word, needles) {
  131. if (needles.hasOwnProperty(AccentFold.fold(word))) {
  132. return template.replace(/\{s\}/g, Escape.html(word));
  133. }
  134.  
  135. return Escape.html(word);
  136. }
  137. });
  138. }
  139. });
  140.