Scroll to top & Refresh on one keypress

User Help for Mozilla Firefox
Kenosis
Posts: 77
Joined: November 11th, 2011, 5:43 am

Scroll to top & Refresh on one keypress

Post by Kenosis »

Hello,

both, my mother and I, had a stroke some time ago. While we learned to live it I'm ofc trying to make our lives as easy as possible. A small but important example for us is Firefox. I bound several actions in Firefox to single keys. This worked great with the "old" Firefox using Dorando's keyconfig. I'm still on ESR 52 but time is slowly running out and keyconfig no longer works on the latest Firefox versions.

I know there is a thread for keyconfig but last time I asked it felt pretty rough and maybe not everyone's looking there so I'm asking here for help.
What I'm looking for is an (easy to understand) way to bind two (or more) functions to a single key. The easiest example I'm using is, when I press F4 Firefox scolls to the top of a page and refreshes it.

The code (in keyconfig) looks like this:
goDoCommand('cmd_scrollTop');
BrowserReload();

Is there ANY way to achieve something like this in the latest Firefox versions? Thanks you very much in advance.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Scroll to top & Refresh on one keypress

Post by morat »

*** for advanced users only ***

You could use the CustomizableUI.createWidget method to create a button and keyboard shortcut combo widget.

left click - go to top of page and reload
F1 - go to top of page and reload

Try this:

* <profile>\chrome\userChrome.css

Code: Select all

/* Firefox userChrome.css */

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");

toolbarbutton#alltabs-button {
  -moz-binding: url("userChrome.xml#js");
}
* <profile>\chrome\userChrome.xml

Code: Select all

<?xml version="1.0"?>

<!-- run userChrome.js userChrome.xul .uc.js .uc.xul .as.css .css files -->
<!-- do not run userChrome.css userContent.css files -->

<bindings xmlns="http://www.mozilla.org/xbl">
  <binding id="js" extends="chrome://global/content/bindings/toolbarbutton.xml#menu">
    <implementation>
      <constructor><![CDATA[
        if (window.userChromeJsMod) return;
        window.userChromeJsMod = true;

        var chromeFiles = FileUtils.getDir("UChrm", []).directoryEntries;
        var xulFiles = [];
        var sss = Cc["@mozilla.org/content/style-sheet-service;1"].
          getService(Ci.nsIStyleSheetService);

        while (chromeFiles.hasMoreElements()) {
          var file = chromeFiles.getNext().QueryInterface(Ci.nsIFile);
          var fileURI = Services.io.newFileURI(file);

          if (file.isFile()) {
            if (/(^userChrome|\.uc)\.js$/i.test(file.leafName)) {
              Services.scriptloader.loadSubScriptWithOptions(fileURI.spec, {target: window, ignoreCache: true});
            } else if (/(^userChrome|\.uc)\.xul$/i.test(file.leafName)) {
              xulFiles.push(fileURI.spec);
            } else if (/\.as\.css$/i.test(file.leafName)) {
              if (!sss.sheetRegistered(fileURI, sss.AGENT_SHEET)) {
                sss.loadAndRegisterSheet(fileURI, sss.AGENT_SHEET);
              }
            } else if (/^(?!(userChrome|userContent)\.css$).+\.css$/i.test(file.leafName)) {
              if (!sss.sheetRegistered(fileURI, sss.USER_SHEET)) {
                sss.loadAndRegisterSheet(fileURI, sss.USER_SHEET);
              }
            }
          }
        }

        setTimeout(function loadXUL() {
          if (xulFiles.length > 0) {
            document.loadOverlay(xulFiles.shift(), null);
            setTimeout(loadXUL, 5);
          }
        }, 0);
      ]]></constructor>
    </implementation>
  </binding>
</bindings>
* <profile>\chrome\ScrollTopReloadFirefoxButton_Movable.uc.js

