Jak dostat upozornění na změny historie přes history.pushState?

Nyní, když HTML5 zavádí history.pushState Chcete-li změnit historii prohlížečů, webové stránky to začnou používat v kombinaci s Ajaxem namísto změny identifikátoru fragmentu adresy URL.

Bohužel to znamená, že tato volání již nelze detekovat pomocí onhashchange .

Moje otázka zní: Existuje spolehlivý způsob (hack?;)), jak zjistit, kdy webová stránka používá history.pushState ? Specifikace neuvádí nic o událostech, které jsou vzneseny (alespoň jsem nic nenašel).
Zkusil jsem vytvořit fasádu a nahradil jsem window.history s mým vlastním objektem JavaScript, ale nemělo to vůbec žádný účinek.

Další vysvětlení: Vyvíjím doplněk Firefoxu, který musí tyto změny detekovat a podle toho jednat.
Vím, že před několika dny byla podobná otázka, která se ptala, zda by bylo efektivní naslouchat některým událostem DOM, ale raději bych na to nespoléhal, protože tyto události lze generovat z mnoha různých důvodů.

Aktualizace:

Zde je soubor jsfiddle (použijte Firefox 4 nebo Chrome 8), který ukazuje, že onpopstate nespustí se při pushState se jmenuje (nebo dělám něco špatně? Klidně to vylepšete!).

Aktualizace 2:

Další (vedlejší) problém je, že window.location není aktualizován při použití pushState (ale o tom jsem už četl tady na SO myslím).

Odpověď

5.5.9.1 Definice událostí

Postátí událost se spustí v určitých případech při navigaci na záznam historie relace.

Podle toho není žádný důvod, aby se popstate spouštěl, když používáte pushState . Ale událost jako pushstate by se hodily. Protože history je hostitelský objekt, měli byste s ním být opatrní, ale Firefox se v tomto případě zdá být pěkný. Tento kód funguje dobře:

(function(history){
    var pushState = history.pushState;
    history.pushState = function(state) {
        if (typeof history.onpushstate == "function") {
            history.onpushstate({state: state});
        }
        // ... whatever else you want to do
        // maybe call onhashchange e.handler
        return pushState.apply(history, arguments);
    };
})(window.history);

Váš jsfiddle se stane :

window.onpopstate = history.onpushstate = function(e) { ... }

Můžete opičí záplatu window.history.replaceState stejným způsobem.

Poznámka:Samozřejmě můžete přidat onpushstate jednoduše do globálního objektu a můžete dokonce zajistit, aby zpracovával více událostí pomocí add/removeListener