Skip to content

Commit

Permalink
ShadowDOM support needs to be fixed.
Browse files Browse the repository at this point in the history
  • Loading branch information
NullVoxPopuli committed Feb 4, 2024
1 parent be68713 commit cca240a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 22 deletions.
48 changes: 27 additions & 21 deletions apps/repl/app/components/shadowed.gts
@@ -1,46 +1,52 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

import { modifier } from 'ember-modifier';
import { cell } from 'ember-resources';

import type { TOC } from '@ember/component/template-only';
const attachShadow = modifier((element: Element, [set]: [(shadowRoot: HTMLDivElement) => void]) => {
let shadow = element.attachShadow({ mode: 'open' });
let div = document.createElement('div');

type SetShadow = ReturnType<typeof cell<ShadowRoot>>['set'];
shadow.appendChild(div);

const attachShadow = modifier((element: Element, [setShadow]: [SetShadow]) => {
setShadow(element.attachShadow({ mode: 'open' }));
set(div);
});

// index.html has the production-fingerprinted references to these links
// Ideally, we'd have some pre-processor scan everything for references to
// assets in public, but idk how to set that up
const getStyles = () => [...document.head.querySelectorAll('link')].map((link) => link.href);

const shadowRoot = () => cell<ShadowRoot>();

export const Shadowed: TOC<{
export class Shadowed extends Component<{
Element: HTMLDivElement;
Args: {
omitStyles?: boolean;
};
Blocks: { default: [] };
}> = <template>
{{#let (shadowRoot) as |shadow|}}
{{! @glint-ignore }}
<div data-shadow {{attachShadow shadow.set}} ...attributes></div>
}> {
@tracked shadow: HTMLDivElement | undefined;

setShadow = async (shadowRoot: HTMLDivElement) => {
await Promise.resolve();

this.shadow = shadowRoot;
}

<template>
<div data-shadow {{attachShadow this.setShadow}} ...attributes></div>

{{#if shadow.current}}
{{#in-element shadow.current}}
{{#if this.shadow}}
{{#in-element this.shadow}}
{{#unless @omitStyles}}
{{#let (getStyles) as |styles|}}
{{#each styles as |styleHref|}}
<link rel="stylesheet" href={{styleHref}} />
{{/each}}
{{/let}}
{{#each (getStyles) as |styleHref|}}
<link rel="stylesheet" href={{styleHref}} />
{{/each}}
{{/unless}}

{{yield}}
{{/in-element}}
{{/if}}
{{/let}}
</template>;
</template>
}

export default Shadowed;
2 changes: 1 addition & 1 deletion apps/repl/package.json
Expand Up @@ -102,7 +102,7 @@
"ember-qunit": "^8.0.2",
"ember-resolver": "^11.0.1",
"ember-route-template": "^1.0.3",
"ember-source": "^5.6.0",
"ember-source": "~5.5.0",
"ember-template-imports": "^3.4.2",
"ember-template-lint": "^5.13.0",
"ember-template-lint-plugin-prettier": "^5.0.0",
Expand Down
27 changes: 27 additions & 0 deletions apps/repl/tests/rendering/components/shadowed-test.gts
@@ -0,0 +1,27 @@
import { find, render } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';

import { Shadowed } from 'limber/components/shadowed';

module('Rendering | <Shadowed>', function (hooks) {
setupRenderingTest(hooks);

test('it works', async function (assert) {
await render(
<template>
out of shadow

<Shadowed>
in shadow
</Shadowed>
</template>
);

assert.dom().hasText('out of shadow');
assert.dom().doesNotContainText('in shadow');
// assort.dom forgot that ShadowDom is a thing
// assert.dom(find('[data-shadow]')?.shadowRoot).hasText('in shadow');
assert.ok(find('[data-shadow]')?.shadowRoot?.textContent?.includes('in shadow'));
});
});

0 comments on commit cca240a

Please sign in to comment.