-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow initAll to be scoped to a specific part of a page #1216
Conversation
One thing to think about is we have had users report errors when running Doesn't necessarily block this, but I think if we solved that other issue it'd be fine to run initAll whenever new markup is injected into the page. It's also worth noting that custom elements (web components) avoid this issue, and are enhanced whenever the browser detects the custom element. If we do go with this approach, we'd need to document this scoping feature and have tests for it. |
I've chatted with @alex-ju about this. It seems that there might be value in building in both approaches:
The main value with 2. is initialising based on a scope with DOM elements that are added after |
Agree it probably makes sense to do both, however...
Since the user will be running 'initAll' themselves I don't think there's much overhead, I'd understand if we were listening to DOM changes with mutation observers maybe... |
I've added done the following:
|
Thanks for taking the time to properly update this PR @NickColley. This is very much aligned with the need for a scoped initialisation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a CHANGELOG entry
@NickColley changelog entry added. thanks a lot for the test and doc! |
OK I think this is ready for review |
@@ -154,6 +154,21 @@ Including the script elsewhere will stop components from functioning or displayi | |||
</html> | |||
``` | |||
|
|||
#### Initialise GOV.UK Frontend in only certain sections of a page |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ 📖
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soupdragon99 has helped on this one
src/all.test.js
Outdated
// that we can interact with to check if they're interactive. | ||
|
||
// Check that the conditional reveal component has a conditional section that would open if enhanced. | ||
await page.waitForSelector('#conditional-not-scoped-1', { visible: false }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use a combination of visible: false
, visible: true
and hidden: true
in this test – is there a difference between them, or are they just opposites of each other?
It'd be good to be consistent with either the key (visible: true
, visible: false
) or the value (visible: true
, hidden: true
) if so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's some nuance to it, you can have something in the DOM but not visible, or something not in the DOM and therefore not visible I believe.
I'll try and clarify this.
await page.click('[for="not-scoped-1"]') | ||
|
||
// Check that when it is clicked that nothing opens, which shows that it has not been enhanced. | ||
await page.waitForSelector('#conditional-not-scoped-1', { hidden: true }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this definitely test what we want? It's 'waiting' for something was hidden to still be hidden (which it already was…), rather that asserting that it never becomes visible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was indeed testing it when I remove the scope functionality and ran these tests.
@@ -90,6 +90,28 @@ describe('GOV.UK Frontend', () => { | |||
}, component) | |||
}) | |||
}) | |||
it('can be initialised scoped to certain sections of the page', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense, but only tests the instantiation of a single component and feels like it could be relatively fragile if we e.g. changed the way that conditional reveals work.
Wondering if there's a better way to test this, maybe as a unit test rather than as an integration test, e.g. passing a stubbed DomElement
as the scope and asserting that querySelectorAll
is called, and/or stubbing document
and asserting that it doesn't get called?
(Just worth thinking about, this isn't a blocking comment 👍)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are somewhat bound by the limitations of our testing setup.
I'll see if I can stub an element like you've suggested...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally fair, don't spend too much time on it 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think we'd have to run the test using JSDOM rather than in a browser, and it's not clear that you can spy on an element so I'll try to make the current setup clearer but not sure it's worth the time spent...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if you think the current approach is too risky
CHANGELOG.md
Outdated
@@ -14,10 +14,29 @@ | |||
|
|||
🆕 New features: | |||
|
|||
- Enable GOV.UK Frontend components to be scoped the a specific container |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this read 'scoped to a specific container' or 'scoped to the specific container' at the moment it's not clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔭
@alex-ju thanks for your patience with these pull requests, sorry I did not fully understand your issue the first time. Let us know when you need us to release these and we'll get it out for you. 👍 |
Thanks a lot for pairing on it @NickColley! Would be great to have it in the next planned release. |
We currently initialise component at the document level, but there are cases when components are being injected after the document is loaded. I'm proposing to allow
initAll
function to be scoped, so it can be called for a specific container or part of the page.Note
We can replace scope with any name that makes more sense.