MozillaZine

Converting a legacy extension to a bootstrapped extension

Talk about add-ons and extension development.
mozray
 
Posts: 52
Joined: March 10th, 2017, 3:48 pm

Post Posted May 10th, 2018, 10:22 am

I've been running Firefox Unbranded so I can still run some legacy extensions.

However, with each release, Firefox is removing some APIs that are breaking some of the legacy extensions that I still use.

In Firefox 60, Auto Focus URL Bar no longer works:
https://addons.mozilla.org/en-US/firefo ... s-url-bar/

If you view the source for that addon, it's very simplistic, so I'm hoping if it is possible to port this over somehow to a bootstrapped addon. It's not possible to port this to a WebExtension due to a lack of APIs.

Can any XUL gurus help me out? I'm familiar with other languages, but XUL escapes me.

mozray
 
Posts: 52
Joined: March 10th, 2017, 3:48 pm

Post Posted May 10th, 2018, 10:28 am

I'm dumb. The Auto Focus URL Bar addon is already a bootstrapped addon. Guess there's nothing I can do here to keep support for this other than go back to Firefox 59.

morat
 
Posts: 2865
Joined: February 3rd, 2009, 6:29 pm

Post Posted May 10th, 2018, 8:48 pm

Are all bootstrapped extensions dead in Firefox 60?

I got the bootstrap.js code working in scratchpad browser environment in Firefox 60.

Code: Select all
(function() {

  if (location != "chrome://browser/content/browser.xul") return;

  const {classes: Cc, interfaces: Ci, utils: Cu} = Components;

  Cu.import("resource://gre/modules/Services.jsm");

  var AutoFocusUrlbar = {
    cs: Services.console, // nsIConsoleService
    ww: Services.ww,      // nsIWindowWatcher
    wm: Services.wm,      // nsIWindowMediator
    ps: Services.prefs,

    get doc() {
      return this.wm.getMostRecentWindow("navigator:browser").document;
    },

    get eres() {
      return this.ps.getCharPref('extensions.AutoFocusUrlbar.excludeChar');
    },

    handleEvent: function(e) {
      var document = this.doc;
      var elm = document.activeElement;
      while (1) {
        if (elm == null) return;
        if (elm.localName == "browser" || elm.localName == "iframe" ||
          elm.localName == "frame") {
          elm = elm.contentDocument.activeElement;
          continue;
        }
        break;
      }
      if (elm.ownerDocument.designMode == 'on' ||
        elm.localName == "input" || elm.localName == "textarea" ||
        elm.localName == "select" ||
        elm.isContentEditable) return;
      var mod = e.ctrlKey || e.metaKey || e.altKey;
      if (mod) return;
      var c = String.fromCharCode(e.charCode);
      var excludePattern;
      try {
        var excludeRegExpString = this.eres;
        excludePattern = new RegExp(excludeRegExpString);
      } catch (err) {
        excludePattern = /[^a-zA-Z]/;
      }
      if (excludePattern.test(c)) return;
      var urlbar = document.getElementById("urlbar");
      if (!urlbar) return;
      e.preventDefault();
      urlbar.focus();
      try {
        urlbar.value = '';
        var evt = document.createEvent("KeyboardEvent");
        evt.initKeyEvent('keypress', false, true, null,
          false, false, false, false, 0, e.charCode);
        var input = urlbar.inputField;
        input.dispatchEvent(evt);
      } catch (err) {
        urlbar.value = c;
      }
    },

    aListener: {
      onOpenWindow: function(aWindow) {
        var win = aWindow.docShell.QueryInterface(Ci
          .nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
        win.addEventListener("load", function() {
          win.removeEventListener("load", arguments.callee, true);
          if (win.document.documentElement.getAttribute("windowtype") !=
            "navigator:browser") return;
          win.addEventListener("keypress", AutoFocusUrlbar, false);
        }, true);
      },
      onCloseWindow: function(aWindow) {},
      onWindowTitleChange: function(aWindow, aTitle) {},
    },

    startup: function() {
      this.wm.addListener(this.aListener);
      var cw = this.wm.getEnumerator("navigator:browser");
      while (cw.hasMoreElements()) {
        var win = cw.getNext().QueryInterface(Ci.nsIDOMWindow);
        win.addEventListener("keypress", this, false);
      }
    },
    shutdown: function() {
      this.wm.removeListener(this.aListener);
      var cw = this.wm.getEnumerator("navigator:browser");
      while (cw.hasMoreElements()) {
        var win = cw.getNext().QueryInterface(Ci.nsIDOMWindow);
        win.removeEventListener("keypress", this, false);
      }
    }
  }

  function startup(data, reason) {
    var cs = Services.console;
    AutoFocusUrlbar.startup();
  }
  startup();

  function shutdown(data, reason) {
    AutoFocusUrlbar.shutdown();
  }

  function install(data, reason) {}

  function uninstall(data, reason) {}

})();

pintassilgo
 
Posts: 155
Joined: August 30th, 2013, 3:50 pm

Post Posted May 10th, 2018, 9:19 pm

Bootstrapped will be removed too:
https://bugzilla.mozilla.org/show_bug.cgi?id=1449052

I'm relying on AutoConfig, the only way I know to run unrestricted JS that doesn't have planned removal (at least for unbranbed/DevEd/Nightly: https://bugzilla.mozilla.org/show_bug.cgi?id=1455601#c8).

mozray
 
Posts: 52
Joined: March 10th, 2017, 3:48 pm

Post Posted May 12th, 2018, 12:10 am

@morat - How do I run your code in Scratchpad?

I copied the code into Scratchpad and under Environment, I selected Browser. Then I hit Run, but that didn't seem to do anything. When Auto Focus URL Bar is active, you can start typing anywhere on the page and the typed text will be displayed in the URL bar instead of focusing the URL bar and then typing the text.

Is there an alternative to running this in Scratchpad?

morat
 
Posts: 2865
Joined: February 3rd, 2009, 6:29 pm

Post Posted May 12th, 2018, 9:19 am

Here are the scratchpad instructions:

* open about:config
* set devtools.chrome.enabled to true
* tools > web developer > scratchpad
* environment > browser
* edit > paste (i.e. copy and paste code above)
* execute > run

Test page
http://www.mozillazine.org/

If the code fails, are you using the multiprocess windows feature?

You can see if the multiprocess windows feature is disabled in the about:support page.

* open about:config
* set browser.tabs.remote.autostart preference to false
* restart
* open about:support

P.S.

Someone got the userChrome.js file working with only the userChrome.css file. (autoconfig alternative)

Firefox Quantum compatible userChrome.js
http://github.com/Sporif/firefox-quantum-userchromejs

Restart Button
http://gist.github.com/Sporif/ad6e917d8 ... 80d3c8918c

Toggle Page Style Button
viewtopic.php?p=14795810#p14795810

mozray
 
Posts: 52
Joined: March 10th, 2017, 3:48 pm

Post Posted May 12th, 2018, 9:46 am

morat wrote:If the code fails, are you using the multiprocess windows feature?

Ahh, that was the problem! I do have e10s enabled. After disabling, the script works.

Bonus is memory usage is a little smaller as well! :)

About userChrome.js, does that rely on having e10s disabled? If not, I might give that a try as well.
Update - just gave userChrome.js a try. It works, but e10s has to stay disabled.

Thanks morat!

Return to Extension Development


Who is online

Users browsing this forum: No registered users and 2 guests