encode.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. var inverseXML = getInverseObj(require("../maps/xml.json")),
  2. xmlReplacer = getInverseReplacer(inverseXML);
  3. exports.XML = getInverse(inverseXML, xmlReplacer);
  4. var inverseHTML = getInverseObj(require("../maps/entities.json")),
  5. htmlReplacer = getInverseReplacer(inverseHTML);
  6. exports.HTML = getInverse(inverseHTML, htmlReplacer);
  7. function getInverseObj(obj){
  8. return Object.keys(obj).sort().reduce(function(inverse, name){
  9. inverse[obj[name]] = "&" + name + ";";
  10. return inverse;
  11. }, {});
  12. }
  13. function getInverseReplacer(inverse){
  14. var single = [],
  15. multiple = [];
  16. Object.keys(inverse).forEach(function(k){
  17. if(k.length === 1){
  18. single.push("\\" + k);
  19. } else {
  20. multiple.push(k);
  21. }
  22. });
  23. //TODO add ranges
  24. multiple.unshift("[" + single.join("") + "]");
  25. return new RegExp(multiple.join("|"), "g");
  26. }
  27. var re_nonASCII = /[^\0-\x7F]/g,
  28. re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
  29. function singleCharReplacer(c){
  30. return "&#x" + c.charCodeAt(0).toString(16).toUpperCase() + ";";
  31. }
  32. function astralReplacer(c){
  33. // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
  34. var high = c.charCodeAt(0);
  35. var low = c.charCodeAt(1);
  36. var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
  37. return "&#x" + codePoint.toString(16).toUpperCase() + ";";
  38. }
  39. function getInverse(inverse, re){
  40. function func(name){
  41. return inverse[name];
  42. }
  43. return function(data){
  44. return data
  45. .replace(re, func)
  46. .replace(re_astralSymbols, astralReplacer)
  47. .replace(re_nonASCII, singleCharReplacer);
  48. };
  49. }
  50. var re_xmlChars = getInverseReplacer(inverseXML);
  51. function escapeXML(data){
  52. return data
  53. .replace(re_xmlChars, singleCharReplacer)
  54. .replace(re_astralSymbols, astralReplacer)
  55. .replace(re_nonASCII, singleCharReplacer);
  56. }
  57. exports.escape = escapeXML;