Ho scoperto che questo bug si manifesta anche come voci nella cronologia di navigazione leggermente corrotte, il che considero un problema più grave. Più specificamente, viene assegnato un nuovo titolo a un vecchio URL quando la navigazione è gestita da JS. Questo accade quasi sempre in Firefox, ma è piuttosto raro in Chrome (ho trovato un’istanza finora: passando da /top a un argomento).
@sam ha ragione sul fatto che è causato dall’ordine delle operazioni in cui l’URL e il titolo vengono modificati. Vorrei che ci fosse una sorta di guida alle best practice pubblicata da qualche parte che dica qual è l’ordine corretto: aggiorna sempre il titolo dopo aver utilizzato l’API history.
Ho provato a fare un po’ di debug (e voglio dire in anticipo che sono piuttosto restio a costruire qualsiasi progetto moderatamente grande adiacente a npm). Inizialmente ho usato questo codice per fare una piccola ricognizione:
Ha effettivamente dimostrato che c’è quasi sempre una modifica del titolo subito prima dell’operazione dell’API history. Sfortunatamente non è stato più utile di così: mettere in relazione ciò che accade in fase di esecuzione con il codice sorgente è stato piuttosto difficile – le operazioni di interesse sono piuttosto sparse, lo stack di chiamate era fuorviante perché l’esecuzione aveva già ceduto al loop degli eventi di Ember, e in generale l’esperienza di debug in Firefox è stata piuttosto infernale. Passando a Chrome, ho avuto un po’ più di successo. In breve, per quanto ne so, Ember decide da solo quando aggiornare l’URL. D’altra parte, la modifica del titolo può essere avviata da due punti: [1] e [2]
Solo quest’ultimo viene mai eseguito prima della chiamata all’API history. L’“antenato comune del codice” di questi si trova qui:
// Esegui tutti gli hook necessari di enter/setup/exit
this.setupContexts(newState, transition); // <- modifica del titolo avviata qui, attivando l'evento `model.title:change`
// Controlla se è avvenuto un reindirizzamento in enter/setup
if (transition.isAborted) {
// TODO: modo più pulito? distinguere tra targetRouteInfos?
this.state!.routeInfos = this.currentRouteInfos!;
return Promise.reject(logAbort(transition));
}
this._updateURL(transition, newState); // <- modifica dell'URL avviata qui
Interessante, “router.js è la libreria di routing microlib utilizzata da Ember.js.”
Ora vorrei passare la gestione del problema a qualcuno che, contrariamente a me, abbia una minima familiarità con il codebase di discourse.
Modifica: ho dimenticato di menzionare: document.title viene modificato da [1] una o più volte dopo (entrambe) le modifiche [2] e la modifica dell’URL tramite l’API history.