@takazudo/zfb 3.2.0 → 4.1.0
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/config.d.ts +33 -3
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins.d.ts +18 -4
- package/dist/plugins.js.map +1 -1
- package/dist/zudo-react/hydrate.js +67 -4
- package/dist/zudo-react/hydrate.js.map +1 -1
- package/dist/zudo-react/jsx-types.d.ts +49 -11
- package/dist/zudo-react/jsx-types.js.map +1 -1
- package/dist/zudo-react/raw-html.js +144 -4
- package/dist/zudo-react/raw-html.js.map +1 -1
- package/dist/zudo-react/render-html.js +14 -5
- package/dist/zudo-react/render-html.js.map +1 -1
- package/dist/zudo-react/root.d.ts +9 -1
- package/dist/zudo-react/root.js +21 -2
- package/dist/zudo-react/root.js.map +1 -1
- package/dist/zudo-react/vocabulary.d.ts +2 -1
- package/dist/zudo-react/vocabulary.js +12 -3
- package/dist/zudo-react/vocabulary.js.map +1 -1
- package/package.json +6 -6
|
@@ -142,33 +142,71 @@ type IframeProps = Omit<HtmlBaseAttributes<HTMLIFrameElement>, "children" | "raw
|
|
|
142
142
|
children?: never;
|
|
143
143
|
rawHtml?: never;
|
|
144
144
|
};
|
|
145
|
-
type InputBase = Omit<HtmlBaseAttributes<HTMLInputElement>, "type"> & DataAria & EventProps<HTMLInputElement, HTMLElementEventMap
|
|
146
|
-
|
|
147
|
-
defaultChecked?: boolean | undefined;
|
|
148
|
-
};
|
|
149
|
-
export type InputProps = InputBase & ({
|
|
145
|
+
type InputBase = Omit<HtmlBaseAttributes<HTMLInputElement>, "type"> & DataAria & EventProps<HTMLInputElement, HTMLElementEventMap>;
|
|
146
|
+
export type InputProps = EventProps<HTMLInputElement, HTMLElementEventMap> & Omit<InputBase, "value"> & (({
|
|
150
147
|
type?: "text" | "search" | "email" | "url" | "tel" | "password" | undefined;
|
|
151
|
-
|
|
148
|
+
defaultChecked?: never;
|
|
152
149
|
modelChecked?: never;
|
|
150
|
+
} & ({
|
|
151
|
+
readonly: true;
|
|
152
|
+
disabled?: BooleanAttribute;
|
|
153
|
+
value?: string | number | null | ReadonlySignal<string>;
|
|
154
|
+
modelValue?: never;
|
|
155
|
+
defaultValue?: never;
|
|
153
156
|
} | {
|
|
157
|
+
disabled: true;
|
|
158
|
+
readonly?: BooleanAttribute;
|
|
159
|
+
value?: string | number | null | ReadonlySignal<string>;
|
|
160
|
+
modelValue?: never;
|
|
161
|
+
defaultValue?: never;
|
|
162
|
+
} | {
|
|
163
|
+
value?: string | number | null;
|
|
164
|
+
modelValue?: Signal<string> | undefined;
|
|
165
|
+
defaultValue?: string | undefined;
|
|
166
|
+
})) | (Pick<InputBase, "value"> & ({
|
|
154
167
|
type: "checkbox";
|
|
168
|
+
defaultValue?: never;
|
|
169
|
+
defaultChecked?: boolean | undefined;
|
|
155
170
|
modelChecked?: Signal<boolean> | undefined;
|
|
156
171
|
modelValue?: never;
|
|
157
172
|
} | {
|
|
158
173
|
type: "radio";
|
|
159
174
|
name: string;
|
|
160
175
|
value: string;
|
|
161
|
-
|
|
176
|
+
defaultValue?: never;
|
|
177
|
+
defaultChecked?: boolean | undefined;
|
|
178
|
+
modelValue: Signal<string | null>;
|
|
179
|
+
modelChecked?: never;
|
|
180
|
+
} | {
|
|
181
|
+
type: "radio";
|
|
182
|
+
defaultValue?: never;
|
|
183
|
+
defaultChecked?: boolean | undefined;
|
|
184
|
+
modelValue?: undefined;
|
|
162
185
|
modelChecked?: never;
|
|
163
186
|
} | {
|
|
164
187
|
type: string;
|
|
188
|
+
defaultValue?: never;
|
|
189
|
+
defaultChecked?: never;
|
|
165
190
|
modelValue?: never;
|
|
166
191
|
modelChecked?: never;
|
|
167
|
-
});
|
|
168
|
-
export type TextareaProps = HTMLAttributes<HTMLTextAreaElement> & {
|
|
192
|
+
})));
|
|
193
|
+
export type TextareaProps = Omit<HTMLAttributes<HTMLTextAreaElement>, "value"> & ({
|
|
194
|
+
readonly: true;
|
|
195
|
+
disabled?: BooleanAttribute;
|
|
196
|
+
value?: string | number | null | ReadonlySignal<string>;
|
|
197
|
+
modelValue?: never;
|
|
198
|
+
defaultValue?: never;
|
|
199
|
+
} | {
|
|
200
|
+
disabled: true;
|
|
201
|
+
readonly?: BooleanAttribute;
|
|
202
|
+
value?: string | number | null | ReadonlySignal<string>;
|
|
203
|
+
modelValue?: never;
|
|
204
|
+
defaultValue?: never;
|
|
205
|
+
} | {
|
|
206
|
+
value?: string | number | null;
|
|
169
207
|
modelValue?: Signal<string> | undefined;
|
|
170
208
|
defaultValue?: string | undefined;
|
|
171
|
-
};
|
|
209
|
+
});
|
|
172
210
|
export type SelectProps = HTMLAttributes<HTMLSelectElement> & {
|
|
173
211
|
modelValue?: Signal<string> | undefined;
|
|
174
212
|
defaultValue?: string | undefined;
|
|
@@ -226,7 +264,7 @@ type CustomProps = ReservedProps & EventProps<HTMLElement, GlobalEventHandlersEv
|
|
|
226
264
|
checked?: null | undefined;
|
|
227
265
|
[attribute: string]: StringAttribute | Child | Ref<Element> | AnyListener | undefined;
|
|
228
266
|
};
|
|
229
|
-
type HtmlTag = "html" | "head" | "body" | "title" | "base" | "link" | "meta" | "style" | "script" | "div" | "span" | "p" | "a" | "br" | "hr" | "main" | "header" | "footer" | "nav" | "section" | "article" | "aside" | "search" | "hgroup" | "menu" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "dl" | "dt" | "dd" | "blockquote" | "pre" | "code" | "strong" | "em" | "b" | "i" | "small" | "mark" | "time" | "figure" | "figcaption" | "img" | "picture" | "source" | "video" | "audio" | "track" | "canvas" | "form" | "label" | "input" | "button" | "textarea" | "select" | "option" | "optgroup" | "fieldset" | "legend" | "output" | "progress" | "meter" | "datalist" | "table" | "caption" | "thead" | "tbody" | "tfoot" | "tr" | "th" | "td" | "col" | "colgroup" | "details" | "summary" | "dialog" | "template" | "slot" | "iframe" | "noscript" | "address" | "abbr" | "bdi" | "bdo" | "cite" | "data" | "del" | "dfn" | "ins" | "kbd" | "map" | "area" | "object" | "param" | "q" | "rp" | "rt" | "ruby" | "s" | "samp" | "sub" | "sup" | "u" | "var" | "wbr" | "embed";
|
|
267
|
+
type HtmlTag = "html" | "head" | "body" | "title" | "base" | "link" | "meta" | "style" | "script" | "div" | "span" | "p" | "a" | "br" | "hr" | "main" | "header" | "footer" | "nav" | "section" | "article" | "aside" | "search" | "hgroup" | "menu" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "dl" | "dt" | "dd" | "blockquote" | "pre" | "code" | "strong" | "em" | "b" | "i" | "small" | "mark" | "time" | "figure" | "figcaption" | "img" | "picture" | "source" | "video" | "audio" | "track" | "canvas" | "form" | "label" | "input" | "button" | "textarea" | "select" | "option" | "optgroup" | "fieldset" | "legend" | "output" | "progress" | "meter" | "datalist" | "table" | "caption" | "thead" | "tbody" | "tfoot" | "tr" | "th" | "td" | "col" | "colgroup" | "details" | "summary" | "dialog" | "template" | "slot" | "iframe" | "noscript" | "address" | "abbr" | "bdi" | "bdo" | "cite" | "data" | "del" | "dfn" | "ins" | "kbd" | "map" | "area" | "object" | "param" | "q" | "rp" | "rb" | "rt" | "ruby" | "s" | "samp" | "sub" | "sup" | "u" | "var" | "wbr" | "embed";
|
|
230
268
|
type SvgTag = "svg" | "g" | "path" | "circle" | "ellipse" | "rect" | "line" | "polyline" | "polygon" | "text" | "tspan" | "defs" | "symbol" | "use" | "clipPath" | "mask" | "linearGradient" | "radialGradient" | "stop" | "desc" | "foreignObject" | "pattern" | "filter" | "marker" | "image";
|
|
231
269
|
/** DOM element corresponding to an owned intrinsic tag. */
|
|
232
270
|
export type ElementForTag<Tag extends HtmlTag | SvgTag> = Tag extends HtmlTag ? Tag extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[Tag] : HTMLElement : Tag extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[Tag] : SVGElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-types.js","sourceRoot":"","sources":["../../src/zudo-react/jsx-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CSSProperties } from \"./style.js\";\nexport type { CSSProperties, CssProperty } from \"./style.js\";\nimport type { Child, Component, Description, Key } from \"./description.js\";\nimport type { Listener, Ref } from \"./index.js\";\nimport type { ReadonlySignal, Signal } from \"./reactive-types.js\";\n\ntype Value<T> = T | ReadonlySignal<T> | undefined;\ntype ScalarAttribute = Value<string | number | boolean | null>;\ntype DimensionAttribute = Value<string | number | null>;\ntype StringAttribute = Value<string | null>;\ntype BooleanAttribute = Value<boolean | null>;\n// The custom-name index must also accept every mapped listener under strict function variance.\ntype AnyListener = Listener<any>;\ntype EventProps<TEl extends Element, TMap extends Record<keyof TMap, Event>> = {\n [K in keyof TMap & string as `on:${K}` | `on:${K}:capture`]?: Listener<\n TMap[K] & { currentTarget: TEl }\n >;\n} & {\n [name: `on:${string}`]: AnyListener | undefined;\n};\ntype DataAria = {\n [name: `data-${string}`]: ScalarAttribute;\n} & {\n [name: `aria-${string}`]: ScalarAttribute;\n};\n\ninterface ReservedProps<T extends Element = Element> {\n children?: Child | undefined;\n key?: Key | undefined;\n ref?: Ref<T> | undefined;\n rawHtml?: Value<string | null>;\n}\n\ninterface CommonAttributes<T extends Element = Element> extends ReservedProps<T> {\n id?: StringAttribute;\n class?: StringAttribute;\n title?: StringAttribute;\n lang?: StringAttribute;\n dir?: StringAttribute;\n slot?: StringAttribute;\n role?: StringAttribute;\n style?: Value<string | CSSProperties | null>;\n hidden?: BooleanAttribute;\n inert?: BooleanAttribute;\n contenteditable?: Value<string | boolean | null>;\n draggable?: Value<string | boolean | null>;\n spellcheck?: Value<string | boolean | null>;\n tabindex?: Value<number | null>;\n accesskey?: StringAttribute;\n translate?: StringAttribute;\n onclick?: string | undefined;\n onload?: string | undefined;\n onerror?: string | undefined;\n}\n\ninterface HtmlBaseAttributes<T extends HTMLElement = HTMLElement> extends CommonAttributes<T> {\n href?: StringAttribute;\n target?: StringAttribute;\n rel?: StringAttribute;\n download?: Value<string | boolean | null>;\n property?: StringAttribute;\n itemprop?: StringAttribute;\n hreflang?: StringAttribute;\n as?: StringAttribute;\n integrity?: StringAttribute;\n async?: BooleanAttribute;\n defer?: BooleanAttribute;\n nonce?: StringAttribute;\n popover?: StringAttribute;\n popovertarget?: StringAttribute;\n popovertargetaction?: StringAttribute;\n srcdoc?: StringAttribute;\n fetchpriority?: StringAttribute;\n inputmode?: StringAttribute;\n autocapitalize?: StringAttribute;\n form?: StringAttribute;\n label?: StringAttribute;\n preload?: StringAttribute;\n playsinline?: BooleanAttribute;\n wrap?: StringAttribute;\n closedby?: StringAttribute;\n src?: StringAttribute;\n alt?: StringAttribute;\n width?: Value<string | number | null>;\n height?: Value<string | number | null>;\n type?: StringAttribute;\n name?: StringAttribute;\n value?: string | number | null | undefined;\n placeholder?: StringAttribute;\n for?: StringAttribute;\n charset?: StringAttribute;\n datetime?: StringAttribute;\n readonly?: BooleanAttribute;\n autofocus?: BooleanAttribute;\n required?: BooleanAttribute;\n disabled?: BooleanAttribute;\n checked?: boolean | null | undefined;\n selected?: BooleanAttribute;\n multiple?: BooleanAttribute;\n reversed?: BooleanAttribute;\n open?: BooleanAttribute;\n controls?: BooleanAttribute;\n muted?: BooleanAttribute;\n loop?: BooleanAttribute;\n autoplay?: BooleanAttribute;\n novalidate?: BooleanAttribute;\n formnovalidate?: BooleanAttribute;\n maxlength?: Value<number | null>;\n minlength?: Value<number | null>;\n min?: StringAttribute;\n max?: StringAttribute;\n step?: StringAttribute;\n start?: Value<string | number | null>;\n pattern?: StringAttribute;\n autocomplete?: StringAttribute;\n accept?: StringAttribute;\n \"accept-charset\"?: StringAttribute;\n \"http-equiv\"?: StringAttribute;\n content?: StringAttribute;\n media?: StringAttribute;\n method?: StringAttribute;\n action?: StringAttribute;\n enctype?: StringAttribute;\n rows?: Value<number | null>;\n cols?: Value<number | null>;\n colspan?: Value<number | null>;\n rowspan?: Value<number | null>;\n scope?: StringAttribute;\n cite?: StringAttribute;\n poster?: StringAttribute;\n loading?: StringAttribute;\n decoding?: StringAttribute;\n sizes?: StringAttribute;\n srcset?: StringAttribute;\n crossorigin?: StringAttribute;\n referrerpolicy?: StringAttribute;\n sandbox?: StringAttribute;\n allow?: StringAttribute;\n allowfullscreen?: BooleanAttribute;\n}\n\nexport type HTMLAttributes<T extends HTMLElement = HTMLElement> = HtmlBaseAttributes<T> &\n DataAria &\n EventProps<T, HTMLElementEventMap>;\ntype RawTextProps<T extends HTMLElement = HTMLElement> = Omit<\n HtmlBaseAttributes<T>,\n \"children\" | \"rawHtml\"\n> &\n DataAria &\n EventProps<T, HTMLElementEventMap> & {\n children?: never;\n rawHtml?: string | undefined;\n };\ntype IframeProps = Omit<HtmlBaseAttributes<HTMLIFrameElement>, \"children\" | \"rawHtml\"> &\n DataAria &\n EventProps<HTMLIFrameElement, HTMLElementEventMap> & {\n children?: never;\n rawHtml?: never;\n };\ntype InputBase = Omit<HtmlBaseAttributes<HTMLInputElement>, \"type\"> &\n DataAria &\n EventProps<HTMLInputElement, HTMLElementEventMap> & {\n defaultValue?: string | undefined;\n defaultChecked?: boolean | undefined;\n };\nexport type InputProps = InputBase &\n (\n | {\n type?: \"text\" | \"search\" | \"email\" | \"url\" | \"tel\" | \"password\" | undefined;\n modelValue?: Signal<string> | undefined;\n modelChecked?: never;\n }\n | {\n type: \"checkbox\";\n modelChecked?: Signal<boolean> | undefined;\n modelValue?: never;\n }\n | {\n type: \"radio\";\n name: string;\n value: string;\n modelValue?: Signal<string | null> | undefined;\n modelChecked?: never;\n }\n | {\n type: string;\n modelValue?: never;\n modelChecked?: never;\n }\n );\nexport type TextareaProps = HTMLAttributes<HTMLTextAreaElement> & {\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n};\nexport type SelectProps = HTMLAttributes<HTMLSelectElement> & {\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n};\n\ninterface SvgBaseAttributes<T extends SVGElement = SVGElement> extends CommonAttributes<T> {\n width?: DimensionAttribute;\n height?: DimensionAttribute;\n viewBox?: StringAttribute;\n preserveAspectRatio?: StringAttribute;\n gradientUnits?: StringAttribute;\n gradientTransform?: StringAttribute;\n markerWidth?: ScalarAttribute;\n markerHeight?: ScalarAttribute;\n refX?: ScalarAttribute;\n refY?: ScalarAttribute;\n \"xlink:href\"?: StringAttribute;\n \"xml:lang\"?: StringAttribute;\n xmlns?: StringAttribute;\n \"xmlns:xlink\"?: StringAttribute;\n href?: StringAttribute;\n focusable?: StringAttribute;\n \"stroke-width\"?: ScalarAttribute;\n \"fill-rule\"?: StringAttribute;\n \"clip-rule\"?: StringAttribute;\n \"stroke-linecap\"?: StringAttribute;\n \"stroke-linejoin\"?: StringAttribute;\n \"stop-color\"?: StringAttribute;\n \"stop-opacity\"?: ScalarAttribute;\n \"fill-opacity\"?: ScalarAttribute;\n \"stroke-dasharray\"?: StringAttribute;\n \"text-anchor\"?: StringAttribute;\n fill?: StringAttribute;\n stroke?: StringAttribute;\n d?: StringAttribute;\n x?: ScalarAttribute;\n y?: ScalarAttribute;\n x1?: ScalarAttribute;\n x2?: ScalarAttribute;\n y1?: ScalarAttribute;\n y2?: ScalarAttribute;\n cx?: ScalarAttribute;\n cy?: ScalarAttribute;\n r?: ScalarAttribute;\n rx?: ScalarAttribute;\n ry?: ScalarAttribute;\n points?: StringAttribute;\n transform?: StringAttribute;\n opacity?: ScalarAttribute;\n offset?: ScalarAttribute;\n id?: StringAttribute;\n}\n\nexport type SVGAttributes<T extends SVGElement = SVGElement> = SvgBaseAttributes<T> &\n DataAria &\n EventProps<T, SVGElementEventMap>;\ntype CustomProps = ReservedProps &\n EventProps<HTMLElement, GlobalEventHandlersEventMap> & {\n value?: string | null | undefined;\n checked?: null | undefined;\n [attribute: string]: StringAttribute | Child | Ref<Element> | AnyListener | undefined;\n };\n\ntype HtmlTag =\n | \"html\"\n | \"head\"\n | \"body\"\n | \"title\"\n | \"base\"\n | \"link\"\n | \"meta\"\n | \"style\"\n | \"script\"\n | \"div\"\n | \"span\"\n | \"p\"\n | \"a\"\n | \"br\"\n | \"hr\"\n | \"main\"\n | \"header\"\n | \"footer\"\n | \"nav\"\n | \"section\"\n | \"article\"\n | \"aside\"\n | \"search\"\n | \"hgroup\"\n | \"menu\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"ul\"\n | \"ol\"\n | \"li\"\n | \"dl\"\n | \"dt\"\n | \"dd\"\n | \"blockquote\"\n | \"pre\"\n | \"code\"\n | \"strong\"\n | \"em\"\n | \"b\"\n | \"i\"\n | \"small\"\n | \"mark\"\n | \"time\"\n | \"figure\"\n | \"figcaption\"\n | \"img\"\n | \"picture\"\n | \"source\"\n | \"video\"\n | \"audio\"\n | \"track\"\n | \"canvas\"\n | \"form\"\n | \"label\"\n | \"input\"\n | \"button\"\n | \"textarea\"\n | \"select\"\n | \"option\"\n | \"optgroup\"\n | \"fieldset\"\n | \"legend\"\n | \"output\"\n | \"progress\"\n | \"meter\"\n | \"datalist\"\n | \"table\"\n | \"caption\"\n | \"thead\"\n | \"tbody\"\n | \"tfoot\"\n | \"tr\"\n | \"th\"\n | \"td\"\n | \"col\"\n | \"colgroup\"\n | \"details\"\n | \"summary\"\n | \"dialog\"\n | \"template\"\n | \"slot\"\n | \"iframe\"\n | \"noscript\"\n | \"address\"\n | \"abbr\"\n | \"bdi\"\n | \"bdo\"\n | \"cite\"\n | \"data\"\n | \"del\"\n | \"dfn\"\n | \"ins\"\n | \"kbd\"\n | \"map\"\n | \"area\"\n | \"object\"\n | \"param\"\n | \"q\"\n | \"rp\"\n | \"rt\"\n | \"ruby\"\n | \"s\"\n | \"samp\"\n | \"sub\"\n | \"sup\"\n | \"u\"\n | \"var\"\n | \"wbr\"\n | \"embed\";\n\ntype SvgTag =\n | \"svg\"\n | \"g\"\n | \"path\"\n | \"circle\"\n | \"ellipse\"\n | \"rect\"\n | \"line\"\n | \"polyline\"\n | \"polygon\"\n | \"text\"\n | \"tspan\"\n | \"defs\"\n | \"symbol\"\n | \"use\"\n | \"clipPath\"\n | \"mask\"\n | \"linearGradient\"\n | \"radialGradient\"\n | \"stop\"\n | \"desc\"\n | \"foreignObject\"\n | \"pattern\"\n | \"filter\"\n | \"marker\"\n | \"image\";\n\n/** DOM element corresponding to an owned intrinsic tag. */\nexport type ElementForTag<Tag extends HtmlTag | SvgTag> = Tag extends HtmlTag\n ? Tag extends keyof HTMLElementTagNameMap\n ? HTMLElementTagNameMap[Tag]\n : HTMLElement\n : Tag extends keyof SVGElementTagNameMap\n ? SVGElementTagNameMap[Tag]\n : SVGElement;\n\nexport namespace JSX {\n export type Element = Description;\n export type HTMLAttributes<T extends HTMLElement = HTMLElement> =\n import(\"./jsx-types.js\").HTMLAttributes<T>;\n export type SVGAttributes<T extends SVGElement = SVGElement> =\n import(\"./jsx-types.js\").SVGAttributes<T>;\n export type CSSProperties = import(\"./jsx-types.js\").CSSProperties;\n export type ElementType =\n | string\n | Component<any>\n | typeof import(\"../island.js\").Island\n | typeof import(\"./description.js\").Fragment;\n export type IntrinsicElements = {\n [K in HtmlTag]: K extends \"input\"\n ? InputProps\n : K extends \"textarea\"\n ? TextareaProps\n : K extends \"select\"\n ? SelectProps\n : K extends \"iframe\"\n ? IframeProps\n : K extends \"script\" | \"style\"\n ? RawTextProps<ElementForTag<K>>\n : HTMLAttributes<ElementForTag<K>>;\n } & {\n [K in SvgTag]: SVGAttributes<ElementForTag<K>>;\n } & {\n [K in `${string}-${string}`]: CustomProps;\n };\n export interface IntrinsicAttributes {\n key?: Key | undefined;\n }\n export interface ElementChildrenAttribute {\n children: unknown;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"jsx-types.js","sourceRoot":"","sources":["../../src/zudo-react/jsx-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CSSProperties } from \"./style.js\";\nexport type { CSSProperties, CssProperty } from \"./style.js\";\nimport type { Child, Component, Description, Key } from \"./description.js\";\nimport type { Listener, Ref } from \"./index.js\";\nimport type { ReadonlySignal, Signal } from \"./reactive-types.js\";\n\ntype Value<T> = T | ReadonlySignal<T> | undefined;\ntype ScalarAttribute = Value<string | number | boolean | null>;\ntype DimensionAttribute = Value<string | number | null>;\ntype StringAttribute = Value<string | null>;\ntype BooleanAttribute = Value<boolean | null>;\n// The custom-name index must also accept every mapped listener under strict function variance.\ntype AnyListener = Listener<any>;\ntype EventProps<TEl extends Element, TMap extends Record<keyof TMap, Event>> = {\n [K in keyof TMap & string as `on:${K}` | `on:${K}:capture`]?: Listener<\n TMap[K] & { currentTarget: TEl }\n >;\n} & {\n [name: `on:${string}`]: AnyListener | undefined;\n};\ntype DataAria = {\n [name: `data-${string}`]: ScalarAttribute;\n} & {\n [name: `aria-${string}`]: ScalarAttribute;\n};\n\ninterface ReservedProps<T extends Element = Element> {\n children?: Child | undefined;\n key?: Key | undefined;\n ref?: Ref<T> | undefined;\n rawHtml?: Value<string | null>;\n}\n\ninterface CommonAttributes<T extends Element = Element> extends ReservedProps<T> {\n id?: StringAttribute;\n class?: StringAttribute;\n title?: StringAttribute;\n lang?: StringAttribute;\n dir?: StringAttribute;\n slot?: StringAttribute;\n role?: StringAttribute;\n style?: Value<string | CSSProperties | null>;\n hidden?: BooleanAttribute;\n inert?: BooleanAttribute;\n contenteditable?: Value<string | boolean | null>;\n draggable?: Value<string | boolean | null>;\n spellcheck?: Value<string | boolean | null>;\n tabindex?: Value<number | null>;\n accesskey?: StringAttribute;\n translate?: StringAttribute;\n onclick?: string | undefined;\n onload?: string | undefined;\n onerror?: string | undefined;\n}\n\ninterface HtmlBaseAttributes<T extends HTMLElement = HTMLElement> extends CommonAttributes<T> {\n href?: StringAttribute;\n target?: StringAttribute;\n rel?: StringAttribute;\n download?: Value<string | boolean | null>;\n property?: StringAttribute;\n itemprop?: StringAttribute;\n hreflang?: StringAttribute;\n as?: StringAttribute;\n integrity?: StringAttribute;\n async?: BooleanAttribute;\n defer?: BooleanAttribute;\n nonce?: StringAttribute;\n popover?: StringAttribute;\n popovertarget?: StringAttribute;\n popovertargetaction?: StringAttribute;\n srcdoc?: StringAttribute;\n fetchpriority?: StringAttribute;\n inputmode?: StringAttribute;\n autocapitalize?: StringAttribute;\n form?: StringAttribute;\n label?: StringAttribute;\n preload?: StringAttribute;\n playsinline?: BooleanAttribute;\n wrap?: StringAttribute;\n closedby?: StringAttribute;\n src?: StringAttribute;\n alt?: StringAttribute;\n width?: Value<string | number | null>;\n height?: Value<string | number | null>;\n type?: StringAttribute;\n name?: StringAttribute;\n value?: string | number | null | undefined;\n placeholder?: StringAttribute;\n for?: StringAttribute;\n charset?: StringAttribute;\n datetime?: StringAttribute;\n readonly?: BooleanAttribute;\n autofocus?: BooleanAttribute;\n required?: BooleanAttribute;\n disabled?: BooleanAttribute;\n checked?: boolean | null | undefined;\n selected?: BooleanAttribute;\n multiple?: BooleanAttribute;\n reversed?: BooleanAttribute;\n open?: BooleanAttribute;\n controls?: BooleanAttribute;\n muted?: BooleanAttribute;\n loop?: BooleanAttribute;\n autoplay?: BooleanAttribute;\n novalidate?: BooleanAttribute;\n formnovalidate?: BooleanAttribute;\n maxlength?: Value<number | null>;\n minlength?: Value<number | null>;\n min?: StringAttribute;\n max?: StringAttribute;\n step?: StringAttribute;\n start?: Value<string | number | null>;\n pattern?: StringAttribute;\n autocomplete?: StringAttribute;\n accept?: StringAttribute;\n \"accept-charset\"?: StringAttribute;\n \"http-equiv\"?: StringAttribute;\n content?: StringAttribute;\n media?: StringAttribute;\n method?: StringAttribute;\n action?: StringAttribute;\n enctype?: StringAttribute;\n rows?: Value<number | null>;\n cols?: Value<number | null>;\n colspan?: Value<number | null>;\n rowspan?: Value<number | null>;\n scope?: StringAttribute;\n cite?: StringAttribute;\n poster?: StringAttribute;\n loading?: StringAttribute;\n decoding?: StringAttribute;\n sizes?: StringAttribute;\n srcset?: StringAttribute;\n crossorigin?: StringAttribute;\n referrerpolicy?: StringAttribute;\n sandbox?: StringAttribute;\n allow?: StringAttribute;\n allowfullscreen?: BooleanAttribute;\n}\n\nexport type HTMLAttributes<T extends HTMLElement = HTMLElement> = HtmlBaseAttributes<T> &\n DataAria &\n EventProps<T, HTMLElementEventMap>;\ntype RawTextProps<T extends HTMLElement = HTMLElement> = Omit<\n HtmlBaseAttributes<T>,\n \"children\" | \"rawHtml\"\n> &\n DataAria &\n EventProps<T, HTMLElementEventMap> & {\n children?: never;\n rawHtml?: string | undefined;\n };\ntype IframeProps = Omit<HtmlBaseAttributes<HTMLIFrameElement>, \"children\" | \"rawHtml\"> &\n DataAria &\n EventProps<HTMLIFrameElement, HTMLElementEventMap> & {\n children?: never;\n rawHtml?: never;\n };\ntype InputBase = Omit<HtmlBaseAttributes<HTMLInputElement>, \"type\"> &\n DataAria &\n EventProps<HTMLInputElement, HTMLElementEventMap>;\n// Keep the event map explicit: Omit alone loses exact contextual event types in JSX.\nexport type InputProps = EventProps<HTMLInputElement, HTMLElementEventMap> &\n Omit<InputBase, \"value\"> &\n (\n | ({\n type?: \"text\" | \"search\" | \"email\" | \"url\" | \"tel\" | \"password\" | undefined;\n defaultChecked?: never;\n modelChecked?: never;\n } & (\n | {\n readonly: true;\n disabled?: BooleanAttribute;\n value?: string | number | null | ReadonlySignal<string>;\n modelValue?: never;\n defaultValue?: never;\n }\n | {\n disabled: true;\n readonly?: BooleanAttribute;\n value?: string | number | null | ReadonlySignal<string>;\n modelValue?: never;\n defaultValue?: never;\n }\n | {\n value?: string | number | null;\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n }\n ))\n | (Pick<InputBase, \"value\"> &\n (\n | {\n type: \"checkbox\";\n defaultValue?: never;\n defaultChecked?: boolean | undefined;\n modelChecked?: Signal<boolean> | undefined;\n modelValue?: never;\n }\n | {\n type: \"radio\";\n name: string;\n value: string;\n defaultValue?: never;\n defaultChecked?: boolean | undefined;\n modelValue: Signal<string | null>;\n modelChecked?: never;\n }\n | {\n type: \"radio\";\n defaultValue?: never;\n defaultChecked?: boolean | undefined;\n modelValue?: undefined;\n modelChecked?: never;\n }\n | {\n type: string;\n defaultValue?: never;\n defaultChecked?: never;\n modelValue?: never;\n modelChecked?: never;\n }\n ))\n );\nexport type TextareaProps = Omit<HTMLAttributes<HTMLTextAreaElement>, \"value\"> &\n (\n | {\n readonly: true;\n disabled?: BooleanAttribute;\n value?: string | number | null | ReadonlySignal<string>;\n modelValue?: never;\n defaultValue?: never;\n }\n | {\n disabled: true;\n readonly?: BooleanAttribute;\n value?: string | number | null | ReadonlySignal<string>;\n modelValue?: never;\n defaultValue?: never;\n }\n | {\n value?: string | number | null;\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n }\n );\nexport type SelectProps = HTMLAttributes<HTMLSelectElement> & {\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n};\n\ninterface SvgBaseAttributes<T extends SVGElement = SVGElement> extends CommonAttributes<T> {\n width?: DimensionAttribute;\n height?: DimensionAttribute;\n viewBox?: StringAttribute;\n preserveAspectRatio?: StringAttribute;\n gradientUnits?: StringAttribute;\n gradientTransform?: StringAttribute;\n markerWidth?: ScalarAttribute;\n markerHeight?: ScalarAttribute;\n refX?: ScalarAttribute;\n refY?: ScalarAttribute;\n \"xlink:href\"?: StringAttribute;\n \"xml:lang\"?: StringAttribute;\n xmlns?: StringAttribute;\n \"xmlns:xlink\"?: StringAttribute;\n href?: StringAttribute;\n focusable?: StringAttribute;\n \"stroke-width\"?: ScalarAttribute;\n \"fill-rule\"?: StringAttribute;\n \"clip-rule\"?: StringAttribute;\n \"stroke-linecap\"?: StringAttribute;\n \"stroke-linejoin\"?: StringAttribute;\n \"stop-color\"?: StringAttribute;\n \"stop-opacity\"?: ScalarAttribute;\n \"fill-opacity\"?: ScalarAttribute;\n \"stroke-dasharray\"?: StringAttribute;\n \"text-anchor\"?: StringAttribute;\n fill?: StringAttribute;\n stroke?: StringAttribute;\n d?: StringAttribute;\n x?: ScalarAttribute;\n y?: ScalarAttribute;\n x1?: ScalarAttribute;\n x2?: ScalarAttribute;\n y1?: ScalarAttribute;\n y2?: ScalarAttribute;\n cx?: ScalarAttribute;\n cy?: ScalarAttribute;\n r?: ScalarAttribute;\n rx?: ScalarAttribute;\n ry?: ScalarAttribute;\n points?: StringAttribute;\n transform?: StringAttribute;\n opacity?: ScalarAttribute;\n offset?: ScalarAttribute;\n id?: StringAttribute;\n}\n\nexport type SVGAttributes<T extends SVGElement = SVGElement> = SvgBaseAttributes<T> &\n DataAria &\n EventProps<T, SVGElementEventMap>;\ntype CustomProps = ReservedProps &\n EventProps<HTMLElement, GlobalEventHandlersEventMap> & {\n value?: string | null | undefined;\n checked?: null | undefined;\n [attribute: string]: StringAttribute | Child | Ref<Element> | AnyListener | undefined;\n };\n\ntype HtmlTag =\n | \"html\"\n | \"head\"\n | \"body\"\n | \"title\"\n | \"base\"\n | \"link\"\n | \"meta\"\n | \"style\"\n | \"script\"\n | \"div\"\n | \"span\"\n | \"p\"\n | \"a\"\n | \"br\"\n | \"hr\"\n | \"main\"\n | \"header\"\n | \"footer\"\n | \"nav\"\n | \"section\"\n | \"article\"\n | \"aside\"\n | \"search\"\n | \"hgroup\"\n | \"menu\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"ul\"\n | \"ol\"\n | \"li\"\n | \"dl\"\n | \"dt\"\n | \"dd\"\n | \"blockquote\"\n | \"pre\"\n | \"code\"\n | \"strong\"\n | \"em\"\n | \"b\"\n | \"i\"\n | \"small\"\n | \"mark\"\n | \"time\"\n | \"figure\"\n | \"figcaption\"\n | \"img\"\n | \"picture\"\n | \"source\"\n | \"video\"\n | \"audio\"\n | \"track\"\n | \"canvas\"\n | \"form\"\n | \"label\"\n | \"input\"\n | \"button\"\n | \"textarea\"\n | \"select\"\n | \"option\"\n | \"optgroup\"\n | \"fieldset\"\n | \"legend\"\n | \"output\"\n | \"progress\"\n | \"meter\"\n | \"datalist\"\n | \"table\"\n | \"caption\"\n | \"thead\"\n | \"tbody\"\n | \"tfoot\"\n | \"tr\"\n | \"th\"\n | \"td\"\n | \"col\"\n | \"colgroup\"\n | \"details\"\n | \"summary\"\n | \"dialog\"\n | \"template\"\n | \"slot\"\n | \"iframe\"\n | \"noscript\"\n | \"address\"\n | \"abbr\"\n | \"bdi\"\n | \"bdo\"\n | \"cite\"\n | \"data\"\n | \"del\"\n | \"dfn\"\n | \"ins\"\n | \"kbd\"\n | \"map\"\n | \"area\"\n | \"object\"\n | \"param\"\n | \"q\"\n | \"rp\"\n | \"rb\"\n | \"rt\"\n | \"ruby\"\n | \"s\"\n | \"samp\"\n | \"sub\"\n | \"sup\"\n | \"u\"\n | \"var\"\n | \"wbr\"\n | \"embed\";\n\ntype SvgTag =\n | \"svg\"\n | \"g\"\n | \"path\"\n | \"circle\"\n | \"ellipse\"\n | \"rect\"\n | \"line\"\n | \"polyline\"\n | \"polygon\"\n | \"text\"\n | \"tspan\"\n | \"defs\"\n | \"symbol\"\n | \"use\"\n | \"clipPath\"\n | \"mask\"\n | \"linearGradient\"\n | \"radialGradient\"\n | \"stop\"\n | \"desc\"\n | \"foreignObject\"\n | \"pattern\"\n | \"filter\"\n | \"marker\"\n | \"image\";\n\n/** DOM element corresponding to an owned intrinsic tag. */\nexport type ElementForTag<Tag extends HtmlTag | SvgTag> = Tag extends HtmlTag\n ? Tag extends keyof HTMLElementTagNameMap\n ? HTMLElementTagNameMap[Tag]\n : HTMLElement\n : Tag extends keyof SVGElementTagNameMap\n ? SVGElementTagNameMap[Tag]\n : SVGElement;\n\nexport namespace JSX {\n export type Element = Description;\n export type HTMLAttributes<T extends HTMLElement = HTMLElement> =\n import(\"./jsx-types.js\").HTMLAttributes<T>;\n export type SVGAttributes<T extends SVGElement = SVGElement> =\n import(\"./jsx-types.js\").SVGAttributes<T>;\n export type CSSProperties = import(\"./jsx-types.js\").CSSProperties;\n export type ElementType =\n | string\n | Component<any>\n | typeof import(\"../island.js\").Island\n | typeof import(\"./description.js\").Fragment;\n export type IntrinsicElements = {\n [K in HtmlTag]: K extends \"input\"\n ? InputProps\n : K extends \"textarea\"\n ? TextareaProps\n : K extends \"select\"\n ? SelectProps\n : K extends \"iframe\"\n ? IframeProps\n : K extends \"script\" | \"style\"\n ? RawTextProps<ElementForTag<K>>\n : HTMLAttributes<ElementForTag<K>>;\n } & {\n [K in SvgTag]: SVGAttributes<ElementForTag<K>>;\n } & {\n [K in `${string}-${string}`]: CustomProps;\n };\n export interface IntrinsicAttributes {\n key?: Key | undefined;\n }\n export interface ElementChildrenAttribute {\n children: unknown;\n }\n}\n"]}
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
// `zr:1:` occurrence: `noscript`/`xmp`/`noembed`/`noframes`/`plaintext` hosts,
|
|
16
16
|
// and payloads naming a RAWTEXT/RCDATA/script/PLAINTEXT element (its end tag may
|
|
17
17
|
// also close a raw-text ancestor) or a CDATA section (foreign content).
|
|
18
|
-
// `script`/`style` hosts
|
|
19
|
-
//
|
|
20
|
-
//
|
|
18
|
+
// `script`/`style` hosts keep the documented marker and closing-tag rules.
|
|
19
|
+
// Script additionally checks whether HTML tokenization consumes its renderer
|
|
20
|
+
// closing tag; style is RAWTEXT and has no script escape states.
|
|
21
21
|
const reservedAttributes = new Set(["data-zfb-island", "data-zfb-island-skip-ssr"]);
|
|
22
22
|
const rawTextHosts = new Set(["noscript", "xmp", "noembed", "noframes", "plaintext"]);
|
|
23
23
|
const unmodeled = /<\/?(?:script|style|textarea|title|xmp|iframe|noembed|noframes|noscript|plaintext)|<!\[cdata\[/i;
|
|
@@ -26,7 +26,8 @@ const nameEnd = /[\t\n\f\r />=]/;
|
|
|
26
26
|
const unquotedEnd = /[\t\n\f\r >]/;
|
|
27
27
|
export function rawHtmlReserved(payload, tag) {
|
|
28
28
|
if (tag === "script" || tag === "style")
|
|
29
|
-
return
|
|
29
|
+
return (/\x3c!--\/?zr:1:|data-zfb-island(?:-skip-ssr)?\s*=/.test(payload) ||
|
|
30
|
+
(tag === "script" && scriptConsumesClosingTag(payload)));
|
|
30
31
|
if (rawTextHosts.has(tag) || unmodeled.test(payload))
|
|
31
32
|
return /data-zfb-island|zr:1:/i.test(payload);
|
|
32
33
|
let i = 0;
|
|
@@ -80,6 +81,145 @@ export function rawHtmlReserved(payload, tag) {
|
|
|
80
81
|
i = end;
|
|
81
82
|
}
|
|
82
83
|
}
|
|
84
|
+
// Walk the WHATWG script-data escape states with the exact suffix emitted by
|
|
85
|
+
// the renderer. A `</script>` in double-escaped text only exits that state;
|
|
86
|
+
// it does not close the element. Incomplete names and `<!--` tails must be
|
|
87
|
+
// evaluated with the suffix attached, rather than classified by payload alone.
|
|
88
|
+
function scriptConsumesClosingTag(payload) {
|
|
89
|
+
// The HTML input stream normalizes CR and CRLF to LF before tokenization.
|
|
90
|
+
const source = `${payload.replace(/\r\n?/g, "\n")}</script>`;
|
|
91
|
+
let state = "data";
|
|
92
|
+
let endFallback = "data";
|
|
93
|
+
let buffer = "";
|
|
94
|
+
for (let i = 0; i < source.length; i++) {
|
|
95
|
+
const c = source[i];
|
|
96
|
+
const alpha = /[a-zA-Z]/.test(c);
|
|
97
|
+
const delimiter = c === "/" || c === ">" || /[\t\n\f ]/.test(c);
|
|
98
|
+
switch (state) {
|
|
99
|
+
case "data":
|
|
100
|
+
if (c === "<")
|
|
101
|
+
state = "less";
|
|
102
|
+
break;
|
|
103
|
+
case "less":
|
|
104
|
+
if (c === "/") {
|
|
105
|
+
endFallback = "data";
|
|
106
|
+
state = "endOpen";
|
|
107
|
+
}
|
|
108
|
+
else if (c === "!")
|
|
109
|
+
state = "escapeStart";
|
|
110
|
+
else {
|
|
111
|
+
state = "data";
|
|
112
|
+
i--;
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
case "escapeStart":
|
|
116
|
+
if (c === "-")
|
|
117
|
+
state = "escapeStartDash";
|
|
118
|
+
else {
|
|
119
|
+
state = "data";
|
|
120
|
+
i--;
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
case "escapeStartDash":
|
|
124
|
+
if (c === "-")
|
|
125
|
+
state = "escapedDashDash";
|
|
126
|
+
else {
|
|
127
|
+
state = "data";
|
|
128
|
+
i--;
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
case "escaped":
|
|
132
|
+
case "escapedDash":
|
|
133
|
+
case "escapedDashDash":
|
|
134
|
+
if (c === "<")
|
|
135
|
+
state = "escapedLess";
|
|
136
|
+
else if (state === "escapedDashDash" && c === ">")
|
|
137
|
+
state = "data";
|
|
138
|
+
else if (c === "-")
|
|
139
|
+
state = state === "escaped" ? "escapedDash" : "escapedDashDash";
|
|
140
|
+
else
|
|
141
|
+
state = "escaped";
|
|
142
|
+
break;
|
|
143
|
+
case "escapedLess":
|
|
144
|
+
if (c === "/") {
|
|
145
|
+
endFallback = "escaped";
|
|
146
|
+
state = "endOpen";
|
|
147
|
+
}
|
|
148
|
+
else if (alpha) {
|
|
149
|
+
buffer = "";
|
|
150
|
+
state = "doubleStart";
|
|
151
|
+
i--;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
state = "escaped";
|
|
155
|
+
i--;
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
case "endOpen":
|
|
159
|
+
if (alpha) {
|
|
160
|
+
buffer = "";
|
|
161
|
+
state = "endName";
|
|
162
|
+
i--;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
state = endFallback;
|
|
166
|
+
i--;
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
case "endName":
|
|
170
|
+
if (alpha)
|
|
171
|
+
buffer = buffer.length < 7 ? buffer + c.toLowerCase() : "!";
|
|
172
|
+
else if (delimiter && buffer === "script" && c === ">")
|
|
173
|
+
return false;
|
|
174
|
+
else {
|
|
175
|
+
state = endFallback;
|
|
176
|
+
i--;
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
case "doubleStart":
|
|
180
|
+
case "doubleEnd":
|
|
181
|
+
if (alpha)
|
|
182
|
+
buffer = buffer.length < 7 ? buffer + c.toLowerCase() : "!";
|
|
183
|
+
else if (delimiter)
|
|
184
|
+
state =
|
|
185
|
+
buffer === "script"
|
|
186
|
+
? state === "doubleStart"
|
|
187
|
+
? "double"
|
|
188
|
+
: "escaped"
|
|
189
|
+
: state === "doubleStart"
|
|
190
|
+
? "escaped"
|
|
191
|
+
: "double";
|
|
192
|
+
else {
|
|
193
|
+
state = state === "doubleStart" ? "escaped" : "double";
|
|
194
|
+
i--;
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
case "double":
|
|
198
|
+
case "doubleDash":
|
|
199
|
+
case "doubleDashDash":
|
|
200
|
+
if (c === "<")
|
|
201
|
+
state = "doubleLess";
|
|
202
|
+
else if (state === "doubleDashDash" && c === ">")
|
|
203
|
+
state = "data";
|
|
204
|
+
else if (c === "-")
|
|
205
|
+
state = state === "double" ? "doubleDash" : "doubleDashDash";
|
|
206
|
+
else
|
|
207
|
+
state = "double";
|
|
208
|
+
break;
|
|
209
|
+
case "doubleLess":
|
|
210
|
+
if (c === "/") {
|
|
211
|
+
buffer = "";
|
|
212
|
+
state = "doubleEnd";
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
state = "double";
|
|
216
|
+
i--;
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
83
223
|
// Returns the index just past the tag's `>`, or -1 when the tag is unterminated
|
|
84
224
|
// or carries a reserved attribute.
|
|
85
225
|
function tagEnd(s, j) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw-html.js","sourceRoot":"","sources":["../../src/zudo-react/raw-html.ts"],"names":[],"mappings":"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","sourcesContent":["// Reserved-boundary guard for rawHtml payloads, shared by the server renderer\n// and the client runtime so both accept exactly the same payloads.\n//\n// Rule: a payload is rejected when it can create a reserved boundary, decided\n// by an HTML-tokenizer pass (WHATWG tokenization, data state), not a text regex:\n// - a start or end tag carrying an attribute whose ASCII-lowercased name is\n// `data-zfb-island` or `data-zfb-island-skip-ssr` (any value form, or none);\n// - a comment, including a bogus `<!…>`, `<?…>` or `</…>` comment, whose data\n// contains `zr:1:` (hydration matches `zr:1:` / `/zr:1:` comment prefixes);\n// - a payload that ends inside a tag, comment or `</`, which would absorb the\n// renderer's closing boundary marker.\n// Marker-like text in character data or quoted attribute values is inert and\n// renders as written. The tokenizer models the data state only, so payloads it\n// cannot model take the textual rule, which rejects any `data-zfb-island` or\n// `zr:1:` occurrence: `noscript`/`xmp`/`noembed`/`noframes`/`plaintext` hosts,\n// and payloads naming a RAWTEXT/RCDATA/script/PLAINTEXT element (its end tag may\n// also close a raw-text ancestor) or a CDATA section (foreign content).\n// `script`/`style` hosts are raw text: their payload cannot form markup, and\n// they keep the documented contract (no protocol comment or island attribute\n// text; the callers reject `</script` / `</style`).\n\nconst reservedAttributes = new Set([\"data-zfb-island\", \"data-zfb-island-skip-ssr\"]);\nconst rawTextHosts = new Set([\"noscript\", \"xmp\", \"noembed\", \"noframes\", \"plaintext\"]);\nconst unmodeled =\n /<\\/?(?:script|style|textarea|title|xmp|iframe|noembed|noframes|noscript|plaintext)|<!\\[cdata\\[/i;\nconst space = /[\\t\\n\\f\\r ]/;\nconst nameEnd = /[\\t\\n\\f\\r />=]/;\nconst unquotedEnd = /[\\t\\n\\f\\r >]/;\n\nexport function rawHtmlReserved(payload: string, tag: string): boolean {\n if (tag === \"script\" || tag === \"style\")\n return /<!--\\/?zr:1:|data-zfb-island(?:-skip-ssr)?\\s*=/.test(payload);\n if (rawTextHosts.has(tag) || unmodeled.test(payload))\n return /data-zfb-island|zr:1:/i.test(payload);\n let i = 0;\n for (;;) {\n const lt = payload.indexOf(\"<\", i);\n if (lt < 0) return false;\n const c = payload[lt + 1];\n let start: number;\n if (c === undefined) return false;\n if (/[a-z]/i.test(c) || (c === \"/\" && /[a-z]/i.test(payload[lt + 2] ?? \"\"))) {\n i = tagEnd(payload, c === \"/\" ? lt + 2 : lt + 1);\n if (i < 0) return true;\n continue;\n }\n if (c === \"!\" && payload.startsWith(\"--\", lt + 2)) {\n start = lt + 4;\n if (payload[start] === \">\" || payload.startsWith(\"->\", start)) {\n i = start;\n continue;\n }\n const dashes = payload.indexOf(\"-->\", start);\n const bang = payload.indexOf(\"--!>\", start);\n const end = dashes < 0 || (bang >= 0 && bang < dashes) ? bang : dashes;\n if (end < 0 || payload.slice(start, end).includes(\"zr:1:\")) return true;\n i = end;\n continue;\n }\n if (c === \"/\") {\n // `</` followed by the closing marker's `<` would open a bogus comment.\n if (lt + 2 >= payload.length) return true;\n if (payload[lt + 2] === \">\") {\n i = lt + 3;\n continue;\n }\n start = lt + 2;\n } else if (c === \"!\" || c === \"?\") start = lt + 1;\n else {\n i = lt + 1;\n continue;\n }\n const end = payload.indexOf(\">\", start);\n if (end < 0 || payload.slice(start, end).includes(\"zr:1:\")) return true;\n i = end;\n }\n}\n\n// Returns the index just past the tag's `>`, or -1 when the tag is unterminated\n// or carries a reserved attribute.\nfunction tagEnd(s: string, j: number): number {\n const n = s.length;\n while (j < n && !space.test(s[j]!) && s[j] !== \"/\" && s[j] !== \">\") j++;\n for (;;) {\n while (j < n && (space.test(s[j]!) || s[j] === \"/\")) j++;\n if (j >= n) return -1;\n if (s[j] === \">\") return j + 1;\n const start = j++;\n while (j < n && !nameEnd.test(s[j]!)) j++;\n if (reservedAttributes.has(s.slice(start, j).toLowerCase())) return -1;\n while (j < n && space.test(s[j]!)) j++;\n if (s[j] !== \"=\") continue;\n j++;\n while (j < n && space.test(s[j]!)) j++;\n const quote = s[j];\n if (quote === '\"' || quote === \"'\") {\n const close = s.indexOf(quote, j + 1);\n if (close < 0) return -1;\n j = close + 1;\n } else while (j < n && !unquotedEnd.test(s[j]!)) j++;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"raw-html.js","sourceRoot":"","sources":["../../src/zudo-react/raw-html.ts"],"names":[],"mappings":"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","sourcesContent":["// Reserved-boundary guard for rawHtml payloads, shared by the server renderer\n// and the client runtime so both accept exactly the same payloads.\n//\n// Rule: a payload is rejected when it can create a reserved boundary, decided\n// by an HTML-tokenizer pass (WHATWG tokenization, data state), not a text regex:\n// - a start or end tag carrying an attribute whose ASCII-lowercased name is\n// `data-zfb-island` or `data-zfb-island-skip-ssr` (any value form, or none);\n// - a comment, including a bogus `<!…>`, `<?…>` or `</…>` comment, whose data\n// contains `zr:1:` (hydration matches `zr:1:` / `/zr:1:` comment prefixes);\n// - a payload that ends inside a tag, comment or `</`, which would absorb the\n// renderer's closing boundary marker.\n// Marker-like text in character data or quoted attribute values is inert and\n// renders as written. The tokenizer models the data state only, so payloads it\n// cannot model take the textual rule, which rejects any `data-zfb-island` or\n// `zr:1:` occurrence: `noscript`/`xmp`/`noembed`/`noframes`/`plaintext` hosts,\n// and payloads naming a RAWTEXT/RCDATA/script/PLAINTEXT element (its end tag may\n// also close a raw-text ancestor) or a CDATA section (foreign content).\n// `script`/`style` hosts keep the documented marker and closing-tag rules.\n// Script additionally checks whether HTML tokenization consumes its renderer\n// closing tag; style is RAWTEXT and has no script escape states.\n\nconst reservedAttributes = new Set([\"data-zfb-island\", \"data-zfb-island-skip-ssr\"]);\nconst rawTextHosts = new Set([\"noscript\", \"xmp\", \"noembed\", \"noframes\", \"plaintext\"]);\nconst unmodeled =\n /<\\/?(?:script|style|textarea|title|xmp|iframe|noembed|noframes|noscript|plaintext)|<!\\[cdata\\[/i;\nconst space = /[\\t\\n\\f\\r ]/;\nconst nameEnd = /[\\t\\n\\f\\r />=]/;\nconst unquotedEnd = /[\\t\\n\\f\\r >]/;\n\nexport function rawHtmlReserved(payload: string, tag: string): boolean {\n if (tag === \"script\" || tag === \"style\")\n return (\n /\\x3c!--\\/?zr:1:|data-zfb-island(?:-skip-ssr)?\\s*=/.test(payload) ||\n (tag === \"script\" && scriptConsumesClosingTag(payload))\n );\n if (rawTextHosts.has(tag) || unmodeled.test(payload))\n return /data-zfb-island|zr:1:/i.test(payload);\n let i = 0;\n for (;;) {\n const lt = payload.indexOf(\"<\", i);\n if (lt < 0) return false;\n const c = payload[lt + 1];\n let start: number;\n if (c === undefined) return false;\n if (/[a-z]/i.test(c) || (c === \"/\" && /[a-z]/i.test(payload[lt + 2] ?? \"\"))) {\n i = tagEnd(payload, c === \"/\" ? lt + 2 : lt + 1);\n if (i < 0) return true;\n continue;\n }\n if (c === \"!\" && payload.startsWith(\"--\", lt + 2)) {\n start = lt + 4;\n if (payload[start] === \">\" || payload.startsWith(\"->\", start)) {\n i = start;\n continue;\n }\n const dashes = payload.indexOf(\"-->\", start);\n const bang = payload.indexOf(\"--!>\", start);\n const end = dashes < 0 || (bang >= 0 && bang < dashes) ? bang : dashes;\n if (end < 0 || payload.slice(start, end).includes(\"zr:1:\")) return true;\n i = end;\n continue;\n }\n if (c === \"/\") {\n // `</` followed by the closing marker's `<` would open a bogus comment.\n if (lt + 2 >= payload.length) return true;\n if (payload[lt + 2] === \">\") {\n i = lt + 3;\n continue;\n }\n start = lt + 2;\n } else if (c === \"!\" || c === \"?\") start = lt + 1;\n else {\n i = lt + 1;\n continue;\n }\n const end = payload.indexOf(\">\", start);\n if (end < 0 || payload.slice(start, end).includes(\"zr:1:\")) return true;\n i = end;\n }\n}\n\n// Walk the WHATWG script-data escape states with the exact suffix emitted by\n// the renderer. A `</script>` in double-escaped text only exits that state;\n// it does not close the element. Incomplete names and `<!--` tails must be\n// evaluated with the suffix attached, rather than classified by payload alone.\nfunction scriptConsumesClosingTag(payload: string): boolean {\n // The HTML input stream normalizes CR and CRLF to LF before tokenization.\n const source = `${payload.replace(/\\r\\n?/g, \"\\n\")}</script>`;\n type State =\n | \"data\"\n | \"less\"\n | \"endOpen\"\n | \"endName\"\n | \"escapeStart\"\n | \"escapeStartDash\"\n | \"escaped\"\n | \"escapedDash\"\n | \"escapedDashDash\"\n | \"escapedLess\"\n | \"doubleStart\"\n | \"double\"\n | \"doubleDash\"\n | \"doubleDashDash\"\n | \"doubleLess\"\n | \"doubleEnd\";\n let state: State = \"data\";\n let endFallback: \"data\" | \"escaped\" = \"data\";\n let buffer = \"\";\n for (let i = 0; i < source.length; i++) {\n const c = source[i]!;\n const alpha = /[a-zA-Z]/.test(c);\n const delimiter = c === \"/\" || c === \">\" || /[\\t\\n\\f ]/.test(c);\n switch (state) {\n case \"data\":\n if (c === \"<\") state = \"less\";\n break;\n case \"less\":\n if (c === \"/\") {\n endFallback = \"data\";\n state = \"endOpen\";\n } else if (c === \"!\") state = \"escapeStart\";\n else {\n state = \"data\";\n i--;\n }\n break;\n case \"escapeStart\":\n if (c === \"-\") state = \"escapeStartDash\";\n else {\n state = \"data\";\n i--;\n }\n break;\n case \"escapeStartDash\":\n if (c === \"-\") state = \"escapedDashDash\";\n else {\n state = \"data\";\n i--;\n }\n break;\n case \"escaped\":\n case \"escapedDash\":\n case \"escapedDashDash\":\n if (c === \"<\") state = \"escapedLess\";\n else if (state === \"escapedDashDash\" && c === \">\") state = \"data\";\n else if (c === \"-\") state = state === \"escaped\" ? \"escapedDash\" : \"escapedDashDash\";\n else state = \"escaped\";\n break;\n case \"escapedLess\":\n if (c === \"/\") {\n endFallback = \"escaped\";\n state = \"endOpen\";\n } else if (alpha) {\n buffer = \"\";\n state = \"doubleStart\";\n i--;\n } else {\n state = \"escaped\";\n i--;\n }\n break;\n case \"endOpen\":\n if (alpha) {\n buffer = \"\";\n state = \"endName\";\n i--;\n } else {\n state = endFallback;\n i--;\n }\n break;\n case \"endName\":\n if (alpha) buffer = buffer.length < 7 ? buffer + c.toLowerCase() : \"!\";\n else if (delimiter && buffer === \"script\" && c === \">\") return false;\n else {\n state = endFallback;\n i--;\n }\n break;\n case \"doubleStart\":\n case \"doubleEnd\":\n if (alpha) buffer = buffer.length < 7 ? buffer + c.toLowerCase() : \"!\";\n else if (delimiter)\n state =\n buffer === \"script\"\n ? state === \"doubleStart\"\n ? \"double\"\n : \"escaped\"\n : state === \"doubleStart\"\n ? \"escaped\"\n : \"double\";\n else {\n state = state === \"doubleStart\" ? \"escaped\" : \"double\";\n i--;\n }\n break;\n case \"double\":\n case \"doubleDash\":\n case \"doubleDashDash\":\n if (c === \"<\") state = \"doubleLess\";\n else if (state === \"doubleDashDash\" && c === \">\") state = \"data\";\n else if (c === \"-\") state = state === \"double\" ? \"doubleDash\" : \"doubleDashDash\";\n else state = \"double\";\n break;\n case \"doubleLess\":\n if (c === \"/\") {\n buffer = \"\";\n state = \"doubleEnd\";\n } else {\n state = \"double\";\n i--;\n }\n break;\n }\n }\n return true;\n}\n\n// Returns the index just past the tag's `>`, or -1 when the tag is unterminated\n// or carries a reserved attribute.\nfunction tagEnd(s: string, j: number): number {\n const n = s.length;\n while (j < n && !space.test(s[j]!) && s[j] !== \"/\" && s[j] !== \">\") j++;\n for (;;) {\n while (j < n && (space.test(s[j]!) || s[j] === \"/\")) j++;\n if (j >= n) return -1;\n if (s[j] === \">\") return j + 1;\n const start = j++;\n while (j < n && !nameEnd.test(s[j]!)) j++;\n if (reservedAttributes.has(s.slice(start, j).toLowerCase())) return -1;\n while (j < n && space.test(s[j]!)) j++;\n if (s[j] !== \"=\") continue;\n j++;\n while (j < n && space.test(s[j]!)) j++;\n const quote = s[j];\n if (quote === '\"' || quote === \"'\") {\n const close = s.indexOf(quote, j + 1);\n if (close < 0) return -1;\n j = close + 1;\n } else while (j < n && !unquotedEnd.test(s[j]!)) j++;\n }\n}\n"]}
|
|
@@ -7,7 +7,7 @@ import { createScope, withScope } from "./scope.js";
|
|
|
7
7
|
import { emptyChildren, normalizeProps } from "./props-transport.js";
|
|
8
8
|
import { islandRootType } from "./island-root-type.js";
|
|
9
9
|
import { isShowType, isForType, showProps, forProps, keyed, keyPayload, view, } from "./structure.js";
|
|
10
|
-
import { attributeError, attributeText, booleanAttrs, commonAttrs, dialectSuggestion, emptyIframeChildren, formProps, htmlAttrs, htmlTags, isDialectProp, reactiveModelSuggestion, svgAttrs, svgTags, voidTags, } from "./vocabulary.js";
|
|
10
|
+
import { attributeError, attributeText, booleanAttrs, commonAttrs, dialectSuggestion, displayOnlyControl, emptyIframeChildren, formProps, htmlAttrs, htmlTags, isDialectProp, reactiveModelSuggestion, svgAttrs, svgTags, voidTags, } from "./vocabulary.js";
|
|
11
11
|
const words = (value) => new Set(value.split(" "));
|
|
12
12
|
const reserved = words("key ref children rawHtml");
|
|
13
13
|
const sensitive = words("noscript xmp iframe noembed noframes plaintext");
|
|
@@ -114,11 +114,16 @@ function attributes(tag, props, context, namespace, custom) {
|
|
|
114
114
|
!/^aria-[\w.-]+$/.test(name) &&
|
|
115
115
|
!/^on[a-z]+$/.test(name))
|
|
116
116
|
fail("ZR_ATTRIBUTE", context, `${tag}.${name}`);
|
|
117
|
+
const displayValue = name === "value" && reactive(original) && displayOnlyControl(tag, props);
|
|
118
|
+
if (displayValue && tag === "textarea")
|
|
119
|
+
continue;
|
|
117
120
|
const value = read(original);
|
|
118
|
-
if ((name === "value" || name === "checked") && reactive(original)) {
|
|
121
|
+
if ((name === "value" || name === "checked") && reactive(original) && !displayValue) {
|
|
119
122
|
const suggestion = reactiveModelSuggestion(tag, name, String(read(props.type) ?? "text"), custom);
|
|
120
123
|
fail("ZR_MODEL_UNSUPPORTED", context, `${tag}.${name} requires ${suggestion ?? "a static value"}`);
|
|
121
124
|
}
|
|
125
|
+
if (displayValue && typeof value !== "string")
|
|
126
|
+
fail("ZR_MODEL_VALUE", context, `${tag} requires string`);
|
|
122
127
|
if (/^on[a-z]/.test(name) && typeof value === "function")
|
|
123
128
|
fail("ZR_PROP_DIALECT", context, `${tag}.${name} must use on:${name.slice(2)}`, {
|
|
124
129
|
name,
|
|
@@ -304,7 +309,10 @@ function element(description, context, namespace, parent) {
|
|
|
304
309
|
tag === "select" ||
|
|
305
310
|
tag === "option"))
|
|
306
311
|
fail("ZR_RAW_HTML", context, tag);
|
|
307
|
-
|
|
312
|
+
const displayValue = reactive(source.value) && displayOnlyControl(tag, source);
|
|
313
|
+
if (tag === "textarea" &&
|
|
314
|
+
hasChildren &&
|
|
315
|
+
(hasValue || source.defaultValue !== undefined || displayValue))
|
|
308
316
|
fail("ZR_MODEL_CONFLICT", context, tag);
|
|
309
317
|
let content = "";
|
|
310
318
|
if (raw !== undefined) {
|
|
@@ -320,8 +328,9 @@ function element(description, context, namespace, parent) {
|
|
|
320
328
|
fail("ZR_RAW_HTML", context, `closing ${tag} in rawHtml`);
|
|
321
329
|
content = tag === "script" || tag === "style" ? payload : region(context, "h", () => payload);
|
|
322
330
|
}
|
|
323
|
-
else if (tag === "textarea" &&
|
|
324
|
-
|
|
331
|
+
else if (tag === "textarea" &&
|
|
332
|
+
(hasValue || source.defaultValue !== undefined || displayValue)) {
|
|
333
|
+
const value = read(source.modelValue ?? source.defaultValue ?? source.value);
|
|
325
334
|
if (typeof value !== "string")
|
|
326
335
|
fail("ZR_MODEL_VALUE", context, "textarea requires string");
|
|
327
336
|
content = `${value.startsWith("\n") ? "\n" : ""}${escapeText(value)}`;
|