/*
* The following functions are lifted from Preact and
* modified.
*
* The MIT License (MIT)
*
* Copyright (c) 2015-present Jason Miller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import {
type Children,
type MaybeSignal,
type RefSignalSetter,
} from "./mod.js";
const IS_NON_DIMENSIONAL =
/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
export const setStyle = (
node: ElementCSSInlineStyle,
key: any,
value: string | number | null | undefined,
): void => {
if (key[0] == "-") {
node.style.setProperty(key, `${value}`);
} else {
node.style[key] =
value == null
? ""
: typeof value != "number" || IS_NON_DIMENSIONAL.test(key)
? `${value}`
: `${value}px`;
}
};
export const setAttr = (
node: any,
name: string,
value: unknown,
heuristic?: boolean,
): void => {
const removeAttribute =
value == null || (value === false && !name.includes("-"));
if (name.startsWith("prop:")) {
node[name.slice(5)] = value;
} else if (name.startsWith("attr:")) {
name = name.slice(5);
if (!removeAttribute) {
node.setAttribute(name, value);
} else {
node.removeAttribute(name);
}
} else if (!["innerHTML", "outerHTML"].includes(name)) {
if (
![
// Default value in browsers is `-1` and an empty string is
// cast to `0` instead
"tabIndex",
"role",
...(heuristic
? [
"width",
"height",
"href",
"list",
"form",
"download",
"rowSpan",
"colSpan",
]
: []),
].includes(name) &&
name in node
) {
try {
node[name] = value;
return;
} catch (e) {}
}
// aria- and data- attributes have no boolean representation.
// A `false` value is different from the attribute not being
// present, so we can't remove it. For non-boolean aria
// attributes we could treat false as a removal, but the
// amount of exceptions would cost too many bytes. On top of
// that other frameworks generally stringify `false`.
if (typeof value == "function") {
// never serialize functions as attribute values
} else if (!removeAttribute) {
node.setAttribute(name, value);
} else {
node.removeAttribute(name);
}
}
};
export interface DomIntrinsicElements {
// HTML
a: HtmlProps & DomEventProps;
abbr: HtmlProps & DomEventProps;
address: HtmlProps & DomEventProps;
area: HtmlProps & DomEventProps;
article: HtmlProps & DomEventProps;
aside: HtmlProps & DomEventProps;
audio: HtmlProps & DomEventProps;
b: HtmlProps & DomEventProps;
base: HtmlProps & DomEventProps;
bdi: HtmlProps & DomEventProps;
bdo: HtmlProps & DomEventProps;
big: HtmlProps & DomEventProps;
blockquote: HtmlProps & DomEventProps;
body: HtmlProps & DomEventProps;
br: HtmlProps & DomEventProps;
button: HtmlProps & DomEventProps;
canvas: HtmlProps & DomEventProps;
caption: HtmlProps &
DomEventProps;
cite: HtmlProps & DomEventProps;
code: HtmlProps & DomEventProps;
col: HtmlProps & DomEventProps;
colgroup: HtmlProps & DomEventProps;
data: HtmlProps & DomEventProps;
datalist: HtmlProps & DomEventProps;
dd: HtmlProps & DomEventProps;
del: HtmlProps & DomEventProps;
details: HtmlProps & DomEventProps;
dfn: HtmlProps & DomEventProps;
dialog: HtmlProps & DomEventProps;
div: HtmlProps & DomEventProps;
dl: HtmlProps & DomEventProps;
dt: HtmlProps & DomEventProps;
em: HtmlProps & DomEventProps;
embed: HtmlProps & DomEventProps;
fieldset: HtmlProps & DomEventProps;
figcaption: HtmlProps & DomEventProps;
figure: HtmlProps & DomEventProps;
footer: HtmlProps & DomEventProps;
form: HtmlProps & DomEventProps;
h1: HtmlProps & DomEventProps;
h2: HtmlProps & DomEventProps;
h3: HtmlProps & DomEventProps;
h4: HtmlProps & DomEventProps;
h5: HtmlProps & DomEventProps;
h6: HtmlProps & DomEventProps;
head: HtmlProps & DomEventProps;
header: HtmlProps & DomEventProps;
hgroup: HtmlProps & DomEventProps;
hr: HtmlProps & DomEventProps;
html: HtmlProps & DomEventProps;
i: HtmlProps & DomEventProps;
iframe: HtmlProps & DomEventProps;
img: HtmlProps & DomEventProps;
input: HtmlProps & DomEventProps;
ins: HtmlProps & DomEventProps;
kbd: HtmlProps & DomEventProps;
keygen: HtmlProps & DomEventProps;
label: HtmlProps & DomEventProps;
legend: HtmlProps & DomEventProps;
li: HtmlProps & DomEventProps;
link: HtmlProps & DomEventProps;
main: HtmlProps & DomEventProps;
map: HtmlProps & DomEventProps;
mark: HtmlProps & DomEventProps;
marquee: HtmlProps & DomEventProps;
menu: HtmlProps & DomEventProps;
menuitem: HtmlProps & DomEventProps;
meta: HtmlProps & DomEventProps;
meter: HtmlProps & DomEventProps;
nav: HtmlProps & DomEventProps;
noscript: HtmlProps & DomEventProps;
object: HtmlProps & DomEventProps;
ol: HtmlProps & DomEventProps;
optgroup: HtmlProps & DomEventProps;
option: HtmlProps & DomEventProps;
output: HtmlProps & DomEventProps;
p: HtmlProps & DomEventProps;
param: HtmlProps & DomEventProps;
picture: HtmlProps & DomEventProps;
pre: HtmlProps & DomEventProps;
progress: HtmlProps & DomEventProps;
q: HtmlProps & DomEventProps;
rp: HtmlProps & DomEventProps;
rt: HtmlProps & DomEventProps;
ruby: HtmlProps & DomEventProps;
s: HtmlProps & DomEventProps;
samp: HtmlProps & DomEventProps;
script: HtmlProps & DomEventProps;
section: HtmlProps & DomEventProps;
select: HtmlProps & DomEventProps;
slot: HtmlProps & DomEventProps;
small: HtmlProps & DomEventProps;
source: HtmlProps & DomEventProps;
span: HtmlProps & DomEventProps;
strong: HtmlProps & DomEventProps;
style: HtmlProps & DomEventProps;
sub: HtmlProps & DomEventProps;
summary: HtmlProps & DomEventProps;
sup: HtmlProps & DomEventProps;
table: HtmlProps & DomEventProps;
tbody: HtmlProps &
DomEventProps;
td: HtmlProps & DomEventProps;
textarea: HtmlProps & DomEventProps;
tfoot: HtmlProps &
DomEventProps;
th: HtmlProps & DomEventProps;
thead: HtmlProps &
DomEventProps;
time: HtmlProps & DomEventProps;
title: HtmlProps & DomEventProps;
tr: HtmlProps & DomEventProps;
track: HtmlProps & DomEventProps;
u: HtmlProps & DomEventProps;
ul: HtmlProps & DomEventProps;
var: HtmlProps & DomEventProps;
video: HtmlProps & DomEventProps;
wbr: HtmlProps & DomEventProps;
//SVG
svg: SvgProps & DomEventProps;
animate: SvgProps & DomEventProps;
circle: SvgProps & DomEventProps;
animateTransform: SvgProps &
DomEventProps;
clipPath: SvgProps & DomEventProps;
defs: SvgProps & DomEventProps;
desc: SvgProps & DomEventProps;
ellipse: SvgProps & DomEventProps;
feBlend: SvgProps & DomEventProps;
feColorMatrix: SvgProps &
DomEventProps;
feComponentTransfer: SvgProps &
DomEventProps;
feComposite: SvgProps &
DomEventProps;
feConvolveMatrix: SvgProps