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

POC Monkey-patch history pushState and replaceState to listen to location changes #455

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

zanderle
Copy link
Collaborator

Closes #157

@zanderle zanderle requested review from humitos and a team as code owners November 29, 2024 13:46
@zanderle zanderle requested a review from agjohnson November 29, 2024 13:46
@zanderle zanderle force-pushed the zanderle/157-listen-on-pushState-and-replaceState-changes branch from 68a5305 to 2f3f8f0 Compare November 29, 2024 13:47
@zanderle
Copy link
Collaborator Author

@humitos this just does the monkey-patching for now (haven't added any listeners yet). Do we want to do a test-build with this, to see if it correctly picks up the "page changes", before we move on to the next step?

@zanderle zanderle force-pushed the zanderle/157-listen-on-pushState-and-replaceState-changes branch from 2f3f8f0 to 7aee62e Compare November 29, 2024 13:50
Copy link
Member

@humitos humitos left a comment

Choose a reason for hiding this comment

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

I did a small review and left a few questions.

Comment on lines +159 to +168
* Setup events firing on history pushState and replaceState
*
* This is needed when addons are used in SPA. A lot of addons rely
* on the current URL. However in the SPA, the pages are not reloaded, so
* the addons never get notified of the changes in the URL.
*
* While History API does have `popstate` event, the only way to listen to
* changes via pushState and replaceState is using monkey-patching, which is
* what this function does. (See https://stackoverflow.com/a/4585031)
* It will fire a "pushState" or "replaceState" event, depending on which method was called.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Setup events firing on history pushState and replaceState
*
* This is needed when addons are used in SPA. A lot of addons rely
* on the current URL. However in the SPA, the pages are not reloaded, so
* the addons never get notified of the changes in the URL.
*
* While History API does have `popstate` event, the only way to listen to
* changes via pushState and replaceState is using monkey-patching, which is
* what this function does. (See https://stackoverflow.com/a/4585031)
* It will fire a "pushState" or "replaceState" event, depending on which method was called.
* Setup events firing on history `pushState` and `replaceState`
*
* This is needed when addons are used in SPA. A lot of addons rely
* on the current URL. However in the SPA, the pages are not reloaded, so
* the addons never get notified of the changes in the URL.
*
* While History API does have `popstate` event, the only way to listen to
* changes via `pushState` and `replaceState` is using monkey-patching, which is
* what this function does. (See https://stackoverflow.com/a/4585031)
* It will fire a `READTHEDOCS_URL_CHANGED` event, on `pushState` and `replaceState`.

Copy link
Member

Choose a reason for hiding this comment

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

Do we need to make the distinction between these two events for our purpose? I think it will be better to expose just READTHEDOCS_URL_CHANGED and always trigger this event either if it's pushState or replaceState. What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, we can do it like that 👍

src/utils.js Show resolved Hide resolved
const originalMethod = history[methodName];
history[methodName] = function () {
const result = originalMethod.apply(this, arguments);
const event = new Event(methodName);
Copy link
Member

Choose a reason for hiding this comment

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

Here is where I think we should create new Event(READTHEDOCS_URL_CHANGED) or similar.

@humitos
Copy link
Member

humitos commented Dec 2, 2024

Do we want to do a test-build with this, to see if it correctly picks up the "page changes", before we move on to the next step?

How hard would it be to create a simple example for this using the index.html page from this repository?

I tested using test-builds locally and I can confirm the custom method is called when changing pages on Docusaurus and Material for MkDocs (I added some small console.log) --but I don't want you to deal with my current setup since it's a complex.

@zanderle
Copy link
Collaborator Author

zanderle commented Dec 2, 2024

Do we want to do a test-build with this, to see if it correctly picks up the "page changes", before we move on to the next step?

How hard would it be to create a simple example for this using the index.html page from this repository?

I tested using test-builds locally and I can confirm the custom method is called when changing pages on Docusaurus and Material for MkDocs (I added some small console.log) --but I don't want you to deal with my current setup since it's a complex.

I think I can make it work locally, to develop, and then I'll ask you to do a proper test on your setup

Copy link
Contributor

@agjohnson agjohnson left a comment

Choose a reason for hiding this comment

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

Changes here seem fine, no additions to the notes here 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Single Page Applications (SPA) for addons that depend on the URL
3 participants