UNPKG

6.95 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.collectNodes = void 0;
4function collectNodes(report, mainSource, spec, document) {
5 const headers = [];
6 const mainGrammar = [];
7 const sdos = [];
8 const earlyErrors = [];
9 const algorithms = [];
10 let failed = false;
11 let inAnnexB = false;
12 const lintWalker = document.createTreeWalker(document.body, 1 /* elements */);
13 function visitCurrentNode() {
14 const node = lintWalker.currentNode;
15 const thisNodeIsAnnexB = node.nodeName === 'EMU-ANNEX' &&
16 node.id === 'sec-additional-ecmascript-features-for-web-browsers';
17 if (thisNodeIsAnnexB) {
18 inAnnexB = true;
19 }
20 // Don't bother collecting early errors and SDOs from Annex B.
21 // This is mostly so we don't have to deal with having two inconsistent copies of some of the grammar productions.
22 if (!inAnnexB) {
23 if (node.nodeName === 'EMU-CLAUSE') {
24 // Look for early errors
25 const first = node.firstElementChild;
26 if (first !== null && first.nodeName === 'H1') {
27 const title = textContentExcludingDeleted(first);
28 headers.push({ element: first, contents: title });
29 if (title.trim() === 'Static Semantics: Early Errors') {
30 let grammar = null;
31 let lists = [];
32 let warned = false;
33 for (const child of node.children) {
34 if (child.nodeName === 'EMU-GRAMMAR') {
35 if (grammar !== null) {
36 if (lists.length === 0) {
37 spec.warn({
38 type: 'node',
39 node: grammar,
40 ruleId: 'early-error-shape',
41 message: 'unrecognized structure for early errors: multiple consecutive <emu-grammar>s without intervening <ul> of errors',
42 });
43 warned = true;
44 break;
45 }
46 earlyErrors.push({ grammar, lists });
47 }
48 grammar = child;
49 lists = [];
50 }
51 else if (child.nodeName === 'UL') {
52 if (grammar === null) {
53 spec.warn({
54 type: 'node',
55 node: child,
56 ruleId: 'early-error-shape',
57 message: 'unrecognized structure for early errors: <ul> without preceding <emu-grammar>',
58 });
59 warned = true;
60 break;
61 }
62 lists.push(child);
63 }
64 }
65 if (grammar === null) {
66 if (!warned) {
67 spec.warn({
68 type: 'node',
69 node,
70 ruleId: 'early-error-shape',
71 message: 'unrecognized structure for early errors: no <emu-grammar>',
72 });
73 }
74 }
75 else if (lists.length === 0) {
76 if (!warned) {
77 spec.warn({
78 type: 'node',
79 node,
80 ruleId: 'early-error-shape',
81 message: 'unrecognized structure for early errors: no <ul> of errors',
82 });
83 }
84 }
85 else {
86 earlyErrors.push({ grammar, lists });
87 }
88 }
89 }
90 }
91 else if (node.nodeName === 'EMU-GRAMMAR' && !node.hasAttribute('example')) {
92 // Look for grammar definitions and SDOs
93 if (node.getAttribute('type') === 'definition') {
94 const loc = spec.locate(node);
95 if (!loc)
96 return;
97 const { source: importSource } = loc;
98 if (loc.endTag == null) {
99 failed = true;
100 // we'll warn for this in collect-tag-diagnostics; no need to do so here
101 }
102 else {
103 const start = loc.startTag.endOffset;
104 const end = loc.endTag.startOffset;
105 const realSource = (importSource !== null && importSource !== void 0 ? importSource : mainSource).slice(start, end);
106 mainGrammar.push({ element: node, source: realSource });
107 }
108 }
109 else {
110 const next = lintWalker.nextSibling();
111 if (next) {
112 if (next.nodeName === 'EMU-ALG') {
113 sdos.push({ grammar: node, alg: next });
114 }
115 lintWalker.previousSibling();
116 }
117 }
118 }
119 }
120 if (node.nodeName === 'EMU-ALG' && !node.hasAttribute('example')) {
121 algorithms.push({ element: node });
122 }
123 const firstChild = lintWalker.firstChild();
124 if (firstChild) {
125 while (true) {
126 visitCurrentNode();
127 const next = lintWalker.nextSibling();
128 if (!next)
129 break;
130 }
131 lintWalker.parentNode();
132 }
133 if (thisNodeIsAnnexB) {
134 inAnnexB = false;
135 }
136 }
137 visitCurrentNode();
138 if (failed) {
139 return { success: false };
140 }
141 return { success: true, mainGrammar, headers, sdos, earlyErrors, algorithms };
142}
143exports.collectNodes = collectNodes;
144function textContentExcludingDeleted(node) {
145 let retval = '';
146 node.childNodes.forEach(value => {
147 if (value.nodeType === 3) {
148 retval += value.nodeValue;
149 }
150 else if (value.nodeType !== 1 || value.tagName !== 'DEL') {
151 retval += textContentExcludingDeleted(value);
152 }
153 });
154 return retval;
155}