{"_id":"@alphanull/domsmith","_rev":"4-d15387291b277accf658cac0cafe4758","name":"@alphanull/domsmith","dist-tags":{"latest":"2.2.0"},"versions":{"2.0.1":{"name":"@alphanull/domsmith","version":"2.0.1","keywords":["dom","dom builder","html","svg","event handling","declarative","ui","frontend"],"author":{"url":"https://alphanull.de","name":"Frank Kudermann","email":"kudermann@alphanull.de"},"license":"MIT","_id":"@alphanull/domsmith@2.0.1","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"homepage":"https://github.com/alphanull/domsmith#readme","bugs":{"url":"https://github.com/alphanull/domsmith/issues"},"dist":{"shasum":"0038892cef854576ba0fe3e77ff20e209afec0d9","tarball":"https://registry.npmjs.org/@alphanull/domsmith/-/domsmith-2.0.1.tgz","fileCount":4,"integrity":"sha512-44LxwJQnrqvyLqZo1N8wGxPGHWDk7Sm6ZIAbARPPKeE7Z6nw0Sg/4jgNM1HOkAoJCJNV17KX+y1h0sHjYP4Hsg==","signatures":[{"sig":"MEYCIQCNrP4ncm9E90bFgKPWy+LGYYqvrDQfyflIemt9Wfg/7gIhAOKBEBN4Eb9aJk5IS10FP/U7+OL6HcN1tfDR9X8wcu4J","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17107},"type":"module","module":"./dist/DomSmith.min.js","engines":{"node":">=16.0.0"},"gitHead":"f18ff4345822b5a889732c987d5e16d562c1173d","scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/DomSmith.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"_npmUser":{"name":"alphanull","email":"kudermann@alphanull.de"},"repository":{"url":"git+https://github.com/alphanull/domsmith.git","type":"git"},"_npmVersion":"11.3.0","description":"DomSmith is a lightweight and declarative DOM builder for JavaScript that enables you to create, update, and remove DOM trees with an intuitive API.","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^4.0.4","eslint":"^9.22.0","rollup":"^4.39.0","globals":"^15.15.0","@eslint/js":"^9.22.0","jsdoc-to-markdown":"^9.1.1","eslint-plugin-jsdoc":"^50.6.9","rollup-plugin-delete":"^3.0.1","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^4.2.0","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/domsmith_2.0.1_1745787600756_0.7019615352354294","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@alphanull/domsmith","version":"2.1.0","keywords":["dom","dom builder","html","svg","event handling","declarative","ui","frontend"],"author":{"url":"https://alphanull.de","name":"Frank Kudermann","email":"kudermann@alphanull.de"},"license":"MIT","_id":"@alphanull/domsmith@2.1.0","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"homepage":"https://github.com/alphanull/domsmith#readme","bugs":{"url":"https://github.com/alphanull/domsmith/issues"},"dist":{"shasum":"669443562e90ba2fb02775d75c4c7c02190b6d2e","tarball":"https://registry.npmjs.org/@alphanull/domsmith/-/domsmith-2.1.0.tgz","fileCount":6,"integrity":"sha512-kegXnGOxsoYbkeZFHm9LgDKq90c6qKP80iVF1q9lhW21yN39di1BUL9rroLYYXWTVeihEUegtCO46wLvXVsJxg==","signatures":[{"sig":"MEUCIQDoJF1q4gQfssYfDwhR0pQz5vLqPpsryKx0SfG8i07tlAIgDrd6f1bAmUXfWDkr9HKmFLDtG5OOY8WbtxUJAB9Oxmg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27753},"type":"module","module":"./dist/DomSmith.min.js","engines":{"node":">=16.0.0"},"gitHead":"1cf28fb8288b8f4cada0647473daa696f39ef84a","scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/DomSmith.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"_npmUser":{"name":"alphanull","email":"kudermann@alphanull.de"},"repository":{"url":"git+https://github.com/alphanull/domsmith.git","type":"git"},"_npmVersion":"11.4.2","description":"DomSmith is a lightweight and declarative DOM builder for JavaScript that enables you to create, update, and remove DOM trees with an intuitive API.","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^4.0.4","eslint":"^9.31.0","rollup":"^4.45.1","globals":"^16.3.0","@eslint/js":"^9.31.0","jsdoc-to-markdown":"^9.1.2","eslint-plugin-jsdoc":"^51.4.1","rollup-plugin-delete":"^3.0.1","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^5.2.2","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/domsmith_2.1.0_1753374146285_0.4235701248068757","host":"s3://npm-registry-packages-npm-production"}},"2.1.1":{"name":"@alphanull/domsmith","version":"2.1.1","keywords":["dom","dom builder","html","svg","event handling","declarative","ui","frontend"],"author":{"url":"https://alphanull.de","name":"Frank Kudermann","email":"kudermann@alphanull.de"},"license":"MIT","_id":"@alphanull/domsmith@2.1.1","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"homepage":"https://github.com/alphanull/domsmith#readme","bugs":{"url":"https://github.com/alphanull/domsmith/issues"},"dist":{"shasum":"e2c78dae63e424e477fa2555c84067b166dd965f","tarball":"https://registry.npmjs.org/@alphanull/domsmith/-/domsmith-2.1.1.tgz","fileCount":6,"integrity":"sha512-wF4b16YfzcJ8NJq7r79Nr/kWVdlaY/BwkfyDajHUnBUcx7QC8q/q3cOKLTnTRyOi1U9DTNWlE+8B3dVqH4u+Xg==","signatures":[{"sig":"MEQCIBQpSYS7vJyAsR26zSiebj7ZEFaX11dTe1Oa8EW7Rm7UAiBc4mnQK2+mGopjiCKTNR4gmO8J4JpC8tBb1giCk75q0w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28216},"type":"module","module":"./dist/DomSmith.min.js","engines":{"node":">=16.0.0"},"gitHead":"4e818359f495d68350b38a2346d4dc7a6b2c4d21","scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/DomSmith.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"_npmUser":{"name":"alphanull","email":"kudermann@alphanull.de"},"repository":{"url":"git+https://github.com/alphanull/domsmith.git","type":"git"},"_npmVersion":"11.7.0","description":"DomSmith is a lightweight and declarative DOM builder for JavaScript that enables you to create, update, and remove DOM trees with an intuitive API.","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^4.0.5","eslint":"^9.39.2","rollup":"^4.53.3","globals":"^16.5.0","@eslint/js":"^9.39.2","jsdoc-to-markdown":"^9.1.3","eslint-plugin-jsdoc":"^61.5.0","rollup-plugin-delete":"^3.0.2","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^5.6.1","@rollup/plugin-node-resolve":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/domsmith_2.1.1_1765662380908_0.6991962607689848","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@alphanull/domsmith","license":"MIT","version":"2.2.0","description":"DomSmith is a lightweight and declarative DOM builder for JavaScript that enables you to create, update, and remove DOM trees with an intuitive API.","keywords":["dom","dom builder","html","svg","event handling","declarative","ui","frontend"],"author":{"name":"Frank Kudermann","email":"kudermann@alphanull.de","url":"https://alphanull.de"},"repository":{"type":"git","url":"git+https://github.com/alphanull/domsmith.git"},"homepage":"https://github.com/alphanull/domsmith#readme","bugs":{"url":"https://github.com/alphanull/domsmith/issues"},"type":"module","module":"./dist/DomSmith.min.js","publishConfig":{"access":"public"},"sideEffects":false,"engines":{"node":">=16.0.0"},"devDependencies":{"@eslint/js":"^9.39.2","@rollup/plugin-node-resolve":"^16.0.3","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^5.6.1","eslint":"^9.39.2","eslint-plugin-jsdoc":"^61.5.0","globals":"^16.5.0","jsdoc":"^4.0.5","jsdoc-to-markdown":"^9.1.3","rollup":"^4.53.3","rollup-plugin-delete":"^3.0.2"},"scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/DomSmith.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"gitHead":"e8f3a8e8f2109a010d4c1ecf302caca3129b1b3f","_id":"@alphanull/domsmith@2.2.0","_nodeVersion":"22.13.1","_npmVersion":"11.7.0","dist":{"integrity":"sha512-HWMyCpdz7vS/L7ur99+m9lb0j5pWTxqqOTWabCpz0kC/EKFTqrPKohdfFpOWIod1XvXxGkpyVRWWyOsS5Ez9mA==","shasum":"844086b5d89b7e2cf038f4c38b9c70eb91f69809","tarball":"https://registry.npmjs.org/@alphanull/domsmith/-/domsmith-2.2.0.tgz","fileCount":6,"unpackedSize":29079,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCpT7/RdGYga+nYtqTP5Di0C4LtVxJQctRUzzd3aNfS6AIgbD/oVT7lesZaaW/CIjKrYXpJRKhkpqH5ilekiKqVQUM="}]},"_npmUser":{"name":"alphanull","email":"kudermann@alphanull.de"},"directories":{},"maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/domsmith_2.2.0_1766153169439_0.7261481263119294"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-27T21:00:00.689Z","modified":"2025-12-19T14:06:09.856Z","2.0.1":"2025-04-27T21:00:00.949Z","2.1.0":"2025-07-24T16:22:26.486Z","2.1.1":"2025-12-13T21:46:21.087Z","2.2.0":"2025-12-19T14:06:09.628Z"},"bugs":{"url":"https://github.com/alphanull/domsmith/issues"},"author":{"name":"Frank Kudermann","email":"kudermann@alphanull.de","url":"https://alphanull.de"},"license":"MIT","homepage":"https://github.com/alphanull/domsmith#readme","keywords":["dom","dom builder","html","svg","event handling","declarative","ui","frontend"],"repository":{"type":"git","url":"git+https://github.com/alphanull/domsmith.git"},"description":"DomSmith is a lightweight and declarative DOM builder for JavaScript that enables you to create, update, and remove DOM trees with an intuitive API.","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"readme":"![License](https://img.shields.io/github/license/alphanull/domsmith)\n![Version](https://img.shields.io/npm/v/@alphanull/domsmith)\n[![JSDoc](https://img.shields.io/badge/docs-JSDoc-blue)](./docs/DomSmith.md)\n![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/@alphanull/domsmith)\n\n# DomSmith\n\n**DomSmith** is a lightweight and declarative DOM builder for JavaScript that enables you to create, update, and remove DOM trees with an intuitive API. It supports both HTML and SVG elements with automatic namespace handling (including `<foreignObject>` support) and centralized event management with proper cleanup. By also providing direct access to element references via the instance, DomSmith aims to simplify UI component creation for modern web applications.\n\n## Features\n\n- **Declarative DOM Creation:** Create complex DOM structures with simple JSON-like configurations.\n- **HTML & SVG Support:** Automatically uses the correct namespace (including `<foreignObject>` support).\n- **Centralized Event Handling:** Easily attach events and ensure proper cleanup.\n- **Direct References:** Expose element references directly on the builder instance.\n- **Node Replacement & Removal:** Dynamically update and remove parts of your DOM tree.\n- **Plugin System:** Extensible architecture with lifecycle hooks and priority-based execution.\n- **Flexible Mounting:** Multiple insert modes (append, before, replace, top) for precise DOM placement.\n- **Memory Management:** Proper cleanup with the `destroy()` method.\n\n## Installation\n\n### Using NPM\n\n```bash\nnpm install @alphanull/domsmith\n```\n\n### Using CDN\n\n[Download latest version](https://cdn.jsdelivr.net/npm/@alphanull/domsmith@2/dist/DomSmith.min.js) from jsDelivr\n[Download latest version](https://unpkg.com/@alphanull/domsmith@2/dist/DomSmith.min.js) from unpkg\n\n### via GitHub\n\n[Download release](https://github.com/alphanull/domsmith/releases) from GitHub\n\n## Usage\n\n### 1. Basic Usage\n\nCreate a simple DOM tree with nested children. The resulting DOM tree is immediately mounted to `document.body`.\n\n```javascript\nimport DomSmith from '@alphanull/domsmith';\n\nconst domConfig = {\n    _tag: 'div', // 'div' is default and can be omitted.\n    _nodes: [ // _nodes array contains child nodes\n        {\n            _tag: 'header', // The tag name\n            _nodes: [\n                {\n                    _tag: 'h1',\n                    // Use a string as a _nodes definition to create a single text node\n                    _nodes: 'Welcome to DomSmith!'\n                }\n            ]\n        },\n        {\n            _tag: 'section',\n            _nodes: [\n                {\n                    _tag: 'p',\n                    // You can also use a string for text node(s) in an _nodes array\n                    _nodes: [\n                        {\n                            _tag: 'span',\n                            _nodes: 'This is a basic usage example. '\n                        },\n                        'Second Text Node'\n                    ]\n                }\n            ]\n        }\n    ]\n};\n\n// New API with extended options (v2.1.0+)\nconst dom = new DomSmith(domConfig, { ele: document.body, insertMode: 'append' });\n// Legacy API shortcut (insertMode defaults to 'append')\nconst dom2 = new DomSmith(domConfig, document.body);\n// Alternatively, if you omit the second parameter, the DOM is not mounted immediately\nconst dom3 = new DomSmith(domConfig);\n// ... later, you can mount manually:\ndom3.mount({ ele: myEle, insertMode: 'replace' });\n```\n\n### 2. Attributes and Properties\n\nAssign attributes and properties directly in the configuration.\n\n```javascript\nconst domConfig = {\n    _tag: 'button',\n    id: 'myButton', // Will be set as an attribute or property.\n    className: 'btn-primary', // Will be set as an attribute or property.\n    'style.backgroundColor': 'skyblue', // Dot notation for nested properties.\n    _nodes: 'I am a Button'\n};\n```\n\nDomSmith automatically determines whether to use `setAttribute()` or set the value directly on the property. If the property exists, direct assignment is used. If the property is not found or assignment fails (for example, due to being readonly on svg elements) `setAttribute()` is used. Also, especially for `style` properties you can use dot notation.\n\n**Please note:**\nIt is strongly recommended to avoid properties beginning with an underscore to prevent conflicts with internal properties.\n\n### 3. References\n\nExpose direct references to DOM elements by specifying the `_ref` property for easy access and further manipulation:\n\n```javascript\nconst domConfig = {\n    _ref: 'container',\n    _nodes: [\n        {\n            _tag: 'p',\n            _nodes: 'Paragraph 1'\n        },\n        {\n            _tag: 'p',\n            _ref: 'secondParagraph',\n            _nodes: 'Paragraph 2'\n        }\n    ]\n};\n\nconst dom = new DomSmith(domConfig, document.body);\n\nconsole.log(dom.container);       // Direct access to the container div\nconsole.log(dom.secondParagraph); // Direct access to the second paragraph\n```\n\nIn case you want to directly reference a **text node**, you can use this format:\n\n```javascript\nconst domConfig = {\n    _ref: 'container',\n    _nodes: [\n        {\n            _ref: 'myText',\n            _text: 'A referenced TextNode'\n        }\n    ]\n};\n\nconst dom = new DomSmith(domConfig, document.body);\ndom.myText.nodeValue = 'Changed Text'; // direct access to TextNode\n```\n\n**Please note:**\nYou can use almost any string as a reference name, but since the refs are exposed on the root of the instance, certain names (especially those reserved for the API) cannot be used. Therefore, it is strongly recommended to avoid refs beginning with an underscore as well as a dollar sign to prevent conflicts with internal properties. Additionally, refs must be unique within each instance; duplicate refs will throw an error.\n\n**Legacy Support:**\nThe old property names (`ref`, `tag`, `text`, `nodes`, `events`) are still supported but will show deprecation warnings. It's recommended to migrate to the new underscore-prefixed versions.\n\n### 4. Events\n\n#### Using the shortcut notation\n\nAttach event listeners directly within the node definition. These event listeners will be automatically removed when `teardown()` or `removeNode()` is called, so manual cleanup is usually unecessary.\n\n```javascript\nconst domConfig = {\n    _tag: 'button',\n    _nodes: 'Click Me',\n    mouseover: () => console.log('Mouse over button'),\n    click: [ // You can bind multiple handlers to the same event by using an array of handlers\n        () => console.log('Button clicked!'),\n        () => console.log('Second Click handlers!')\n    ]\n};\n```\n\n**Please note:**\nEvent names are derived dynamically at runtime and only cover events that have a corresponding “on” property (e.g., `onclick`). Some events, such as `compositionupdate`, do not have this equivalent, nor do custom events. In those cases, you can specify events explicitly:\n\n#### Setting events explicity (mostly for edge cases and custom events)\n\n```javascript\nconst domConfig = {\n    _tag: 'input',\n    _events: {\n        compositionupdate: () => console.log('Composition updated')\n    }\n};\n```\n\n#### Manually adding and removing events\n\nYou can also add or remove events manually after creating the DomSmith Instance by using a reference:\n\n```javascript\nconst domConfig = {\n    _tag: 'button',\n    _nodes: 'Click Me',\n    _ref: 'button',\n    mouseover: () => console.log('Mouse over button')\n};\n\nconst dom = new DomSmith(domConfig, document.body);\n\ndom.addEvent('button', 'click', () => console.log('Button clicked!')); // add another listener\ndom.removeEvent('button', 'mouseover'); // removes all 'mouseover' events\ndom.removeEvent('button'); // removes _all_ events\n```\n\n### 5. Node Replacement and Removal\n\nDynamically replace or remove nodes from the DOM tree. This process also cleans up any attached event listeners.\n\n```javascript\nconst domConfig = {\n    _nodes: [\n        {\n            _tag: 'p',\n            _ref: 'message',\n            _nodes: 'Old content'\n        }\n    ]\n};\n\nconst dom = new DomSmith(domConfig, { ele: document.body });\n\n// Replace the paragraph with new content\ndom.replaceNode('message', {\n    _tag: 'p',\n    _ref: 'message',\n    _nodes: 'New content'\n});\n\n// Remove the paragraph after 3 seconds\nsetTimeout(() => {\n    dom.removeNode(dom.message);\n}, 3000);\n```\n\n### 6. Multiple Root Nodes\n\nThis example demonstrates how to pass an array as the node definition so that multiple sibling nodes are created as the root. Each node is appended individually to the specified parent element, and the defined refs become direct properties on the instance.\n\n```javascript\nconst domConfig = [\n    {\n        _tag: 'header',\n        _nodes: 'Header Content',\n    },\n    {\n        _tag: 'main',\n        _ref: 'main',\n        _nodes: [\n            {\n                _tag: 'p',\n                _nodes: 'This is the main content.'\n            }\n        ]\n    },\n    {\n        _tag: 'footer',\n        _nodes: 'Footer Content'\n    }\n];\n```\n\n### 7. SVG\n\nThis example shows how DomSmith supports SVG elements, including the use of <foreignObject>. Child nodes within a <foreignObject> are created in the HTML namespace, while the rest of the SVG uses the SVG namespace:\n\n```javascript\nconst domConfig = {\n    _tag: 'svg',\n    width: 300,\n    height: 200,\n    _nodes: [\n        {\n            _tag: 'rect',\n            x: 10,\n            y: 10,\n            width: 280,\n            height: 180,\n            fill: 'lightblue'\n        },\n        {\n            _tag: 'foreignObject',\n            width: 100,\n            height: 50,\n            // Within a foreignObject, child nodes are created in the HTML namespace.\n            _nodes: [\n                {\n                    _nodes: 'HTML inside foreignObject',\n                    style: 'color: red; font-size: 14px;'\n                }\n            ]\n        }\n    ]\n});\n```\n\n### 8. Plugin System\n\nDomSmith includes a powerful plugin system that allows you to extend functionality. Plugins can hook into various lifecycle events and modify node definitions.\n\n#### Built-in Plugins\n\nDomSmith comes with two built-in plugins that are available as separate modules:\n\n**Input Range Plugin**: Enhances `<input type=\"range\">` elements with touch-drag support for mobile devices.\n\n```javascript\n// Automatically applied to all range inputs\nconst rangeConfig = {\n    _tag: 'input',\n    type: 'range',\n    min: 0,\n    max: 100,\n    value: 50\n    // Touch-drag support is automatically added\n};\n\n// Disable the plugin for specific elements\nconst disabledRangeConfig = {\n    _tag: 'input',\n    type: 'range',\n    $rangeFixDisable: true // Plugin will be skipped for this element\n};\n```\n\n**Select Wrapper Plugin**: Automatically wraps `<select>` elements for enhanced styling.\n\n```javascript\n// Automatically wrapped in .select-wrapper container\nconst selectConfig = {\n    _tag: 'select',\n    _nodes: [\n        { _tag: 'option', _nodes: 'Option 1' },\n        { _tag: 'option', _nodes: 'Option 2' }\n    ]\n};\n```\n\n#### Using Built-in Plugins\n\nThe built-in plugins are also available as separate modules for optional usage:\n\n```javascript\nimport DomSmith from '@alphanull/domsmith';\nimport inputRangePlugin from '@alphanull/domsmith/plugins/domSmithInputRange.min.js';\nimport selectPlugin from '@alphanull/domsmith/plugins/domSmithSelect.min.js';\n\n// Register plugins manually\nDomSmith.registerPlugin(inputRangePlugin);\nDomSmith.registerPlugin(selectPlugin);\n\n// Now use DomSmith with plugin support\nconst dom = new DomSmith(config, { ele: document.body });\n```\n\n#### Custom Plugins\n\nYou can create custom plugins by implementing certain lifecycle hooks. Plugins are executed in priority order (higher priority runs first).\n\n**Available Lifecycle Hooks:**\n\n- `addNode(nodeDef)` - Called during node creation, can modify and return the node definition\n- `removeNode(nodeDef)` - Called during node removal, can modify and return the node definition\n- `mount(dom, mountContext)` - Called when DOM is mounted\n- `unmount(dom, mountContext)` - Called when DOM is unmounted\n- `destroy()` - Called when the DomSmith instance is destroyed\n- `destroyPlugin()` - Called when global `DomSmith.destroyPlugins()` is called\n\n```javascript\nconst myPlugin = {\n    addNode(nodeDef) {\n        // Modify node definition during creation\n        if (nodeDef._tag === 'button') {\n            nodeDef.className = 'custom-button';\n        }\n        return nodeDef;\n    },\n\n    mount(dom, mountContext) {\n        // Called when DOM is mounted\n        console.log('DOM mounted:', mountContext);\n    },\n\n    destroy() {\n        // Called when instance is destroyed\n        console.log('Plugin cleanup');\n    }\n};\n\n// Register plugin with priority (higher runs earlier)\nDomSmith.registerPlugin(myPlugin, { priority: 10 });\n\n// Destroy all plugins\nDomSmith.destroyPlugins();\n```\n\n#### Plugin Configuration with $ Variables\n\nPlugins can be configured using `$`-prefixed properties in node definitions. These properties are not rendered to the DOM but are used by plugins for configuration.\n\n```javascript\nconst myCustomPlugin = {\n    addNode(nodeDef) {\n        // Check for plugin-specific configuration\n        if (nodeDef.$myPluginEnabled === false) return; // Skip processing\n\n        if (nodeDef._tag === 'div' && nodeDef.$myPluginClass) {\n            nodeDef.className = nodeDef.$myPluginClass;\n        }\n\n        return nodeDef;\n    }\n};\n\n// Usage in node definitions\nconst config = {\n    _tag: 'div',\n    $myPluginEnabled: true,\n    $myPluginClass: 'special-styling',\n    _nodes: 'Content'\n};\n```\n\n#### Plugin Chaining\n\nPlugins are executed in sequence, allowing them to build upon each other's modifications:\n\n```javascript\nconst plugin1 = {\n    addNode(nodeDef) {\n        if (nodeDef._tag === 'button') {\n            nodeDef.className = 'base-button';\n        }\n        return nodeDef;\n    }\n};\n\nconst plugin2 = {\n    addNode(nodeDef) {\n        if (nodeDef._tag === 'button' && nodeDef.className === 'base-button') {\n            nodeDef.className += ' enhanced-button';\n        }\n        return nodeDef;\n    }\n};\n\n// Register plugins with different priorities\nDomSmith.registerPlugin(plugin1, { priority: 10 }); // Runs first\nDomSmith.registerPlugin(plugin2, { priority: 5 });  // Runs second\n\n// Result: button will have className 'base-button enhanced-button'\n```\n\n**Important Notes:**\n\n- Plugins are registered globally and affect all DomSmith instances\n- Duplicate plugin instances are automatically ignored\n- `$`-prefixed properties are automatically filtered out and not rendered to the DOM\n- Plugin execution order is determined by priority (higher numbers run first)\n- If a plugin hook returns `undefined`, the original node definition is preserved\n\n### 9. Mount Options\n\nDomSmith supports multiple insert modes for precise DOM placement:\n\n```javascript\n// Append (default) - adds to end of parent\nconst dom1 = new DomSmith(config, { ele: parent, insertMode: 'append' });\n// Before - inserts before target element\nconst dom2 = new DomSmith(config, { ele: target, insertMode: 'before' });\n// Replace - replaces target element\nconst dom3 = new DomSmith(config, { ele: target, insertMode: 'replace' });\n// Top - inserts as first child of parent\nconst dom4 = new DomSmith(config, { ele: parent, insertMode: 'top' });\n```\n\n### 10. Unmount & Cleanup\n\nUse `unmount()` to remove the DomSmith elements from the DOM while preserving event bindings, allowing you to remount the instance later.\n\n```javascript\nconst dom = new DomSmith(domConfig, { ele: document.body });\ndom.unmount();\n// Later...\ndom.mount(); // Re-mounts to original location\n```\n\nUse `destroy()` to completely remove the DomSmith instance, including all event listeners, mounted elements, and references.\n\n```javascript\nconst dom = new DomSmith(domConfig, { ele: document.body });\ndom.destroy(); // Complete cleanup\n```\n\n**Note**: The old `teardown()` method is deprecated and will show a warning. Use `destroy()` instead.\n\n## Docs\n\nFor more detailed docs, see [JSDoc Documentation](docs/DomSmith.md)\n\n## License\n\n[MIT](https://opensource.org/license/MIT)\n\nCopyright © 2016-present Frank Kudermann @ alphanull.de","readmeFilename":"README.md"}