parse5 1.5.0 → 1.5.1
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/CHANGELOG.md +69 -66
- package/docs/build/index.md +963 -0
- package/lib/common/doctype.js +134 -134
- package/lib/serialization/serializer.js +178 -179
- package/lib/simple_api/simple_api_parser.js +107 -107
- package/lib/simple_api/tokenizer_proxy.js +122 -122
- package/lib/tokenization/named_entity_trie.js +1 -54
- package/lib/tokenization/preprocessor.js +115 -115
- package/lib/tree_adapters/htmlparser2.js +317 -317
- package/lib/tree_construction/location_info_mixin.js +197 -197
- package/lib/tree_construction/parser.js +2827 -2827
- package/package.json +47 -47
package/lib/common/doctype.js
CHANGED
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
//Const
|
|
4
|
-
var VALID_DOCTYPE_NAME = 'html',
|
|
5
|
-
QUIRKS_MODE_SYSTEM_ID = 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd',
|
|
6
|
-
QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
|
|
7
|
-
"+//silmaril//dtd html pro v0r11 19970101//en",
|
|
8
|
-
"-//advasoft ltd//dtd html 3.0 aswedit + extensions//en",
|
|
9
|
-
"-//as//dtd html 3.0 aswedit + extensions//en",
|
|
10
|
-
"-//ietf//dtd html 2.0 level 1//en",
|
|
11
|
-
"-//ietf//dtd html 2.0 level 2//en",
|
|
12
|
-
"-//ietf//dtd html 2.0 strict level 1//en",
|
|
13
|
-
"-//ietf//dtd html 2.0 strict level 2//en",
|
|
14
|
-
"-//ietf//dtd html 2.0 strict//en",
|
|
15
|
-
"-//ietf//dtd html 2.0//en",
|
|
16
|
-
"-//ietf//dtd html 2.1e//en",
|
|
17
|
-
"-//ietf//dtd html 3.0//en",
|
|
18
|
-
"-//ietf//dtd html 3.0//en//",
|
|
19
|
-
"-//ietf//dtd html 3.2 final//en",
|
|
20
|
-
"-//ietf//dtd html 3.2//en",
|
|
21
|
-
"-//ietf//dtd html 3//en",
|
|
22
|
-
"-//ietf//dtd html level 0//en",
|
|
23
|
-
"-//ietf//dtd html level 0//en//2.0",
|
|
24
|
-
"-//ietf//dtd html level 1//en",
|
|
25
|
-
"-//ietf//dtd html level 1//en//2.0",
|
|
26
|
-
"-//ietf//dtd html level 2//en",
|
|
27
|
-
"-//ietf//dtd html level 2//en//2.0",
|
|
28
|
-
"-//ietf//dtd html level 3//en",
|
|
29
|
-
"-//ietf//dtd html level 3//en//3.0",
|
|
30
|
-
"-//ietf//dtd html strict level 0//en",
|
|
31
|
-
"-//ietf//dtd html strict level 0//en//2.0",
|
|
32
|
-
"-//ietf//dtd html strict level 1//en",
|
|
33
|
-
"-//ietf//dtd html strict level 1//en//2.0",
|
|
34
|
-
"-//ietf//dtd html strict level 2//en",
|
|
35
|
-
"-//ietf//dtd html strict level 2//en//2.0",
|
|
36
|
-
"-//ietf//dtd html strict level 3//en",
|
|
37
|
-
"-//ietf//dtd html strict level 3//en//3.0",
|
|
38
|
-
"-//ietf//dtd html strict//en",
|
|
39
|
-
"-//ietf//dtd html strict//en//2.0",
|
|
40
|
-
"-//ietf//dtd html strict//en//3.0",
|
|
41
|
-
"-//ietf//dtd html//en",
|
|
42
|
-
"-//ietf//dtd html//en//2.0",
|
|
43
|
-
"-//ietf//dtd html//en//3.0",
|
|
44
|
-
"-//metrius//dtd metrius presentational//en",
|
|
45
|
-
"-//microsoft//dtd internet explorer 2.0 html strict//en",
|
|
46
|
-
"-//microsoft//dtd internet explorer 2.0 html//en",
|
|
47
|
-
"-//microsoft//dtd internet explorer 2.0 tables//en",
|
|
48
|
-
"-//microsoft//dtd internet explorer 3.0 html strict//en",
|
|
49
|
-
"-//microsoft//dtd internet explorer 3.0 html//en",
|
|
50
|
-
"-//microsoft//dtd internet explorer 3.0 tables//en",
|
|
51
|
-
"-//netscape comm. corp.//dtd html//en",
|
|
52
|
-
"-//netscape comm. corp.//dtd strict html//en",
|
|
53
|
-
"-//o'reilly and associates//dtd html 2.0//en",
|
|
54
|
-
"-//o'reilly and associates//dtd html extended 1.0//en",
|
|
55
|
-
"-//spyglass//dtd html 2.0 extended//en",
|
|
56
|
-
"-//sq//dtd html 2.0 hotmetal + extensions//en",
|
|
57
|
-
"-//sun microsystems corp.//dtd hotjava html//en",
|
|
58
|
-
"-//sun microsystems corp.//dtd hotjava strict html//en",
|
|
59
|
-
"-//w3c//dtd html 3 1995-03-24//en",
|
|
60
|
-
"-//w3c//dtd html 3.2 draft//en",
|
|
61
|
-
"-//w3c//dtd html 3.2 final//en",
|
|
62
|
-
"-//w3c//dtd html 3.2//en",
|
|
63
|
-
"-//w3c//dtd html 3.2s draft//en",
|
|
64
|
-
"-//w3c//dtd html 4.0 frameset//en",
|
|
65
|
-
"-//w3c//dtd html 4.0 transitional//en",
|
|
66
|
-
"-//w3c//dtd html experimental 19960712//en",
|
|
67
|
-
"-//w3c//dtd html experimental 970421//en",
|
|
68
|
-
"-//w3c//dtd w3 html//en",
|
|
69
|
-
"-//w3o//dtd w3 html 3.0//en",
|
|
70
|
-
"-//w3o//dtd w3 html 3.0//en//",
|
|
71
|
-
"-//webtechs//dtd mozilla html 2.0//en",
|
|
72
|
-
"-//webtechs//dtd mozilla html//en"
|
|
73
|
-
],
|
|
74
|
-
QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
|
|
75
|
-
'-//w3c//dtd html 4.01 frameset//',
|
|
76
|
-
'-//w3c//dtd html 4.01 transitional//'
|
|
77
|
-
],
|
|
78
|
-
QUIRKS_MODE_PUBLIC_IDS = [
|
|
79
|
-
'-//w3o//dtd w3 html strict 3.0//en//',
|
|
80
|
-
'-/w3c/dtd html 4.0 transitional/en',
|
|
81
|
-
'html'
|
|
82
|
-
];
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
//Utils
|
|
86
|
-
function enquoteDoctypeId(id) {
|
|
87
|
-
var quote = id.indexOf('"') !== -1 ? '\'' : '"';
|
|
88
|
-
|
|
89
|
-
return quote + id + quote;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
//API
|
|
94
|
-
exports.isQuirks = function (name, publicId, systemId) {
|
|
95
|
-
if (name !== VALID_DOCTYPE_NAME)
|
|
96
|
-
return true;
|
|
97
|
-
|
|
98
|
-
if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID)
|
|
99
|
-
return true;
|
|
100
|
-
|
|
101
|
-
if (publicId !== null) {
|
|
102
|
-
publicId = publicId.toLowerCase();
|
|
103
|
-
|
|
104
|
-
if (QUIRKS_MODE_PUBLIC_IDS.indexOf(publicId) > -1)
|
|
105
|
-
return true;
|
|
106
|
-
|
|
107
|
-
var prefixes = QUIRKS_MODE_PUBLIC_ID_PREFIXES;
|
|
108
|
-
|
|
109
|
-
if (systemId === null)
|
|
110
|
-
prefixes = prefixes.concat(QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES);
|
|
111
|
-
|
|
112
|
-
for (var i = 0; i < prefixes.length; i++) {
|
|
113
|
-
if (publicId.indexOf(prefixes[i]) === 0)
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return false;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
exports.serializeContent = function (name, publicId, systemId) {
|
|
122
|
-
var str = '!DOCTYPE ' + name;
|
|
123
|
-
|
|
124
|
-
if (publicId !== null)
|
|
125
|
-
str += ' PUBLIC ' + enquoteDoctypeId(publicId);
|
|
126
|
-
|
|
127
|
-
else if (systemId !== null)
|
|
128
|
-
str += ' SYSTEM';
|
|
129
|
-
|
|
130
|
-
if (systemId !== null)
|
|
131
|
-
str += ' ' + enquoteDoctypeId(systemId);
|
|
132
|
-
|
|
133
|
-
return str;
|
|
134
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
//Const
|
|
4
|
+
var VALID_DOCTYPE_NAME = 'html',
|
|
5
|
+
QUIRKS_MODE_SYSTEM_ID = 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd',
|
|
6
|
+
QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
|
|
7
|
+
"+//silmaril//dtd html pro v0r11 19970101//en",
|
|
8
|
+
"-//advasoft ltd//dtd html 3.0 aswedit + extensions//en",
|
|
9
|
+
"-//as//dtd html 3.0 aswedit + extensions//en",
|
|
10
|
+
"-//ietf//dtd html 2.0 level 1//en",
|
|
11
|
+
"-//ietf//dtd html 2.0 level 2//en",
|
|
12
|
+
"-//ietf//dtd html 2.0 strict level 1//en",
|
|
13
|
+
"-//ietf//dtd html 2.0 strict level 2//en",
|
|
14
|
+
"-//ietf//dtd html 2.0 strict//en",
|
|
15
|
+
"-//ietf//dtd html 2.0//en",
|
|
16
|
+
"-//ietf//dtd html 2.1e//en",
|
|
17
|
+
"-//ietf//dtd html 3.0//en",
|
|
18
|
+
"-//ietf//dtd html 3.0//en//",
|
|
19
|
+
"-//ietf//dtd html 3.2 final//en",
|
|
20
|
+
"-//ietf//dtd html 3.2//en",
|
|
21
|
+
"-//ietf//dtd html 3//en",
|
|
22
|
+
"-//ietf//dtd html level 0//en",
|
|
23
|
+
"-//ietf//dtd html level 0//en//2.0",
|
|
24
|
+
"-//ietf//dtd html level 1//en",
|
|
25
|
+
"-//ietf//dtd html level 1//en//2.0",
|
|
26
|
+
"-//ietf//dtd html level 2//en",
|
|
27
|
+
"-//ietf//dtd html level 2//en//2.0",
|
|
28
|
+
"-//ietf//dtd html level 3//en",
|
|
29
|
+
"-//ietf//dtd html level 3//en//3.0",
|
|
30
|
+
"-//ietf//dtd html strict level 0//en",
|
|
31
|
+
"-//ietf//dtd html strict level 0//en//2.0",
|
|
32
|
+
"-//ietf//dtd html strict level 1//en",
|
|
33
|
+
"-//ietf//dtd html strict level 1//en//2.0",
|
|
34
|
+
"-//ietf//dtd html strict level 2//en",
|
|
35
|
+
"-//ietf//dtd html strict level 2//en//2.0",
|
|
36
|
+
"-//ietf//dtd html strict level 3//en",
|
|
37
|
+
"-//ietf//dtd html strict level 3//en//3.0",
|
|
38
|
+
"-//ietf//dtd html strict//en",
|
|
39
|
+
"-//ietf//dtd html strict//en//2.0",
|
|
40
|
+
"-//ietf//dtd html strict//en//3.0",
|
|
41
|
+
"-//ietf//dtd html//en",
|
|
42
|
+
"-//ietf//dtd html//en//2.0",
|
|
43
|
+
"-//ietf//dtd html//en//3.0",
|
|
44
|
+
"-//metrius//dtd metrius presentational//en",
|
|
45
|
+
"-//microsoft//dtd internet explorer 2.0 html strict//en",
|
|
46
|
+
"-//microsoft//dtd internet explorer 2.0 html//en",
|
|
47
|
+
"-//microsoft//dtd internet explorer 2.0 tables//en",
|
|
48
|
+
"-//microsoft//dtd internet explorer 3.0 html strict//en",
|
|
49
|
+
"-//microsoft//dtd internet explorer 3.0 html//en",
|
|
50
|
+
"-//microsoft//dtd internet explorer 3.0 tables//en",
|
|
51
|
+
"-//netscape comm. corp.//dtd html//en",
|
|
52
|
+
"-//netscape comm. corp.//dtd strict html//en",
|
|
53
|
+
"-//o'reilly and associates//dtd html 2.0//en",
|
|
54
|
+
"-//o'reilly and associates//dtd html extended 1.0//en",
|
|
55
|
+
"-//spyglass//dtd html 2.0 extended//en",
|
|
56
|
+
"-//sq//dtd html 2.0 hotmetal + extensions//en",
|
|
57
|
+
"-//sun microsystems corp.//dtd hotjava html//en",
|
|
58
|
+
"-//sun microsystems corp.//dtd hotjava strict html//en",
|
|
59
|
+
"-//w3c//dtd html 3 1995-03-24//en",
|
|
60
|
+
"-//w3c//dtd html 3.2 draft//en",
|
|
61
|
+
"-//w3c//dtd html 3.2 final//en",
|
|
62
|
+
"-//w3c//dtd html 3.2//en",
|
|
63
|
+
"-//w3c//dtd html 3.2s draft//en",
|
|
64
|
+
"-//w3c//dtd html 4.0 frameset//en",
|
|
65
|
+
"-//w3c//dtd html 4.0 transitional//en",
|
|
66
|
+
"-//w3c//dtd html experimental 19960712//en",
|
|
67
|
+
"-//w3c//dtd html experimental 970421//en",
|
|
68
|
+
"-//w3c//dtd w3 html//en",
|
|
69
|
+
"-//w3o//dtd w3 html 3.0//en",
|
|
70
|
+
"-//w3o//dtd w3 html 3.0//en//",
|
|
71
|
+
"-//webtechs//dtd mozilla html 2.0//en",
|
|
72
|
+
"-//webtechs//dtd mozilla html//en"
|
|
73
|
+
],
|
|
74
|
+
QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
|
|
75
|
+
'-//w3c//dtd html 4.01 frameset//',
|
|
76
|
+
'-//w3c//dtd html 4.01 transitional//'
|
|
77
|
+
],
|
|
78
|
+
QUIRKS_MODE_PUBLIC_IDS = [
|
|
79
|
+
'-//w3o//dtd w3 html strict 3.0//en//',
|
|
80
|
+
'-/w3c/dtd html 4.0 transitional/en',
|
|
81
|
+
'html'
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
//Utils
|
|
86
|
+
function enquoteDoctypeId(id) {
|
|
87
|
+
var quote = id.indexOf('"') !== -1 ? '\'' : '"';
|
|
88
|
+
|
|
89
|
+
return quote + id + quote;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
//API
|
|
94
|
+
exports.isQuirks = function (name, publicId, systemId) {
|
|
95
|
+
if (name !== VALID_DOCTYPE_NAME)
|
|
96
|
+
return true;
|
|
97
|
+
|
|
98
|
+
if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID)
|
|
99
|
+
return true;
|
|
100
|
+
|
|
101
|
+
if (publicId !== null) {
|
|
102
|
+
publicId = publicId.toLowerCase();
|
|
103
|
+
|
|
104
|
+
if (QUIRKS_MODE_PUBLIC_IDS.indexOf(publicId) > -1)
|
|
105
|
+
return true;
|
|
106
|
+
|
|
107
|
+
var prefixes = QUIRKS_MODE_PUBLIC_ID_PREFIXES;
|
|
108
|
+
|
|
109
|
+
if (systemId === null)
|
|
110
|
+
prefixes = prefixes.concat(QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES);
|
|
111
|
+
|
|
112
|
+
for (var i = 0; i < prefixes.length; i++) {
|
|
113
|
+
if (publicId.indexOf(prefixes[i]) === 0)
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return false;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
exports.serializeContent = function (name, publicId, systemId) {
|
|
122
|
+
var str = '!DOCTYPE ' + name;
|
|
123
|
+
|
|
124
|
+
if (publicId !== null)
|
|
125
|
+
str += ' PUBLIC ' + enquoteDoctypeId(publicId);
|
|
126
|
+
|
|
127
|
+
else if (systemId !== null)
|
|
128
|
+
str += ' SYSTEM';
|
|
129
|
+
|
|
130
|
+
if (systemId !== null)
|
|
131
|
+
str += ' ' + enquoteDoctypeId(systemId);
|
|
132
|
+
|
|
133
|
+
return str;
|
|
134
|
+
};
|
|
@@ -1,179 +1,178 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var DefaultTreeAdapter = require('../tree_adapters/default'),
|
|
4
|
-
Doctype = require('../common/doctype'),
|
|
5
|
-
Utils = require('../common/utils'),
|
|
6
|
-
HTML = require('../common/html');
|
|
7
|
-
|
|
8
|
-
//Aliases
|
|
9
|
-
var $ = HTML.TAG_NAMES,
|
|
10
|
-
NS = HTML.NAMESPACES;
|
|
11
|
-
|
|
12
|
-
//Default serializer options
|
|
13
|
-
var DEFAULT_OPTIONS = {
|
|
14
|
-
encodeHtmlEntities: true
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
//Escaping regexes
|
|
18
|
-
var AMP_REGEX = /&/g,
|
|
19
|
-
NBSP_REGEX = /\u00a0/g,
|
|
20
|
-
DOUBLE_QUOTE_REGEX = /"/g,
|
|
21
|
-
LT_REGEX = /</g,
|
|
22
|
-
GT_REGEX = />/g;
|
|
23
|
-
|
|
24
|
-
//Escape string
|
|
25
|
-
function escapeString(str, attrMode) {
|
|
26
|
-
str = str
|
|
27
|
-
.replace(AMP_REGEX, '&')
|
|
28
|
-
.replace(NBSP_REGEX, ' ');
|
|
29
|
-
|
|
30
|
-
if (attrMode)
|
|
31
|
-
str = str.replace(DOUBLE_QUOTE_REGEX, '"');
|
|
32
|
-
|
|
33
|
-
else {
|
|
34
|
-
str = str
|
|
35
|
-
.replace(LT_REGEX, '<')
|
|
36
|
-
.replace(GT_REGEX, '>');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return str;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
//Enquote doctype ID
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
//Serializer
|
|
48
|
-
var Serializer = module.exports = function (treeAdapter, options) {
|
|
49
|
-
this.treeAdapter = treeAdapter || DefaultTreeAdapter;
|
|
50
|
-
this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//API
|
|
55
|
-
Serializer.prototype.serialize = function (node) {
|
|
56
|
-
this.html = '';
|
|
57
|
-
this._serializeChildNodes(node);
|
|
58
|
-
|
|
59
|
-
return this.html;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//Internals
|
|
64
|
-
Serializer.prototype._serializeChildNodes = function (parentNode) {
|
|
65
|
-
var childNodes = this.treeAdapter.getChildNodes(parentNode);
|
|
66
|
-
|
|
67
|
-
if (childNodes) {
|
|
68
|
-
for (var i = 0, cnLength = childNodes.length; i < cnLength; i++) {
|
|
69
|
-
var currentNode = childNodes[i];
|
|
70
|
-
|
|
71
|
-
if (this.treeAdapter.isElementNode(currentNode))
|
|
72
|
-
this._serializeElement(currentNode);
|
|
73
|
-
|
|
74
|
-
else if (this.treeAdapter.isTextNode(currentNode))
|
|
75
|
-
this._serializeTextNode(currentNode);
|
|
76
|
-
|
|
77
|
-
else if (this.treeAdapter.isCommentNode(currentNode))
|
|
78
|
-
this._serializeCommentNode(currentNode);
|
|
79
|
-
|
|
80
|
-
else if (this.treeAdapter.isDocumentTypeNode(currentNode))
|
|
81
|
-
this._serializeDocumentTypeNode(currentNode);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
Serializer.prototype._serializeElement = function (node) {
|
|
87
|
-
var tn = this.treeAdapter.getTagName(node),
|
|
88
|
-
ns = this.treeAdapter.getNamespaceURI(node)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
tn !== $.
|
|
97
|
-
tn !== $.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var DefaultTreeAdapter = require('../tree_adapters/default'),
|
|
4
|
+
Doctype = require('../common/doctype'),
|
|
5
|
+
Utils = require('../common/utils'),
|
|
6
|
+
HTML = require('../common/html');
|
|
7
|
+
|
|
8
|
+
//Aliases
|
|
9
|
+
var $ = HTML.TAG_NAMES,
|
|
10
|
+
NS = HTML.NAMESPACES;
|
|
11
|
+
|
|
12
|
+
//Default serializer options
|
|
13
|
+
var DEFAULT_OPTIONS = {
|
|
14
|
+
encodeHtmlEntities: true
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//Escaping regexes
|
|
18
|
+
var AMP_REGEX = /&/g,
|
|
19
|
+
NBSP_REGEX = /\u00a0/g,
|
|
20
|
+
DOUBLE_QUOTE_REGEX = /"/g,
|
|
21
|
+
LT_REGEX = /</g,
|
|
22
|
+
GT_REGEX = />/g;
|
|
23
|
+
|
|
24
|
+
//Escape string
|
|
25
|
+
function escapeString(str, attrMode) {
|
|
26
|
+
str = str
|
|
27
|
+
.replace(AMP_REGEX, '&')
|
|
28
|
+
.replace(NBSP_REGEX, ' ');
|
|
29
|
+
|
|
30
|
+
if (attrMode)
|
|
31
|
+
str = str.replace(DOUBLE_QUOTE_REGEX, '"');
|
|
32
|
+
|
|
33
|
+
else {
|
|
34
|
+
str = str
|
|
35
|
+
.replace(LT_REGEX, '<')
|
|
36
|
+
.replace(GT_REGEX, '>');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return str;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
//Enquote doctype ID
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
//Serializer
|
|
48
|
+
var Serializer = module.exports = function (treeAdapter, options) {
|
|
49
|
+
this.treeAdapter = treeAdapter || DefaultTreeAdapter;
|
|
50
|
+
this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
//API
|
|
55
|
+
Serializer.prototype.serialize = function (node) {
|
|
56
|
+
this.html = '';
|
|
57
|
+
this._serializeChildNodes(node);
|
|
58
|
+
|
|
59
|
+
return this.html;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
//Internals
|
|
64
|
+
Serializer.prototype._serializeChildNodes = function (parentNode) {
|
|
65
|
+
var childNodes = this.treeAdapter.getChildNodes(parentNode);
|
|
66
|
+
|
|
67
|
+
if (childNodes) {
|
|
68
|
+
for (var i = 0, cnLength = childNodes.length; i < cnLength; i++) {
|
|
69
|
+
var currentNode = childNodes[i];
|
|
70
|
+
|
|
71
|
+
if (this.treeAdapter.isElementNode(currentNode))
|
|
72
|
+
this._serializeElement(currentNode);
|
|
73
|
+
|
|
74
|
+
else if (this.treeAdapter.isTextNode(currentNode))
|
|
75
|
+
this._serializeTextNode(currentNode);
|
|
76
|
+
|
|
77
|
+
else if (this.treeAdapter.isCommentNode(currentNode))
|
|
78
|
+
this._serializeCommentNode(currentNode);
|
|
79
|
+
|
|
80
|
+
else if (this.treeAdapter.isDocumentTypeNode(currentNode))
|
|
81
|
+
this._serializeDocumentTypeNode(currentNode);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
Serializer.prototype._serializeElement = function (node) {
|
|
87
|
+
var tn = this.treeAdapter.getTagName(node),
|
|
88
|
+
ns = this.treeAdapter.getNamespaceURI(node);
|
|
89
|
+
|
|
90
|
+
this.html += '<' + tn;
|
|
91
|
+
this._serializeAttributes(node);
|
|
92
|
+
this.html += '>';
|
|
93
|
+
|
|
94
|
+
if (tn !== $.AREA && tn !== $.BASE && tn !== $.BASEFONT && tn !== $.BGSOUND && tn !== $.BR && tn !== $.BR &&
|
|
95
|
+
tn !== $.COL && tn !== $.EMBED && tn !== $.FRAME && tn !== $.HR && tn !== $.IMG && tn !== $.INPUT &&
|
|
96
|
+
tn !== $.KEYGEN && tn !== $.LINK && tn !== $.MENUITEM && tn !== $.META && tn !== $.PARAM && tn !== $.SOURCE &&
|
|
97
|
+
tn !== $.TRACK && tn !== $.WBR) {
|
|
98
|
+
|
|
99
|
+
if (tn === $.PRE || tn === $.TEXTAREA || tn === $.LISTING) {
|
|
100
|
+
var firstChild = this.treeAdapter.getFirstChild(node);
|
|
101
|
+
|
|
102
|
+
if (firstChild && this.treeAdapter.isTextNode(firstChild)) {
|
|
103
|
+
var content = this.treeAdapter.getTextNodeContent(firstChild);
|
|
104
|
+
|
|
105
|
+
if (content[0] === '\n')
|
|
106
|
+
this.html += '\n';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
var childNodesHolder = tn === $.TEMPLATE && ns === NS.HTML ?
|
|
111
|
+
this.treeAdapter.getChildNodes(node)[0] :
|
|
112
|
+
node;
|
|
113
|
+
|
|
114
|
+
this._serializeChildNodes(childNodesHolder);
|
|
115
|
+
this.html += '</' + tn + '>';
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
Serializer.prototype._serializeAttributes = function (node) {
|
|
120
|
+
var attrs = this.treeAdapter.getAttrList(node);
|
|
121
|
+
|
|
122
|
+
for (var i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
|
|
123
|
+
var attr = attrs[i],
|
|
124
|
+
value = this.options.encodeHtmlEntities ? escapeString(attr.value, true) : attr.value;
|
|
125
|
+
|
|
126
|
+
this.html += ' ';
|
|
127
|
+
|
|
128
|
+
if (!attr.namespace)
|
|
129
|
+
this.html += attr.name;
|
|
130
|
+
|
|
131
|
+
else if (attr.namespace === NS.XML)
|
|
132
|
+
this.html += 'xml:' + attr.name;
|
|
133
|
+
|
|
134
|
+
else if (attr.namespace === NS.XMLNS) {
|
|
135
|
+
if (attr.name !== 'xmlns')
|
|
136
|
+
this.html += 'xmlns:';
|
|
137
|
+
|
|
138
|
+
this.html += attr.name;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
else if (attr.namespace === NS.XLINK)
|
|
142
|
+
this.html += 'xlink:' + attr.name;
|
|
143
|
+
|
|
144
|
+
else
|
|
145
|
+
this.html += attr.namespace + ':' + attr.name;
|
|
146
|
+
|
|
147
|
+
this.html += '="' + value + '"';
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
Serializer.prototype._serializeTextNode = function (node) {
|
|
152
|
+
var content = this.treeAdapter.getTextNodeContent(node),
|
|
153
|
+
parent = this.treeAdapter.getParentNode(node),
|
|
154
|
+
parentTn = void 0;
|
|
155
|
+
|
|
156
|
+
if (parent && this.treeAdapter.isElementNode(parent))
|
|
157
|
+
parentTn = this.treeAdapter.getTagName(parent);
|
|
158
|
+
|
|
159
|
+
if (parentTn === $.STYLE || parentTn === $.SCRIPT || parentTn === $.XMP || parentTn === $.IFRAME ||
|
|
160
|
+
parentTn === $.NOEMBED || parentTn === $.NOFRAMES || parentTn === $.PLAINTEXT || parentTn === $.NOSCRIPT) {
|
|
161
|
+
this.html += content;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
else
|
|
165
|
+
this.html += this.options.encodeHtmlEntities ? escapeString(content, false) : content;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
Serializer.prototype._serializeCommentNode = function (node) {
|
|
169
|
+
this.html += '<!--' + this.treeAdapter.getCommentNodeContent(node) + '-->';
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
Serializer.prototype._serializeDocumentTypeNode = function (node) {
|
|
173
|
+
var name = this.treeAdapter.getDocumentTypeNodeName(node),
|
|
174
|
+
publicId = this.treeAdapter.getDocumentTypeNodePublicId(node),
|
|
175
|
+
systemId = this.treeAdapter.getDocumentTypeNodeSystemId(node);
|
|
176
|
+
|
|
177
|
+
this.html += '<' + Doctype.serializeContent(name, publicId, systemId) + '>';
|
|
178
|
+
};
|