From b7b81ce6d3e736a3f596d8b76549cda10ca321f7 Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Thu, 4 Jan 2024 10:19:54 +0100 Subject: [PATCH 1/2] feat(core polyfills): Add polyfill for navigation API. This polyfill adds support for the "navigate" event on the navigation object. We path "history.pushState" and "history.replaceState" to send the "navigate" event on the "window.navigation" object when the URL changes. This polyfill is for current Firefox and Safari. Chrome based browsers already support this. More information on: https://developer.mozilla.org/en-US/docs/Web/API/Navigation/navigate_event --- src/core/polyfills.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/core/polyfills.js b/src/core/polyfills.js index f1de8a1fa..6f616f8ed 100644 --- a/src/core/polyfills.js +++ b/src/core/polyfills.js @@ -33,3 +33,30 @@ true ); })(); + +// Navigation polyfill for Firefox and Safari, as of 2024-01-04 +// NOTE: this is a very basic polyfill, it only supports firing a `navigate` +// event on location change and even that without interception support, etc. +!(function () { + if (window.navigation == undefined) { + // Create a navigation object on the window + // We create a DOM element for the navigation object so that we can + // attach events on it. + window.navigation = document.createElement("div"); + + // Patch pushState to trigger an `navigate` event on the navigation + // object when the URL changes. + const pushState = window.history.pushState; + window.history.pushState = function () { + pushState.apply(window.history, arguments); + window.navigation.dispatchEvent(new Event("navigate")); + }; + + // Same with replaceState + const replaceState = window.history.replaceState; + window.history.replaceState = function () { + replaceState.apply(window.history, arguments); + window.navigation.dispatchEvent(new Event("navigate")); + }; + } +})(); From 2301c73f450a3e2057df4ddf2d9a12b66042c465 Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Mon, 13 Jan 2025 00:02:58 +0100 Subject: [PATCH 2/2] fix(core polyfills): Pass a destination object with a url property along with the navigate event. --- src/core/polyfills.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/core/polyfills.js b/src/core/polyfills.js index 6f616f8ed..79920231c 100644 --- a/src/core/polyfills.js +++ b/src/core/polyfills.js @@ -39,24 +39,38 @@ // event on location change and even that without interception support, etc. !(function () { if (window.navigation == undefined) { + + class NavigationEvent extends CustomEvent { + constructor() { + super("navigate"); + this.destination = { url: undefined }; + } + } + // Create a navigation object on the window // We create a DOM element for the navigation object so that we can // attach events on it. window.navigation = document.createElement("div"); + const create_event = (args) => { + const event = new NavigationEvent(); + event.destination.url = args[2]; + return event; + }; + // Patch pushState to trigger an `navigate` event on the navigation // object when the URL changes. const pushState = window.history.pushState; window.history.pushState = function () { pushState.apply(window.history, arguments); - window.navigation.dispatchEvent(new Event("navigate")); + window.navigation.dispatchEvent(create_event(arguments)); }; // Same with replaceState const replaceState = window.history.replaceState; window.history.replaceState = function () { replaceState.apply(window.history, arguments); - window.navigation.dispatchEvent(new Event("navigate")); + window.navigation.dispatchEvent(create_event(arguments)); }; } })();