/* global CHROME URLS */
/* exported navigatorUtil */
'use strict';
const navigatorUtil = (() => {
const handler = {
urlChange: null
};
return extendNative({onUrlChange});
function onUrlChange(fn) {
initUrlChange();
handler.urlChange.push(fn);
}
function initUrlChange() {
if (handler.urlChange) {
return;
handler.urlChange = [];
chrome.webNavigation.onCommitted.addListener(data =>
fixNTPUrl(data)
.then(() => executeCallbacks(handler.urlChange, data, 'committed'))
.catch(console.error)
);
chrome.webNavigation.onHistoryStateUpdated.addListener(data =>
.then(() => executeCallbacks(handler.urlChange, data, 'historyStateUpdated'))
chrome.webNavigation.onReferenceFragmentUpdated.addListener(data =>
.then(() => executeCallbacks(handler.urlChange, data, 'referenceFragmentUpdated'))
function fixNTPUrl(data) {
if (
!CHROME ||
!URLS.chromeProtectsNTP ||
!data.url.startsWith('https://www.google.') ||
!data.url.includes('/_/chrome/newtab?')
) {
return Promise.resolve();
return browser.tabs.get(data.tabId)
.then(tab => {
const url = tab.pendingUrl || tab.url;
if (url === 'chrome://newtab/') {
data.url = url;
});
function executeCallbacks(callbacks, data, type) {
for (const cb of callbacks) {
cb(data, type);
function extendNative(target) {
return new Proxy(target, {
get: (target, prop) => {
if (target[prop]) {
return target[prop];
return chrome.webNavigation[prop].addListener.bind(chrome.webNavigation[prop]);
})();