Code: Select all

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

  /* CustomizableUI
     http://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm
     http://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm/API-provided_widgets
  */

  try {
    CustomizableUI.createWidget({
      id: "__unique_identifier_scroll_top_reload_button", // should match id below
      type: "custom",
      defaultArea: CustomizableUI.AREA_MENUBAR,
   // defaultArea: CustomizableUI.AREA_NAVBAR,
      onBuild: function (aDocument) {
        var keyset = aDocument.getElementById("mainKeyset");
        var key = aDocument.createElement("key");
        key.setAttribute("id", "__unique_identifier_scroll_top_reload_key");
        key.setAttribute("keycode", "VK_F1"); // F1
        // key.setAttribute("key", "");
        // key.setAttribute("modifiers", "control,shift"); // Ctrl+Shift
        key.setAttribute("oncommand", "goDoCommand('cmd_scrollTop'); BrowserReload();");
        keyset.appendChild(key);
        var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
        var toolbaritem = aDocument.createElementNS(XUL_NS, "toolbarbutton");
        toolbaritem.onclick = event => onClick(event);
        var props = {
          id: "__unique_identifier_scroll_top_reload_button",
          class: "toolbarbutton-1 chromeclass-toolbar-additional",
          label: "Scroll Top Reload",
          tooltiptext: "Go to top of page and reload",
          style: 'list-style-image: url("chrome://branding/content/icon16.png");',
        };
        for (var p in props) toolbaritem.setAttribute(p, props[p]);
        return toolbaritem;
      },
    });
  } catch (e) {};

  function onClick(aEvent) {
    // Services.console.logStringMessage("test browser console");
    var win = aEvent.target.ownerDocument.defaultView;
    if (aEvent.button == 0) {
      win.goDoCommand("cmd_scrollTop");
      win.BrowserReload();
    } else if (aEvent.button == 1) {
      // win.alert("test middle click");
    }
  }
})();
Firefox Quantum compatible userChrome.js
http://github.com/Sporif/firefox-quantum-userchromejs

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

CustomizableUI
http://developer.mozilla.org/docs/Mozil ... ableUI.jsm
http://developer.mozilla.org/docs/Mozil ... ed_widgets

Firefox 61.0
Windows 7 SP1 32-bit
Last edited by morat on June 29th, 2018, 12:04 am, edited 3 times in total.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Scroll to top & Refresh on one keypress

Post by morat »

You could create a keyboard shortcut to simulate pressing other keyboard shortcuts using AutoHotkey.

Command: Go to top of page, Shortcut: Home
Command: Reload, Shortcut: F5

AutoHotkey forums
http://autohotkey.com/boards/

You could create a node.js native messaging WebExtension to create the keyboard shortcut and using the NirCmd utility to send the keypresses.

You would need to hire a developer to create the extension.
allande
Posts: 188
Joined: July 20th, 2017, 11:58 am

Re: Scroll to top & Refresh on one keypress

Post by allande »

You can bind one (of a limited list of actions) action to one key with the Shortkeys addon. https://addons.mozilla.org/en-US/firefo ... shortkeys/ Some keys are not programmable, and it does not take effect until a webpage is fully loaded, does not work on about: pages, etc. So, if F4 is one of the allowed programmable keys you could make F4 be scroll to top and F5 is already reload so you would then press F4, followed by F5.

As above, Autohotkey utility would give you more flexibility. In the long run the Firefox keyboard shortcut API may be extended.
User avatar
jscher2000
Posts: 11762
Joined: December 19th, 2004, 12:26 am
Location: Silicon Valley, CA USA
Contact:

Re: Scroll to top & Refresh on one keypress

Post by jscher2000 »

Usually when you reload a page using either

* F5
* Ctrl+r

Firefox keeps your current place. If you reload the page bypassing cached files, then Firefox always has to return to the top of the page. That gives you the effect you want, but many more files will be updated from the server.

If you want to try it anyway, you can use either

* Ctrl+F5
* Ctrl+Shift+r

I guess that's a lot of keys...
Kenosis
Posts: 77
Joined: November 11th, 2011, 5:43 am

Re: Scroll to top & Refresh on one keypress

Post by Kenosis »

This is going to be a bit of a longer reply but basicly it's just a thank you guys.
morat wrote:You would need to hire a developer to create the extension.
As silly as it may sound but that's something I often thought about. Problem is, where do I find someone willing to code such an addon? Also I was told this is no longer possible in the new Firefox.
allande wrote:You can bind one (of a limited list of actions) action to one key with the Shortkeys addon. https://addons.mozilla.org/en-US/firefox/addon/shortkeys/
Thank you for this link. I searched the Firefox addons several times but I never saw this one. Weird but maybe I just suck at searching.
morat wrote:*** for advanced users only ***
You could use the CustomizableUI.createWidget method to create a button and keyboard shortcut combo widget.
To be honest, I was looking at what you wrote for several minutes and thought I would never understand it. But holy hell, it works. You sir are a genius. Thank you very much.
Now you only need to tell me how I change F1 to F4 (because of course I failed at trying). Also I would love to donate you something if there is a way.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Scroll to top & Refresh on one keypress

