@pushwoosh/dumb-components 1.1.38 → 1.1.39
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,3 +1,4 @@
|
|
|
1
1
|
import { type ScalarValue, type ASTNodeList, type IfOperator } from './types';
|
|
2
|
+
export declare const voidTags: Set<string>;
|
|
2
3
|
export declare const ifOperatorFns: Record<IfOperator, (a: ScalarValue, b: ScalarValue) => boolean>;
|
|
3
4
|
export declare function stringToAst(template: string): ASTNodeList;
|
|
@@ -7,6 +7,8 @@ const pairedControlTokensReversed = {
|
|
|
7
7
|
endfor: 'for',
|
|
8
8
|
endif: 'if'
|
|
9
9
|
};
|
|
10
|
+
// Add a list of void/self-closing HTML-like tags that do not require an explicit closing tag
|
|
11
|
+
export const voidTags = new Set(['br', 'hr', 'img']);
|
|
10
12
|
function tokenizeLiquid(template) {
|
|
11
13
|
const tokens = [];
|
|
12
14
|
let cursor = 0;
|
|
@@ -106,25 +108,40 @@ function tokenizeLiquid(template) {
|
|
|
106
108
|
}
|
|
107
109
|
};
|
|
108
110
|
const captureTag = () => {
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
111
|
+
const raw = captureUntil('>', 1);
|
|
112
|
+
const value = raw.trim();
|
|
113
|
+
// Closing tag: </tag>
|
|
114
|
+
if (value.startsWith('/')) {
|
|
115
|
+
const endName = value.slice(1).trim();
|
|
112
116
|
tokens.push({
|
|
113
117
|
type: 'TagEnd',
|
|
114
|
-
value:
|
|
118
|
+
value: endName,
|
|
115
119
|
lineNo
|
|
116
120
|
});
|
|
117
|
-
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// Detect explicit self-closing syntax: <tag ... /> or <tag/>
|
|
124
|
+
const hasExplicitSelfClose = /\/$/.test(value);
|
|
125
|
+
const normalized = hasExplicitSelfClose ? value.replace(/\/$/, '').trimEnd() : value;
|
|
126
|
+
const [tagNameRaw, args] = smartSplitAtFirstDelimiter(normalized, ' ');
|
|
127
|
+
const tagName = tagNameRaw.trim();
|
|
128
|
+
tokens.push({
|
|
129
|
+
type: 'Tag',
|
|
130
|
+
value: tagName,
|
|
131
|
+
lineNo
|
|
132
|
+
});
|
|
133
|
+
tokens.push({
|
|
134
|
+
type: 'TagArg',
|
|
135
|
+
value: (args || '').trim(),
|
|
136
|
+
lineNo
|
|
137
|
+
});
|
|
138
|
+
// If the tag is a known void tag or explicitly self-closed, emit an immediate TagEnd
|
|
139
|
+
if (hasExplicitSelfClose || voidTags.has(tagName.toLowerCase())) {
|
|
118
140
|
tokens.push({
|
|
119
|
-
type: '
|
|
141
|
+
type: 'TagEnd',
|
|
120
142
|
value: tagName,
|
|
121
143
|
lineNo
|
|
122
144
|
});
|
|
123
|
-
tokens.push({
|
|
124
|
-
type: 'TagArg',
|
|
125
|
-
value: args || '',
|
|
126
|
-
lineNo
|
|
127
|
-
});
|
|
128
145
|
}
|
|
129
146
|
};
|
|
130
147
|
while (!isEOF()) {
|
|
@@ -4,7 +4,7 @@ import { Color } from '@pushwoosh/kit-constants';
|
|
|
4
4
|
import { variants } from '@pushwoosh/kit-typography/map';
|
|
5
5
|
import { filters } from './filters';
|
|
6
6
|
import { stringifyScalarOrVariable, unpackScalarOrValue } from './helpers';
|
|
7
|
-
import { ifOperatorFns } from './parser';
|
|
7
|
+
import { ifOperatorFns, voidTags } from './parser';
|
|
8
8
|
// Applies a filter to a value.
|
|
9
9
|
// @param filterName The name of the filter to apply.
|
|
10
10
|
// @param value The value to which the filter should be applied.
|
|
@@ -75,7 +75,13 @@ function renderNodesToArray(ast, context, renderTag) {
|
|
|
75
75
|
return output;
|
|
76
76
|
}
|
|
77
77
|
export function renderToString(ast, context) {
|
|
78
|
-
const outArr = renderNodesToArray(ast, context, (tagNode, children) =>
|
|
78
|
+
const outArr = renderNodesToArray(ast, context, (tagNode, children) => {
|
|
79
|
+
const attrs = Object.entries(tagNode.params).map(([key, value]) => `${key}=${stringifyScalarOrVariable(value)}`).join(' ');
|
|
80
|
+
if (voidTags.has(tagNode.name)) {
|
|
81
|
+
return [attrs ? `<${tagNode.name} ${attrs}/>` : `<${tagNode.name}/>`];
|
|
82
|
+
}
|
|
83
|
+
return [attrs ? `<${tagNode.name} ${attrs}>` : `<${tagNode.name}>`, ...children, `</${tagNode.name}>`];
|
|
84
|
+
});
|
|
79
85
|
return outArr.join('');
|
|
80
86
|
}
|
|
81
87
|
function getColor(color) {
|
|
@@ -107,6 +113,12 @@ export function renderToReact(ast, context) {
|
|
|
107
113
|
key: key
|
|
108
114
|
}, children)];
|
|
109
115
|
}
|
|
116
|
+
if (voidTags.has(TagName)) {
|
|
117
|
+
return [React.createElement(TagName, {
|
|
118
|
+
...props,
|
|
119
|
+
key: key
|
|
120
|
+
})];
|
|
121
|
+
}
|
|
110
122
|
return [React.createElement(TagName, {
|
|
111
123
|
...props,
|
|
112
124
|
key: key
|