Skip to content
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

Merged
merged 4 commits into from
Mar 8, 2019
Merged

Allow initAll to be scoped to a specific part of a page #1216

merged 4 commits into from
Mar 8, 2019

Conversation

alex-ju
Copy link
Contributor

@alex-ju alex-ju commented Feb 21, 2019

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.

@NickColley
Copy link
Contributor

NickColley commented Feb 21, 2019

One thing to think about is we have had users report errors when running initAll twice, and we thought about solving that a different way by making it safe to call it multiple times:

#1127

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.

@NickColley NickColley added the awaiting triage Needs triaging by team label Feb 21, 2019
@kellylee-gds kellylee-gds added submitted-by-user ⚠️ high priority Used by the team when triaging and removed awaiting triage Needs triaging by team labels Feb 27, 2019
@kellylee-gds kellylee-gds added this to Needs review in Design System Sprint Board via automation Feb 27, 2019
@kellylee-gds kellylee-gds moved this from Needs review to In progress in Design System Sprint Board Feb 27, 2019
@kellylee-gds kellylee-gds moved this from In progress to Icebox in Design System Sprint Board Feb 27, 2019
@hannalaakso
Copy link
Member

hannalaakso commented Feb 28, 2019

I've chatted with @alex-ju about this. It seems that there might be value in building in both approaches:

  1. Do a check to see if the component is already initialised (Investigate components being initialised more than once #1127 and what @NickColley drafted)
  2. Initialising against a certain scope

The main value with 2. is initialising based on a scope with DOM elements that are added after document.load to avoid querying the whole DOM (this is linked to #1215).

@NickColley
Copy link
Contributor

NickColley commented Mar 4, 2019

Agree it probably makes sense to do both, however...

avoid querying the whole DOM

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...

@timpaul timpaul moved this from Icebox to Backlog in Design System Sprint Board Mar 4, 2019
@NickColley
Copy link
Contributor

NickColley commented Mar 5, 2019

I've added done the following:

  1. Made the JavaScript work without ES2015 features
  2. Add a test page that demonstrates the scoping and corresponding puppeteer tests.
  3. Added some documentation to the installation instructions to explain how to use this feature.

@alex-ju
Copy link
Contributor Author

alex-ju commented Mar 5, 2019

Thanks for taking the time to properly update this PR @NickColley. This is very much aligned with the need for a scoped initialisation.

Copy link
Contributor

@NickColley NickColley left a 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

Design System Sprint Board automation moved this from Backlog to In progress Mar 6, 2019
@NickColley NickColley added this to the [NEXT] milestone Mar 6, 2019
@NickColley NickColley moved this from In progress to Needs review in Design System Sprint Board Mar 6, 2019
@alex-ju
Copy link
Contributor Author

alex-ju commented Mar 6, 2019

@NickColley changelog entry added. thanks a lot for the test and doc!

@NickColley NickColley dismissed their stale review March 6, 2019 16:28

Changelog has been added

Design System Sprint Board automation moved this from Needs review to In progress Mar 6, 2019
@NickColley
Copy link
Contributor

OK I think this is ready for review

@kellylee-gds kellylee-gds moved this from In progress to Needs review in Design System Sprint Board Mar 7, 2019
@alphagov alphagov deleted a comment from alex-ju Mar 8, 2019
@@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️ 📖

Copy link
Contributor

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 })
Copy link
Member

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.

Copy link
Contributor

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 })
Copy link
Member

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.

Copy link
Contributor

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 () => {
Copy link
Member

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 👍)

Copy link
Contributor

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...

Copy link
Member

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 👍

Copy link
Contributor

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...

Copy link
Contributor

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

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.

Copy link
Member

@36degrees 36degrees left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔭

Design System Sprint Board automation moved this from Needs review to Ready to merge Mar 8, 2019
@NickColley NickColley merged commit 74f6d5a into alphagov:master Mar 8, 2019
Design System Sprint Board automation moved this from Ready to merge to Done Mar 8, 2019
@NickColley
Copy link
Contributor

@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. 👍

@alex-ju
Copy link
Contributor Author

alex-ju commented Mar 12, 2019

Thanks a lot for pairing on it @NickColley! Would be great to have it in the next planned release.

@alex-ju alex-ju deleted the allow-scoped-init branch March 12, 2019 09:04
@NickColley NickColley mentioned this pull request Mar 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚠️ high priority Used by the team when triaging
Projects
Development

Successfully merging this pull request may close these issues.

None yet

6 participants