entities 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +2 -4
- package/index.js +10 -17
- package/lib/decode.js +48 -50
- package/lib/decode_codepoint.js +15 -16
- package/lib/encode.js +51 -42
- package/package.json +8 -4
- package/readme.md +5 -5
- package/test/test.js +149 -147
package/.travis.yml
CHANGED
package/index.js
CHANGED
|
@@ -1,33 +1,26 @@
|
|
|
1
1
|
var encode = require("./lib/encode.js"),
|
|
2
2
|
decode = require("./lib/decode.js");
|
|
3
3
|
|
|
4
|
-
exports.decode = function(data, level){
|
|
5
|
-
|
|
4
|
+
exports.decode = function(data, level) {
|
|
5
|
+
return (!level || level <= 0 ? decode.XML : decode.HTML)(data);
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
exports.decodeStrict = function(data, level){
|
|
9
|
-
|
|
8
|
+
exports.decodeStrict = function(data, level) {
|
|
9
|
+
return (!level || level <= 0 ? decode.XML : decode.HTMLStrict)(data);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
exports.encode = function(data, level){
|
|
13
|
-
|
|
12
|
+
exports.encode = function(data, level) {
|
|
13
|
+
return (!level || level <= 0 ? encode.XML : encode.HTML)(data);
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
exports.encodeXML = encode.XML;
|
|
17
17
|
|
|
18
|
-
exports.encodeHTML4 =
|
|
19
|
-
exports.encodeHTML5 =
|
|
20
|
-
exports.encodeHTML = encode.HTML;
|
|
18
|
+
exports.encodeHTML4 = exports.encodeHTML5 = exports.encodeHTML = encode.HTML;
|
|
21
19
|
|
|
22
|
-
exports.decodeXML =
|
|
23
|
-
exports.decodeXMLStrict = decode.XML;
|
|
20
|
+
exports.decodeXML = exports.decodeXMLStrict = decode.XML;
|
|
24
21
|
|
|
25
|
-
exports.decodeHTML4 =
|
|
26
|
-
exports.decodeHTML5 =
|
|
27
|
-
exports.decodeHTML = decode.HTML;
|
|
22
|
+
exports.decodeHTML4 = exports.decodeHTML5 = exports.decodeHTML = decode.HTML;
|
|
28
23
|
|
|
29
|
-
exports.decodeHTML4Strict =
|
|
30
|
-
exports.decodeHTML5Strict =
|
|
31
|
-
exports.decodeHTMLStrict = decode.HTMLStrict;
|
|
24
|
+
exports.decodeHTML4Strict = exports.decodeHTML5Strict = exports.decodeHTMLStrict = decode.HTMLStrict;
|
|
32
25
|
|
|
33
26
|
exports.escape = encode.escape;
|
package/lib/decode.js
CHANGED
|
@@ -1,72 +1,70 @@
|
|
|
1
1
|
var entityMap = require("../maps/entities.json"),
|
|
2
2
|
legacyMap = require("../maps/legacy.json"),
|
|
3
|
-
xmlMap
|
|
3
|
+
xmlMap = require("../maps/xml.json"),
|
|
4
4
|
decodeCodePoint = require("./decode_codepoint.js");
|
|
5
5
|
|
|
6
|
-
var decodeXMLStrict
|
|
6
|
+
var decodeXMLStrict = getStrictDecoder(xmlMap),
|
|
7
7
|
decodeHTMLStrict = getStrictDecoder(entityMap);
|
|
8
8
|
|
|
9
|
-
function getStrictDecoder(map){
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
function getStrictDecoder(map) {
|
|
10
|
+
var keys = Object.keys(map).join("|"),
|
|
11
|
+
replace = getReplacer(map);
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
keys += "|#[xX][\\da-fA-F]+|#\\d+";
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
var re = new RegExp("&(?:" + keys + ");", "g");
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
return function(str) {
|
|
18
|
+
return String(str).replace(re, replace);
|
|
19
|
+
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
var decodeHTML = (function(){
|
|
23
|
-
|
|
24
|
-
.sort(sorter);
|
|
22
|
+
var decodeHTML = (function() {
|
|
23
|
+
var legacy = Object.keys(legacyMap).sort(sorter);
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
.sort(sorter);
|
|
25
|
+
var keys = Object.keys(entityMap).sort(sorter);
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
for (var i = 0, j = 0; i < keys.length; i++) {
|
|
28
|
+
if (legacy[j] === keys[i]) {
|
|
29
|
+
keys[i] += ";?";
|
|
30
|
+
j++;
|
|
31
|
+
} else {
|
|
32
|
+
keys[i] += ";";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"),
|
|
37
|
+
replace = getReplacer(entityMap);
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
function replacer(str) {
|
|
40
|
+
if (str.substr(-1) !== ";") str += ";";
|
|
41
|
+
return replace(str);
|
|
42
|
+
}
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}()
|
|
44
|
+
//TODO consider creating a merged map
|
|
45
|
+
return function(str) {
|
|
46
|
+
return String(str).replace(re, replacer);
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
51
49
|
|
|
52
|
-
function sorter(a, b){
|
|
53
|
-
|
|
50
|
+
function sorter(a, b) {
|
|
51
|
+
return a < b ? 1 : -1;
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
function getReplacer(map){
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
function getReplacer(map) {
|
|
55
|
+
return function replace(str) {
|
|
56
|
+
if (str.charAt(1) === "#") {
|
|
57
|
+
if (str.charAt(2) === "X" || str.charAt(2) === "x") {
|
|
58
|
+
return decodeCodePoint(parseInt(str.substr(3), 16));
|
|
59
|
+
}
|
|
60
|
+
return decodeCodePoint(parseInt(str.substr(2), 10));
|
|
61
|
+
}
|
|
62
|
+
return map[str.slice(1, -1)];
|
|
63
|
+
};
|
|
66
64
|
}
|
|
67
65
|
|
|
68
66
|
module.exports = {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
67
|
+
XML: decodeXMLStrict,
|
|
68
|
+
HTML: decodeHTML,
|
|
69
|
+
HTMLStrict: decodeHTMLStrict
|
|
70
|
+
};
|
package/lib/decode_codepoint.js
CHANGED
|
@@ -3,24 +3,23 @@ var decodeMap = require("../maps/decode.json");
|
|
|
3
3
|
module.exports = decodeCodePoint;
|
|
4
4
|
|
|
5
5
|
// modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
|
|
6
|
-
function decodeCodePoint(codePoint){
|
|
6
|
+
function decodeCodePoint(codePoint) {
|
|
7
|
+
if ((codePoint >= 0xd800 && codePoint <= 0xdfff) || codePoint > 0x10ffff) {
|
|
8
|
+
return "\uFFFD";
|
|
9
|
+
}
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
if (codePoint in decodeMap) {
|
|
12
|
+
codePoint = decodeMap[codePoint];
|
|
13
|
+
}
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
codePoint = decodeMap[codePoint];
|
|
14
|
-
}
|
|
15
|
+
var output = "";
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
if (codePoint > 0xffff) {
|
|
18
|
+
codePoint -= 0x10000;
|
|
19
|
+
output += String.fromCharCode(((codePoint >>> 10) & 0x3ff) | 0xd800);
|
|
20
|
+
codePoint = 0xdc00 | (codePoint & 0x3ff);
|
|
21
|
+
}
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
output += String.fromCharCode(codePoint >>> 10 & 0x3FF | 0xD800);
|
|
21
|
-
codePoint = 0xDC00 | codePoint & 0x3FF;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
output += String.fromCharCode(codePoint);
|
|
25
|
-
return output;
|
|
23
|
+
output += String.fromCharCode(codePoint);
|
|
24
|
+
return output;
|
|
26
25
|
}
|
package/lib/encode.js
CHANGED
|
@@ -8,66 +8,75 @@ var inverseHTML = getInverseObj(require("../maps/entities.json")),
|
|
|
8
8
|
|
|
9
9
|
exports.HTML = getInverse(inverseHTML, htmlReplacer);
|
|
10
10
|
|
|
11
|
-
function getInverseObj(obj){
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
function getInverseObj(obj) {
|
|
12
|
+
return Object.keys(obj)
|
|
13
|
+
.sort()
|
|
14
|
+
.reduce(function(inverse, name) {
|
|
15
|
+
inverse[obj[name]] = "&" + name + ";";
|
|
16
|
+
return inverse;
|
|
17
|
+
}, {});
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
function getInverseReplacer(inverse){
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
function getInverseReplacer(inverse) {
|
|
21
|
+
var single = [],
|
|
22
|
+
multiple = [];
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
Object.keys(inverse).forEach(function(k) {
|
|
25
|
+
if (k.length === 1) {
|
|
26
|
+
single.push("\\" + k);
|
|
27
|
+
} else {
|
|
28
|
+
multiple.push(k);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
//TODO add ranges
|
|
33
|
+
multiple.unshift("[" + single.join("") + "]");
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
return new RegExp(multiple.join("|"), "g");
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
var re_nonASCII = /[^\0-\x7F]/g,
|
|
37
39
|
re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
38
40
|
|
|
39
|
-
function singleCharReplacer(c){
|
|
40
|
-
|
|
41
|
+
function singleCharReplacer(c) {
|
|
42
|
+
return (
|
|
43
|
+
"&#x" +
|
|
44
|
+
c
|
|
45
|
+
.charCodeAt(0)
|
|
46
|
+
.toString(16)
|
|
47
|
+
.toUpperCase() +
|
|
48
|
+
";"
|
|
49
|
+
);
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
function astralReplacer(c){
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
function astralReplacer(c) {
|
|
53
|
+
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
|
54
|
+
var high = c.charCodeAt(0);
|
|
55
|
+
var low = c.charCodeAt(1);
|
|
56
|
+
var codePoint = (high - 0xd800) * 0x400 + low - 0xdc00 + 0x10000;
|
|
57
|
+
return "&#x" + codePoint.toString(16).toUpperCase() + ";";
|
|
49
58
|
}
|
|
50
59
|
|
|
51
|
-
function getInverse(inverse, re){
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
function getInverse(inverse, re) {
|
|
61
|
+
function func(name) {
|
|
62
|
+
return inverse[name];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return function(data) {
|
|
66
|
+
return data
|
|
67
|
+
.replace(re, func)
|
|
68
|
+
.replace(re_astralSymbols, astralReplacer)
|
|
69
|
+
.replace(re_nonASCII, singleCharReplacer);
|
|
70
|
+
};
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
var re_xmlChars = getInverseReplacer(inverseXML);
|
|
65
74
|
|
|
66
|
-
function escapeXML(data){
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
function escapeXML(data) {
|
|
76
|
+
return data
|
|
77
|
+
.replace(re_xmlChars, singleCharReplacer)
|
|
78
|
+
.replace(re_astralSymbols, astralReplacer)
|
|
79
|
+
.replace(re_nonASCII, singleCharReplacer);
|
|
71
80
|
}
|
|
72
81
|
|
|
73
82
|
exports.escape = escapeXML;
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "entities",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Encode & decode XML/HTML entities with ease",
|
|
5
5
|
"author": "Felix Boehm <me@feedic.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"html",
|
|
8
8
|
"xml",
|
|
9
9
|
"entity",
|
|
10
|
+
"decoding",
|
|
10
11
|
"encoding"
|
|
11
12
|
],
|
|
12
13
|
"main": "./index.js",
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
"test": "test"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
|
-
"mocha": "1",
|
|
18
|
+
"mocha": "^5.0.1",
|
|
18
19
|
"mocha-lcov-reporter": "*",
|
|
19
20
|
"coveralls": "*",
|
|
20
21
|
"istanbul": "*",
|
|
@@ -28,9 +29,9 @@
|
|
|
28
29
|
},
|
|
29
30
|
"repository": {
|
|
30
31
|
"type": "git",
|
|
31
|
-
"url": "git://github.com/fb55/
|
|
32
|
+
"url": "git://github.com/fb55/entities.git"
|
|
32
33
|
},
|
|
33
|
-
"license": "BSD-
|
|
34
|
+
"license": "BSD-2-Clause",
|
|
34
35
|
"jshintConfig": {
|
|
35
36
|
"eqeqeq": true,
|
|
36
37
|
"freeze": true,
|
|
@@ -49,5 +50,8 @@
|
|
|
49
50
|
"describe": true,
|
|
50
51
|
"it": true
|
|
51
52
|
}
|
|
53
|
+
},
|
|
54
|
+
"prettier": {
|
|
55
|
+
"tabWidth": 4
|
|
52
56
|
}
|
|
53
57
|
}
|
package/readme.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
#entities [](https://npmjs.org/package/entities) [](https://npmjs.org/package/entities) [](https://npmjs.org/package/entities) [](https://npmjs.org/package/entities) [](http://travis-ci.org/fb55/entities) [](https://coveralls.io/r/fb55/entities)
|
|
2
2
|
|
|
3
3
|
En- & decoder for XML/HTML entities.
|
|
4
4
|
|
|
5
|
-
##How to…
|
|
5
|
+
## How to…
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
### …install `entities`
|
|
8
8
|
|
|
9
9
|
npm i entities
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### …use `entities`
|
|
12
12
|
|
|
13
13
|
```javascript
|
|
14
14
|
var entities = require("entities");
|
|
@@ -24,4 +24,4 @@ entities.decodeHTML("asdf & ÿ ü '"); // "asdf & ÿ ü '"
|
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
License: BSD-
|
|
27
|
+
License: BSD-2-Clause
|
package/test/test.js
CHANGED
|
@@ -2,167 +2,169 @@ var assert = require("assert"),
|
|
|
2
2
|
path = require("path"),
|
|
3
3
|
entities = require("../");
|
|
4
4
|
|
|
5
|
-
describe("Encode->decode test", function(){
|
|
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
|
-
|
|
5
|
+
describe("Encode->decode test", function() {
|
|
6
|
+
var testcases = [
|
|
7
|
+
{
|
|
8
|
+
input: "asdf & ÿ ü '",
|
|
9
|
+
xml: "asdf & ÿ ü '",
|
|
10
|
+
html: "asdf & ÿ ü '"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
input: "&",
|
|
14
|
+
xml: "&#38;",
|
|
15
|
+
html: "&#38;"
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
testcases.forEach(function(tc) {
|
|
19
|
+
var encodedXML = entities.encodeXML(tc.input);
|
|
20
|
+
it("should XML encode " + tc.input, function() {
|
|
21
|
+
assert.equal(encodedXML, tc.xml);
|
|
22
|
+
});
|
|
23
|
+
it("should default to XML encode " + tc.input, function() {
|
|
24
|
+
assert.equal(entities.encode(tc.input), tc.xml);
|
|
25
|
+
});
|
|
26
|
+
it("should XML decode " + encodedXML, function() {
|
|
27
|
+
assert.equal(entities.decodeXML(encodedXML), tc.input);
|
|
28
|
+
});
|
|
29
|
+
it("should default to XML encode " + encodedXML, function() {
|
|
30
|
+
assert.equal(entities.decode(encodedXML), tc.input);
|
|
31
|
+
});
|
|
32
|
+
it("should default strict to XML encode " + encodedXML, function() {
|
|
33
|
+
assert.equal(entities.decodeStrict(encodedXML), tc.input);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
var encodedHTML5 = entities.encodeHTML5(tc.input);
|
|
37
|
+
it("should HTML5 encode " + tc.input, function() {
|
|
38
|
+
assert.equal(encodedHTML5, tc.html);
|
|
39
|
+
});
|
|
40
|
+
it("should HTML5 decode " + encodedHTML5, function() {
|
|
41
|
+
assert.equal(entities.decodeHTML(encodedHTML5), tc.input);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should encode data URIs (issue 16)", function() {
|
|
46
|
+
var data = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAALAAABAAEAAAIBRAA7";
|
|
47
|
+
assert.equal(entities.decode(entities.encode(data)), data);
|
|
48
|
+
});
|
|
48
49
|
});
|
|
49
50
|
|
|
50
|
-
describe("Decode test", function(){
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
51
|
+
describe("Decode test", function() {
|
|
52
|
+
var testcases = [
|
|
53
|
+
{ input: "&amp;", output: "&" },
|
|
54
|
+
{ input: "&#38;", output: "&" },
|
|
55
|
+
{ input: "&#x26;", output: "&" },
|
|
56
|
+
{ input: "&#X26;", output: "&" },
|
|
57
|
+
{ input: "&#38;", output: "&" },
|
|
58
|
+
{ input: "&#38;", output: "&" },
|
|
59
|
+
{ input: "&#38;", output: "&" },
|
|
60
|
+
{ input: ":", output: ":" },
|
|
61
|
+
{ input: ":", output: ":" },
|
|
62
|
+
{ input: ":", output: ":" },
|
|
63
|
+
{ input: ":", output: ":" }
|
|
64
|
+
];
|
|
65
|
+
testcases.forEach(function(tc) {
|
|
66
|
+
it("should XML decode " + tc.input, function() {
|
|
67
|
+
assert.equal(entities.decodeXML(tc.input), tc.output);
|
|
68
|
+
});
|
|
69
|
+
it("should HTML4 decode " + tc.input, function() {
|
|
70
|
+
assert.equal(entities.decodeHTML(tc.input), tc.output);
|
|
71
|
+
});
|
|
72
|
+
it("should HTML5 decode " + tc.input, function() {
|
|
73
|
+
assert.equal(entities.decodeHTML(tc.input), tc.output);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
75
76
|
});
|
|
76
77
|
|
|
77
78
|
var levels = ["xml", "entities"];
|
|
78
79
|
|
|
79
|
-
describe("Documents", function(){
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
80
|
+
describe("Documents", function() {
|
|
81
|
+
levels
|
|
82
|
+
.map(function(n) {
|
|
83
|
+
return path.join("..", "maps", n);
|
|
84
|
+
})
|
|
85
|
+
.map(require)
|
|
86
|
+
.forEach(function(doc, i) {
|
|
87
|
+
describe("Decode", function() {
|
|
88
|
+
it(levels[i], function() {
|
|
89
|
+
Object.keys(doc).forEach(function(e) {
|
|
90
|
+
for (var l = i; l < levels.length; l++) {
|
|
91
|
+
assert.equal(entities.decode("&" + e + ";", l), doc[e]);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe("Decode strict", function() {
|
|
98
|
+
it(levels[i], function() {
|
|
99
|
+
Object.keys(doc).forEach(function(e) {
|
|
100
|
+
for (var l = i; l < levels.length; l++) {
|
|
101
|
+
assert.equal(entities.decodeStrict("&" + e + ";", l), doc[e]);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe("Encode", function() {
|
|
108
|
+
it(levels[i], function() {
|
|
109
|
+
Object.keys(doc).forEach(function(e) {
|
|
110
|
+
for (var l = i; l < levels.length; l++) {
|
|
111
|
+
assert.equal(entities.decode(entities.encode(doc[e], l), l), doc[e]);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
var legacy = require("../maps/legacy.json");
|
|
119
|
+
|
|
120
|
+
describe("Legacy", function() {
|
|
121
|
+
it("should decode", runLegacy);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
function runLegacy() {
|
|
125
|
+
Object.keys(legacy).forEach(function(e) {
|
|
126
|
+
assert.equal(entities.decodeHTML("&" + e), legacy[e]);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
126
129
|
});
|
|
127
130
|
|
|
128
131
|
var astral = {
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
"1D306": "\uD834\uDF06",
|
|
133
|
+
"1D11E": "\uD834\uDD1E"
|
|
131
134
|
};
|
|
132
135
|
|
|
133
136
|
var astralSpecial = {
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
"80": "\u20AC",
|
|
138
|
+
"110000": "\uFFFD"
|
|
136
139
|
};
|
|
137
140
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
141
|
+
describe("Astral entities", function() {
|
|
142
|
+
Object.keys(astral).forEach(function(c) {
|
|
143
|
+
it("should decode " + astral[c], function() {
|
|
144
|
+
assert.equal(entities.decode("&#x" + c + ";"), astral[c]);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("should encode " + astral[c], function() {
|
|
148
|
+
assert.equal(entities.encode(astral[c]), "&#x" + c + ";");
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("should escape " + astral[c], function() {
|
|
152
|
+
assert.equal(entities.escape(astral[c]), "&#x" + c + ";");
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
Object.keys(astralSpecial).forEach(function(c) {
|
|
157
|
+
it("special should decode \\u" + c, function() {
|
|
158
|
+
assert.equal(entities.decode("&#x" + c + ";"), astralSpecial[c]);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
159
161
|
});
|
|
160
162
|
|
|
161
|
-
describe("Escape", function(){
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
describe("Escape", function() {
|
|
164
|
+
it("should always decode ASCII chars", function() {
|
|
165
|
+
for (var i = 0; i < 0x7f; i++) {
|
|
166
|
+
var c = String.fromCharCode(i);
|
|
167
|
+
assert.equal(entities.decodeXML(entities.escape(c)), c);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
168
170
|
});
|