@herb-tools/rewriter 0.9.2 → 0.9.3
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/dist/index.cjs +575 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +575 -17
- package/dist/index.esm.js.map +1 -1
- package/dist/loader.cjs +575 -17
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.esm.js +575 -17
- package/dist/loader.esm.js.map +1 -1
- package/dist/types/built-ins/action-view-tag-helper-to-html.d.ts +1 -1
- package/package.json +4 -4
- package/src/built-ins/action-view-tag-helper-to-html.ts +54 -10
- package/src/built-ins/html-to-action-view-tag-helper.ts +19 -4
|
@@ -4,5 +4,5 @@ import type { Node } from "@herb-tools/core";
|
|
|
4
4
|
export declare class ActionViewTagHelperToHTMLRewriter extends ASTRewriter {
|
|
5
5
|
get name(): string;
|
|
6
6
|
get description(): string;
|
|
7
|
-
rewrite<T extends Node>(node: T,
|
|
7
|
+
rewrite<T extends Node>(node: T, context: RewriteContext): T;
|
|
8
8
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herb-tools/rewriter",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "Rewriter system for transforming HTML+ERB AST nodes and formatted strings",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://herb-tools.dev",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@herb-tools/core": "0.9.
|
|
42
|
-
"@herb-tools/tailwind-class-sorter": "0.9.
|
|
41
|
+
"@herb-tools/core": "0.9.3",
|
|
42
|
+
"@herb-tools/tailwind-class-sorter": "0.9.3",
|
|
43
43
|
"tinyglobby": "^0.2.15"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@herb-tools/printer": "0.9.
|
|
46
|
+
"@herb-tools/printer": "0.9.3"
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
49
|
"package.json",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Visitor, Location, HTMLOpenTagNode, HTMLCloseTagNode, HTMLElementNode, HTMLAttributeValueNode, WhitespaceNode, ERBContentNode } from "@herb-tools/core"
|
|
2
|
-
import { isHTMLAttributeNode, isERBOpenTagNode, isRubyLiteralNode, isRubyHTMLAttributesSplatNode, createSyntheticToken } from "@herb-tools/core"
|
|
2
|
+
import { isHTMLAttributeNode, isERBOpenTagNode, isRubyLiteralNode, isRubyHTMLAttributesSplatNode, isWhitespaceNode, createSyntheticToken } from "@herb-tools/core"
|
|
3
3
|
|
|
4
4
|
import { ASTRewriter } from "../ast-rewriter.js"
|
|
5
5
|
import { asMutable } from "../mutable.js"
|
|
@@ -17,6 +17,45 @@ function createWhitespaceNode(): WhitespaceNode {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
class ActionViewTagHelperToHTMLVisitor extends Visitor {
|
|
20
|
+
private shallow: boolean
|
|
21
|
+
private includeBody: boolean
|
|
22
|
+
|
|
23
|
+
constructor(options: { shallow?: boolean; includeBody?: boolean } = {}) {
|
|
24
|
+
super()
|
|
25
|
+
this.shallow = options.shallow ?? false
|
|
26
|
+
this.includeBody = options.includeBody ?? true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
visitHTMLOpenTagNode(node: HTMLOpenTagNode): void {
|
|
30
|
+
const newChildren: Node[] = []
|
|
31
|
+
|
|
32
|
+
for (let index = 0; index < node.children.length; index++) {
|
|
33
|
+
const child = node.children[index]
|
|
34
|
+
|
|
35
|
+
if (isHTMLAttributeNode(child)) {
|
|
36
|
+
if (child.equals && child.equals.value !== "=") {
|
|
37
|
+
asMutable(child).equals = createSyntheticToken("=")
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (child.value) {
|
|
41
|
+
this.transformAttributeValue(child.value)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const previous = index > 0 ? node.children[index - 1] : null
|
|
45
|
+
|
|
46
|
+
if (!previous || !isWhitespaceNode(previous)) {
|
|
47
|
+
newChildren.push(createWhitespaceNode())
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
newChildren.push(child)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
asMutable(node).children = newChildren
|
|
55
|
+
|
|
56
|
+
this.visitChildNodes(node)
|
|
57
|
+
}
|
|
58
|
+
|
|
20
59
|
visitHTMLElementNode(node: HTMLElementNode): void {
|
|
21
60
|
if (!node.element_source) {
|
|
22
61
|
this.visitChildNodes(node)
|
|
@@ -104,7 +143,9 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
|
|
|
104
143
|
|
|
105
144
|
asMutable(node).element_source = "HTML"
|
|
106
145
|
|
|
107
|
-
if (
|
|
146
|
+
if (!this.includeBody) {
|
|
147
|
+
asMutable(node).body = []
|
|
148
|
+
} else if (node.body) {
|
|
108
149
|
asMutable(node).body = node.body.map(child => {
|
|
109
150
|
if (isRubyLiteralNode(child)) {
|
|
110
151
|
return new ERBContentNode({
|
|
@@ -120,7 +161,10 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
|
|
|
120
161
|
})
|
|
121
162
|
}
|
|
122
163
|
|
|
123
|
-
this.
|
|
164
|
+
if (!this.shallow) {
|
|
165
|
+
this.visit(child)
|
|
166
|
+
}
|
|
167
|
+
|
|
124
168
|
return child
|
|
125
169
|
})
|
|
126
170
|
}
|
|
@@ -150,12 +194,12 @@ class ActionViewTagHelperToHTMLVisitor extends Visitor {
|
|
|
150
194
|
})
|
|
151
195
|
|
|
152
196
|
mutableValue.children = newChildren
|
|
197
|
+
}
|
|
153
198
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
199
|
+
if (!value.quoted) {
|
|
200
|
+
mutableValue.quoted = true
|
|
201
|
+
mutableValue.open_quote = createSyntheticToken('"')
|
|
202
|
+
mutableValue.close_quote = createSyntheticToken('"')
|
|
159
203
|
}
|
|
160
204
|
}
|
|
161
205
|
}
|
|
@@ -169,8 +213,8 @@ export class ActionViewTagHelperToHTMLRewriter extends ASTRewriter {
|
|
|
169
213
|
return "Converts ActionView tag helpers to raw HTML elements"
|
|
170
214
|
}
|
|
171
215
|
|
|
172
|
-
rewrite<T extends Node>(node: T,
|
|
173
|
-
const visitor = new ActionViewTagHelperToHTMLVisitor()
|
|
216
|
+
rewrite<T extends Node>(node: T, context: RewriteContext): T {
|
|
217
|
+
const visitor = new ActionViewTagHelperToHTMLVisitor({ shallow: context.shallow, includeBody: context.includeBody })
|
|
174
218
|
|
|
175
219
|
visitor.visit(node)
|
|
176
220
|
|
|
@@ -124,9 +124,10 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
|
|
|
124
124
|
const isAnchor = tagName.value === "a"
|
|
125
125
|
const isTurboFrame = tagName.value === "turbo-frame"
|
|
126
126
|
const isScript = tagName.value === "script"
|
|
127
|
+
const isImg = tagName.value === "img"
|
|
127
128
|
const attributes = openTag.children.filter(child => !isWhitespaceNode(child))
|
|
128
|
-
const hasSrcAttribute = isScript && attributes.some(child => isHTMLAttributeNode(child) && getStaticAttributeName(child.name!) === "src")
|
|
129
|
-
const { attributes: attributesString, href, id, src } = serializeAttributes(attributes, { extractHref: isAnchor, extractId: isTurboFrame, extractSrc: isScript })
|
|
129
|
+
const hasSrcAttribute = (isScript || isImg) && attributes.some(child => isHTMLAttributeNode(child) && getStaticAttributeName(child.name!) === "src")
|
|
130
|
+
const { attributes: attributesString, href, id, src } = serializeAttributes(attributes, { extractHref: isAnchor, extractId: isTurboFrame, extractSrc: isScript || isImg })
|
|
130
131
|
const hasBody = node.body && node.body.length > 0 && !node.is_void
|
|
131
132
|
const isInlineContent = hasBody && isTextOnlyBody(node.body)
|
|
132
133
|
|
|
@@ -145,6 +146,9 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
|
|
|
145
146
|
} else if (isScript) {
|
|
146
147
|
content = this.buildJavascriptTagContent(node, attributesString, isInlineContent)
|
|
147
148
|
elementSource = "ActionView::Helpers::JavaScriptHelper#javascript_tag"
|
|
149
|
+
} else if (isImg) {
|
|
150
|
+
content = this.buildImageTagContent(attributesString, src)
|
|
151
|
+
elementSource = "ActionView::Helpers::AssetTagHelper#image_tag"
|
|
148
152
|
} else {
|
|
149
153
|
content = this.buildTagContent(tagName.value, node, attributesString, isInlineContent)
|
|
150
154
|
elementSource = "ActionView::Helpers::TagHelper#tag"
|
|
@@ -165,7 +169,7 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
|
|
|
165
169
|
asMutable(node).element_source = elementSource
|
|
166
170
|
|
|
167
171
|
const isInlineLiteralContent = isScript && hasBody && node.body.length === 1 && isLiteralNode(node.body[0]) && !node.body[0].content.includes("\n")
|
|
168
|
-
const isInlineForm = isInlineContent || isInlineLiteralContent || (isTurboFrame && !hasBody) || (isScript && hasSrcAttribute)
|
|
172
|
+
const isInlineForm = isInlineContent || isInlineLiteralContent || (isTurboFrame && !hasBody) || (isScript && hasSrcAttribute) || isImg
|
|
169
173
|
|
|
170
174
|
if (node.is_void) {
|
|
171
175
|
asMutable(node).close_tag = null
|
|
@@ -270,6 +274,17 @@ class HTMLToActionViewTagHelperVisitor extends Visitor {
|
|
|
270
274
|
return argString ? ` javascript_include_tag ${argString} ` : ` javascript_include_tag `
|
|
271
275
|
}
|
|
272
276
|
|
|
277
|
+
private buildImageTagContent(attributes: string, source: string | null): string {
|
|
278
|
+
const args: string[] = []
|
|
279
|
+
|
|
280
|
+
if (source) args.push(source)
|
|
281
|
+
if (attributes) args.push(attributes)
|
|
282
|
+
|
|
283
|
+
const argString = args.join(", ")
|
|
284
|
+
|
|
285
|
+
return argString ? ` image_tag ${argString} ` : ` image_tag `
|
|
286
|
+
}
|
|
287
|
+
|
|
273
288
|
private buildLinkToContent(node: HTMLElementNode, attribute: string, href: string | null, isInlineContent: boolean): string {
|
|
274
289
|
const args: string[] = []
|
|
275
290
|
|
|
@@ -301,7 +316,7 @@ export class HTMLToActionViewTagHelperRewriter extends ASTRewriter {
|
|
|
301
316
|
}
|
|
302
317
|
|
|
303
318
|
get description(): string {
|
|
304
|
-
return "Converts raw HTML elements to ActionView tag helpers (tag.*, turbo_frame_tag, javascript_tag, javascript_include_tag)"
|
|
319
|
+
return "Converts raw HTML elements to ActionView tag helpers (tag.*, turbo_frame_tag, javascript_tag, javascript_include_tag, image_tag)"
|
|
305
320
|
}
|
|
306
321
|
|
|
307
322
|
rewrite<T extends Node>(node: T, _context: RewriteContext): T {
|