Blame view

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