@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.
@@ -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
- defaultValue?: string | undefined;
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
- modelValue?: Signal<string> | undefined;
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
- modelValue?: Signal<string | null> | undefined;
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 are raw text: their payload cannot form markup, and
19
- // they keep the documented contract (no protocol comment or island attribute
20
- // text; the callers reject `</script` / `</style`).
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 /<!--\/?zr:1:|data-zfb-island(?:-skip-ssr)?\s*=/.test(payload);
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
- if (tag === "textarea" && hasChildren && (hasValue || source.defaultValue !== undefined))
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" && (hasValue || source.defaultValue !== undefined)) {
324
- const value = read(source.modelValue ?? source.defaultValue);
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)}`;