{"id":10940,"library":"get-root-node-polyfill","title":"Node.prototype.getRootNode Polyfill","description":"This package provides a polyfill for the `Node.prototype.getRootNode` DOM method, as defined by the WHATWG DOM specification. It allows developers to use this modern DOM API in environments that do not natively support it, ensuring consistent behavior across various browsers and Node.js environments where DOM-like structures might exist (e.g., JSDOM). The current stable version is 1.0.0. Polyfills like this typically have a low release cadence, updating primarily for specification changes or critical bug fixes, as their goal is to align with native browser implementations. Its key differentiator is its focused and spec-compliant implementation of a specific web standard, enabling forward compatibility for applications targeting modern DOM APIs while supporting older runtimes. This project helps bridge the gap for applications needing to support a wide range of browser versions.","status":"active","version":"1.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/foobarhq/get-root-node-polyfill","tags":["javascript","DOM","DOM4","Polyfill","getRootNode","rootNode","Node"],"install":[{"cmd":"npm install get-root-node-polyfill","lang":"bash","label":"npm"},{"cmd":"yarn add get-root-node-polyfill","lang":"bash","label":"yarn"},{"cmd":"pnpm add get-root-node-polyfill","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This module applies the polyfill as a side effect, directly modifying `Node.prototype` if the method is not natively available. It is typically imported once at application startup to ensure the API is present globally. This pattern is CommonJS-specific; for ESM, it would typically be `import 'get-root-node-polyfill/implement';`.","symbol":"Node.prototype.getRootNode (polyfill implementation)","correct":"require('get-root-node-polyfill/implement');"},{"note":"This imports the `getRootNode` function as a standalone utility, allowing it to be called with `.call()` or `.apply()` on any node-like object without modifying `Node.prototype`. The package's main entry point uses CommonJS exports, so direct ES module default imports are incorrect; `import * as getRootNode from 'get-root-node-polyfill';` would be the closest ESM equivalent for named exports in a CJS module.","wrong":"import getRootNode from 'get-root-node-polyfill';","symbol":"getRootNode (standalone function)","correct":"const getRootNode = require('get-root-node-polyfill');"},{"note":"Imports a function that returns a boolean indicating whether `Node.prototype.getRootNode` is natively available in the current environment. This can be used to conditionally apply the polyfill.","symbol":"isImplemented","correct":"const isImplemented = require('get-root-node-polyfill/is-implemented');"}],"quickstart":{"code":"// Quickstart:\n// Ensure the polyfill is applied early in your application lifecycle.\n// In a browser environment, this would extend the native Node.prototype.\nrequire('get-root-node-polyfill/implement');\n\n// A minimal mock-up of a DOM Node for demonstration in a non-browser environment\n// In a real browser application, you'd use actual DOM elements.\nclass MockNode {\n  constructor(name, parent = null, host = null) {\n    this.nodeName = name; // For identification in logs\n    this.parentNode = parent; // Standard DOM parent\n    this.host = host;       // For elements inside a Shadow DOM, this points to the Shadow Host\n  }\n\n  // Simulate calling the getRootNode method (which is now polyfilled on Node.prototype)\n  // If MockNode were a real Node, we'd just call this.getRootNode(options)\n  // For this example, we directly call the polyfilled method, passing 'this' as context.\n  getTheRootNode(options) {\n    // The polyfill, once 'implement' is called, makes this available on Node.prototype.\n    // We simulate its call here for our mock object.\n    const getRootNodePolyfill = require('get-root-node-polyfill');\n    return getRootNodePolyfill.call(this, options);\n  }\n}\n\n// 1. Regular DOM-like structure\nconst docRoot = new MockNode('document');\nconst body = new MockNode('body', docRoot);\nconst div = new MockNode('div', body);\nconst span = new MockNode('span', div);\n\nconsole.log('--- Regular DOM-like structure ---');\n// Get root node for a regular element (span)\nlet root = span.getTheRootNode({ composed: true });\nconsole.log(`Span root (composed: true): ${root.nodeName} (Expected: document - ${root.nodeName === docRoot.nodeName})`);\n\nroot = span.getTheRootNode({ composed: false });\nconsole.log(`Span root (composed: false): ${root.nodeName} (Expected: document - ${root.nodeName === docRoot.nodeName})`);\n\n\n// 2. Structure involving a \"Shadow DOM\" host\n// The shadow host is 'shadow-host-element'\nconst shadowHostElement = new MockNode('shadow-host-element', body);\n// The shadow root itself is conceptually contained by shadowHostElement.\n// For the purpose of getRootNode, an element *inside* a shadow tree has its 'host' property set.\nconst elementInShadowTree = new MockNode('element-in-shadow-tree', null, shadowHostElement); // parentNode is null, host is shadowHostElement\n\nconsole.log('\n--- Shadow DOM-like structure ---');\n// Get root node for element within shadow tree\nroot = elementInShadowTree.getTheRootNode({ composed: true });\nconsole.log(`Element in Shadow Tree root (composed: true): ${root.nodeName} (Expected: document - ${root.nodeName === docRoot.nodeName})`);\n\nroot = elementInShadowTree.getTheRootNode({ composed: false });\nconsole.log(`Element in Shadow Tree root (composed: false): ${root.nodeName} (Expected: shadow-host-element - ${root.nodeName === shadowHostElement.nodeName})`);\n\n// Check if the polyfill was actually applied\nconst isImplementedNatively = require('get-root-node-polyfill/is-implemented')();\nconsole.log(`\nIs Node.prototype.getRootNode natively implemented? ${isImplementedNatively ? 'Yes' : 'No (polyfill active)'}`);","lang":"javascript","description":"Demonstrates how to apply the `getRootNode` polyfill and then use the method on simulated DOM-like nodes. It showcases the behavior of the `composed` option for both regular and shadow DOM-like hierarchies in a runnable JavaScript environment."},"warnings":[{"fix":"Ensure that `require('get-root-node-polyfill/implement');` is called only once in your application's bootstrap process, or conditionally apply it after checking `require('get-root-node-polyfill/is-implemented')()`.","message":"Including `get-root-node-polyfill/implement` multiple times or alongside other `getRootNode` polyfills can lead to conflicts or unexpected behavior if they are not idempotent or implement the spec differently. It may overwrite existing implementations.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always explicitly specify `{ composed: true }` when you intend to get the true root of the document, even if the element is inside a Shadow DOM. Use `{ composed: false }` when you need the root of the current inclusive ancestor's tree (e.g., the ShadowRoot itself).","message":"The `composed` option (defaulting to `false`) dictates whether the `getRootNode` method should traverse beyond shadow boundaries. Misunderstanding this option can lead to incorrect root node identification, especially in applications heavily utilizing Shadow DOM.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Profile your application in target environments to identify any performance bottlenecks. Consider using tools like Babel's `useBuiltIns: 'usage'` with core-js to only include necessary polyfills for specific target environments, reducing bundle size and potential overhead.","message":"While this polyfill provides spec-compliant behavior, relying on any polyfill can introduce a slight performance overhead compared to native browser implementations. This is generally negligible but can be a factor in highly performance-sensitive applications or on extremely old/resource-constrained devices.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add `require('get-root-node-polyfill/implement');` at the entry point of your application to ensure the polyfill is active. If in a Node.js environment without a DOM, use a library like JSDOM or explicitly call the standalone function: `const getRootNode = require('get-root-node-polyfill'); getRootNode.call(someElement, options);`.","cause":"The `Node.prototype.getRootNode` method was called on an element before the polyfill (via `get-root-node-polyfill/implement`) was applied, or in an environment where `Node` is not globally defined and the standalone function was not used.","error":"TypeError: someElement.getRootNode is not a function"},{"fix":"If working with DOM-like structures in Node.js, integrate a DOM emulation library like `jsdom`. Alternatively, when using `get-root-node-polyfill` directly, ensure you are using the standalone function (`require('get-root-node-polyfill')`) and applying it to your custom objects, rather than relying on `Node.prototype` modification.","cause":"This error occurs in Node.js environments when the polyfill or its related logic expects the global `Node` constructor (part of the DOM API) to be present, but it's not. Standard Node.js does not have a DOM.","error":"ReferenceError: Node is not defined"}],"ecosystem":"npm"}