Skip to content

Commit

Permalink
[labs/testing] Fix DSD feature detection and use setHTMLUnsafe for pa…
Browse files Browse the repository at this point in the history
…rsing (#4541)
  • Loading branch information
augustjk committed Feb 7, 2024
1 parent d68f5c7 commit d128391
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-rats-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lit-labs/testing': patch
---

Fix declarative shadowroot detection and parsing to use the correct spec behavior.
36 changes: 11 additions & 25 deletions packages/labs/testing/src/lib/fixtures/ssr-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,11 @@ import type {LitElement, TemplateResult} from 'lit';
import type {FixtureOptions, SsrFixtureOptions} from './fixture-options.js';
import type {Payload} from '../lit-ssr-plugin.js';

// Enhance DOMParser's parseFromString method to include `includeShadowRoots`
// option for browsers that support declarative shadow DOM as proposed in
// https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md#mitigation.
// Enhance `Element` with method that parses declarative shadow DOM
// See https://github.com/whatwg/html/pull/9538
declare global {
interface DOMParser {
parseFromString(
string: string,
type: DOMParserSupportedType,
option: {includeShadowRoots: boolean}
): Document;
interface Element {
setHTMLUnsafe(html: string): void;
}
}

Expand Down Expand Up @@ -77,22 +72,13 @@ export async function ssrFixture<T extends HTMLElement>(

const container = createContainer();

if (HTMLTemplateElement.prototype.hasOwnProperty('shadowRoot')) {
// Browser natively supports declarative shadowroot.
// Shadowroots are only parsed and attached during initial HTML parsing.
// innerHTML will not work and must use DOMParser.
// See https://web.dev/declarative-shadow-dom/#parser-only
const fragment = new DOMParser().parseFromString(
// DOMParser could separate opening lit-part comment from others as it
// selectively places some elements into <body>. Wrapping the entire
// rendered content in <body> preserves order.
'<body>' + rendered + '</body>',
'text/html',
{
includeShadowRoots: true,
}
);
container.replaceChildren(...Array.from(fragment.body.childNodes));
if (
HTMLTemplateElement.prototype.hasOwnProperty('shadowRootMode') &&
'setHTMLUnsafe' in Element.prototype
) {
// Browser natively supports Declarative Shadow DOM and `setHTMLUnsafe()`
// which is needed for DSD to be parsed and attached.
container.setHTMLUnsafe(rendered);
} else {
// Utilize ponyfill
container.innerHTML = rendered;
Expand Down

0 comments on commit d128391

Please sign in to comment.