index.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. 'use strict';
  2. var extend = require('extend-shallow');
  3. var regexCache = {};
  4. var all;
  5. var charSets = {
  6. default: {
  7. '"': '"',
  8. '"': '"',
  9. ''': '\'',
  10. ''': '\'',
  11. '&': '&',
  12. '&': '&',
  13. '>': '>',
  14. '>': '>',
  15. '&lt;': '<',
  16. '&#60;': '<'
  17. },
  18. extras: {
  19. '&cent;': '¢',
  20. '&#162;': '¢',
  21. '&copy;': '©',
  22. '&#169;': '©',
  23. '&euro;': '€',
  24. '&#8364;': '€',
  25. '&pound;': '£',
  26. '&#163;': '£',
  27. '&reg;': '®',
  28. '&#174;': '®',
  29. '&yen;': '¥',
  30. '&#165;': '¥'
  31. }
  32. };
  33. // don't merge char sets unless "all" is explicitly called
  34. Object.defineProperty(charSets, 'all', {
  35. get: function() {
  36. return all || (all = extend({}, charSets.default, charSets.extras));
  37. }
  38. });
  39. /**
  40. * Convert HTML entities to HTML characters.
  41. *
  42. * @param {String} `str` String with HTML entities to un-escape.
  43. * @return {String}
  44. */
  45. function unescape(str, type) {
  46. if (!isString(str)) return '';
  47. var chars = charSets[type || 'default'];
  48. var regex = toRegex(type, chars);
  49. return str.replace(regex, function(m) {
  50. return chars[m];
  51. });
  52. }
  53. function toRegex(type, chars) {
  54. if (regexCache[type]) {
  55. return regexCache[type];
  56. }
  57. var keys = Object.keys(chars).join('|');
  58. var regex = new RegExp('(?=(' + keys + '))\\1', 'g');
  59. regexCache[type] = regex;
  60. return regex;
  61. }
  62. /**
  63. * Returns true if str is a non-empty string
  64. */
  65. function isString(str) {
  66. return str && typeof str === 'string';
  67. }
  68. /**
  69. * Expose charSets
  70. */
  71. unescape.chars = charSets.default;
  72. unescape.extras = charSets.extras;
  73. // don't trip the "charSets" getter unless it's explicitly called
  74. Object.defineProperty(unescape, 'all', {
  75. get: function() {
  76. return charSets.all;
  77. }
  78. });
  79. /**
  80. * Expose `unescape`
  81. */
  82. module.exports = unescape;