Wrong title in the history popup (firefox)

Hello,
in Firefox, the previous page title that appears with a right clic on the “previous page” arrow is overwritten with the current page title.

For instance, if the first page displayed is:
https://meta.discourse.org/
see what the right click on arrow looks like (it is correct):

then going on any topic, such as:

the title of the previous page has been overwritten with the current page title:

Nevertheless, the link is still valid.

any idea about this bug?

It does indeed look like a bug possibly in the way / sequence that we replace history or a firefox quirk.

I am able to reproduce.

Since it is fairly minor I am going to put a #pr-welcome in case the community would like to pitch in and propose a fix.

alright, thanks for your answer

I have found out that this bug also surfaces out as history entries in browsing history being somewhat corrupted which I consider a more severe issue. More specifically a new title is assigned to an old URL when navigation is handled by JS. This happens pretty much always in Firefox but is quite rare in Chrome (I found one instance so far: going from /top to a topic).

@sam is right that it’s caused by the order of operations in which the URL and title are modified. I wish there were some kind best practices guide published somewhere that says what the correct order is: always update the title after using history API.

I’ve tried to do some debugging (and I wanna say in advance that I’m quite averse to building any moderately big npm adjacent project). Initially I used this code to do a small reconnaissance:

Object.defineProperty(document, "title", {
  get() {
    return document.head.querySelector('title').innerText;
  },
  set(t) {
    console.debug('title', t, new Error("title!").stack)
    debugger;
    document.head.querySelector('title').innerText = t;
  },
  enumerable: true,
  configurable: true,
});
let ___push___ = window.history.pushState;
window.history.pushState = function(...args) {
  console.debug('push', args[0], new Error().stack);
  debugger;
  ___push___.apply(this, args);
};

let ___replace___ = window.history.replaceState;
window.history.replaceState = function(...args) {
  console.debug('replace', args[0], new Error().stack);
  debugger;
  ___replace___.apply(this, args);
};

It indeed has shown that there’s almost always one title modification right before history API operation. Unfortunately it wasn’t more helpful than that: relating what happens at runtime to the source code was quite hard – the operations of interest are quite scattered, call stack was misleading b/c execution already yielded to Ember’s event loop, and generally debugging experience in Firefox was quite hellish. Having switched to Chrome, I was a bit more successful. Long story short, AFAIK Ember decides by itself when to update URL. On the other hand, modification of the title can be initiated from two places: [1] and [2]

Only the latter is ever executed before the history API call. The ‘common code ancestor’ of them is located here:

// Run all the necessary enter/setup/exit hooks
this.setupContexts(newState, transition); // <- title change initiated here, by triggering `model.title:change` event

// Check if a redirect occurred in enter/setup
if (transition.isAborted) {
  // TODO: cleaner way? distinguish b/w targetRouteInfos?
  this.state!.routeInfos = this.currentRouteInfos!;
  return Promise.reject(logAbort(transition));
}

this._updateURL(transition, newState); // <- url change initiated here

Interestingly, “router.js is the routing microlib used by Ember.js.”

Now I would like to hand out handling the issue to some one that’s, contraty to me, remotely familiar with discourse codebase.

Edit: forgot to mention: document.title is modified by [1] one or more times after (both) it being modified [2] and url being modified by history API.

1 Like

(as new user I can’t put more than 2 links per post :frowning: )

[1] (https://github.com/discourse/discourse/blob/245e9f30a4825beb86fcbfcf718208752748e5b4/app/assets/javascripts/discourse/app/lib/page-tracker.js#L35)

[2] (https://github.com/discourse/discourse/blob/542f77181a47df8aa0f909f69814406491d08c5e/app/assets/javascripts/discourse/app/controllers/topic.js#L141)

1 Like