I am developing a Chrome extension to tweak Facebook. However, catching browsing actions within HTML5-enabled sites such as Facebook requires an override of window.history.pushState
as explained in this SO question.
Unfortunately, it seems that Chrome's isolated worlds prevent this sort of override. Is there any other method of catching history changes (other than polling document.location.href
)?
Yes,
One way is to create a script tag and put your code there:
html = "window.history.pushState = function(a,b,c) { alert('Change !'); };";
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.innerHTML = html;
headID.appendChild(newScript);
Not sure whether you trying to do this in background.js or content.js, but if it is the former, you can do so using webNavigation events:
You need to set permissions for webNavigation
in manifest.json:
"permissions": [
"webNavigation"
],
Then in background.js:
chrome.webNavigation.onHistoryStateUpdated.addListener(function(details) {
console.log('Page uses History API and we heard a pushSate/replaceState.');
// do your thing
});
Source: Chrome Extension docs for webNavigation
Building on @Boris's answer: to continue with the default action, save a reference to the original pushState function, and then call it:
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = chrome.extension.getURL('script.js');
headID.appendChild(newScript);
script.js:
window.history.pushState = (function(nativePushState) {
return function(a,b,c) {
// Do something
nativePushState.apply(this, arguments); //Continue by calling native history.pushState
};
})(window.history.pushState)