He descubierto que este error también se manifiesta como entradas en el historial de navegación que están algo corruptas, lo cual considero un problema más grave. Más específicamente, se asigna un nuevo título a una URL antigua cuando la navegación es manejada por JS. Esto ocurre casi siempre en Firefox, pero es bastante raro en Chrome (he encontrado una instancia hasta ahora: al pasar de /top a un tema).
@sam tiene razón en que se debe al orden de las operaciones en las que se modifican la URL y el título. Ojalá hubiera alguna guía de mejores prácticas publicada en algún lugar que dijera cuál es el orden correcto: siempre actualizar el título después de usar la API history.
He intentado depurar un poco (y quiero decir de antemano que soy bastante reacio a construir cualquier proyecto medianamente grande adyacente a npm). Inicialmente usé este código para hacer un pequeño reconocimiento:
Efectivamente, demostró que casi siempre hay una modificación del título justo antes de la operación de la API history. Desafortunadamente, no fue más útil que eso: relacionar lo que sucede en tiempo de ejecución con el código fuente fue bastante difícil – las operaciones de interés están bastante dispersas, la pila de llamadas era engañosa porque la ejecución ya había cedido al bucle de eventos de Ember, y en general la experiencia de depuración en Firefox fue bastante infernal. Al cambiar a Chrome, tuve un poco más de éxito. En resumen, hasta donde sé, Ember decide por sí mismo cuándo actualizar la URL. Por otro lado, la modificación del título puede iniciarse desde dos lugares: [1] y [2]
Solo el último se ejecuta antes de la llamada a la API history. El ‘ancestro de código común’ de ellos se encuentra aquí:
// Ejecutar todos los hooks necesarios de entrada/configuración/salida
this.setupContexts(newState, transition); // <- cambio de título iniciado aquí, al activar el evento `model.title:change`
// Comprobar si se produjo una redirección en la entrada/configuración
if (transition.isAborted) {
// TODO: ¿forma más limpia? ¿distinguir entre routeInfos de destino?
this.state!.routeInfos = this.currentRouteInfos!;
return Promise.reject(logAbort(transition));
}
this._updateURL(transition, newState); // <- cambio de URL iniciado aquí
Curiosamente, “router.js es la microbiblioteca de enrutamiento utilizada por Ember.js”.
Ahora me gustaría ceder el manejo del problema a alguien que, a diferencia de mí, esté remotamente familiarizado con la base de código de discourse.
Editar: olvidé mencionar: document.title es modificado por [1] una o más veces después de (ambos) ser modificado [2] y la URL ser modificada por la API history.