Post by morat »

Here is how to change the keyboard shortcut from F1 to F4 in the ScrollTopReload...js file.

Find:

Code: Select all

key.setAttribute("keycode", "VK_F1"); // F1
Replace with:

Code: Select all

key.setAttribute("keycode", "VK_F4"); // F4
Kenosis wrote:I was told this is no longer possible in the new Firefox.
Andy Portmen's "Open In" extensions for Firefox are node.js native messaging WebExtensions.

Extensions by Andy Portmen
http://add0n.com/open-in.html

I wrote a personal node.js native messaging extension for Chrome based on Andy's extensions. It can send a single keypress or multiple keypresses when I click a menu item in the button popup. I'm using the NirCmd utility to send the keypresses.
Kenosis wrote:I would love to donate you something if there is a way.
Please donate to your local church.
Kenosis
Posts: 77
Joined: November 11th, 2011, 5:43 am

Re: Scroll to top & Refresh on one keypress

Post by Kenosis »

morat wrote:
Kenosis wrote:I would love to donate you something if there is a way.
Please donate to your local church.
Thank you very much again for your help.

And since I like your idea, but not being a church person, I donated money to a local charitable foundation that helps people who had a stroke.
Image
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Scroll to top & Refresh on one keypress

Post by morat »

Well done.

=D>
Kenosis
Posts: 77
Joined: November 11th, 2011, 5:43 am

Re: Scroll to top & Refresh on one keypress

Post by Kenosis »

Hello,

sorry for reviving this thread but with FF69 being released, or in my case switching from ESR 60.x to Normal 69, I can't get this to work. I did set "toolkit.legacyUserProfileCustomizations.stylesheets" to true. I also think I did correctly edit (fix) the code from http://github.com/Sporif/firefox-quantum-userchromejs (Quantum compatible userChrome.js) and http://gist.github.com/Sporif/ad6e917d8 ... 80d3c8918c (Restart Button). But I can't get the (for me) most important part, the scroll to top and reload) functionalty back to work.

Can you help me please? Thanks in advance.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Scroll to top & Refresh on one keypress

Post by morat »

Try this:

* <profile>\chrome\userChrome.css

Code: Select all

/* Firefox userChrome.css */

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");

toolbarbutton#alltabs-button {
  -moz-binding: url("userChrome.xml#js");
}
* <profile>\chrome\userChrome.xml

Code: Select all

<?xml version="1.0"?>

<!-- run userChrome.js userChrome.xul example.uc.js example.uc.xul example.as.css example.css files -->
<!-- do not run userChrome.css userContent.css example.js files -->

<!-- bug 1448162, disable xul overlays, breaks userChrome.xul example.uc.xul files in fx 61 -->

<bindings xmlns="http://www.mozilla.org/xbl">
  <!-- binding id="js" extends="chrome://global/content/bindings/toolbarbutton.xml#menu" -->
  <!-- binding id="js" extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-badged" -->
  <binding id="js">
    <implementation>
      <constructor><![CDATA[
        if (window.userChromeJsMod) return;
        window.userChromeJsMod = true;

        var chromeFiles = FileUtils.getDir("UChrm", []).directoryEntries;
        var xulFiles = [];
        var sss = Cc["@mozilla.org/content/style-sheet-service;1"].
          getService(Ci.nsIStyleSheetService);

        while (chromeFiles.hasMoreElements()) {
          var file = chromeFiles.getNext().QueryInterface(Ci.nsIFile);
          var fileURI = Services.io.newFileURI(file);

          if (file.isFile()) {
            if (/(^userChrome|\.uc)\.js$/i.test(file.leafName)) {
              Services.scriptloader.loadSubScriptWithOptions(fileURI.spec, {target: window, ignoreCache: true});
            } else if (/(^userChrome|\.uc)\.xul$/i.test(file.leafName)) {
              xulFiles.push(fileURI.spec);
            } else if (/\.as\.css$/i.test(file.leafName)) {
              if (!sss.sheetRegistered(fileURI, sss.AGENT_SHEET)) {
                sss.loadAndRegisterSheet(fileURI, sss.AGENT_SHEET);
              }
            } else if (/^(?!(userChrome|userContent)\.css$).+\.css$/i.test(file.leafName)) {
              if (!sss.sheetRegistered(fileURI, sss.USER_SHEET)) {
                sss.loadAndRegisterSheet(fileURI, sss.USER_SHEET);
              }
            }
          }
        }

        setTimeout(function loadXUL() {
          if (xulFiles.length > 0) {
            document.loadOverlay(xulFiles.shift(), null);
            setTimeout(loadXUL, 5);
          }
        }, 0);
      ]]></constructor>
    </implementation>
  </binding>
