Description
I'd like to propose a feature enhancement for highlightAll()
to support modern web development patterns, specifically Web Components and Shadow DOM.
The Current Limitation
Currently, hljs.highlightAll()
is hardcoded to search the global document
for code blocks to highlight. This works perfectly for static websites but presents a challenge when content is rendered within an encapsulated scope, such as a Shadow DOM root or a specific element loaded dynamically.
Proposed Solution
I propose that highlightAll()
be updated to optionally accept a configuration object with a root
property. This would allow developers to specify the parent element within which highlightAll
should search for code blocks.
The new signature could look like this:
hljs.highlightAll({ root = document })
This would be fully backward-compatible. Calling hljs.highlightAll()
with no arguments would default to the current behavior of using document
as the root.
My Use Case
I am the author of a browser userscript that injects a UI onto third-party pages to interact with an AI. To prevent any CSS conflicts with the host page, my entire UI is rendered inside a Shadow DOM.
When the AI returns a response containing code blocks, they are added to my UI inside this shadow root. Because hljs.highlightAll()
cannot see inside the Shadow DOM, I cannot use it.
Current Method (verbose and requires manual iteration):
My current, working solution requires manually querying the shadow root and iterating over the results, which is less convenient and elegant.
// This code must be run every time new content is added.
const shadowRoot = document.getElementById('my-script-container').shadowRoot;
shadowRoot.querySelectorAll('pre code').forEach(hljs.highlightElement);
Proposed Method (clean and intuitive):
If this feature were implemented, the code would be simplified to a single, intuitive call. This becomes especially powerful when dealing with dynamic content.
// This single call would handle everything within my UI's scope.
const shadowRoot = document.getElementById('my-script-container').shadowRoot;
hljs.highlightAll({ root: shadowRoot });
Why This Should Be a Feature
-
Aligns with Modern Web Development: Web Components and the Shadow DOM are now standard browser features used to build encapsulated, reusable widgets. Libraries, browser extensions, and embedded components all rely on this encapsulation. A scoped
highlightAll()
would make the library significantly easier to use in these modern contexts. -
Improves Developer Experience (DX): It provides a much cleaner, more declarative API. The developer's intent is "highlight everything in this area," and
hljs.highlightAll({ root: myArea })
expresses that perfectly. It removes the need for manual querying and looping boilerplate. -
Potential Performance Gains: In large Single-Page Applications (SPAs), re-running
highlightAll()
on the entiredocument
can be inefficient. A scoped version would allow developers to efficiently re-highlight only the specific parts of the view that have been updated.
Thank you for your consideration. I believe this enhancement would be a great addition to an already fantastic library and would be highly appreciated by the developer community working with modern web components.