UNPKG

1.81 kBJavaScriptView Raw
1var inverseXML = getInverseObj(require("../maps/xml.json")),
2 xmlReplacer = getInverseReplacer(inverseXML);
3
4exports.XML = getInverse(inverseXML, xmlReplacer);
5
6var inverseHTML = getInverseObj(require("../maps/entities.json")),
7 htmlReplacer = getInverseReplacer(inverseHTML);
8
9exports.HTML = getInverse(inverseHTML, htmlReplacer);
10
11function getInverseObj(obj){
12 return Object.keys(obj).sort().reduce(function(inverse, name){
13 inverse[obj[name]] = "&" + name + ";";
14 return inverse;
15 }, {});
16}
17
18function 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 //TODO add ranges
31 multiple.unshift("[" + single.join() + "]");
32
33 return new RegExp(multiple.join("|"), "g");
34}
35
36var re_nonASCII = /[^\0-\x7F]/g,
37 re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
38
39function singleCharReplacer(c){
40 return "&#x" + c.charCodeAt(0).toString(16).toUpperCase() + ";";
41}
42
43function astralReplacer(c){
44 // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
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
51function 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
64var re_xmlChars = getInverseReplacer(inverseXML);
65
66function escapeXML(data){
67 return data
68 .replace(re_xmlChars, singleCharReplacer)
69 .replace(re_astralSymbols, astralReplacer)
70 .replace(re_nonASCII, singleCharReplacer);
71}
72
73exports.escape = escapeXML;