-
Notifications
You must be signed in to change notification settings - Fork 20
Use an AddonsApplication
to manage load/reload of all addons
#504
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
Conversation
Additional elements shouldn't be needed in our structure. This is how we can use ContextRoot with `document.html` as the context root for providers/consumers of the config context.
Everything is loaded by the `application.js` file now.
a090d72
to
6887d85
Compare
This is to be able to use our own event without defining the META HTML attribute on every single page. We don't depend on a specific API response.
This is required to be able to dynamically update the URLs from the versions in the flyout when the page is changed using `history` object (without reloading / SPA) as Docusaurus does. In that scenario we cannot use the HTML META tag because it was injected with the old value by CF Worker. Note that the CF Worker is not run after the initial request on SPA. The addons frontend will use this attribute to update those URLs accordingly when the URL changes. Required by: * readthedocs/addons#504
We cannot use the META HTML tag because it's added only on the first request. See readthedocs/readthedocs.org#11940
I was able to make everything work here 🎉 and I'm very happy with the solution I arrived at. It's a lot simpler than the original proposal. This PR is ready for review. |
63c3a6b
to
fb64f99
Compare
Hrm, I'm a bit confused on this pattern, there seems to be a few patterns mixing here. Why use the context API at all here? The context API is specifically for reactive element properties, so if this context isn't read from each addon element ( What you have here doesn't seem like it will give a reactive property to each addon -- if we update With this approach, we also don't need a It's a little difficult to follow but it feels like what you have here could be simplified down to executing this logic in |
Yes.
Currently, without the code of this PR, the Addons API is fetch only once when the page is loaded. If the user clicks on another page that doesn't perform a full reload (eg. as Docusaurus does) there is no new request to Addons API and addons are not re-initialized. That means that all the URLs from the flyout are out of date and point to the wrong page. You can try the current behavior following these steps:
|
The question is: can we use We don't require a reactive property on each addon -- we only need to subscribe as a |
It seems that's not possible. I gave it a quick try and I got the error:
|
ecef590
to
4ee0573
Compare
Boom! 💯 Lit Context are not required at all for what I want to do, actually. Thanks for your comment, it helped me to understand the workflow a lot better. I'm using just events to communicate internally and pass the I re-wrote the code to remove everything related to Lit Context. The structure was correct (using a manager class, like Let me know your thoughts! I think it's very clear now. |
4ee0573
to
237aa0d
Compare
The `AddonsApplication` keeps a list of all the addons instances created when the page was loaded (`AddonsApplication.addonsInstances`). Then, when the `READTHEDOCS_URL_CHANGED` event is fired, we check if we already have instances created and, in that case, we call `addon.loadConfig(config)` to re-configure those instances with the new `config` object --without creating new ones. This commit includes some refactor as well: - Share all the `constructor()` method all accross addons - Override the `constructor()` for those addons that are not LitElements - Create `loadConfig()` methods for those addons that are not LitElements - Remove code commented out
Before dispatching the URL changed event, we check for the third argument (url). If it's passed it means that we are changing the URL and we trigger the event in that scenario. This avoids hitting the API twice on each page change.
I went ahead and implemented this. Now, we call |
We are immediatley calling `.loadConfig(config)` that changes the `config` reactive propertly, which will trigger a render automatically.
Yes, already saw that previously. I described above using the context API from the *Addon classes instead of from our elements which I think avoids most of the concerns you listed.
I wasn't describing moving validation logic into This would still use a reactive property
Side effects will happen without us noticing or knowing what to watch. Logic beyond validation and updating the element That is why if we only need validation and to update
This is safer for now. If we're able to use the context API, the code will look similar to this -- we won't reinitialize each addon again. |
// We cannot use `render(this.elements[0], document.body)` because there is a race conditions between all the addons. | ||
// So, we append the web-component first and then request an update of 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.
Could you describe this in more detail here? What race condition?
I feel this should be a solvable problem, but likely comes from using promises to initialize addons asynchronously? If we truly want promises handling the addon initialization, we can structure the promises to respect initialization order.
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.
I didn't write that note. I just copied and pasted from another addon while doing the refactor. I think you wrote it when you started with the flyout work 😄
In any case, I tried using render()
and it doesn't work 🤷🏼
Cool! I will keep this in mind and keep experimenting with Context API in future iteration. I think it's still useful to give it a try if we can remove all the complexity I found myself limiting moving forward with that. I suppose we can change the "base event handling at |
Check if from/to URL are different after removing `?readthedocs-diff=` attribute because we don't want to trigger the even when the user enabled docdiff in the current page. Closes #506
…ns into humitos/lit-context-app
Co-authored-by: Anthony <[email protected]>
The filetreediff test started to failed, but I'm not sure why.
I'll merge this PR for now, and research a little more why this is happening here. |
This PR follows the approach exposed in #491 (comment). Basically, it manage all the
ContextRoot
logic in one place and update all the addons as needed.This approach is a lot simpler and easier to follow than the one originally done in #419. It also requires less code changes.
Closes #157