{"_id":"@camilaprav/filterclone","_rev":"3-a6fb650562ab89a9f91fb2ae5be2653b","name":"@camilaprav/filterclone","dist-tags":{"latest":"2.0.1"},"versions":{"1.0.0":{"name":"@camilaprav/filterclone","version":"1.0.0","author":{"name":"Camila Prá"},"license":"ISC","_id":"@camilaprav/filterclone@1.0.0","maintainers":[{"name":"camilaprav","email":"camila@guiprav.com"}],"dist":{"shasum":"e8b3ce0510d3e6b41cfba5c158b1d50b39df9400","tarball":"https://registry.npmjs.org/@camilaprav/filterclone/-/filterclone-1.0.0.tgz","fileCount":4,"integrity":"sha512-p0wcU2Hqo3loxcMF1GqMQUjzjcoOURTPTOhK7WUj/DGQbWHZDvlUXxb0Yg88YySReJonxV9yBh8EzH6xNru6sw==","signatures":[{"sig":"MEUCIHx3CvIILWdARP7SD7NqGBV0KxlYUhkvTlBfEXs/u6XgAiEA+za5daaY6oVoqQPkRDBsVFfEtErOeECURsJI0sump1o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4349},"main":"filterclone.js","gitHead":"d70c3740f64a8985152d71766d2b9bf561ff7019","_npmUser":{"name":"camilaprav","email":"camila@guiprav.com"},"_npmVersion":"10.9.2","description":"Tiny, zero-dependency JavaScript function for selectively deep-cloning and/or modifying the cloned DOM subtree","directories":{},"_nodeVersion":"23.11.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/filterclone_1.0.0_1745975965559_0.8324867744469662","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@camilaprav/filterclone","version":"2.0.0","author":{"name":"Camila Prá"},"license":"ISC","_id":"@camilaprav/filterclone@2.0.0","maintainers":[{"name":"camilaprav","email":"camila@guiprav.com"}],"dist":{"shasum":"0d7d3f6a75ed48d517c7035df9e0b08e17e266c8","tarball":"https://registry.npmjs.org/@camilaprav/filterclone/-/filterclone-2.0.0.tgz","fileCount":4,"integrity":"sha512-jlOWTCT+cTScAXyElL+VP0ZJFrQm5wPQFZA1KYVbJrS/dTwXl59JarZuaophyrrgZUPhnrYlf3jGb5XU+UN7Ag==","signatures":[{"sig":"MEQCIEHstd42nHoFmlC+mzEhGGrLDZN/O4Kj5rGXVynkFi5FAiAogKhVh/frvjRt1kMRvFi3dYR503z/lHXlQ/3BuVPa0g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":6821},"main":"filterclone.js","gitHead":"22acf8e5eba160a4b64689fbb754b8d16edb8f13","_npmUser":{"name":"camilaprav","email":"camila@guiprav.com"},"repository":{"url":"git@githubcom:camilaprav/filterclone.git","type":"git"},"_npmVersion":"10.9.2","description":"Tiny, zero-dependency JavaScript function for selectively deep-cloning and/or modifying the cloned DOM subtree","directories":{},"_nodeVersion":"23.11.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/filterclone_2.0.0_1747352133353_0.774625734842558","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@camilaprav/filterclone","version":"2.0.1","description":"Tiny, zero-dependency JavaScript function for selectively deep-cloning and/or modifying the cloned DOM subtree","main":"filterclone.js","browser":"filterclone.js","repository":{"type":"git","url":"git@githubcom:camilaprav/filterclone.git"},"author":{"name":"Camila Prá"},"license":"ISC","_id":"@camilaprav/filterclone@2.0.1","gitHead":"98c892a3ace92b2a1432c25bfd0346b1a59b043a","_nodeVersion":"23.11.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-WuD24RQ3d2VnMete6aB5TY5nAsEVYwF50uD/GQu3Qzy4pYsiy+bCmeaYYscNq8C/dyFbwy3T9yxzzWnuL3TGpA==","shasum":"df2daaae357a582b321d4184ee8c885dd6c80b00","tarball":"https://registry.npmjs.org/@camilaprav/filterclone/-/filterclone-2.0.1.tgz","fileCount":4,"unpackedSize":6852,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIA3NBoNYgROt/xDkja1zS9BBOEp7oQrVgI0Tm319s1XoAiEA02IrL1AsyXeDo01pRyWKhluNsFq+68YdjKpq+tFkBqE="}]},"_npmUser":{"name":"camilaprav","email":"camila@guiprav.com"},"directories":{},"maintainers":[{"name":"camilaprav","email":"camila@guiprav.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/filterclone_2.0.1_1747352774283_0.2897722622936607"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-30T01:19:25.492Z","modified":"2025-05-15T23:46:14.588Z","1.0.0":"2025-04-30T01:19:25.738Z","2.0.0":"2025-05-15T23:35:33.552Z","2.0.1":"2025-05-15T23:46:14.429Z"},"author":{"name":"Camila Prá"},"license":"ISC","repository":{"type":"git","url":"git@githubcom:camilaprav/filterclone.git"},"description":"Tiny, zero-dependency JavaScript function for selectively deep-cloning and/or modifying the cloned DOM subtree","maintainers":[{"name":"camilaprav","email":"camila@guiprav.com"}],"readme":"# ⚗️ filterclone\n\n`filterclone` is a *very* tiny, zero-dependency JavaScript function for selectively deep-cloning and/or modifying the cloned DOM subtree.\nIt applies a filter function to control which nodes are cloned and included in the resulting subtree.\n\n## Features\n\n- Recursively clones DOM nodes with filtering logic\n- Non-mutating: original DOM remains untouched\n- Super lightweight and framework-agnostic\n- Supports iframe content cloning (same-origin only)\n- Optional `nothrow` argument to suppress errors during filtering (defaults to true)\n\n## Installation\n\n```bash\nnpm install filterclone\n```\n\nOr simply use it via CDN:\n\n```html\n<script type=\"module\">\n  import filterclone from 'https://esm.sh/@camilaprav/filterclone';\n</script>\n```\n\n## Usage\n\n```js\n<script type=\"module\">\n  import filterclone from 'https://esm.sh/@camilaprav/filterclone';\n\n  let filtered = filterclone(document.body, x => {\n    if (x.ELEMENT_NODE && x.tagName === 'SCRIPT') return;\n    return x;\n  });\n\n  console.log(filtered.outerHTML);\n</script>\n```\n\nThe example above clones the body excluding all `<script>` tags.\n\n## API\n\n### `filterclone(root, filterFn, iframes?, nothrow = true)`\n\n- **`root`**: `Node` - The root of the DOM subtree to clone.\n- **`filterFn`**: `(node: Node, original: Node) => Node | falsy` - A function called on each node (including root) with its clone and original. Return the clone (or a modified version) to keep it, or falsy to exclude it from the final tree. Anything else will throw (regardless of `nothrow` in this case).\n- **`iframes`** *(optional)*: `boolean` - If `true`, attempts to clone contents of same-origin iframes (wrapping them in a div instead).\n- **`nothrow`** *(optional)*: `boolean` (default: `true`) - If `true`, suppresses clone errors during filtering and logs warnings instead.\n\nReturns: A cloned subtree root node, or `null` if the root itself was filtered out.\n\n## Why?\n\nSometimes you need to deeply clone a DOM structure but with control over what gets included. `filterclone` gives you that flexibility without heavy dependencies or awkward tree-walking boilerplate.\n\nUsed in: [htmlsnap](https://github.com/camilaprav/htmlsnap) and [KittyGPT](https://github.com/camilaprav/kittygpt).\n\n## Testing\n\nThis library is implicitly tested by the extensive test coverage found in [KittyGPT](https://github.com/camilaprav/kittygpt), which exercises all of its functionality.\n\n---\n\n## License\n\n### ISC (Internet Systems Consortium)\n\nfilterclone is free software: you can redistribute it and/or modify it under the terms of the [ISC License](COPYING).\n\n## Exclusion of warranty\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n","readmeFilename":"README.md"}