Comparing version 3.5.1 to 3.6.0
@@ -1,6 +0,6 @@ | ||
import { VNode, VNodeData } from "./vnode"; | ||
export declare type VNodes = VNode[]; | ||
export declare type VNodeChildElement = VNode | string | number | String | Number | undefined | null; | ||
export declare type ArrayOrElement<T> = T | T[]; | ||
export declare type VNodeChildren = ArrayOrElement<VNodeChildElement>; | ||
import { VNode, VNodeData } from "./vnode.js"; | ||
export type VNodes = VNode[]; | ||
export type VNodeChildElement = VNode | string | number | String | Number | undefined | null; | ||
export type ArrayOrElement<T> = T | T[]; | ||
export type VNodeChildren = ArrayOrElement<VNodeChildElement>; | ||
export declare function addNS(data: any, children: Array<VNode | string> | undefined, sel: string | undefined): void; | ||
@@ -7,0 +7,0 @@ export declare function h(sel: string): VNode; |
@@ -1,3 +0,3 @@ | ||
import { vnode } from "./vnode"; | ||
import * as is from "./is"; | ||
import { vnode } from "./vnode.js"; | ||
import * as is from "./is.js"; | ||
export function addNS(data, children, sel) { | ||
@@ -56,5 +56,3 @@ data.ns = "http://www.w3.org/2000/svg"; | ||
} | ||
if (sel[0] === "s" && | ||
sel[1] === "v" && | ||
sel[2] === "g" && | ||
if (sel.startsWith("svg") && | ||
(sel.length === 3 || sel[3] === "." || sel[3] === "#")) { | ||
@@ -61,0 +59,0 @@ addNS(data, children, sel); |
@@ -1,2 +0,2 @@ | ||
import { VNode } from "../vnode"; | ||
import { VNode } from "../vnode.js"; | ||
export interface AttachData { | ||
@@ -3,0 +3,0 @@ [key: string]: any; |
@@ -1,12 +0,12 @@ | ||
import { VNode } from "./vnode"; | ||
export declare type PreHook = () => any; | ||
export declare type InitHook = (vNode: VNode) => any; | ||
export declare type CreateHook = (emptyVNode: VNode, vNode: VNode) => any; | ||
export declare type InsertHook = (vNode: VNode) => any; | ||
export declare type PrePatchHook = (oldVNode: VNode, vNode: VNode) => any; | ||
export declare type UpdateHook = (oldVNode: VNode, vNode: VNode) => any; | ||
export declare type PostPatchHook = (oldVNode: VNode, vNode: VNode) => any; | ||
export declare type DestroyHook = (vNode: VNode) => any; | ||
export declare type RemoveHook = (vNode: VNode, removeCallback: () => void) => any; | ||
export declare type PostHook = () => any; | ||
import { VNode } from "./vnode.js"; | ||
export type PreHook = () => any; | ||
export type InitHook = (vNode: VNode) => any; | ||
export type CreateHook = (emptyVNode: VNode, vNode: VNode) => any; | ||
export type InsertHook = (vNode: VNode) => any; | ||
export type PrePatchHook = (oldVNode: VNode, vNode: VNode) => any; | ||
export type UpdateHook = (oldVNode: VNode, vNode: VNode) => any; | ||
export type PostPatchHook = (oldVNode: VNode, vNode: VNode) => any; | ||
export type DestroyHook = (vNode: VNode) => any; | ||
export type RemoveHook = (vNode: VNode, removeCallback: () => void) => any; | ||
export type PostHook = () => any; | ||
export interface Hooks { | ||
@@ -13,0 +13,0 @@ pre?: PreHook; |
@@ -112,4 +112,4 @@ function createElement(tagName, options) { | ||
isComment, | ||
isDocumentFragment, | ||
isDocumentFragment | ||
}; | ||
//# sourceMappingURL=htmldomapi.js.map |
@@ -1,17 +0,30 @@ | ||
export { DOMAPI, htmlDomApi } from "./htmldomapi"; | ||
export { init, Options } from "./init"; | ||
export { ThunkData, Thunk, ThunkFn, thunk } from "./thunk"; | ||
export { Key, VNode, VNodeData, vnode } from "./vnode"; | ||
export { AttachData, attachTo } from "./helpers/attachto"; | ||
export { array, primitive } from "./is"; | ||
export { toVNode } from "./tovnode"; | ||
export { VNodes, VNodeChildElement, ArrayOrElement, VNodeChildren, h, fragment, } from "./h"; | ||
export * from "./hooks"; | ||
export { Module } from "./modules/module"; | ||
export { Attrs, attributesModule } from "./modules/attributes"; | ||
export { Classes, classModule } from "./modules/class"; | ||
export { Dataset, datasetModule } from "./modules/dataset"; | ||
export { On, eventListenersModule } from "./modules/eventlisteners"; | ||
export { Props, propsModule } from "./modules/props"; | ||
export { VNodeStyle, styleModule } from "./modules/style"; | ||
export { JsxVNodeChild, JsxVNodeChildren, FunctionComponent, jsx, Fragment, } from "./jsx"; | ||
export { htmlDomApi } from "./htmldomapi.js"; | ||
export { init } from "./init.js"; | ||
export { thunk } from "./thunk.js"; | ||
export { vnode } from "./vnode.js"; | ||
export type { DOMAPI } from "./htmldomapi.js"; | ||
export type { Options } from "./init.js"; | ||
export type { ThunkData, Thunk, ThunkFn } from "./thunk.js"; | ||
export type { Key, VNode, VNodeData } from "./vnode.js"; | ||
export { attachTo } from "./helpers/attachto.js"; | ||
export { array, primitive } from "./is.js"; | ||
export { toVNode } from "./tovnode.js"; | ||
export { h, fragment } from "./h.js"; | ||
export type { AttachData } from "./helpers/attachto.js"; | ||
export type { VNodes, VNodeChildElement, ArrayOrElement, VNodeChildren } from "./h.js"; | ||
export * from "./hooks.js"; | ||
export type { Module } from "./modules/module.js"; | ||
export { attributesModule } from "./modules/attributes.js"; | ||
export { classModule } from "./modules/class.js"; | ||
export { datasetModule } from "./modules/dataset.js"; | ||
export { eventListenersModule } from "./modules/eventlisteners.js"; | ||
export { propsModule } from "./modules/props.js"; | ||
export { styleModule } from "./modules/style.js"; | ||
export type { Attrs } from "./modules/attributes.js"; | ||
export type { Classes } from "./modules/class.js"; | ||
export type { Dataset } from "./modules/dataset.js"; | ||
export type { On } from "./modules/eventlisteners.js"; | ||
export type { Props } from "./modules/props.js"; | ||
export type { VNodeStyle } from "./modules/style.js"; | ||
export { jsx, Fragment } from "./jsx.js"; | ||
export type { JsxVNodeChild, JsxVNodeChildren, FunctionComponent } from "./jsx.js"; |
@@ -1,22 +0,21 @@ | ||
// core | ||
export { htmlDomApi } from "./htmldomapi"; | ||
export { init } from "./init"; | ||
export { thunk } from "./thunk"; | ||
export { vnode } from "./vnode"; | ||
export { htmlDomApi } from "./htmldomapi.js"; | ||
export { init } from "./init.js"; | ||
export { thunk } from "./thunk.js"; | ||
export { vnode } from "./vnode.js"; | ||
// helpers | ||
export { attachTo } from "./helpers/attachto"; | ||
export { array, primitive } from "./is"; | ||
export { toVNode } from "./tovnode"; | ||
export { h, fragment, } from "./h"; | ||
export { attachTo } from "./helpers/attachto.js"; | ||
export { array, primitive } from "./is.js"; | ||
export { toVNode } from "./tovnode.js"; | ||
export { h, fragment } from "./h.js"; | ||
// types | ||
export * from "./hooks"; | ||
export * from "./hooks.js"; | ||
// modules | ||
export { attributesModule } from "./modules/attributes"; | ||
export { classModule } from "./modules/class"; | ||
export { datasetModule } from "./modules/dataset"; | ||
export { eventListenersModule } from "./modules/eventlisteners"; | ||
export { propsModule } from "./modules/props"; | ||
export { styleModule } from "./modules/style"; | ||
export { attributesModule } from "./modules/attributes.js"; | ||
export { classModule } from "./modules/class.js"; | ||
export { datasetModule } from "./modules/dataset.js"; | ||
export { eventListenersModule } from "./modules/eventlisteners.js"; | ||
export { propsModule } from "./modules/props.js"; | ||
export { styleModule } from "./modules/style.js"; | ||
// JSX | ||
export { jsx, Fragment, } from "./jsx"; | ||
export { jsx, Fragment } from "./jsx.js"; | ||
//# sourceMappingURL=index.js.map |
@@ -1,5 +0,5 @@ | ||
import { Module } from "./modules/module"; | ||
import { VNode } from "./vnode"; | ||
import { DOMAPI } from "./htmldomapi"; | ||
export declare type Options = { | ||
import { Module } from "./modules/module.js"; | ||
import { VNode } from "./vnode.js"; | ||
import { DOMAPI } from "./htmldomapi.js"; | ||
export type Options = { | ||
experimental?: { | ||
@@ -6,0 +6,0 @@ fragments?: boolean; |
@@ -1,4 +0,4 @@ | ||
import { vnode } from "./vnode"; | ||
import * as is from "./is"; | ||
import { htmlDomApi } from "./htmldomapi"; | ||
import { vnode } from "./vnode.js"; | ||
import * as is from "./is.js"; | ||
import { htmlDomApi } from "./htmldomapi.js"; | ||
function isUndef(s) { | ||
@@ -50,3 +50,3 @@ return s === undefined; | ||
"pre", | ||
"post", | ||
"post" | ||
]; | ||
@@ -60,3 +60,3 @@ export function init(modules, domApi, options) { | ||
pre: [], | ||
post: [], | ||
post: [] | ||
}; | ||
@@ -87,3 +87,5 @@ const api = domApi !== undefined ? domApi : htmlDomApi; | ||
const parent = api.parentNode(childElm); | ||
api.removeChild(parent, childElm); | ||
if (parent !== null) { | ||
api.removeChild(parent, childElm); | ||
} | ||
} | ||
@@ -111,2 +113,6 @@ }; | ||
} | ||
else if (sel === "") { | ||
// textNode has no selector | ||
vnode.elm = api.createTextNode(vnode.text); | ||
} | ||
else if (sel !== undefined) { | ||
@@ -131,2 +137,7 @@ // Parse selector | ||
cbs.create[i](emptyNode, vnode); | ||
if (is.primitive(vnode.text) && | ||
(!is.array(children) || children.length === 0)) { | ||
// allow h1 and similar nodes to be created w/ text and empty child list | ||
api.appendChild(elm, api.createTextNode(vnode.text)); | ||
} | ||
if (is.array(children)) { | ||
@@ -140,5 +151,2 @@ for (i = 0; i < children.length; ++i) { | ||
} | ||
else if (is.primitive(vnode.text)) { | ||
api.appendChild(elm, api.createTextNode(vnode.text)); | ||
} | ||
const hook = vnode.data.hook; | ||
@@ -145,0 +153,0 @@ if (isDef(hook)) { |
@@ -1,12 +0,7 @@ | ||
import { Key, VNode, VNodeData } from "./vnode"; | ||
import { ArrayOrElement } from "./h"; | ||
declare namespace JSXInternal { | ||
type Element = VNode; | ||
interface IntrinsicElements { | ||
[elemName: string]: VNodeData; | ||
} | ||
} | ||
export declare type JsxVNodeChild = VNode | string | number | boolean | undefined | null; | ||
export declare type JsxVNodeChildren = ArrayOrElement<JsxVNodeChild>; | ||
export declare type FunctionComponent = (props: { | ||
import { Key, VNode, VNodeData } from "./vnode.js"; | ||
import { ArrayOrElement } from "./h.js"; | ||
import { Props } from "./modules/props.js"; | ||
export type JsxVNodeChild = VNode | string | number | boolean | undefined | null; | ||
export type JsxVNodeChildren = ArrayOrElement<JsxVNodeChild>; | ||
export type FunctionComponent = (props: { | ||
[prop: string]: any; | ||
@@ -23,4 +18,21 @@ } | null, children?: VNode[]) => VNode; | ||
export declare namespace jsx { | ||
export import JSX = JSXInternal; | ||
type Element = VNode; | ||
type IfEquals<X, Y, Output> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? Output : never; | ||
type WritableKeys<T> = { | ||
[P in keyof T]-?: IfEquals<{ | ||
[Q in P]: T[P]; | ||
}, { | ||
-readonly [Q in P]: T[P]; | ||
}, P>; | ||
}[keyof T]; | ||
type ElementProperties<T> = { | ||
[Property in WritableKeys<T> as T[Property] extends string | number | null | undefined ? Property : never]?: T[Property]; | ||
}; | ||
type VNodeProps<T> = ElementProperties<T> & Props; | ||
type HtmlElements = { | ||
[Property in keyof HTMLElementTagNameMap]: VNodeData<VNodeProps<HTMLElementTagNameMap[Property]>>; | ||
}; | ||
interface IntrinsicElements extends HtmlElements { | ||
[elemName: string]: VNodeData; | ||
} | ||
} | ||
export {}; |
@@ -1,3 +0,2 @@ | ||
/* eslint-disable @typescript-eslint/no-namespace, import/export */ | ||
import { vnode } from "./vnode"; | ||
import { vnode } from "./vnode.js"; | ||
import { h } from "./h"; | ||
@@ -60,4 +59,2 @@ export function Fragment(data, ...children) { | ||
} | ||
(function (jsx) { | ||
})(jsx || (jsx = {})); | ||
//# sourceMappingURL=jsx.js.map |
@@ -1,3 +0,3 @@ | ||
import { Module } from "./module"; | ||
export declare type Attrs = Record<string, string | number | boolean>; | ||
import { Module } from "./module.js"; | ||
export type Attrs = Record<string, string | number | boolean>; | ||
export declare const attributesModule: Module; |
const xlinkNS = "http://www.w3.org/1999/xlink"; | ||
const xmlnsNS = "http://www.w3.org/2000/xmlns/"; | ||
const xmlNS = "http://www.w3.org/XML/1998/namespace"; | ||
const colonChar = 58; | ||
const xChar = 120; | ||
const mChar = 109; | ||
function updateAttrs(oldVnode, vnode) { | ||
@@ -36,4 +38,6 @@ let key; | ||
else if (key.charCodeAt(5) === colonChar) { | ||
// Assume xlink namespace | ||
elm.setAttributeNS(xlinkNS, key, cur); | ||
// Assume 'xmlns' or 'xlink' namespace | ||
key.charCodeAt(1) === mChar | ||
? elm.setAttributeNS(xmlnsNS, key, cur) | ||
: elm.setAttributeNS(xlinkNS, key, cur); | ||
} | ||
@@ -57,4 +61,4 @@ else { | ||
create: updateAttrs, | ||
update: updateAttrs, | ||
update: updateAttrs | ||
}; | ||
//# sourceMappingURL=attributes.js.map |
@@ -1,3 +0,3 @@ | ||
import { Module } from "./module"; | ||
export declare type Classes = Record<string, boolean>; | ||
import { Module } from "./module.js"; | ||
export type Classes = Record<string, boolean>; | ||
export declare const classModule: Module; |
@@ -1,3 +0,3 @@ | ||
import { Module } from "./module"; | ||
export declare type Dataset = Record<string, string>; | ||
import { Module } from "./module.js"; | ||
export type Dataset = Record<string, string>; | ||
export declare const datasetModule: Module; |
@@ -15,3 +15,3 @@ const CAPS_REGEX = /[A-Z]/g; | ||
for (key in oldDataset) { | ||
if (!dataset[key]) { | ||
if (!(key in dataset)) { | ||
if (d) { | ||
@@ -40,4 +40,4 @@ if (key in d) { | ||
create: updateDataset, | ||
update: updateDataset, | ||
update: updateDataset | ||
}; | ||
//# sourceMappingURL=dataset.js.map |
@@ -1,5 +0,5 @@ | ||
import { VNode } from "../vnode"; | ||
import { Module } from "./module"; | ||
declare type Listener<T> = (this: VNode, ev: T, vnode: VNode) => void; | ||
export declare type On = { | ||
import { VNode } from "../vnode.js"; | ||
import { Module } from "./module.js"; | ||
type Listener<T> = (this: VNode, ev: T, vnode: VNode) => void; | ||
export type On = { | ||
[N in keyof HTMLElementEventMap]?: Listener<HTMLElementEventMap[N]> | Array<Listener<HTMLElementEventMap[N]>>; | ||
@@ -6,0 +6,0 @@ } & { |
@@ -82,4 +82,4 @@ function invokeHandler(handler, vnode, event) { | ||
update: updateEventListeners, | ||
destroy: updateEventListeners, | ||
destroy: updateEventListeners | ||
}; | ||
//# sourceMappingURL=eventlisteners.js.map |
@@ -1,3 +0,3 @@ | ||
import { PreHook, CreateHook, UpdateHook, DestroyHook, RemoveHook, PostHook } from "../hooks"; | ||
export declare type Module = Partial<{ | ||
import { PreHook, CreateHook, UpdateHook, DestroyHook, RemoveHook, PostHook } from "../hooks.js"; | ||
export type Module = Partial<{ | ||
pre: PreHook; | ||
@@ -4,0 +4,0 @@ create: CreateHook; |
@@ -1,3 +0,3 @@ | ||
import { Module } from "./module"; | ||
export declare type Props = Record<string, any>; | ||
import { Module } from "./module.js"; | ||
export type Props = Record<string, any>; | ||
export declare const propsModule: Module; |
@@ -1,6 +0,7 @@ | ||
import { Module } from "./module"; | ||
export declare type VNodeStyle = Record<string, string> & { | ||
delayed?: Record<string, string>; | ||
remove?: Record<string, string>; | ||
import { Module } from "./module.js"; | ||
export type ElementStyle = Partial<CSSStyleDeclaration>; | ||
export type VNodeStyle = ElementStyle & Record<string, string> & { | ||
delayed?: ElementStyle & Record<string, string>; | ||
remove?: ElementStyle & Record<string, string>; | ||
}; | ||
export declare const styleModule: Module; |
@@ -1,5 +0,5 @@ | ||
// Bindig `requestAnimationFrame` like this fixes a bug in IE/Edge. See #360 and #409. | ||
const raf = (typeof window !== "undefined" && | ||
window.requestAnimationFrame.bind(window)) || | ||
setTimeout; | ||
// Binding `requestAnimationFrame` like this fixes a bug in IE/Edge. See #360 and #409. | ||
const raf = typeof (window === null || window === void 0 ? void 0 : window.requestAnimationFrame) === "function" | ||
? window.requestAnimationFrame.bind(window) | ||
: setTimeout; | ||
const nextFrame = function (fn) { | ||
@@ -30,3 +30,3 @@ raf(function () { | ||
for (name in oldStyle) { | ||
if (!style[name]) { | ||
if (!(name in style)) { | ||
if (name[0] === "-" && name[1] === "-") { | ||
@@ -113,4 +113,4 @@ elm.style.removeProperty(name); | ||
destroy: applyDestroyStyle, | ||
remove: applyRemoveStyle, | ||
remove: applyRemoveStyle | ||
}; | ||
//# sourceMappingURL=style.js.map |
@@ -1,2 +0,2 @@ | ||
import { VNode, VNodeData } from "./vnode"; | ||
import { VNode, VNodeData } from "./vnode.js"; | ||
export interface ThunkData extends VNodeData { | ||
@@ -3,0 +3,0 @@ fn: () => VNode; |
@@ -1,2 +0,2 @@ | ||
import { h, addNS } from "./h"; | ||
import { h, addNS } from "./h.js"; | ||
function copyToThunk(vnode, thunk) { | ||
@@ -47,5 +47,5 @@ var _a; | ||
fn: fn, | ||
args: args, | ||
args: args | ||
}); | ||
}; | ||
//# sourceMappingURL=thunk.js.map |
@@ -1,3 +0,3 @@ | ||
import { VNode } from "./vnode"; | ||
import { DOMAPI } from "./htmldomapi"; | ||
import { VNode } from "./vnode.js"; | ||
import { DOMAPI } from "./htmldomapi.js"; | ||
export declare function toVNode(node: Node, domApi?: DOMAPI): VNode; |
@@ -1,4 +0,4 @@ | ||
import { addNS } from "./h"; | ||
import { vnode } from "./vnode"; | ||
import { htmlDomApi } from "./htmldomapi"; | ||
import { addNS } from "./h.js"; | ||
import { vnode } from "./vnode.js"; | ||
import { htmlDomApi } from "./htmldomapi.js"; | ||
export function toVNode(node, domApi) { | ||
@@ -22,7 +22,3 @@ const api = domApi !== undefined ? domApi : htmlDomApi; | ||
name = elmAttrs[i].nodeName; | ||
if (name[0] === "d" && | ||
name[1] === "a" && | ||
name[2] === "t" && | ||
name[3] === "a" && | ||
name[4] === "-") { | ||
if (name.startsWith("data-")) { | ||
dataset[name.slice(5)] = elmAttrs[i].nodeValue || ""; | ||
@@ -41,5 +37,3 @@ } | ||
data.dataset = dataset; | ||
if (sel[0] === "s" && | ||
sel[1] === "v" && | ||
sel[2] === "g" && | ||
if (sel.startsWith("svg") && | ||
(sel.length === 3 || sel[3] === "." || sel[3] === "#")) { | ||
@@ -46,0 +40,0 @@ addNS(data, children, sel); |
@@ -1,10 +0,10 @@ | ||
import { Hooks } from "./hooks"; | ||
import { AttachData } from "./helpers/attachto"; | ||
import { VNodeStyle } from "./modules/style"; | ||
import { On } from "./modules/eventlisteners"; | ||
import { Attrs } from "./modules/attributes"; | ||
import { Classes } from "./modules/class"; | ||
import { Props } from "./modules/props"; | ||
import { Dataset } from "./modules/dataset"; | ||
export declare type Key = string | number | symbol; | ||
import { Hooks } from "./hooks.js"; | ||
import { AttachData } from "./helpers/attachto.js"; | ||
import { VNodeStyle } from "./modules/style.js"; | ||
import { On } from "./modules/eventlisteners.js"; | ||
import { Attrs } from "./modules/attributes.js"; | ||
import { Classes } from "./modules/class.js"; | ||
import { Props } from "./modules/props.js"; | ||
import { Dataset } from "./modules/dataset.js"; | ||
export type Key = string | number | symbol; | ||
export interface VNode { | ||
@@ -18,4 +18,4 @@ sel: string | undefined; | ||
} | ||
export interface VNodeData { | ||
props?: Props; | ||
export interface VNodeData<VNodeProps = Props> { | ||
props?: VNodeProps; | ||
attrs?: Attrs; | ||
@@ -22,0 +22,0 @@ class?: Classes; |
{ | ||
"name": "snabbdom", | ||
"version": "3.5.1", | ||
"version": "3.6.0", | ||
"description": "A virtual DOM library with focus on simplicity, modularity, powerful features and performance.", | ||
@@ -13,2 +13,3 @@ "homepage": "https://github.com/snabbdom/snabbdom#readme", | ||
"dom", | ||
"vdom", | ||
"light", | ||
@@ -24,54 +25,52 @@ "kiss", | ||
"engines": { | ||
"node": ">=8.3.0" | ||
"node": ">=12.17.0" | ||
}, | ||
"main": "build/snabbdom.cjs.js", | ||
"module": "build/index.js", | ||
"files": [ | ||
"build" | ||
], | ||
"type": "module", | ||
"main": "build/index.js", | ||
"types": "build/index.d.ts", | ||
"sideEffects": false, | ||
"scripts": { | ||
"build": "tsc && npm run bundle:cjs", | ||
"bundle:cjs": "rollup build/index.js --format cjs --file build/snabbdom.cjs.js", | ||
"build": "tsc && ts-add-js-extension --dir=build", | ||
"examples": "serve .", | ||
"format": "prettier --write .", | ||
"format-check": "prettier --check .", | ||
"prepare": "husky install", | ||
"lint": "eslint --ext .ts,.tsx,.js --ignore-path .gitignore .", | ||
"unit": "cross-env FILES_PATTERN=\"test/unit/*.ts,test/unit/*.tsx\" karma start karma.conf.js", | ||
"lint": "eslint .", | ||
"unit": "web-test-runner \"test/unit/*.{ts,tsx}\" --node-resolve --coverage", | ||
"release": "npm run test && release-it", | ||
"test:ci": "npm test && cross-env ES5=true npm run unit", | ||
"test": "npm run build && npm run lint && npm run unit" | ||
"test": "npm run build && npm run lint && npm run unit", | ||
"test:watch": "web-test-runner \"test/unit/*.{tsx,tsx}\" --node-resolve --watch" | ||
}, | ||
"devDependencies": { | ||
"@release-it/conventional-changelog": "^4.3.0", | ||
"@types/chai": "4.3.1", | ||
"@types/lodash.shuffle": "4.2.7", | ||
"@types/mocha": "9.1.1", | ||
"@typescript-eslint/eslint-plugin": "5.21.0", | ||
"@typescript-eslint/parser": "^5.21.0", | ||
"chai": "4.3.6", | ||
"@esm-bundle/chai": "^4.3.4-fix.0", | ||
"@release-it/conventional-changelog": "^7.0.2", | ||
"@types/chai": "4.3.9", | ||
"@types/mocha": "10.0.3", | ||
"@typescript-eslint/eslint-plugin": "6.8.0", | ||
"@typescript-eslint/parser": "^6.8.0", | ||
"@web/dev-server-esbuild": "^0.4.3", | ||
"@web/test-runner": "^0.17.2", | ||
"@web/test-runner-browserstack": "^0.6.2", | ||
"commithelper": "^1.2.0", | ||
"conventional-changelog-angular": "^5.0.13", | ||
"cross-env": "7.0.3", | ||
"eslint": "8.14.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-import": "2.26.0", | ||
"eslint-plugin-markdown": "2.2.1", | ||
"conventional-changelog-angular": "^7.0.0", | ||
"eslint": "8.52.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"eslint-plugin-import": "2.29.0", | ||
"eslint-plugin-markdown": "3.0.1", | ||
"eslint-plugin-node": "11.1.0", | ||
"husky": "7.0.4", | ||
"karma": "6.3.19", | ||
"karma-browserstack-launcher": "1.6.0", | ||
"karma-chrome-launcher": "3.1.1", | ||
"karma-firefox-launcher": "2.1.2", | ||
"karma-mocha": "2.0.1", | ||
"karma-mocha-reporter": "^2.2.5", | ||
"karma-typescript": "^5.5.3", | ||
"lint-staged": "^12.4.1", | ||
"lodash.shuffle": "4.2.0", | ||
"mocha": "9.2.2", | ||
"prettier": "^2.6.2", | ||
"release-it": "^14.14.2", | ||
"rollup": "^2.70.2", | ||
"serve": "^13.0.2", | ||
"typescript": "4.6.3" | ||
"husky": "8.0.3", | ||
"lint-staged": "^15.0.2", | ||
"mocha": "10.2.0", | ||
"prettier": "^3.0.3", | ||
"release-it": "^16.2.1", | ||
"serve": "^14.2.1", | ||
"ts-add-js-extension": "^1.6.0", | ||
"typescript": "5.2.2" | ||
}, | ||
"prettier": {}, | ||
"prettier": { | ||
"trailingComma": "none" | ||
}, | ||
"lint-staged": { | ||
@@ -78,0 +77,0 @@ "*.(ts|tsx|js|md)": "prettier --write" |
175
README.md
@@ -1,4 +0,4 @@ | ||
<img alt="Snabbdom" src="readme-title.svg" width="356px"> | ||
<img alt="Snabbdom" src="https://raw.githubusercontent.com/snabbdom/snabbdom/master/readme-title.svg" width="356px"> | ||
A virtual DOM library with focus on simplicity, modularity, powerful features | ||
A virtual DOM library with a focus on simplicity, modularity, powerful features | ||
and performance. | ||
@@ -9,3 +9,3 @@ | ||
[![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) | ||
[![Build Status](https://github.com/snabbdom/snabbdom/actions/workflows/steps.yml/badge.svg)](https://github.com/snabbdom/snabbdom/actions/workflows/steps.yml) | ||
[![Build Status](https://github.com/snabbdom/snabbdom/actions/workflows/test.yml/badge.svg)](https://github.com/snabbdom/snabbdom/actions/workflows/test.yml) | ||
[![npm version](https://badge.fury.io/js/snabbdom.svg)](https://badge.fury.io/js/snabbdom) | ||
@@ -22,3 +22,3 @@ [![npm downloads](https://img.shields.io/npm/dm/snabbdom.svg)](https://www.npmjs.com/package/snabbdom) | ||
English | [简体中文](./README-zh_CN.md) | ||
English | [简体中文](./README-zh_CN.md) | [Hindi](./README-in_HN.md) | ||
@@ -28,7 +28,7 @@ ## Introduction | ||
Virtual DOM is awesome. It allows us to express our application's view | ||
as a function of its state. But existing solutions were way way too | ||
as a function of its state. But existing solutions were way too | ||
bloated, too slow, lacked features, had an API biased towards OOP | ||
and/or lacked features I needed. | ||
, and/or lacked features I needed. | ||
Snabbdom consists of an extremely simple, performant and extensible | ||
Snabbdom consists of an extremely simple, performant, and extensible | ||
core that is only ≈ 200 SLOC. It offers a modular architecture with | ||
@@ -38,6 +38,6 @@ rich functionality for extensions through custom modules. To keep the | ||
You can mold Snabbdom into whatever you desire! Pick, choose and | ||
You can mold Snabbdom into whatever you desire! Pick, choose, and | ||
customize the functionality you want. Alternatively you can just use | ||
the default extensions and get a virtual DOM library with high | ||
performance, small size and all the features listed below. | ||
performance, small size, and all the features listed below. | ||
@@ -77,3 +77,3 @@ ## Features | ||
eventListenersModule, | ||
h, | ||
h | ||
} from "snabbdom"; | ||
@@ -86,3 +86,3 @@ | ||
styleModule, // handles styling on elements with support for animations | ||
eventListenersModule, // attaches event listeners | ||
eventListenersModule // attaches event listeners | ||
]); | ||
@@ -92,7 +92,11 @@ | ||
const vnode = h("div#container.two.classes", { on: { click: someFn } }, [ | ||
h("span", { style: { fontWeight: "bold" } }, "This is bold"), | ||
" and this is just normal text", | ||
h("a", { props: { href: "/foo" } }, "I'll take you places!"), | ||
]); | ||
const vnode = h( | ||
"div#container.two.classes", | ||
{ on: { click: () => console.log("div clicked") } }, | ||
[ | ||
h("span", { style: { fontWeight: "bold" } }, "This is bold"), | ||
" and this is just normal text", | ||
h("a", { props: { href: "/foo" } }, "I'll take you places!") | ||
] | ||
); | ||
// Patch into empty DOM element – this modifies the DOM as a side effect | ||
@@ -103,3 +107,3 @@ patch(container, vnode); | ||
"div#container.two.classes", | ||
{ on: { click: anotherEventHandler } }, | ||
{ on: { click: () => console.log("updated div clicked") } }, | ||
[ | ||
@@ -112,3 +116,3 @@ h( | ||
" and this is still just normal text", | ||
h("a", { props: { href: "/bar" } }, "I'll take you places!"), | ||
h("a", { props: { href: "/bar" } }, "I'll take you places!") | ||
] | ||
@@ -136,3 +140,3 @@ ); | ||
- [`fragment`](#fragment-experimental) (experimental) | ||
- [`tovnode`](#tovnode) | ||
- [`toVNode`](#tovnode) | ||
- [Hooks](#hooks) | ||
@@ -166,3 +170,3 @@ - [Overview](#overview) | ||
- [data : Object](#data--object) | ||
- [children : Array<vnode>](#children--arrayvnode) | ||
- [children : Array\<vnode\>](#children--arrayvnode) | ||
- [text : string](#text--string) | ||
@@ -172,2 +176,5 @@ - [elm : Element](#elm--element) | ||
- [Structuring applications](#structuring-applications) | ||
* [Related packages](#related-packages) | ||
- [Common errors](#common-errors) | ||
@@ -226,4 +233,4 @@ - [Opportunity for community feedback](#opportunity-for-community-feedback) | ||
/* patch complete */ | ||
}, | ||
}, | ||
} | ||
} | ||
}) | ||
@@ -238,4 +245,4 @@ ); | ||
It is recommended that you use `h` to create vnodes. It accepts a | ||
tag/selector as a string, an optional data object and an optional string or | ||
array of children. | ||
tag/selector as a string, an optional data object, and an optional string or | ||
an array of children. | ||
@@ -247,3 +254,3 @@ ```mjs | ||
h("h1", "Headline"), | ||
h("p", "A paragraph"), | ||
h("p", "A paragraph") | ||
]); | ||
@@ -260,4 +267,4 @@ ``` | ||
experimental: { | ||
fragments: true, | ||
}, | ||
fragments: true | ||
} | ||
}); | ||
@@ -274,6 +281,6 @@ ``` | ||
### `tovnode` | ||
### `toVNode` | ||
Converts a DOM node into a virtual node. Especially good for patching over an pre-existing, | ||
server-side generated content. | ||
Converts a DOM node into a virtual node. Especially good for patching over pre-existing, | ||
server-side generated HTML content. | ||
@@ -283,16 +290,12 @@ ```mjs | ||
init, | ||
classModule, | ||
propsModule, | ||
styleModule, | ||
eventListenersModule, | ||
attributesModule, | ||
h, | ||
toVNode, | ||
toVNode | ||
} from "snabbdom"; | ||
const patch = init([ | ||
// Init patch function with chosen modules | ||
classModule, // makes it easy to toggle classes | ||
propsModule, // for setting properties on DOM elements | ||
styleModule, // handles styling on elements with support for animations | ||
eventListenersModule, // attaches event listeners | ||
// Initialize a `patch` function with the modules used by `toVNode` | ||
attributesModule // handles attributes from the DOM node | ||
datasetModule, // handles `data-*` attributes from the DOM node | ||
]); | ||
@@ -303,2 +306,3 @@ | ||
h("p", "A paragraph"), | ||
h("img", { attrs: { src: "sunrise.png", alt: "morning sunrise" } }) | ||
]); | ||
@@ -349,4 +353,4 @@ | ||
movie.elmHeight = vnode.elm.offsetHeight; | ||
}, | ||
}, | ||
} | ||
} | ||
}); | ||
@@ -410,3 +414,3 @@ ``` | ||
Modules works by registering global listeners for [hooks](#hooks). A module is simply a dictionary mapping hook names to functions. | ||
Modules work by registering global listeners for [hooks](#hooks). A module is simply a dictionary mapping hook names to functions. | ||
@@ -420,3 +424,3 @@ ```mjs | ||
// invoked whenever a virtual node is updated | ||
}, | ||
} | ||
}; | ||
@@ -437,3 +441,3 @@ ``` | ||
elements. It expects an object in the `class` data property. The | ||
object should map class names to booleans that indicates whether or | ||
object should map class names to booleans that indicate whether or | ||
not the class should stay or go on the vnode. | ||
@@ -532,4 +536,4 @@ | ||
color: "#c0ffee", | ||
fontWeight: "bold", | ||
}, | ||
fontWeight: "bold" | ||
} | ||
}, | ||
@@ -547,3 +551,3 @@ "Say my name, and every colour illuminates" | ||
color: "#c0ffee", | ||
fontWeight: "bold", | ||
fontWeight: "bold" | ||
}} | ||
@@ -563,3 +567,3 @@ /> | ||
{ | ||
style: { "--warnColor": "yellow" }, | ||
style: { "--warnColor": "yellow" } | ||
}, | ||
@@ -582,4 +586,4 @@ "Warning" | ||
transition: "opacity 1s", | ||
delayed: { opacity: "1" }, | ||
}, | ||
delayed: { opacity: "1" } | ||
} | ||
}, | ||
@@ -608,4 +612,4 @@ "Imma fade right in!" | ||
transition: "opacity 1s", | ||
remove: { opacity: "0" }, | ||
}, | ||
remove: { opacity: "0" } | ||
} | ||
}, | ||
@@ -629,4 +633,4 @@ "It's better to fade out than to burn away" | ||
transition: "opacity 1s", | ||
destroy: { opacity: "0" }, | ||
}, | ||
destroy: { opacity: "0" } | ||
} | ||
}, | ||
@@ -647,3 +651,3 @@ "It's better to fade out than to burn away" | ||
you want to listen to. The function will be called when the event | ||
happens and will be passed the event object that belongs to it. | ||
happens and will be passed to the event object that belongs to it. | ||
@@ -679,3 +683,3 @@ ```mjs | ||
console.log("you chose: " + e.target.value); | ||
}, | ||
} | ||
}; | ||
@@ -685,12 +689,12 @@ h("div", [ | ||
props: { type: "radio", name: "test", value: "0" }, | ||
on: sharedHandler, | ||
on: sharedHandler | ||
}), | ||
h("input", { | ||
props: { type: "radio", name: "test", value: "1" }, | ||
on: sharedHandler, | ||
on: sharedHandler | ||
}), | ||
h("input", { | ||
props: { type: "radio", name: "test", value: "2" }, | ||
on: sharedHandler, | ||
}), | ||
on: sharedHandler | ||
}) | ||
]); | ||
@@ -710,12 +714,12 @@ ``` | ||
props: { type: "radio", name: "test", value: "0" }, | ||
on: { change: sharedHandler }, | ||
on: { change: sharedHandler } | ||
}), | ||
h("input", { | ||
props: { type: "radio", name: "test", value: "1" }, | ||
on: { change: sharedHandler }, | ||
on: { change: sharedHandler } | ||
}), | ||
h("input", { | ||
props: { type: "radio", name: "test", value: "2" }, | ||
on: { change: sharedHandler }, | ||
}), | ||
on: { change: sharedHandler } | ||
}) | ||
]); | ||
@@ -740,6 +744,6 @@ ``` | ||
"stroke-width": 4, | ||
fill: "yellow", | ||
}, | ||
}), | ||
]), | ||
fill: "yellow" | ||
} | ||
}) | ||
]) | ||
]); | ||
@@ -765,3 +769,3 @@ ``` | ||
The `renderFn` is invoked only if the `renderFn` is changed or `[stateArguments]` array length or it's elements are changed. | ||
The `renderFn` is invoked only if the `renderFn` is changed or `[stateArguments]` array length or its elements are changed. | ||
@@ -893,3 +897,3 @@ The `key` is optional. It should be supplied when the `selector` is | ||
The `.sel` property of a virtual node is the CSS selector passed to | ||
[`h()`](#snabbdomh) during creation. For example: `h('div#container', {}, [...])` will create a a virtual node which has `div#container` as | ||
[`h()`](#snabbdomh) during creation. For example: `h('div#container', {}, [...])` will create a virtual node that has `div#container` as | ||
its `.sel` property. | ||
@@ -911,4 +915,4 @@ | ||
props: { | ||
className: "container", | ||
}, | ||
className: "container" | ||
} | ||
}); | ||
@@ -919,3 +923,3 @@ ``` | ||
### children : Array<vnode> | ||
### children : Array\<vnode\> | ||
@@ -938,4 +942,4 @@ The `.children` property of a virtual node is the third (optional) | ||
elm: Element, | ||
key: undefined, | ||
}, | ||
key: undefined | ||
} | ||
]; | ||
@@ -987,3 +991,3 @@ ``` | ||
a repository containing several example applications that | ||
demonstrates an architecture that uses Snabbdom. | ||
demonstrate an architecture that uses Snabbdom. | ||
- [Cycle.js](https://cycle.js.org/) – | ||
@@ -1003,3 +1007,3 @@ "A functional and reactive JavaScript framework for cleaner code" | ||
- [Tung](https://github.com/Reon90/tung) – | ||
A JavaScript library for rendering html. Tung helps to divide html and JavaScript development. | ||
A JavaScript library for rendering HTML. Tung helps to divide HTML and JavaScript development. | ||
- [sprotty](https://github.com/theia-ide/sprotty) - "A web-based diagramming framework" uses Snabbdom. | ||
@@ -1018,2 +1022,7 @@ - [Mark Text](https://github.com/marktext/marktext) - "Realtime preview Markdown Editor" build on Snabbdom. | ||
## Related packages | ||
Packages related to snabbdom should be tagged with the `snabbdom` keyword and published on npm. | ||
They can be found [using the query string `keywords:snabbdom`](https://www.npmjs.com/search?q=keywords:snabbdom). | ||
## Common errors | ||
@@ -1026,3 +1035,3 @@ | ||
The reason for this error is reusing of vnodes between patches (see code example), snabbdom stores actual dom nodes inside the virtual dom nodes passed to it as performance improvement, so reusing nodes between patches is not supported. | ||
The reason for this error is the reusing of vnodes between patches (see code example), snabbdom stores actual dom nodes inside the virtual dom nodes passed to it as performance improvement, so reusing nodes between patches is not supported. | ||
@@ -1034,3 +1043,3 @@ ```mjs | ||
h("div", {}, ["Two"]), | ||
h("div", {}, [sharedNode]), | ||
h("div", {}, [sharedNode]) | ||
]); | ||
@@ -1040,3 +1049,3 @@ const vnode2 = h("div", [ | ||
h("div", {}, [sharedNode]), | ||
h("div", {}, ["Three"]), | ||
h("div", {}, ["Three"]) | ||
]); | ||
@@ -1053,3 +1062,3 @@ patch(container, vnode1); | ||
h("div", {}, [{ ...sharedNode }]), | ||
h("div", {}, ["Three"]), | ||
h("div", {}, ["Three"]) | ||
]); | ||
@@ -1065,3 +1074,3 @@ ``` | ||
h("div", {}, ["Two"]), | ||
h("div", {}, [sharedNode()]), | ||
h("div", {}, [sharedNode()]) | ||
]); | ||
@@ -1073,2 +1082,2 @@ ``` | ||
Pull requests that the community may care to provide feedback on should be | ||
merged after such opportunity of a few days was provided. | ||
merged after such an opportunity of a few days was provided. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
24
1036
0
Yes
127780
57
1405
1