keyconfig 20110522

Announce and Discuss the Latest Theme and Extension Releases.
Post Reply
morat
Posts: 6404
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

You can create keyboard shortcuts that execute custom commands with the tbkeys addon.

tbkeys
http://github.com/wshanks/tbkeys#tbkeys

tbkeys-lite
http://addons.thunderbird.net/thunderbird/addon/987885

Troubleshooting:

You cannot run arbitrary javascript with tbkeys-lite. There is a tbkeys.xpi link on the GitHub releases page.

Remember to include the window object in custom commands. The first example fails with a reference error.

Code: Select all

alert('example 1');

Code: Select all

window.alert('example 2');

Code: Select all

(function () { var text = 'example 3'; window.alert(text); })();
The settings page will not allow invalid JSON to be submitted.

Remember to remove the newline characters in custom commands so the input is a valid JSON string.

Remember to remove the trailing comma after the last key so the input is a valid JSON string.

Code: Select all

{
    "ctrl+1": "window.alert('example 1');",
    "ctrl+2": "window.alert('example 2');",
    "ctrl+3": "(function () { var text = 'example 3'; window.alert(text); })();"
}
Online Multiline to Single Line Converter
http://tools.knowledgewalls.com/online- ... -converter

JSON Validator
http://jsonlint.com/

You can use the cmd shorthand and func shorthand with tbkeys and tbkeys-lite.

Use the cmd shorthand for calling a command using the goDoCommand method.

For example, "cmd:cmd_nextMsg" is the same as "window.goDoCommand('cmd_nextMsg');".

Use the func shorthand for calling a function on the window object without an argument.

For example, "func:MsgNewMessage" is the same as "window.MsgNewMessage();".

Tips:

You can change some addon shortcuts in the Addons Manager tab.

i.e. Tools > Addons > Extensions > Cogwheel > Manage Extension Shortcuts

You can use a menu item label to run a command.

Code: Select all

window.document.getElementsByAttribute('label', 'Open Message in New Tab')[0].doCommand();

Code: Select all

window.document.getElementsByAttribute('label', 'Find in This Message\u2026')[0].doCommand();
Ellipsis character
http://www.fileformat.info/info/unicode ... /index.htm

You can use the following code to easily extract a command using the error console. The trick does not work for all user interface elements.

Code: Select all

function getCommand(event) {
  window.removeEventListener("command", getCommand, true);
  event.preventDefault();
  event.stopPropagation();
  alert(event.originalTarget.getAttribute("oncommand") ||
    event.originalTarget.getAttribute("onclick"));
}
window.addEventListener("command", getCommand, true);
Extract the mark as unread command:

* run code in error console
* right click a message
* open "Mark" menu
* left click "As Unread" menu item

Code: Select all

window.goDoCommand('cmd_markAsUnread');
You can use the following code to show commands using the error console.

Code: Select all

