From 08fda887b78ea7e2c6ddaa4aa79ffc9b91d956e2 Mon Sep 17 00:00:00 2001 From: ba55ie Date: Fri, 6 Jan 2023 11:56:16 +0100 Subject: [PATCH 1/3] Fix add the missing slot attribute to child nodes --- packages/integrations/lit/package.json | 3 ++- packages/integrations/lit/server.js | 21 ++++++++++++++++----- pnpm-lock.yaml | 12 ++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/integrations/lit/package.json b/packages/integrations/lit/package.json index 9781094c7003..24410f7e8fb5 100644 --- a/packages/integrations/lit/package.json +++ b/packages/integrations/lit/package.json @@ -33,7 +33,8 @@ "test": "mocha" }, "dependencies": { - "@lit-labs/ssr": "^2.2.0" + "@lit-labs/ssr": "^2.2.0", + "parse5": "^7.1.2" }, "devDependencies": { "astro": "workspace:*", diff --git a/packages/integrations/lit/server.js b/packages/integrations/lit/server.js index 2f90766729b9..59c79f55befd 100644 --- a/packages/integrations/lit/server.js +++ b/packages/integrations/lit/server.js @@ -1,6 +1,7 @@ import './server-shim.js'; import '@lit-labs/ssr/lib/render-lit-html.js'; import { LitElementRenderer } from '@lit-labs/ssr/lib/lit-element-renderer.js'; +import * as parse5 from 'parse5'; function isCustomElementTag(name) { return typeof name === 'string' && /-/.test(name); @@ -58,12 +59,22 @@ function* render(Component, attrs, slots) { yield ''; } if (slots) { - for (const [slot, value] of Object.entries(slots)) { - if (slot === 'default') { - yield `${value || ''}`; - } else { - yield `${value || ''}`; + for (let [slot, value = ''] of Object.entries(slots)) { + if (slot !== 'default' && value) { + // Parse the value as a concatenated string + const fragment = parse5.parseFragment(`${value}`); + + // Add the missing slot attribute to child Element nodes + for (const node of fragment.childNodes) { + if (node.tagName && !node.attrs.some(({ name }) => name === 'slot')) { + node.attrs.push({ name: 'slot', value: slot}); + } + } + + value = parse5.serialize(fragment); } + + yield value; } } yield ``; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a91c27eb8359..94120de9316a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2874,9 +2874,11 @@ importers: cheerio: ^1.0.0-rc.11 lit: ^2.2.5 mocha: ^9.2.2 + parse5: ^7.1.2 sass: ^1.52.2 dependencies: '@lit-labs/ssr': 2.2.3 + parse5: 7.1.2 devDependencies: astro: link:../../astro astro-scripts: link:../../../scripts @@ -11158,7 +11160,7 @@ packages: domhandler: 5.0.3 domutils: 3.0.1 htmlparser2: 8.0.1 - parse5: 7.1.1 + parse5: 7.1.2 parse5-htmlparser2-tree-adapter: 7.0.0 dev: true @@ -11869,7 +11871,6 @@ packages: /entities/4.4.0: resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} engines: {node: '>=0.12'} - dev: true /eol/0.9.1: resolution: {integrity: sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==} @@ -15788,18 +15789,17 @@ packages: resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} dependencies: domhandler: 5.0.3 - parse5: 7.1.1 + parse5: 7.1.2 dev: true /parse5/6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} dev: false - /parse5/7.1.1: - resolution: {integrity: sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==} + /parse5/7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} dependencies: entities: 4.4.0 - dev: true /parseurl/1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} From ad9575bfe74a6779ff61c6a40ce7c8300bcc870f Mon Sep 17 00:00:00 2001 From: ba55ie Date: Fri, 6 Jan 2023 11:56:55 +0100 Subject: [PATCH 2/3] Add lit slot tests --- .../lit-element/src/pages/slots.astro | 30 +++++++++++++++-- .../test/fixtures/lit-element/tsconfig.json | 4 ++- packages/astro/test/lit-element.test.js | 32 +++++++++++++++---- packages/astro/test/ssr-lit.test.js | 2 +- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/packages/astro/test/fixtures/lit-element/src/pages/slots.astro b/packages/astro/test/fixtures/lit-element/src/pages/slots.astro index b8fc4963c6f0..6ef0cd1832a7 100644 --- a/packages/astro/test/fixtures/lit-element/src/pages/slots.astro +++ b/packages/astro/test/fixtures/lit-element/src/pages/slots.astro @@ -7,9 +7,33 @@ import {MyElement} from '../components/my-element.js'; LitElement | Slot - -
default
-
named
+ +
my-element default 1
+
my-element default 2
+ +

my-element named 1

+

my-element named 2

+ +
    +
  • Custom elements
  • +
  • Shadow DOM
  • +
  • HTML templates
  • +
+ + +

slotted my-element default

+ +
slotted my-element named 1
+
slotted my-element named 2
+ + +

slotted slotted my-element default 1

+
slotted slotted my-element default 2
+ +
slotted slotted my-element named 1
+
slotted slotted my-element named 2
+
+
diff --git a/packages/astro/test/fixtures/lit-element/tsconfig.json b/packages/astro/test/fixtures/lit-element/tsconfig.json index f79d7bdca151..504cd646e149 100644 --- a/packages/astro/test/fixtures/lit-element/tsconfig.json +++ b/packages/astro/test/fixtures/lit-element/tsconfig.json @@ -1,3 +1,5 @@ { - "experimentalDecorators": true + "compilerOptions": { + "experimentalDecorators": true + } } diff --git a/packages/astro/test/lit-element.test.js b/packages/astro/test/lit-element.test.js index 3ee0a00a52d1..c14f5af55388 100644 --- a/packages/astro/test/lit-element.test.js +++ b/packages/astro/test/lit-element.test.js @@ -70,15 +70,35 @@ describe('LitElement test', function () { const html = await fixture.readFile('/slots/index.html'); const $ = cheerio.load(html); - expect($('my-element').length).to.equal(1); + const $rootMyElement = $('#root'); + const $slottedMyElement = $('#slotted'); + const $slottedSlottedMyElement = $('#slotted-slotted'); - const [defaultSlot, namedSlot] = $('template').siblings().toArray(); + expect($('my-element').length).to.equal(3); - // has default slot content in lightdom - expect($(defaultSlot).text()).to.equal('default'); + // Root my-element + expect($rootMyElement.children('.default').length).to.equal(2); + expect($rootMyElement.children('.default').eq(1).text()).to.equal('my-element default 2'); - // has named slot content in lightdom - expect($(namedSlot).text()).to.equal('named'); + expect($rootMyElement.children('[slot="named"]').length).to.equal(4); + expect($rootMyElement.children('[slot="named"]').eq(1).text()).to.equal('my-element named 2'); + expect($rootMyElement.children('[slot="named"]').eq(2).attr('id')).to.equal('list'); + expect($rootMyElement.children('[slot="named"]').eq(3).attr('id')).to.equal('slotted'); + + // Slotted my-element first level + expect($slottedMyElement.children('.default').length).to.equal(1); + expect($slottedMyElement.children('.default').eq(0).text()).to.equal('slotted my-element default'); + + expect($slottedMyElement.children('[slot="named"]').length).to.equal(3); + expect($slottedMyElement.children('[slot="named"]').eq(1).text()).to.equal('slotted my-element named 2'); + expect($slottedMyElement.children('[slot="named"]').eq(2).attr('id')).to.equal('slotted-slotted'); + + // Slotted my-element second level + expect($slottedSlottedMyElement.children('.default').length).to.equal(2); + expect($slottedSlottedMyElement.children('.default').eq(1).text()).to.equal('slotted slotted my-element default 2'); + + expect($slottedSlottedMyElement.children('[slot="named"]').length).to.equal(2); + expect($slottedSlottedMyElement.children('[slot="named"]').eq(1).text()).to.equal('slotted slotted my-element named 2'); }); it('Is able to build when behind getStaticPaths', async () => { diff --git a/packages/astro/test/ssr-lit.test.js b/packages/astro/test/ssr-lit.test.js index 53555b9838ac..98d58b395acd 100644 --- a/packages/astro/test/ssr-lit.test.js +++ b/packages/astro/test/ssr-lit.test.js @@ -25,7 +25,7 @@ describe('Lit integration in SSR', () => { } it('Is able to load', async () => { - delete globalThis.window; + delete globalThis.window; // On Windows this results in `ReferenceError: window is not defined` const html = await fetchHTML('/'); const $ = cheerioLoad(html); expect($('#win').text()).to.equal('function'); From a1b10b98a9bf9065069b6572604981cfa02a0466 Mon Sep 17 00:00:00 2001 From: ba55ie Date: Fri, 6 Jan 2023 12:49:36 +0100 Subject: [PATCH 3/3] Add changeset --- .changeset/kind-beers-give.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/kind-beers-give.md diff --git a/.changeset/kind-beers-give.md b/.changeset/kind-beers-give.md new file mode 100644 index 000000000000..2cda00bcfd51 --- /dev/null +++ b/.changeset/kind-beers-give.md @@ -0,0 +1,6 @@ +--- +'astro': patch +'@astrojs/lit': patch +--- + +Fix Lit slotted content