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