@jsenv/ast 6.10.5 → 6.10.7
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/ast",
|
|
3
|
-
"version": "6.10.
|
|
3
|
+
"version": "6.10.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Parse and transform HTML, CSS and JS",
|
|
6
6
|
"repository": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"@babel/core": "8.0.1",
|
|
30
30
|
"@babel/helper-module-imports": "8.0.0",
|
|
31
31
|
"@babel/parser": "8.0.4",
|
|
32
|
-
"@jsenv/humanize": "1.8.
|
|
33
|
-
"@jsenv/urls": "2.9.
|
|
32
|
+
"@jsenv/humanize": "1.8.3",
|
|
33
|
+
"@jsenv/urls": "2.9.14",
|
|
34
34
|
"@jsenv/utils": "2.3.1",
|
|
35
35
|
"acorn": "8.18.0",
|
|
36
36
|
"acorn-import-attributes": "1.9.5",
|
|
@@ -34,6 +34,12 @@ export const getUrlForContentInsideHtml = (node, htmlUrlInfo, reference) => {
|
|
|
34
34
|
return inlineContentUrl;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
// a node injected by jsenv has no place in the original html, so its position
|
|
38
|
+
// is read in the generated one: a coordinate space the page own nodes are not
|
|
39
|
+
// numbered in. Both spaces would mint the same url for different content.
|
|
40
|
+
if (getHtmlNodeAttribute(node, "jsenv-injected-by")) {
|
|
41
|
+
basename = "injected";
|
|
42
|
+
}
|
|
37
43
|
const { line, column, lineEnd, columnEnd } = getHtmlNodePosition(node, {
|
|
38
44
|
preferOriginal: true,
|
|
39
45
|
});
|
package/src/html/html_node.js
CHANGED
|
@@ -54,7 +54,6 @@ export const injectJsenvScript = (
|
|
|
54
54
|
htmlAst,
|
|
55
55
|
{ type, src, content, initCall, pluginName = "jsenv", ...attributes },
|
|
56
56
|
) => {
|
|
57
|
-
const jsenvScriptsNode = getJsenvScriptsNode(htmlAst);
|
|
58
57
|
if (type === "module") {
|
|
59
58
|
if (src) {
|
|
60
59
|
if (initCall) {
|
|
@@ -67,7 +66,7 @@ export const injectJsenvScript = (
|
|
|
67
66
|
|
|
68
67
|
${stringifyCall(initCall)};`,
|
|
69
68
|
});
|
|
70
|
-
|
|
69
|
+
injectScriptNode(htmlAst, inlineScriptNode);
|
|
71
70
|
return;
|
|
72
71
|
}
|
|
73
72
|
const remoteScriptNode = createHtmlNode({
|
|
@@ -77,7 +76,7 @@ ${stringifyCall(initCall)};`,
|
|
|
77
76
|
"jsenv-injected-by": pluginName,
|
|
78
77
|
...attributes,
|
|
79
78
|
});
|
|
80
|
-
|
|
79
|
+
injectScriptNode(htmlAst, remoteScriptNode);
|
|
81
80
|
return;
|
|
82
81
|
}
|
|
83
82
|
const inlineScriptNode = createHtmlNode({
|
|
@@ -87,7 +86,7 @@ ${stringifyCall(initCall)};`,
|
|
|
87
86
|
"children": content,
|
|
88
87
|
...attributes,
|
|
89
88
|
});
|
|
90
|
-
|
|
89
|
+
injectScriptNode(htmlAst, inlineScriptNode);
|
|
91
90
|
return;
|
|
92
91
|
}
|
|
93
92
|
if (src) {
|
|
@@ -97,7 +96,7 @@ ${stringifyCall(initCall)};`,
|
|
|
97
96
|
"jsenv-injected-by": pluginName,
|
|
98
97
|
...attributes,
|
|
99
98
|
});
|
|
100
|
-
|
|
99
|
+
injectScriptNode(htmlAst, remoteScriptNode);
|
|
101
100
|
if (initCall) {
|
|
102
101
|
const inlineScriptNode = createHtmlNode({
|
|
103
102
|
"tagName": "script",
|
|
@@ -105,7 +104,7 @@ ${stringifyCall(initCall)};`,
|
|
|
105
104
|
"children": `${stringifyCall(initCall)};`,
|
|
106
105
|
...attributes,
|
|
107
106
|
});
|
|
108
|
-
|
|
107
|
+
injectScriptNode(htmlAst, inlineScriptNode);
|
|
109
108
|
}
|
|
110
109
|
return;
|
|
111
110
|
}
|
|
@@ -115,54 +114,69 @@ ${stringifyCall(initCall)};`,
|
|
|
115
114
|
"children": content,
|
|
116
115
|
...attributes,
|
|
117
116
|
});
|
|
118
|
-
|
|
117
|
+
injectScriptNode(htmlAst, inlineScriptNode);
|
|
119
118
|
};
|
|
120
119
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
// Scripts injected by jsenv are kept together between two marker comments, so
|
|
121
|
+
// the served html shows at a glance what the page wrote and what jsenv added.
|
|
122
|
+
// Comments are used rather than a wrapper element because the group lives in
|
|
123
|
+
// <head>, where an unknown tag would end <head> and reparent everything below
|
|
124
|
+
// it into <body>.
|
|
125
|
+
const JSENV_SCRIPTS_START = " jsenv scripts ";
|
|
126
|
+
const JSENV_SCRIPTS_END = " /jsenv scripts ";
|
|
127
|
+
|
|
128
|
+
const injectScriptNode = (htmlAst, scriptNode) => {
|
|
129
|
+
const endComment = findHtmlNode(
|
|
124
130
|
htmlAst,
|
|
125
|
-
(node) => node.nodeName === "
|
|
131
|
+
(node) => node.nodeName === "#comment" && node.data === JSENV_SCRIPTS_END,
|
|
126
132
|
);
|
|
127
|
-
if (
|
|
128
|
-
|
|
133
|
+
if (endComment) {
|
|
134
|
+
insertHtmlNodeBefore(scriptNode, endComment);
|
|
135
|
+
return;
|
|
129
136
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
insertFirstScriptNode(htmlAst, scriptNode);
|
|
138
|
+
insertHtmlNodeBefore(createHtmlComment(JSENV_SCRIPTS_START), scriptNode);
|
|
139
|
+
insertHtmlNodeAfter(createHtmlComment(JSENV_SCRIPTS_END), scriptNode);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// the group opens in <head> after any <link>, <meta> and <script
|
|
143
|
+
// type="importmap">, and before the first script the page wrote itself
|
|
144
|
+
const insertFirstScriptNode = (htmlAst, scriptNode) => {
|
|
133
145
|
const headNode = findChild(htmlAst, (node) => node.nodeName === "html")
|
|
134
146
|
.childNodes[0];
|
|
135
147
|
let after = headNode.childNodes[0];
|
|
136
148
|
for (const child of headNode.childNodes) {
|
|
137
|
-
if (child.nodeName === "link") {
|
|
149
|
+
if (child.nodeName === "link" || child.nodeName === "meta") {
|
|
138
150
|
after = child;
|
|
139
151
|
continue;
|
|
140
152
|
}
|
|
141
153
|
if (child.nodeName === "script") {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return jsenvScripts;
|
|
154
|
+
if (getHtmlNodeAttribute(child, "jsenv-injected-by")) {
|
|
155
|
+
after = child;
|
|
156
|
+
continue;
|
|
146
157
|
}
|
|
158
|
+
const { type } = analyzeScriptNode(child);
|
|
147
159
|
if (type === "importmap") {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
if (type === "js_module") {
|
|
152
|
-
insertHtmlNodeBefore(jsenvScripts, child);
|
|
153
|
-
return jsenvScripts;
|
|
160
|
+
after = child;
|
|
161
|
+
continue;
|
|
154
162
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
after = child;
|
|
163
|
+
insertHtmlNodeBefore(scriptNode, child);
|
|
164
|
+
return;
|
|
158
165
|
}
|
|
159
166
|
}
|
|
160
167
|
if (after) {
|
|
161
|
-
insertHtmlNodeAfter(
|
|
162
|
-
return
|
|
168
|
+
insertHtmlNodeAfter(scriptNode, after);
|
|
169
|
+
return;
|
|
163
170
|
}
|
|
164
|
-
injectHtmlNode(
|
|
165
|
-
|
|
171
|
+
injectHtmlNode(
|
|
172
|
+
htmlAst,
|
|
173
|
+
scriptNode,
|
|
174
|
+
getHtmlNodeAttribute(scriptNode, "jsenv-injected-by"),
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const createHtmlComment = (data) => {
|
|
179
|
+
return parseFragment(`<!--${data}-->`).childNodes[0];
|
|
166
180
|
};
|
|
167
181
|
const stringifyCall = (initCall, { pretty = true } = {}) => {
|
|
168
182
|
if (!Object.hasOwn(initCall, "params")) {
|