@jsenv/ast 3.0.7 → 3.0.8

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.
@@ -1,47 +1,51 @@
1
- import { parseFragment } from "parse5"
1
+ import { parseFragment } from "parse5";
2
2
 
3
- import { setHtmlNodeAttributes } from "./html_node_attributes.js"
4
- import { findHtmlNode } from "./html_search.js"
5
- import { analyzeScriptNode } from "./html_analysis.js"
3
+ import { setHtmlNodeAttributes } from "./html_node_attributes.js";
4
+ import { findHtmlNode } from "./html_search.js";
5
+ import { analyzeScriptNode } from "./html_analysis.js";
6
6
  import {
7
7
  getIndentation,
8
8
  increaseIndentation,
9
9
  getHtmlNodeText,
10
10
  setHtmlNodeText,
11
- } from "./html_node_text.js"
11
+ } from "./html_node_text.js";
12
12
 
13
13
  export const removeHtmlNode = (htmlNode) => {
14
- const { childNodes } = htmlNode.parentNode
15
- childNodes.splice(childNodes.indexOf(htmlNode), 1)
16
- }
14
+ const { childNodes } = htmlNode.parentNode;
15
+ childNodes.splice(childNodes.indexOf(htmlNode), 1);
16
+ };
17
17
 
18
18
  export const createHtmlNode = ({ tagName, textContent = "", ...rest }) => {
19
19
  const html = `<${tagName} ${stringifyAttributes(
20
20
  rest,
21
- )}>${textContent}</${tagName}>`
22
- const fragment = parseFragment(html)
23
- return fragment.childNodes[0]
24
- }
21
+ )}>${textContent}</${tagName}>`;
22
+ const fragment = parseFragment(html);
23
+ return fragment.childNodes[0];
24
+ };
25
25
 
26
26
  export const injectHtmlNode = (htmlAst, node, jsenvPluginName = "jsenv") => {
27
27
  setHtmlNodeAttributes(node, {
28
28
  "jsenv-injected-by": jsenvPluginName,
29
- })
30
- const htmlNode = findChild(htmlAst, (node) => node.nodeName === "html")
31
- const bodyNode = findChild(htmlNode, (node) => node.nodeName === "body")
32
- let after
29
+ });
30
+ const htmlNode = findChild(htmlAst, (node) => node.nodeName === "html");
31
+ const bodyNode = findChild(htmlNode, (node) => node.nodeName === "body");
32
+ let after;
33
33
  if (node.nodeName !== "#text") {
34
34
  // last child that is not a text
35
35
  for (const child of bodyNode.childNodes) {
36
36
  if (child.nodeName !== "#text") {
37
- after = child
38
- break
37
+ after = child;
38
+ break;
39
39
  }
40
- after = child
40
+ after = child;
41
41
  }
42
42
  }
43
- insertHtmlNodeAfter(node, after)
44
- }
43
+ if (after) {
44
+ insertHtmlNodeAfter(node, after);
45
+ } else {
46
+ injectWithWhitespaces(node, bodyNode, 0);
47
+ }
48
+ };
45
49
 
46
50
  export const injectHtmlNodeAsEarlyAsPossible = (
47
51
  htmlAst,
@@ -50,136 +54,139 @@ export const injectHtmlNodeAsEarlyAsPossible = (
50
54
  ) => {
51
55
  setHtmlNodeAttributes(node, {
52
56
  "jsenv-injected-by": jsenvPluginName,
53
- })
54
- const isScript = node.nodeName === "script"
57
+ });
58
+ const isScript = node.nodeName === "script";
55
59
 
56
60
  if (isScript) {
57
- const isJsModule = analyzeScriptNode(node).type === "js_module"
61
+ const isJsModule = analyzeScriptNode(node).type === "js_module";
58
62
  if (isJsModule) {
59
63
  const firstImportmapScript = findHtmlNode(htmlAst, (node) => {
60
64
  return (
61
65
  node.nodeName === "script" &&
62
66
  analyzeScriptNode(node).type === "importmap"
63
- )
64
- })
67
+ );
68
+ });
65
69
 
66
70
  if (firstImportmapScript) {
67
- const importmapParent = firstImportmapScript.parentNode
68
- const importmapSiblings = importmapParent.childNodes
71
+ const importmapParent = firstImportmapScript.parentNode;
72
+ const importmapSiblings = importmapParent.childNodes;
69
73
  const nextSiblings = importmapSiblings.slice(
70
74
  importmapSiblings.indexOf(firstImportmapScript) + 1,
71
- )
72
- let after = firstImportmapScript
75
+ );
76
+ let after = firstImportmapScript;
73
77
  for (const nextSibling of nextSiblings) {
74
78
  if (nextSibling.nodeName === "script") {
75
- insertHtmlNodeBefore(node, nextSibling)
76
- return
79
+ insertHtmlNodeBefore(node, nextSibling);
80
+ return;
77
81
  }
78
82
  if (nextSibling.nodeName === "link") {
79
- after = nextSibling
83
+ after = nextSibling;
80
84
  }
81
85
  }
82
- insertHtmlNodeAfter(node, after)
83
- return
86
+ insertHtmlNodeAfter(node, after);
87
+ return;
84
88
  }
85
89
  }
86
90
  const headNode = findChild(htmlAst, (node) => node.nodeName === "html")
87
- .childNodes[0]
88
- let after = headNode.childNodes[0]
91
+ .childNodes[0];
92
+ let after = headNode.childNodes[0];
89
93
  for (const child of headNode.childNodes) {
90
94
  if (child.nodeName === "script") {
91
- insertHtmlNodeBefore(node, child)
92
- return
95
+ insertHtmlNodeBefore(node, child);
96
+ return;
93
97
  }
94
98
  if (child.nodeName === "link") {
95
- after = child
99
+ after = child;
96
100
  }
97
101
  }
98
- insertHtmlNodeAfter(node, after)
99
- return
102
+ if (after) {
103
+ insertHtmlNodeAfter(node, after);
104
+ }
105
+ return;
100
106
  }
101
107
 
102
- injectHtmlNode(htmlAst, node)
103
- return
104
- }
108
+ injectHtmlNode(htmlAst, node);
109
+ return;
110
+ };
105
111
 
106
112
  export const insertHtmlNodeBefore = (nodeToInsert, futureNextSibling) => {
107
- const futureParentNode = futureNextSibling.parentNode
108
- const { childNodes = [] } = futureParentNode
109
- const futureIndex = childNodes.indexOf(futureNextSibling)
110
- injectWithWhitespaces(nodeToInsert, futureParentNode, futureIndex)
111
- }
113
+ const futureParentNode = futureNextSibling.parentNode;
114
+ const { childNodes = [] } = futureParentNode;
115
+ const futureIndex = childNodes.indexOf(futureNextSibling);
116
+ injectWithWhitespaces(nodeToInsert, futureParentNode, futureIndex);
117
+ };
112
118
 
113
119
  export const insertHtmlNodeAfter = (nodeToInsert, futurePrevSibling) => {
114
- const futureParentNode = futurePrevSibling.parentNode
115
- const { childNodes = [] } = futureParentNode
116
- const futureIndex = childNodes.indexOf(futurePrevSibling) + 1
117
- injectWithWhitespaces(nodeToInsert, futureParentNode, futureIndex)
118
- }
120
+ const futureParentNode = futurePrevSibling.parentNode;
121
+ const { childNodes = [] } = futureParentNode;
122
+ const futureIndex = childNodes.indexOf(futurePrevSibling) + 1;
123
+ injectWithWhitespaces(nodeToInsert, futureParentNode, futureIndex);
124
+ };
119
125
 
120
126
  const injectWithWhitespaces = (nodeToInsert, futureParentNode, futureIndex) => {
121
- const { childNodes = [] } = futureParentNode
122
- const previousSiblings = childNodes.slice(0, futureIndex)
123
- const nextSiblings = childNodes.slice(futureIndex)
124
- const futureChildNodes = []
127
+ const { childNodes = [] } = futureParentNode;
128
+ const previousSiblings = childNodes.slice(0, futureIndex);
129
+ const nextSiblings = childNodes.slice(futureIndex);
130
+ const futureChildNodes = [];
125
131
 
126
132
  if (previousSiblings.length) {
127
- futureChildNodes.push(...previousSiblings)
133
+ futureChildNodes.push(...previousSiblings);
128
134
  }
129
- const previousSibling = childNodes[futureIndex - 1]
135
+ const previousSibling = childNodes[futureIndex - 1];
130
136
  if (
131
137
  nodeToInsert.nodeName !== "#text" &&
132
138
  (!previousSibling || !isWhitespaceNode(previousSibling))
133
139
  ) {
134
- let indentation
140
+ let indentation;
135
141
  if (childNodes.length) {
136
- indentation = getIndentation(childNodes[childNodes.length - 1])
142
+ indentation = getIndentation(childNodes[childNodes.length - 1]);
137
143
  } else {
138
- const parentIndentation = getIndentation(futureParentNode)
139
- indentation = increaseIndentation(parentIndentation, 2)
144
+ const parentIndentation = getIndentation(futureParentNode);
145
+ indentation = increaseIndentation(parentIndentation, 2);
140
146
  }
141
147
  futureChildNodes.push({
142
148
  nodeName: "#text",
143
149
  value: `\n${indentation}`,
144
150
  parentNode: futureParentNode,
145
- })
151
+ });
146
152
  }
147
- futureChildNodes.push(nodeToInsert)
148
- nodeToInsert.parentNode = futureParentNode
153
+ futureChildNodes.push(nodeToInsert);
154
+ nodeToInsert.parentNode = futureParentNode;
149
155
  if (nextSiblings.length) {
150
- futureChildNodes.push(...nextSiblings)
156
+ futureChildNodes.push(...nextSiblings);
151
157
  }
152
- futureParentNode.childNodes = futureChildNodes
158
+ futureParentNode.childNodes = futureChildNodes;
153
159
 
154
160
  // update indentation when node contains text
155
- const text = getHtmlNodeText(nodeToInsert)
161
+ const text = getHtmlNodeText(nodeToInsert);
156
162
  if (text) {
157
- setHtmlNodeText(nodeToInsert, text, { indentation: "auto" })
163
+ setHtmlNodeText(nodeToInsert, text, { indentation: "auto" });
158
164
  }
159
- }
165
+ };
160
166
 
161
167
  const isWhitespaceNode = (node) => {
162
- if (node.nodeName !== "#text") return false
163
- if (node.value.length === 0) return false
164
- return /^\s+$/.test(node.value)
165
- }
168
+ if (node.nodeName !== "#text") return false;
169
+ if (node.value.length === 0) return false;
170
+ return /^\s+$/.test(node.value);
171
+ };
166
172
 
167
- const findChild = ({ childNodes = [] }, predicate) => childNodes.find(predicate)
173
+ const findChild = ({ childNodes = [] }, predicate) =>
174
+ childNodes.find(predicate);
168
175
 
169
176
  const stringifyAttributes = (object) => {
170
- let string = ""
177
+ let string = "";
171
178
  Object.keys(object).forEach((key) => {
172
- const value = object[key]
173
- if (value === undefined) return
174
- if (string !== "") string += " "
175
- string += `${key}=${valueToHtmlAttributeValue(value)}`
176
- })
177
- return string
178
- }
179
+ const value = object[key];
180
+ if (value === undefined) return;
181
+ if (string !== "") string += " ";
182
+ string += `${key}=${valueToHtmlAttributeValue(value)}`;
183
+ });
184
+ return string;
185
+ };
179
186
 
180
187
  const valueToHtmlAttributeValue = (value) => {
181
188
  if (typeof value === "string") {
182
- return JSON.stringify(value)
189
+ return JSON.stringify(value);
183
190
  }
184
- return `"${JSON.stringify(value)}"`
185
- }
191
+ return `"${JSON.stringify(value)}"`;
192
+ };
@@ -1,43 +1,43 @@
1
1
  export const getHtmlNodeAttribute = (htmlNode, attributeName) => {
2
- const attribute = getHtmlAttributeByName(htmlNode, attributeName)
3
- return attribute ? attribute.value || "" : undefined
4
- }
2
+ const attribute = getHtmlAttributeByName(htmlNode, attributeName);
3
+ return attribute ? attribute.value || "" : undefined;
4
+ };
5
5
 
6
6
  export const setHtmlNodeAttributes = (htmlNode, attributesToAssign) => {
7
7
  if (typeof attributesToAssign !== "object") {
8
- throw new TypeError(`attributesToAssign must be an object`)
8
+ throw new TypeError(`attributesToAssign must be an object`);
9
9
  }
10
- const { attrs } = htmlNode
11
- if (!attrs) return
10
+ const { attrs } = htmlNode;
11
+ if (!attrs) return;
12
12
  Object.keys(attributesToAssign).forEach((key) => {
13
- const existingAttributeIndex = attrs.findIndex(({ name }) => name === key)
14
- const value = attributesToAssign[key]
13
+ const existingAttributeIndex = attrs.findIndex(({ name }) => name === key);
14
+ const value = attributesToAssign[key];
15
15
  // remove no-op
16
16
  if (existingAttributeIndex === -1 && value === undefined) {
17
- return
17
+ return;
18
18
  }
19
19
  // add
20
20
  if (existingAttributeIndex === -1 && value !== undefined) {
21
21
  attrs.push({
22
22
  name: key,
23
23
  value,
24
- })
25
- return
24
+ });
25
+ return;
26
26
  }
27
27
  // remove
28
28
  if (value === undefined) {
29
- attrs.splice(existingAttributeIndex, 1)
30
- return
29
+ attrs.splice(existingAttributeIndex, 1);
30
+ return;
31
31
  }
32
32
  // update
33
- attrs[existingAttributeIndex].value = value
34
- })
35
- }
33
+ attrs[existingAttributeIndex].value = value;
34
+ });
35
+ };
36
36
 
37
37
  const getHtmlAttributeByName = (htmlNode, attributeName) => {
38
- const attrs = htmlNode.attrs
38
+ const attrs = htmlNode.attrs;
39
39
  const attribute = attrs
40
40
  ? attrs.find((attr) => attr.name === attributeName)
41
- : null
42
- return attribute
43
- }
41
+ : null;
42
+ return attribute;
43
+ };
@@ -1,99 +1,99 @@
1
1
  import {
2
2
  getHtmlNodeAttribute,
3
3
  setHtmlNodeAttributes,
4
- } from "./html_node_attributes.js"
4
+ } from "./html_node_attributes.js";
5
5
 
6
6
  export const storeHtmlNodePosition = (node) => {
7
- const originalPositionAttributeName = `original-position`
7
+ const originalPositionAttributeName = `original-position`;
8
8
  const originalPosition = getHtmlNodeAttribute(
9
9
  node,
10
10
  originalPositionAttributeName,
11
- )
11
+ );
12
12
  if (originalPosition !== undefined) {
13
- return true
13
+ return true;
14
14
  }
15
- const { sourceCodeLocation } = node
15
+ const { sourceCodeLocation } = node;
16
16
  if (!sourceCodeLocation) {
17
- return false
17
+ return false;
18
18
  }
19
- const { startLine, startCol, endLine, endCol } = sourceCodeLocation
19
+ const { startLine, startCol, endLine, endCol } = sourceCodeLocation;
20
20
  setHtmlNodeAttributes(node, {
21
21
  [originalPositionAttributeName]: `${startLine}:${startCol};${endLine}:${endCol}`,
22
- })
23
- return true
24
- }
22
+ });
23
+ return true;
24
+ };
25
25
  export const storeHtmlNodeAttributePosition = (node, attributeName) => {
26
- const { sourceCodeLocation } = node
26
+ const { sourceCodeLocation } = node;
27
27
  if (!sourceCodeLocation) {
28
- return false
28
+ return false;
29
29
  }
30
- const attributeValue = getHtmlNodeAttribute(node, attributeName)
30
+ const attributeValue = getHtmlNodeAttribute(node, attributeName);
31
31
  if (attributeValue === undefined) {
32
- return false
32
+ return false;
33
33
  }
34
- const attributeLocation = sourceCodeLocation.attrs[attributeName]
34
+ const attributeLocation = sourceCodeLocation.attrs[attributeName];
35
35
  if (!attributeLocation) {
36
- return false
36
+ return false;
37
37
  }
38
- const originalPositionAttributeName = `original-${attributeName}-position`
38
+ const originalPositionAttributeName = `original-${attributeName}-position`;
39
39
  const originalPosition = getHtmlNodeAttribute(
40
40
  node,
41
41
  originalPositionAttributeName,
42
- )
42
+ );
43
43
  if (originalPosition !== undefined) {
44
- return true
44
+ return true;
45
45
  }
46
- const { startLine, startCol, endLine, endCol } = attributeLocation
46
+ const { startLine, startCol, endLine, endCol } = attributeLocation;
47
47
  setHtmlNodeAttributes(node, {
48
48
  [originalPositionAttributeName]: `${startLine}:${startCol};${endLine}:${endCol}`,
49
- })
50
- return true
51
- }
49
+ });
50
+ return true;
51
+ };
52
52
 
53
53
  export const getHtmlNodePosition = (node, { preferOriginal = false } = {}) => {
54
- const position = {}
55
- const { sourceCodeLocation } = node
54
+ const position = {};
55
+ const { sourceCodeLocation } = node;
56
56
  if (sourceCodeLocation) {
57
- const { startLine, startCol, endLine, endCol } = sourceCodeLocation
57
+ const { startLine, startCol, endLine, endCol } = sourceCodeLocation;
58
58
  Object.assign(position, {
59
59
  line: startLine,
60
60
  lineEnd: endLine,
61
61
  column: startCol,
62
62
  columnEnd: endCol,
63
- })
63
+ });
64
64
  }
65
- const originalPosition = getHtmlNodeAttribute(node, "original-position")
65
+ const originalPosition = getHtmlNodeAttribute(node, "original-position");
66
66
  if (originalPosition === undefined) {
67
- return position
67
+ return position;
68
68
  }
69
- const [start, end] = originalPosition.split(";")
70
- const [originalLine, originalColumn] = start.split(":")
71
- const [originalLineEnd, originalColumnEnd] = end.split(":")
69
+ const [start, end] = originalPosition.split(";");
70
+ const [originalLine, originalColumn] = start.split(":");
71
+ const [originalLineEnd, originalColumnEnd] = end.split(":");
72
72
  Object.assign(position, {
73
73
  originalLine: parseInt(originalLine),
74
74
  originalColumn: parseInt(originalColumn),
75
75
  originalLineEnd: parseInt(originalLineEnd),
76
76
  originalColumnEnd: parseInt(originalColumnEnd),
77
- })
77
+ });
78
78
  if (preferOriginal) {
79
- position.line = position.originalLine
80
- position.column = position.originalColumn
81
- position.lineEnd = position.originalLineEnd
82
- position.columnEnd = position.originalColumnEnd
83
- position.isOriginal = true
79
+ position.line = position.originalLine;
80
+ position.column = position.originalColumn;
81
+ position.lineEnd = position.originalLineEnd;
82
+ position.columnEnd = position.originalColumnEnd;
83
+ position.isOriginal = true;
84
84
  }
85
- return position
86
- }
85
+ return position;
86
+ };
87
87
  export const getHtmlNodeAttributePosition = (node, attributeName) => {
88
- const position = {}
89
- const { sourceCodeLocation } = node
88
+ const position = {};
89
+ const { sourceCodeLocation } = node;
90
90
  if (sourceCodeLocation) {
91
- const attributeLocation = sourceCodeLocation.attrs[attributeName]
91
+ const attributeLocation = sourceCodeLocation.attrs[attributeName];
92
92
  if (attributeLocation) {
93
93
  Object.assign(position, {
94
94
  line: attributeLocation.startLine,
95
95
  column: attributeLocation.startCol,
96
- })
96
+ });
97
97
  }
98
98
  }
99
99
  const originalPositionAttributeName =
@@ -101,22 +101,22 @@ export const getHtmlNodeAttributePosition = (node, attributeName) => {
101
101
  ? "original-src-position"
102
102
  : attributeName === "inlined-from-href"
103
103
  ? "original-href-position"
104
- : `original-${attributeName}-position`
104
+ : `original-${attributeName}-position`;
105
105
  const originalPosition = getHtmlNodeAttribute(
106
106
  node,
107
107
  originalPositionAttributeName,
108
- )
108
+ );
109
109
  if (originalPosition === undefined) {
110
- return position
110
+ return position;
111
111
  }
112
- const [start, end] = originalPosition.split(";")
113
- const [originalLine, originalColumn] = start.split(":")
114
- const [originalLineEnd, originalColumnEnd] = end.split(":")
112
+ const [start, end] = originalPosition.split(";");
113
+ const [originalLine, originalColumn] = start.split(":");
114
+ const [originalLineEnd, originalColumnEnd] = end.split(":");
115
115
  Object.assign(position, {
116
116
  originalLine: parseInt(originalLine),
117
117
  originalColumn: parseInt(originalColumn),
118
118
  originalLineEnd: parseInt(originalLineEnd),
119
119
  originalColumnEnd: parseInt(originalColumnEnd),
120
- })
121
- return position
122
- }
120
+ });
121
+ return position;
122
+ };