(function () {
  var tagNames = ["command", "key", "menuitem"];
  var collection = new Object();
  for (var i = 0; i < tagNames.length; i++) {
    collection[tagNames[i]] = document.getElementsByTagName(tagNames[i]);
  }
  var out = new Array();
  var xai = Components.classes["@mozilla.org/xre/app-info;1"].
    getService(Components.interfaces.nsIXULAppInfo);
  out.push(xai.name + " " + xai.version);
  out.push(document.documentElement.getAttribute("windowtype"));
  var menuitems = document.getElementsByTagName("menuitem");
  for (var i in collection) {
    var count = 0;
    out.push("_____ ^ " + i + " " + Array(72 - i.length).join("_"));
    for (var j = 0; j < collection[i].length; j++) {
      var id = collection[i][j].getAttribute("id");
      var oncommand = collection[i][j].getAttribute("oncommand");
      var label = collection[i][j].getAttribute("label");
      var tooltiptext = collection[i][j].getAttribute("tooltiptext");
      var text = label || tooltiptext;
      if (id && oncommand) {
        count++;
        var tagNames = ["command", "key", "observes"];
        for (var m = 0; m < tagNames.length; m++) {
          if (!text) {
            for (var n = 0; n < menuitems.length; n++) {
              if (menuitems[n].getAttribute(tagNames[m]) == id) {
                text = menuitems[n].getAttribute("label");
                break;
              }
            }
          }
        }
        id = text ? id + " \u25ba " + text : id;
        oncommand = oncommand.search(/\x29$/) > -1 ? oncommand + ";" : oncommand;
        oncommand = oncommand.replace(/\s\s+/g, " ");
        out.push(id + "\n" + oncommand);
      }
    }
    out.push(i + " count " + count);
  }
  for (var i = 0; i < out.length; i++) {
    var suc = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
      createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    suc.charset = "UTF-8";
    out[i] = suc.ConvertFromUnicode(out[i]);
    out[i] = out[i].replace(/&/g, "&");
    out[i] = out[i].replace(/>/g, ">");
    out[i] = out[i].replace(/</g, "<");
    out[i] = out[i].replace(/"/g, """);
    out[i] = out[i].replace(/'/g, "&apos;");
  }
  var data = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">';
  data += "<html><head><title>" + out[1] + "</title>";
  data += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
  data += "</head><body><pre>" + out.join("\n\n") + "</pre></body></html>";
  openContentTab("data:text/html;charset=utf-8;base64," + btoa(data));
})();
The above code can be run in the compose window using the developer toolbox console.

Thunderbird commands (last edited in 2013)
http://kb.mozillazine.org/Keyconfig_ext ... hunderbird

Thunderbird shortcuts
http://support.mozilla.org/kb/keyboard-shortcuts

Thunderbird source
http://searchfox.org/comm-esr102/source/
http://searchfox.org/comm-esr102/source ... .inc.xhtml (more commands)
http://searchfox.org/comm-esr102/search ... egexp=true
http://searchfox.org/comm-esr102/source ... ersion.txt

Thunderbird command names like cmd_scrollTop are not included in the Thunderbird source.

Code: Select all

window.goDoCommand('cmd_scrollTop');
Firefox source
http://searchfox.org/mozilla-esr102/source/
http://searchfox.org/mozilla-esr102/sou ... mmands.cpp (more commands)
http://searchfox.org/mozilla-esr102/sea ... itions.cpp
http://searchfox.org/mozilla-esr102/sou ... ersion.txt

How to add key bindings support for message window: viewtopic.php?p=14919152#p14919152

How to define global functions with userChromeJS: viewtopic.php?p=14900570#p14900570

How to execute MailExtension command: viewtopic.php?p=14922347#p14922347

How to simulate or synthesize a keypress or a mouse click: viewtopic.php?p=14949538#p14949538
Last edited by morat on February 5th, 2024, 9:42 am, edited 53 times in total.
Oomingmak
Posts: 203
Joined: July 10th, 2004, 7:46 pm
Location: UK

Re: keyconfig 20110522

Post by Oomingmak »

morat wrote:@Oomingmak

Try something like:

Code: Select all

(function () {
  var uri = gBrowser.contentDocument.documentURIObject.spec;
  // var uri = gBrowser.contentDocument.location.href;
  // var uri = gBrowser.contentWindow.location.href;
  // var uri = content.location.href;
  var win = OpenBrowserWindow();
  win.addEventListener("load", function () {
    win.setTimeout(function () {
      win.loadURI(uri);
      // win.gBrowser.loadURI(uri);
      // win.content.location.href = uri;
    }, 0);
  }, true);
})();
Similar thread: http://forums.mozillazine.org/viewtopic ... &t=3028803
I appreciate your reply, morat.

Unfortunately I have been unable to make this work using the code as provided. I tried substituting the OpenBrowserWindow({remote: false}); code (from the thread that you linked) for the standard OpenBrowserWindow(); into the code sample you provided (I'm not sure if that was the correct thing to do), but nothing happens.

The OpenBrowserWindow({remote: false}); command works fine on its own (although it just opens a blank window) but my attempts to pass the active tab uri to the new window have all failed. Apologies, I'm really inexperienced with this kind of stuff.

Any pointers to where I might be going wrong?
morat
Posts: 6404
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@Oomingmak

Are you running the code in a e10s enabled window in Waterfox 56? If so, then that is why the code fails.
TypeError: gBrowser.contentDocument is null
The following code works here in Firefox 81. It should also work in Firefox 52.

Code: Select all

(function () {
  var uri = "http://www.mozillazine.org/";
  var win = OpenBrowserWindow();
  win.addEventListener("load", function () {
    win.setTimeout(function () {
      win.alert(uri);
    }, 0);
  }, true);
})();
The following e10s compatible code works here in Firefox 81.

Code: Select all

(function () {
  var script = "data:text/plain," + encodeURIComponent(`
    var data = {};
    data.href = content.location.href;
    sendAsyncMessage("foobar", data);
  `);
  gBrowser.selectedBrowser.messageManager.addMessageListener("foobar", function removeMe(message) {
    gBrowser.selectedBrowser.messageManager.removeMessageListener("foobar", removeMe);
    var uri = message.data.href;
    var win = OpenBrowserWindow();
    win.addEventListener("load", function () {
      win.setTimeout(function () {
        win.alert(uri);
      }, 0);
    }, true);
  });
  gBrowser.selectedBrowser.messageManager.loadFrameScript(script, false);
})();
The following code doesn't disable e10s in the new window in Firefox 81. I can check the multiprocess status in the about:support tab.

Code: Select all

OpenBrowserWindow({remote: false});
Firefox 52 Reference
http://dxr.mozilla.org/mozilla-esr52/se ... rect=false
http://dxr.mozilla.org/mozilla-esr52/so ... ersion.txt

Waterfox 56 Reference
http://github.com/MrAlex94/Waterfox/blo ... browser.js
http://github.com/MrAlex94/Waterfox/blo ... ersion.txt
Oomingmak
Posts: 203
Joined: July 10th, 2004, 7:46 pm
Location: UK

Re: keyconfig 20110522

Post by Oomingmak »

Thanks so much for your detailed reply.

Yes, I am running the code in an e10s enabled Waterfox window (hence the desire to find a hotkey to open a non-e10s window when necessary).

I seem to be getting closer to a working result.

Your latest code example opens a non-e10s window and correctly detects the current page uri to be loaded into the new non-e10s window. However, instead of loading the URI I instead get a javascript warning pop-up dialog that contains no message other than the URI of the page that is being passed to the non-e10s window. Meanwhile the non e10s window does open, but it always just defaults to my home page.

Image

The same thing happens with your first code example: a non-e10s window opens, but I get a javascript application warning saying: http://www.mozillazine.org/ (which is the URI stated in the first code example).

So, the correct page URI is now being forwarded (for whatever page is currently active at the time the code is run), but something is causing it to fall at last hurdle and the URI is not actually loaded.
morat
Posts: 6404
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@Oomingmak

Try this:

Code: Select all

(function () {
  var script = "data:text/plain," + encodeURIComponent(`
    var data = {};
    data.href = content.location.href;
    sendAsyncMessage("foobar", data);
  `);
  gBrowser.selectedBrowser.messageManager.addMessageListener("foobar", function removeMe(message) {
    gBrowser.selectedBrowser.messageManager.removeMessageListener("foobar", removeMe);
    var uri = message.data.href;
    var win = OpenBrowserWindow();
    win.addEventListener("load", function () {
      win.setTimeout(function () {
        win.gBrowser.loadURI(uri);
      }, 0);
    }, true);
  });
  gBrowser.selectedBrowser.messageManager.loadFrameScript(script, false);
})();
P.S.

You need to provide the triggeringPrincipal property starting in Firefox 64.

Code: Select all

gBrowser.loadURI("http://www.mozillazine.org/", {
  triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
avada
Posts: 1932
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Re: keyconfig 20110522

Post by avada »

Hi!

Did anyone transition to this updated keyconfig for current Firefox? (A couple of other useful XUL addons were also updated here.)

I tried moving my custom keys to my new profile by copying all extensions.dorandoKeyConfig.* items from prefs.js, but for some reason they don't appear or work.
Only one of them worked after the transition, which is funnily the one to open the keyconfig window. But even that wasn't colored purple as it is normal in Dorando keyconfig for custom items.
What could have gone wrong? I was expecting actual defined keys not working but, not the keys failing to survive the transition.
morat
Posts: 6404
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

It's likely easier to convert tbkeys to a Firefox addon, then update keyconfig. Not that I want to convert it.

tbkeys (an experiment_apis addon)
http://github.com/willsALMANJ/tbkeys

WebExtensions Experiments
http://firefox-source-docs.mozilla.org/ ... xperiments
avada
Posts: 1932
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Re: keyconfig 20110522

Post by avada »

morat wrote:It's likely easier to convert tbkeys to a Firefox addon, then update keyconfig. Not that I want to convert it.
Well, something must havevgone wrong, because I repeated the process, and now all my keys are there. So the addon seems to have been successfully updated.
Of course many of the keys are broken. Even some simple stuff as opening an url in a tab.
morat
Posts: 6404
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

It sounds like you don't know if the addon is broken or just your keys.

Try testing the code snippets ( i.e. keys ) in the browser console.

Code: Select all

(function () {
  alert("example");
})();
avada
Posts: 1932
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Re: keyconfig 20110522

Post by avada »

morat wrote:It sounds like you don't know if the addon is broken or just your keys.

Try testing the code snippets ( i.e. keys ) in the browser console.

Code: Select all

(function () {
  alert("example");
})();
I'm quite sure it does now, only firefox changed a lot. That example alert works as well.
But simple stuff like opening an url don't work. (eg: openUILinkIn("about:config", "tab"); ) I get some missing triggeringprincipal error on the console.

I had some often used keys for DownThemAll.
One of them (the one that's used to download a hovered link) broke. I'm quite sure you gave it to me in the first place, actually.
Do you think it's fixable?

Code: Select all

    /*Code*/
    // Save Link with dTa! OneClick
    Components.utils.import("resource://gre/modules/ctypes.jsm");
    var user32 = ctypes.open("user32");
    var BOOL = ctypes.int;
    var LONG = ctypes.long;
    var POINT = ctypes.StructType("tagPOINT", [{x:LONG}, {y:LONG}]);
    var LPPOINT = POINT.ptr;
    var GetCursorPos = user32.declare('GetCursorPos', ctypes.winapi_abi, BOOL, LPPOINT);
    var point = new POINT;
    if (GetCursorPos(point.address())) {
      var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
        getInterface(Components.interfaces.nsIDOMWindowUtils);
      var MOUSEEVENTF_RIGHTDOWN = 0x0008;
      var MOUSEEVENTF_RIGHTUP = 0x0010;
      utils.sendNativeMouseEvent(point.x, point.y, MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, null);
    }
    user32.close();
    setTimeout(function () {
      document.getElementById("dta:turbo-link").doCommand();
      document.getElementById("contentAreaContextMenu").hidePopup();
      setTimeout(function () {
        var win = Services.wm.getMostRecentWindow("alert:alert");
        if (win &&
            win.document.getElementById("alertTitleLabel") &&
            win.document.getElementById("alertTitleLabel").value == "DownThemAll!") {
          win.onAlertClose();
        }
      }, 2000);
    }, 1000);
morat
Posts: 6404
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

Try this:

Code: Select all

openUILinkIn("about:config", "tab", {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
The other code is for the legacy DownThemAll! addon.

Code: Select all

- var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
-   getInterface(Components.interfaces.nsIDOMWindowUtils);
+ var utils = window.windowUtils;
I doubt the "dta:turbo-link" id exists in the WebExtension DownThemAll! addon.

I would think the "alert:alert" window is for legacy addons only.

DownThemAll!
http://addons.mozilla.org/firefox/addon/201
avada
Posts: 1932
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Re: keyconfig 20110522

Post by avada »

morat wrote:Try this:

Code: Select all

openUILinkIn("about:config", "tab", {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
The other code is for the legacy DownThemAll! addon.

Code: Select all

- var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
-   getInterface(Components.interfaces.nsIDOMWindowUtils);
+ var utils = window.windowUtils;
I doubt the "dta:turbo-link" id exists in the WebExtension DownThemAll! addon.

I would think the "alert:alert" window is for legacy addons only.

DownThemAll!
http://addons.mozilla.org/firefox/addon/201
Thanks! I'll try when I get home.

DTA is not webextension, it's the old addon updated to work with recent FF. Keyconfig, and some other addons were also updated by the same person: https://github.com/xiaoxiaoflood/firefo ... extensions
Last edited by avada on November 19th, 2020, 11:19 am, edited 1 time in total.
pacocasc
Posts: 10
Joined: November 19th, 2020, 9:38 am

Re: keyconfig 20110522

Post by pacocasc »

Hello:
Please, Can someone please help me to write a keyboard shortcut in tbkeys to mark messages as replied.

I had it with dorando keyconfig, like this

user_pref("extensions.dorandoKeyConfig.main.xxx_key__Mark Msg Answered", "][Z][][var hdr=gDBView.db.MarkHdrReplied(gDBView.hdrForFirstSelectedMessage, true, null);");

user_pref("extensions.dorandoKeyConfig.main.xxx_key__Unmark Msg Answered", "shift][Z][][var hdr=gDBView.db.MarkHdrReplied(gDBView.hdrForFirstSelectedMessage, false, null);][");
morat
Posts: 6404
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@pacocasc

Try this:

Code: Select all

(function () {
  var msgHdr = window.gFolderDisplay.selectedMessage;
  if (msgHdr.flags & window.Components.interfaces.nsMsgMessageFlags.Replied) {
    msgHdr.folder.msgDatabase.MarkHdrReplied(msgHdr, false, null);
  } else {
    msgHdr.folder.msgDatabase.MarkHdrReplied(msgHdr, true, null);
  }
  msgHdr.folder.msgDatabase = null;
})();
Reference
http://developer.mozilla.org/docs/Mozil ... sIMsgDBHdr
http://developer.mozilla.org/docs/Mozil ... sgDatabase
http://developer.mozilla.org/docs/Mozil ... sagesFlags

Tips: http://forums.mozillazine.org/viewtopic ... #p14872763
pacocasc
Posts: 10
Joined: November 19th, 2020, 9:38 am

Re: keyconfig 20110522

Post by pacocasc »

morat wrote:@pacocasc

Try this:

Code: Select all

(function () {
  var msgHdr = window.gFolderDisplay.selectedMessage;
  if (msgHdr.flags & window.Components.interfaces.nsMsgMessageFlags.Replied) {
    msgHdr.folder.msgDatabase.MarkHdrReplied(msgHdr, false, null);
  } else {
    msgHdr.folder.msgDatabase.MarkHdrReplied(msgHdr, true, null);
  }
  msgHdr.folder.msgDatabase = null;
})();
Reference
http://developer.mozilla.org/docs/Mozil ... sIMsgDBHdr
http://developer.mozilla.org/docs/Mozil ... sgDatabase
http://developer.mozilla.org/docs/Mozil ... sagesFlags

Tips: http://forums.mozillazine.org/viewtopic ... #p14872763
Thanks a lot Morat. I tried the code. But tbkeys(thunderbird 78) won't let me save it. It gives me error

Code: Select all

"z": "(function () {
  var msgHdr = window.gFolderDisplay.selectedMessage;
  if (msgHdr.flags & window.Components.interfaces.nsMsgMessageFlags.Replied) {
    msgHdr.folder.msgDatabase.MarkHdrReplied(msgHdr, false, null);
  } else {
    msgHdr.folder.msgDatabase.MarkHdrReplied(msgHdr, true, null);
  }
  msgHdr.folder.msgDatabase = null;
})();"
Post Reply