</bindings>
* <profile>\chrome\ScrollTopReloadFirefoxButton_Movable.uc.js

Code: Select all

(function () {
  if (location != "chrome://browser/content/browser.xul" &&         // fx 68 uses browser.xul
      location != "chrome://browser/content/browser.xhtml") return; // fx 69 uses browser.xhtml

  /* CustomizableUI
     http://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm
     http://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm/API-provided_widgets
  */

  try {
    CustomizableUI.createWidget({
      id: "__unique_identifier_scroll_top_reload_button", // should match id below
      type: "custom",
      defaultArea: CustomizableUI.AREA_MENUBAR,
   // defaultArea: CustomizableUI.AREA_NAVBAR,
      onBuild: function (aDocument) {
        var keyset = aDocument.getElementById("mainKeyset");
        // var key = aDocument.createElement("key"); // obsolete in fx 69
        var key = aDocument.createXULElement("key");
        key.setAttribute("id", "__unique_identifier_scroll_top_reload_key");
        key.setAttribute("keycode", "VK_F4"); // F4
        // key.setAttribute("key", "");
        // key.setAttribute("modifiers", "control,shift"); // Ctrl+Shift
        key.setAttribute("oncommand", "goDoCommand('cmd_scrollTop'); BrowserReload();");
        keyset.appendChild(key);
        var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
        var toolbaritem = aDocument.createElementNS(XUL_NS, "toolbarbutton");
        toolbaritem.onclick = event => onClick(event);
        var props = {
          id: "__unique_identifier_scroll_top_reload_button",
          class: "toolbarbutton-1 chromeclass-toolbar-additional",
          label: "Scroll Top Reload",
          tooltiptext: "Go to top of page and reload",
          style: 'list-style-image: url("chrome://branding/content/icon16.png");',
        };
        for (var p in props) toolbaritem.setAttribute(p, props[p]);
        return toolbaritem;
      },
    });
  } catch (e) {};

  function onClick(aEvent) {
    // Services.console.logStringMessage("test browser console");
    var win = aEvent.target.ownerDocument.defaultView;
    if (aEvent.button == 0) {
      win.goDoCommand("cmd_scrollTop");
      win.BrowserReload();
    } else if (aEvent.button == 1) {
      // win.alert("test middle click");
    }
  }
})();
Firefox 69.0
Windows 7 SP1 32-bit
Kenosis
Posts: 77
Joined: November 11th, 2011, 5:43 am

Re: Scroll to top & Refresh on one keypress

Post by Kenosis »

Works like a charm. Thank you very much once again. :)
Kenosis
Posts: 77
Joined: November 11th, 2011, 5:43 am

Re: Scroll to top & Refresh on one keypress

Post by Kenosis »

Looks like FF 72.0.1 broke it.

Edit: Looks like I was able to fix it myself. For anyone interested, the fixed files are available at https://github.com/alice0775/userChrome ... /master/72 and the instructions by rpolo77 found here https://gist.github.com/Sporif/ad6e917d ... 80d3c8918c.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Scroll to top & Refresh on one keypress

Post by morat »

Here are my config files in Firefox 72.

userChrome.js hacks
http://forums.mozillazine.org/viewtopic ... #p14854175

Alice0775's tweak doesn't run AGENT_SHEET example.as.css and USER_SHEET example.css files. It doesn't ignore the javascript cache like Sporif's tweak.

Firefox has a javascript cache, which is not automatically cleared across restarts. To clear the cache when restarting, add a -purgecaches flag to the executable commandline.

i.e.

firefox.exe -purgecaches
FirefoxPortable.exe -purgecaches
Kenosis
Posts: 77
Joined: November 11th, 2011, 5:43 am

Re: Scroll to top & Refresh on one keypress

Post by Kenosis »

Thanks you morat. I will try your version as soon as I can.

Funny thing is, I was about to ask if "purgecaches" is needed if cache is set to 0 anyway... just to notice that setting has gone as well. I only ever stored cookies but never used to cache images etc.
Post Reply