document.head.appendChild(document.createElement("script")).text =
	"(" +
	function () {
		// injected DOM script is not a content script anymore,
		// it can modify objects and functions of the page
		var _pushState = history.pushState;
		history.pushState = function (state, title, url) {
			_pushState.call(this, state, title, url);
			window.dispatchEvent(new CustomEvent("state-changed", { state }));
		};
		// repeat the above for replaceState too
	} +
	")(); this.remove();"; // remove the DOM script element

// And here content script listens to our DOM script custom events
window.addEventListener("state-changed", function (e) {
	console.log("History state changed", e.state, location.hash);
	doSomething();
});