Skip to content

Commit

Permalink
feat(jsx-runtime): identify keyed vnodes during jsx preprocessing
Browse files Browse the repository at this point in the history
  • Loading branch information
aidenybai committed Aug 16, 2021
1 parent 2fa3003 commit 121c610
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 21 deletions.
40 changes: 20 additions & 20 deletions src/jsx.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
import { m, VNode, VProps, VElement, VFlags, VDelta, className, style, svg } from './index';

// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace JSXInternal {
export type Element = VElement;
export interface IntrinsicElements {
[elemName: string]: VProps;
}
}

export type JSXVNode = VNode | number | boolean | undefined | null;
export type FC = (props?: VProps, children?: VNode[], delta?: VDelta) => VElement;

const h = (tag: string, props?: VProps, children?: VNode[], delta?: VDelta) => {
let type = VFlags.NO_CHILDREN;
if (children) {
const keyCache = new Set();
type = VFlags.ANY_CHILDREN;
if (children.some((child) => typeof child === 'string')) {
type = VFlags.ONLY_TEXT_CHILDREN;
}
}
if (props) {
if (props.className && typeof props.className === 'object') {
props.className = className(props.className);
for (const child of children) {
if (typeof child === 'object' && child.key) {
keyCache.add(child.key);
}
}
if (props.style && typeof props.style === 'object') {
props.style = style(props.style);
if (keyCache.size === children.length) {
type = VFlags.ONLY_KEYED_CHILDREN;
}
}
if (typeof props?.className === 'object') {
props.className = className(props.className);
}
if (typeof props?.style === 'object') {
props.style = style(props.style);
}

const vnode = m(tag, props, children, type, delta);
return !props?.ns && tag === 'svg' ? svg(vnode) : vnode;
return tag === 'svg' ? svg(vnode) : vnode;
};

const normalize = (children: JSXVNode[], normalizedChildren: VNode[]) => {
const normalizeChildren = (children: JSXVNode[], normalizedChildren: VNode[]) => {
if (!children || children.length === 0) return undefined;
for (const child of children) {
if (child !== undefined && child !== null && child !== false && child !== '') {
if (Array.isArray(child)) {
normalize(child, normalizedChildren);
normalizeChildren(child, normalizedChildren);
} else if (
typeof child === 'string' ||
typeof child === 'number' ||
Expand All @@ -55,16 +54,17 @@ const normalize = (children: JSXVNode[], normalizedChildren: VNode[]) => {
const jsx = (tag: string | FC, props?: VProps, ...children: JSXVNode[]): VNode => {
let delta: VDelta | undefined;
if (props) {
if (props.delta && (<VDelta>(<unknown>props.delta)).length > 0) {
delta = <VDelta>(<unknown>props.delta);
const rawDelta = <VDelta>(<unknown>props.delta);
if (props.delta && rawDelta.length > 0) {
delta = rawDelta;
delete props.delta;
}
if (props.children) {
children = <VNode[]>(<unknown>props.children);
delete props.children;
}
}
const normalizedChildren = normalize(children, []);
const normalizedChildren = normalizeChildren(children, []);
if (typeof tag === 'function') {
return tag(props, normalizedChildren, delta);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/m.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const svg = (vnode: VElement): VElement => {
};

export const ns = (tag: string, props: VProps, children?: VNode[]): void => {
props.ns = 'http://www.w3.org/2000/svg';
if (!props.ns) props.ns = 'http://www.w3.org/2000/svg';
if (children && tag !== 'foreignObject') {
for (const child of children) {
if (typeof child !== 'string' && child.props) ns(child.tag, child.props, child.children);
Expand Down

0 comments on commit 121c610

Please sign in to comment.