flypig.co.uk

Gecko-dev Diary

Between August 2023 and September 2024 I upgrading the Sailfish OS browser from Gecko version ESR 78 to ESR 91, writing a daily blog as I went along. This page catalogues my progress, alongside the other browser-related topics I've looked in to since.

Latest code changes are in the gecko-dev sailfishos-esr91 branch.

There is an index of all posts in case you want to jump to a particular day.

Gecko RSS feed Click the icon for the Gecko-dev Diary RSS feed.

Gecko

5 most recent items

10 Feb 2024 : Day 152 #
This morning I woke to find the build had completed. Hooray! That means I can test the changes I made yesterday to add an InitSessionHistory() call into the EmbedLite code.

After installing and running the code I still see the occasional related error, but the main errors we were getting before about the sessionHistory being null are no longer appearing.

That's a small but important step. But even more important is the fact that the Back and Forwards buttons are now working as well. Not only a good sign, but also important functionality being restored. I've been finding it quite challenging using the browser without the navigation buttons. So this is a very welcome result.

A couple of additional errors are also appearing now. These are new; first another error related to the history:
Warning: couldn't PurgeHistory. Was it a file download? TypeError: 
    legacyHistory.PurgeHistory is not a function
But also an error about the LoginManager:
JavaScript error: resource://gre/modules/LoginManagerChild.jsm, line 541:
    NotFoundError: WindowGlobalChild.getActor:
    No such JSWindowActor 'LoginManager'
Starting with the first error, the PurgeHistory() method certainly exists in nsISHistory.idl:
  /**
   * Called to purge older documents from history.
   * Documents can be removed from session history for various
   * reasons. For example to  control memory usage of the browser, to
   * prevent users from loading documents from history, to erase evidence of
   * prior page loads etc...
   *
   * @param numEntries        The number of toplevel documents to be
   *                          purged from history. During purge operation,
   *                          the latest documents are maintained and older
   *                          'numEntries' documents are removed from history.
   * @throws                  <code>NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA</code>
   *                          Purge was vetod.
   * @throws                  <code>NS_ERROR_FAILURE</code> numEntries is
   *                          invalid or out of bounds with the size of history.
   */
  void PurgeHistory(in long aNumEntries);
It's no longer present in ESR 91 though. Let's find out why not.
$ git log -1 -S "PurgeHistory" docshell/shistory/nsISHistory.idl
commit f9f96d23ca42f359e143d0ae98234021e86179a7
Author: Andreas Farre <farre@mozilla.com>
Date:   Wed Sep 16 14:51:01 2020 +0000

    Bug 1662410 - Part 1: Fix usage of ChildSHistory.legacySHistory . r=peterv
    
    ChildSHistory.legacySHistory isn't valid for content processes when
    session history in the parent is enabled. We try to fix this by either
    delegating to the parent by IPC or move the implementation partially
    or as a whole to the parent.
    
    Differential Revision: https://phabricator.services.mozilla.com/D89353
This is definitely the problem that's causing the issue, as we can see in the diff:
$ git diff f9f96d23ca42f359e143d0ae98234021e86179a7~ \
    f9f96d23ca42f359e143d0ae98234021e86179a7 \
    -- docshell/shistory/nsISHistory.idl
diff --git a/docshell/shistory/nsISHistory.idl b/docshell/shistory/
    nsISHistory.idl
index 3d914924c94d..1f5b9c5477e9 100644
--- a/docshell/shistory/nsISHistory.idl
+++ b/docshell/shistory/nsISHistory.idl
@@ -87,7 +87,7 @@ interface nsISHistory: nsISupports
    * @throws                  <code>NS_ERROR_FAILURE</code> numEntries is
    *                          invalid or out of bounds with the size of history.
    */
-  void PurgeHistory(in long aNumEntries);
+  void purgeHistory(in long aNumEntries);
 
   /**
    * Called to register a listener for the session history component.
@@ -255,7 +255,7 @@ interface nsISHistory: nsISupports
    * Collect docshellIDs from aEntry's children and remove those
    * entries from history.
    *
-   * @param aEntry           Children docshellID's will be collected from 
+   * @param aEntry           Children docshellID's will be collected from
    *                         this entry and passed to RemoveEntries as aIDs.
   */
   [noscript, notxpcom]
@@ -265,7 +265,7 @@ interface nsISHistory: nsISupports
   void Reload(in unsigned long aReloadFlags);
 
   [notxpcom] void EnsureCorrectEntryAtCurrIndex(in nsISHEntry aEntry);
-  
+
   [notxpcom] void EvictContentViewersOrReplaceEntry(in nsISHEntry aNewSHEntry,
       in bool aReplace);
 
   nsISHEntry createEntry();
Helpfully we can immediately see from this that the call hasn't exactly been removed. It's just been slightly renamed, switching the initial uppercase "P" for a lowercase "p". With any luck then, this should be an easy fix.

This is where the call is defined, but to fix it we also now need to know where the call comes from. Doing a quick grep on the code highlights that it's being called in embedhelper.js which is part of the embedlite-components package.

Here's the relevant section:
      case "embedui:addhistory": {
        // aMessage.data contains: 1) list of 'links' loaded from DB, 2) current 'index'.

        let docShell = content.docShell;
        let sessionHistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
        let legacyHistory = sessionHistory.legacySHistory;
        let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);

        try {
          // Initially we load the current URL and that creates an unneeded entry in History -> purge it.
          if (legacyHistory.count > 0) {
            legacyHistory.PurgeHistory(1);
          }
        } catch (e) {
            Logger.warn("Warning: couldn't PurgeHistory. Was it a file download?", e);
        }

Changing legacyHistory.PurgeHistory(1) to legacyHistory.purgeHistory(1) will hopefully do the trick. Unfortunately I'm already out of time for today, so we'll have to wait until tomorrow to find out for certain. But I feel like we're making progress.

If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.

Comments

Uncover Disqus comments