MozillaZine

keyconfig 20110522

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

Post Posted September 18th, 2020, 1:25 pm

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

tbkeys (allow custom commands)
http://github.com/willsALMANJ/tbkeys#tbkeys

tbkeys lite (does not allow custom commands)
http://addons.thunderbird.net/thunderbird/addon/987885

Tips:

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/char/2026/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, "&amp;");
    out[i] = out[i].replace(/>/g, "&gt;");
    out[i] = out[i].replace(/</g, "&lt;");
    out[i] = out[i].replace(/"/g, "&quot;");
    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
http://kb.mozillazine.org/Keyconfig_extension:_Thunderbird

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

Thunderbird source
http://searchfox.org/comm-esr78/source/
http://searchfox.org/comm-esr78/source/mail/base/content/mainCommandSet.inc.xhtml
http://searchfox.org/comm-esr78/source/mail/config/version.txt

Troubleshooting:

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 () { window.alert('example 3'); })();

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
{
    "1": "alert('example 1');",
    "2": "window.alert('example 2');",
    "3": "(function () { window.alert('example 3'); })();"
}

JSON Validator
http://jsonlint.com/

How to add key bindings support for message window: viewtopic.php?p=14872137#p14872137
Last edited by morat on November 25th, 2020, 7:11 am, edited 24 times in total.

Oomingmak
 
Posts: 198
Joined: July 10th, 2004, 7:46 pm
Location: UK

Post Posted October 10th, 2020, 8:12 am

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: viewtopic.php?f=23&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: 4097
Joined: February 3rd, 2009, 6:29 pm

Post Posted October 10th, 2020, 10:06 am

@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/search?q=function+OpenBrowserWindow&redirect=false
http://dxr.mozilla.org/mozilla-esr52/source/browser/config/version.txt

Waterfox 56 Reference
http://github.com/MrAlex94/Waterfox/blob/classic/browser/base/content/browser.js
http://github.com/MrAlex94/Waterfox/blob/classic/browser/config/version.txt

Oomingmak
 
Posts: 198
Joined: July 10th, 2004, 7:46 pm
Location: UK

Post Posted October 10th, 2020, 11:21 am

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: 4097
Joined: February 3rd, 2009, 6:29 pm

Post Posted October 10th, 2020, 1:09 pm

@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: 1880
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Post Posted November 16th, 2020, 4:24 pm

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: 4097
Joined: February 3rd, 2009, 6:29 pm

Post Posted November 17th, 2020, 8:47 pm

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: 1880
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Post Posted November 18th, 2020, 5:49 am

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: 4097
Joined: February 3rd, 2009, 6:29 pm

Post Posted November 18th, 2020, 12:36 pm

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: 1880
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Post Posted November 19th, 2020, 3:43 am

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: 4097
Joined: February 3rd, 2009, 6:29 pm

Post Posted November 19th, 2020, 7:29 am

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: 1880
Joined: February 10th, 2008, 6:30 am
Location: Hungary

Post Posted November 19th, 2020, 9:25 am

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: 3
Joined: November 19th, 2020, 9:38 am

Post Posted November 19th, 2020, 10:17 am

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: 4097
Joined: February 3rd, 2009, 6:29 pm

Post Posted November 19th, 2020, 2:39 pm

@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/Mozilla/Tech/XPCOM/Reference/Interface/nsIMsgDBHdr
http://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIMsgDatabase
http://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/nsMsgMessagesFlags

Tips: viewtopic.php?p=14872763#p14872763

pacocasc
 
Posts: 3
Joined: November 19th, 2020, 9:38 am

Post Posted November 20th, 2020, 1:13 am

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/Mozilla/Tech/XPCOM/Reference/Interface/nsIMsgDBHdr
http://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIMsgDatabase
http://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/nsMsgMessagesFlags

Tips: viewtopic.php?p=14872763#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;
})();"

Return to Extension/Theme Releases


Who is online

Users browsing this forum: No registered users and 3 guests