From d43ce003c45eb94872843cab2e2e72d4eef1a5a2 Mon Sep 17 00:00:00 2001 From: Tobias Date: Tue, 11 Mar 2025 16:14:24 +0100 Subject: [PATCH 1/3] fix: Resolve issue with shadow DOM Router should now be able to find tags within open shadow DOMs. --- src/router.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/router.js b/src/router.js index ac5d5cc..bfec0c6 100644 --- a/src/router.js +++ b/src/router.js @@ -16,7 +16,8 @@ const UPDATE = (state, url) => { return state; } - const link = url.target.closest('a[href]'), + const elements = url.composedPath(); + const link = elements.find(el => el.tagName?.toLowerCase() === 'a' && el.href), href = link && link.getAttribute('href'); if ( !link || From 5250fa2f9f02cf5f8462d34bcdee9a983ac2bd9f Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 12 Mar 2025 15:17:23 +0100 Subject: [PATCH 2/3] test: Add test case for shadow DOM --- test/router.test.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/router.test.js b/test/router.test.js index 984699f..e091a2d 100644 --- a/test/router.test.js +++ b/test/router.test.js @@ -927,6 +927,41 @@ describe('Router', () => { await sleep(10); expect(scratch).to.have.property('textContent', 'data'); }); + + it('should intercept clicks on links inside open shadow DOM', async () => { + const shadowlink = document.createElement('a'); + shadowlink.href = '/shadow'; + shadowlink.textContent = 'Shadow Link'; + shadowlink.addEventListener('click', e => e.preventDefault()); + + const attachShadow = (el) => { + if (!el || el.shadowRoot) return; + const shadowroot = el.attachShadow({ mode: 'open' }); + shadowroot.appendChild(shadowlink); + } + + const Home = sinon.fake(() =>
); + const Shadow = sinon.fake(() =>
Shadow Route
); + + render( + + + + + + + , + scratch + ); + + shadowlink.click(); + + await sleep(1); + + expect(loc).to.deep.include({ url: '/shadow' }); + expect(Shadow).to.have.been.calledOnce; + expect(scratch).to.have.property('textContent', 'Shadow Route'); + }); }); const MODE_HYDRATE = 1 << 5; From 812fc6cfc64419bd2bd43cd923674fc42c3f55cc Mon Sep 17 00:00:00 2001 From: Tobias Jensen Date: Wed, 12 Mar 2025 15:21:22 +0100 Subject: [PATCH 3/3] Update src/router.js Co-authored-by: Ryan Christian <33403762+rschristian@users.noreply.github.com> --- src/router.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/router.js b/src/router.js index bfec0c6..4926f33 100644 --- a/src/router.js +++ b/src/router.js @@ -16,8 +16,7 @@ const UPDATE = (state, url) => { return state; } - const elements = url.composedPath(); - const link = elements.find(el => el.tagName?.toLowerCase() === 'a' && el.href), + const link = url.composedPath().find(el => el.nodeName == 'A' && el.href), href = link && link.getAttribute('href'); if ( !link ||