+29
-1
@@ -0,6 +1,34 @@ | ||
| /** | ||
| * See https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements | ||
| */ | ||
| declare type CustomElement = HTMLElement & { | ||
| /** | ||
| * Invoked each time the custom element is moved to a new document. | ||
| * See https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks | ||
| */ | ||
| adoptedCallback?(): void; | ||
| /** | ||
| * Invoked each time the custom element is appended into a document-connected element. This will happen each time the node is moved, and may happen before the element's contents have been fully parsed. | ||
| * Note that `connectedCallback` may be called once your element is no longer connected. Use [`Node.isConnected`](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to make sure. | ||
| * See https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks | ||
| */ | ||
| connectedCallback?(): void; | ||
| /** | ||
| * Invoked each time the custom element is disconnected from the document's DOM. | ||
| * See https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks | ||
| */ | ||
| disconnectedCallback?(): void; | ||
| /** | ||
| * Invoked each time one of the custom element's attributes is added, removed, or changed. Which attributes to notice change for is specified in a static get `observedAttributes` method | ||
| * See https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks | ||
| */ | ||
| attributeChangedCallback?(name: string, oldValue: string, newValue: string): void; | ||
| }; | ||
| declare namespace JSX { | ||
| type Element = HTMLElement; | ||
| type ElementClass = CustomElement; | ||
| type ElementIndex = { | ||
| [key: string]: | ||
| ((this: GlobalEventHandlers, e?: Event) => any) | | ||
| ((this: GlobalEventHandlers, e: Event) => any) | | ||
| string | | ||
@@ -7,0 +35,0 @@ number | |
+4
-4
@@ -27,11 +27,11 @@ module.exports.h = function h(TagOrElement, props = {}, ...childNodes) { | ||
| else if (node instanceof NodeList || node instanceof HTMLCollection) { | ||
| for (const n of [...node]) { | ||
| appendChild(n); | ||
| for (const n of Array.prototype.slice.call(node)) { | ||
| element.appendChild(n); | ||
| } | ||
| } | ||
| else if (node != null) { | ||
| else { | ||
| element.appendChild(document.createTextNode(String(node))); | ||
| } | ||
| }; | ||
| for (const node of childNodes) { | ||
| for (const node of childNodes.filter(x => x != null)) { | ||
| if (Array.isArray(node)) { | ||
@@ -38,0 +38,0 @@ for (const n of node) { |
+4
-4
@@ -27,11 +27,11 @@ export function h(TagOrElement, props = {}, ...childNodes) { | ||
| else if (node instanceof NodeList || node instanceof HTMLCollection) { | ||
| for (const n of [...node]) { | ||
| appendChild(n); | ||
| for (const n of Array.prototype.slice.call(node)) { | ||
| element.appendChild(n); | ||
| } | ||
| } | ||
| else if (node != null) { | ||
| else { | ||
| element.appendChild(document.createTextNode(String(node))); | ||
| } | ||
| }; | ||
| for (const node of childNodes) { | ||
| for (const node of childNodes.filter(x => x != null)) { | ||
| if (Array.isArray(node)) { | ||
@@ -38,0 +38,0 @@ for (const n of node) { |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,CAAC,CAChB,YAAmB,EACnB,QAAkC,EAAE,EACpC,GAAG,UAAqB;IAExB,MAAM,OAAO,GAAG,OAAO,YAAY,KAAK,QAAQ;QAC/C,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC;QACtC,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC;IAEtB,IAAI,KAAK,KAAK,IAAI,EAAE;QACnB,KAAK,GAAG,EAAE,CAAC;KACX;IAED,MAAM,WAAW,GAAG,CAAC,GAA8B,EAAE,KAAU,EAAE,EAAE;QAClE,IAAI,GAAG,IAAI,IAAI,EAAE;YAChB,OAAO;SACP;QACD,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE;YAChC,OAAO,CAAC,GAA2B,CAAC,GAAG,KAAK,CAAC;SAC7C;aAAM;YACN,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;SACjE;IACF,CAAC,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACrC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;KAC7B;IAED,MAAM,WAAW,GAAG,CAAC,IAAa,EAAE,EAAE;QACrC,IAAI,IAAI,YAAY,IAAI,EAAE;YACzB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAC1B;aAAM,IAAI,IAAI,YAAY,QAAQ,IAAI,IAAI,YAAY,cAAc,EAAE;YACtE,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAC1B,WAAW,CAAC,CAAC,CAAC,CAAC;aACf;SACD;aAAM,IAAI,IAAI,IAAI,IAAI,EAAE;YACxB,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SAC3D;IACF,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE;QAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACxB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;gBACrB,WAAW,CAAC,CAAC,CAAC,CAAC;aACf;SACD;aAAM;YACN,WAAW,CAAC,IAAI,CAAC,CAAC;SAClB;KACD;IAED,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["// tslint:disable-next-line:no-reference\n/// <reference path=\"global.d.ts\" />\n\nexport function h<T extends keyof JSX.ElementTagNameMap, E extends JSX.Element & (new () => E)>(\n\tTagOrElement: T | E,\n\tprops: { [index: string]: any } = {},\n\t...childNodes: unknown[]\n) {\n\tconst element = typeof TagOrElement === 'string'\n\t\t? document.createElement(TagOrElement)\n\t\t: new TagOrElement();\n\n\tif (props === null) {\n\t\tprops = {};\n\t}\n\n\tconst setProperty = (key: string | null | undefined, value: any) => {\n\t\tif (key == null) {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof value === 'function') {\n\t\t\telement[key as keyof typeof element] = value;\n\t\t} else {\n\t\t\telement.setAttribute(key, value == null ? '' : value.toString());\n\t\t}\n\t};\n\n\tfor (const key of Object.keys(props)) {\n\t\tsetProperty(key, props[key]);\n\t}\n\n\tconst appendChild = (node: unknown) => {\n\t\tif (node instanceof Node) {\n\t\t\telement.appendChild(node);\n\t\t} else if (node instanceof NodeList || node instanceof HTMLCollection) {\n\t\t\tfor (const n of [...node]) {\n\t\t\t\tappendChild(n);\n\t\t\t}\n\t\t} else if (node != null) {\n\t\t\telement.appendChild(document.createTextNode(String(node)));\n\t\t}\n\t};\n\tfor (const node of childNodes) {\n\t\tif (Array.isArray(node)) {\n\t\t\tfor (const n of node) {\n\t\t\t\tappendChild(n);\n\t\t\t}\n\t\t} else {\n\t\t\tappendChild(node);\n\t\t}\n\t}\n\n\treturn element;\n}\n"]} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,CAAC,CAChB,YAAmB,EACnB,QAAkC,EAAE,EACpC,GAAG,UAAqB;IAExB,MAAM,OAAO,GAAG,OAAO,YAAY,KAAK,QAAQ;QAC/C,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC;QACtC,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC;IAEtB,IAAI,KAAK,KAAK,IAAI,EAAE;QACnB,KAAK,GAAG,EAAE,CAAC;KACX;IAED,MAAM,WAAW,GAAG,CAAC,GAA8B,EAAE,KAAU,EAAE,EAAE;QAClE,IAAI,GAAG,IAAI,IAAI,EAAE;YAChB,OAAO;SACP;QACD,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE;YAChC,OAAO,CAAC,GAA2B,CAAC,GAAG,KAAK,CAAC;SAC7C;aAAM;YACN,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;SACjE;IACF,CAAC,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACrC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;KAC7B;IAED,MAAM,WAAW,GAAG,CAAC,IAAa,EAAE,EAAE;QACrC,IAAI,IAAI,YAAY,IAAI,EAAE;YACzB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAC1B;aAAM,IAAI,IAAI,YAAY,QAAQ,IAAI,IAAI,YAAY,cAAc,EAAE;YACtE,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACjD,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;aACvB;SACD;aAAM;YACN,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SAC3D;IACF,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE;QACrD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACxB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;gBACrB,WAAW,CAAC,CAAC,CAAC,CAAC;aACf;SACD;aAAM;YACN,WAAW,CAAC,IAAI,CAAC,CAAC;SAClB;KACD;IAED,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["// tslint:disable-next-line:no-reference\n/// <reference path=\"global.d.ts\" />\n\nexport function h<T extends keyof JSX.ElementTagNameMap, E extends JSX.Element & (new () => E)>(\n\tTagOrElement: T | E,\n\tprops: { [index: string]: any } = {},\n\t...childNodes: unknown[]\n) {\n\tconst element = typeof TagOrElement === 'string'\n\t\t? document.createElement(TagOrElement)\n\t\t: new TagOrElement();\n\n\tif (props === null) {\n\t\tprops = {};\n\t}\n\n\tconst setProperty = (key: string | null | undefined, value: any) => {\n\t\tif (key == null) {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof value === 'function') {\n\t\t\telement[key as keyof typeof element] = value;\n\t\t} else {\n\t\t\telement.setAttribute(key, value == null ? '' : value.toString());\n\t\t}\n\t};\n\n\tfor (const key of Object.keys(props)) {\n\t\tsetProperty(key, props[key]);\n\t}\n\n\tconst appendChild = (node: unknown) => {\n\t\tif (node instanceof Node) {\n\t\t\telement.appendChild(node);\n\t\t} else if (node instanceof NodeList || node instanceof HTMLCollection) {\n\t\t\tfor (const n of Array.prototype.slice.call(node)) {\n\t\t\t\telement.appendChild(n);\n\t\t\t}\n\t\t} else {\n\t\t\telement.appendChild(document.createTextNode(String(node)));\n\t\t}\n\t};\n\tfor (const node of childNodes.filter(x => x != null)) {\n\t\tif (Array.isArray(node)) {\n\t\t\tfor (const n of node) {\n\t\t\t\tappendChild(n);\n\t\t\t}\n\t\t} else {\n\t\t\tappendChild(node);\n\t\t}\n\t}\n\n\treturn element;\n}\n"]} |
+9
-7
| { | ||
| "name": "@ledge/jsx", | ||
| "version": "1.2.3", | ||
| "version": "1.3.0", | ||
| "description": "Simple JSX implementation for working directly with HTML elements. Types included.", | ||
@@ -22,6 +22,8 @@ "homepage": "https://git.sr.ht/~ledge", | ||
| "scripts": { | ||
| "compile": "tsc index.ts --sourcemap --inlineSources --declaration --removeComments --strict --target es2015 --lib dom,es2015 --types ' ' && sed -E 's|export function ([a-z]+)|module.exports.\\1 = function \\1|;$d' index.js > index.cjs", | ||
| "lint": "tslint -p .", | ||
| "test": "ava", | ||
| "prepare": "tsc index.ts --sourcemap --inlineSources --declaration --removeComments -t es2015 --lib dom,dom.iterable,es2015 && sed -E 's|export function ([a-z]+)|module.exports.\\1 = function \\1|;$d' index.js > index.cjs", | ||
| "prepublishOnly": "npm run lint && npm test" | ||
| "pretest": "npm run compile", | ||
| "prepare": "npm run compile", | ||
| "prepublishOnly": "npm run lint && npm test --ignore-scripts" | ||
| }, | ||
@@ -38,7 +40,8 @@ "license": "EUPL-1.2", | ||
| "@ledge/configs": "23.3.223", | ||
| "ava": "3.14.0", | ||
| "browser-env": "3.3.0", | ||
| "@types/jsdom": "16.2.5", | ||
| "ava": "3.15.0", | ||
| "jsdom": "16.4.0", | ||
| "ts-node": "9.1.1", | ||
| "tslint": "6.1.3", | ||
| "typescript": "4.1.2" | ||
| "typescript": "4.1.3" | ||
| }, | ||
@@ -50,3 +53,2 @@ "ava": { | ||
| "require": [ | ||
| "browser-env/register", | ||
| "ts-node/register" | ||
@@ -53,0 +55,0 @@ ] |
+47
-18
@@ -5,7 +5,26 @@ # @ledge/jsx [](https://builds.sr.ht/~ledge/jsx?) | ||
| ## Features | ||
| - Full [Custom Elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) support | ||
| - Full TypeScript support | ||
| - Tiny footprint | ||
| - Zero runtime dependencies | ||
| - Zero virtualization overhead | ||
| ## Usage | ||
| ```jsx | ||
| import { h } from '@ledge/jsx'; | ||
| let clickCounter = 0; | ||
| const jsxButton = <button id='native-onlick' class='btn btn-dark my-4' | ||
| onclick={() => console.info(`Clicked ${++clickCounter} times`)}> | ||
| Click Me | ||
| </button>; | ||
| jsxButton.click(); // "Clicked 1 times" | ||
| jsxButton.click(); // "Clicked 2 times" | ||
| class CustomElementExample extends HTMLElement { | ||
| public connectedCallback() { | ||
| connectedCallback() { | ||
| this.classList.add('lead'); | ||
@@ -17,8 +36,2 @@ } | ||
| let clickCounter = 0; | ||
| const jsxButton = <button id='native-onlick' class='btn btn-dark my-4' | ||
| onclick={() => console.info(`Clicked ${++clickCounter} times`)}> | ||
| Try clicking this button! | ||
| </button>; | ||
| const jsxSection = | ||
@@ -37,7 +50,4 @@ <section class='card'> | ||
| jsxButton.click(); // "Clicked 1 times" | ||
| jsxButton.click(); // "Clicked 2 times" | ||
| console.log(jsxSection.parentElement === document.body); // true | ||
| console.log(jsxButton.closest('.card') === jsxSection); // true | ||
| jsxSection.parentElement === document.body; // true | ||
| jsxButton.closest('.card') === jsxSection; // true | ||
| ``` | ||
@@ -47,3 +57,3 @@ | ||
| The minimum following configuration is required: | ||
| The following configuration is required: | ||
@@ -53,7 +63,3 @@ ```json | ||
| "compilerOptions": { | ||
| "lib": [ | ||
| "es2015", | ||
| "dom", | ||
| "dom.iterable" | ||
| ], | ||
| "lib": ["dom"], | ||
| "jsx": "react", | ||
@@ -64,1 +70,24 @@ "jsxFactory": "h" | ||
| ``` | ||
| By default, the assigned type will be `HTMLElement`. If you need the subtype, cast the expression: | ||
| ```tsx | ||
| const tpl = <template>{/** ... */}</template> as HTMLTemplateElement; | ||
| const tplClone = tpl.content.cloneNode(true); // ok | ||
| ``` | ||
| A global `CustomElement` interface is provided for working with Custom Elements: | ||
| ```ts | ||
| // error without extending HTMLElement | ||
| class CustomElementExample extends HTMLElement implements CustomElement { | ||
| // autocompletion & documentation for callbacks | ||
| public connectedCallback() { | ||
| // ... | ||
| } | ||
| // error on mistyped parameter | ||
| public attributeChangedCallback(name: string) { | ||
| // ... | ||
| } | ||
| } | ||
| ``` |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
25457
11.64%141
23.68%88
49.15%7
16.67%2
100%