keyconfig 20110522

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

Re: keyconfig 20110522

Post by morat »

You're welcome.
bege
Posts: 153
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Switch Dictionary in compose window of TB 68

Post by bege »

Hello,
I want to switch the current dictionary in the compose window of Thunderbird 68. The codes I found in this thread switch the preference (to be seen in about:config) but don't switch the dictionary in the current compose window.
Can someone help with a code to select a certain dictionary (eg. en-US, en-GB, de-DE ...) that works in Thunderbird 68?
morat
Posts: 6403
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@bege

Try this:

* toggle between two languages in compose window

Code: Select all

(function () {
  var lang = document.documentElement.getAttribute("lang");
  if (lang == "en-US") {
    ComposeChangeLanguage("de-DE");
  } else if (lang == "de-DE") {
    ComposeChangeLanguage("en-US");
  }
})();
German Dictionary (de-DE)
http://addons.thunderbird.net/thunderbird/addon/3077

Use another else if statement if you want to toggle between three languages.

P.S.

You can find the ComposeChangeLanguage function using the Developer Toolbox. (same as Browser Toolbox in Firefox)

More info: http://forums.mozillazine.org/viewtopic ... &t=3034448

Select the messengercompose.xul file. (picture)

Find the label="English (United States)" toolbarbutton in the inspector.

Code: Select all

<toolbarbutton xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  id="languageStatusButton"
  tooltiptext="Spellcheck language"
  oncommand="showPopupById('languageMenuList','languageStatusButton', before_start');"
  label="English (United States)"/>
Find the id="languageMenuList" menupopup in the inspector.

Code: Select all

<menupopup xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  id="languageMenuList"
  oncommand="ChangeLanguage(event);"
  onpopupshowing="OnShowDictionaryMenu(event.target);"
  hasbeenopened="true">...</menupopup>
Examine the ChangeLanguage function in the console to get the definition.

Code: Select all

function ChangeLanguage(event) {
  ComposeChangeLanguage(event.target.value);
  event.stopPropagation();
}
bege
Posts: 153
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Re: keyconfig 20110522

Post by bege »

@morat
Thank you very much, works perfect.
And thank you for the explanation how to find it out. I am familiar with the browser toolbox and have come until languageMenuList but then I didn't know how to continue.
How can I examine the function in the console? What exactly must I enter into the console? How to find ComposeChangeLanguage?
And I didn't know about document.documentElement.getAttribute("lang").
I am afraid I have to ask again in a similar case.
morat
Posts: 6403
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

You can find the id="languageMenuList" menupopup by searching for a css selector in the "Search HTML" textbox in the inspector.

e.g. #languageMenuList

You can use the "Jump to definition" icon in the console after you type "ChangeLanguage" and press enter.

Image

If you get a "ChangeLanguage is not defined" error, then you are likely in the 3pane window, not the compose window.

3pane window i.e. chrome://messenger/content/messenger.xul
compose window i.e. chrome://messenger/content/messengercompose/messengercompose.xul

Targeting a document
http://developer.mozilla.org/docs/Tools ... a_document

The lang attribute code snippet is in the ComposeChangeLanguage function.
bege
Posts: 153
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Re: keyconfig 20110522

Post by bege »

@morat
Thank you. =D>
This time I could follow, but I am not sure whether I can transform that for my next question. I will try and see and hope you are there if I fail :-k
Oomingmak
Posts: 203
Joined: July 10th, 2004, 7:46 pm
Location: UK

Re: keyconfig 20110522

Post by Oomingmak »

I have a couple of questions that I hope I can get some help with:

1. I'm using this code in KeyConfig: http://forums.mozillazine.org/viewtopic ... #p13105961

The code contains a section that focuses an existing tab (instead of opening a new one) if a tab with a specific URI already exists.

Here is what I think is the relevant section (copied from the post linked above).

Code: Select all

      // This will switch to the tab in aWindow having aURI, if present.
      function switchIfURIInWindow(aWindow, aURI) {
        if ("PrivateBrowsingUtils" in window) { // Fx 20+
          // Only switch to the tab if neither the source and desination window are
          // private and they are not in permanent private borwsing mode
          if ((PrivateBrowsingUtils.isWindowPrivate(window) ||
              PrivateBrowsingUtils.isWindowPrivate(aWindow)) &&
              !PrivateBrowsingUtils.permanentPrivateBrowsing) {
            return false;
          }
        }

        var browsers = aWindow.gBrowser.browsers;
        for (var i = 0; i < browsers.length; i++) {
          var browser = browsers[i];
          if (browser.currentURI.equals(aURI)) {
            // Focus the matching window & tab
            aWindow.focus();
            aWindow.gBrowser.tabContainer.selectedIndex = i;
            return true;
          }
        }
        return false;
      }

      var URI = "chrome://browser/content/places/places.xul";
 
I would like to modify this so that the tab matching is done based on the Title of the tab, and not its URI. How does the code need to be adjusted to achieve this?

I'm assuming it's just a matter of substituting (browser.currentURI.equals(aURI)) with the title-based equivalent command, then specifying the tab title instead of a URI (but I don't know how to do that).



2. In one of my other KeyConfig entries I have some code that contains this command:

Code: Select all

  event.originalTarget.title = "Bookmarks";

It allows the display name of a tab to be changed to whatever title is specified between the quote marks.

This got me wondering, would it be possible to somehow detect which of the 4 main tree branches has focus in the Library (i.e. History, Downloads, Tags, Bookmarks) and then set event.originalTarget.title to change the title of that particular Library tab to match whichever branch currently has focus?

If so, how would this best be done? I'm not even sure where the code would go (perhaps Greasemonkey / Violentmonkey).

The reason I ask is that I would like to use such a feature in conjunction with point number 1. above, so that I can open a Library tab with the focus set to, say, a Bookmark folder, and then later use my History hotkey (which uses the code above) to open a separate Library tab instead of switching to my existing Library tab and grabbing focus away from my currently selected bookmark folder. However, if the existing Library tab is already focussed to History, then my hotkey would simply switch to that instead of opening a second History-focussed tab.

Thanks!
morat
Posts: 6403
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@Oomingmak

1.

Try this:

Code: Select all

  var browser = browsers[i];
- if (browser.currentURI.equals(aURI)) {
+ if (browser.contentDocument.title == "whatever") {
2.

Maybe you could use userChromeJS, not Greasemonkey. I'm not going to help with that.

Code: Select all

/* Firefox userChrome.js */

if (location == "chrome://browser/content/places/places.xul") {
  setTimeout(function () {
    alert("example");
  }, 3000);
}
userChromeJS
http://userchromejs.mozdev.org/
http://userchromejs.mozdev.org/faq.html
bege
Posts: 153
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Re: keyconfig 20110522

Post by bege »

morat wrote:@bege

Try this:

* toggle between two languages in compose window

Code: Select all

(function () {
  var lang = document.documentElement.getAttribute("lang");
  if (lang == "en-US") {
    ComposeChangeLanguage("de-DE");
  } else if (lang == "de-DE") {
    ComposeChangeLanguage("en-US");
  }
})();
German Dictionary (de-DE)
http://addons.thunderbird.net/thunderbird/addon/3077

Use another else if statement if you want to toggle between three languages.

P.S.

You can find the ComposeChangeLanguage function using the Developer Toolbox. (same as Browser Toolbox in Firefox)

More info: http://forums.mozillazine.org/viewtopic ... &t=3034448

Select the messengercompose.xul file. (picture)

Find the label="English (United States)" toolbarbutton in the inspector.

Code: Select all

<toolbarbutton xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  id="languageStatusButton"
  tooltiptext="Spellcheck language"
  oncommand="showPopupById('languageMenuList','languageStatusButton', before_start');"
  label="English (United States)"/>
Find the id="languageMenuList" menupopup in the inspector.

Code: Select all

<menupopup xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  id="languageMenuList"
  oncommand="ChangeLanguage(event);"
  onpopupshowing="OnShowDictionaryMenu(event.target);"
  hasbeenopened="true">...</menupopup>
Examine the ChangeLanguage function in the console to get the definition.

Code: Select all

function ChangeLanguage(event) {
  ComposeChangeLanguage(event.target.value);
  event.stopPropagation();
}
@morat, I tried to transfer this to use in Firefox but I failed. Can you, please, help again?
morat
Posts: 6403
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@bege

Try this:

* toggle between two languages

Code: Select all

(function () {
  var spellChecker = Components.classes["@mozilla.org/spellchecker/engine;1"].
    getService(Components.interfaces.mozISpellCheckingEngine);
  var dictionaryList = spellChecker.getDictionaryList();
  for (var i = 0; i < dictionaryList.length; i++) {
    var dictionary = dictionaryList[i];
    if (dictionary != Services.prefs.getCharPref("spellchecker.dictionary")) {
      spellChecker.dictionary = dictionaryList[i];
      var contentPref = Components.classes["@mozilla.org/content-pref/service;1"].
        getService(Components.interfaces.nsIContentPrefService2);
      var target = document.commandDispatcher.focusedWindow;
      var loadContext = target.docShell.
        QueryInterface(Components.interfaces.nsIInterfaceRequestor).
          getInterface(Components.interfaces.nsIWebNavigation).
            QueryInterface(Components.interfaces.nsILoadContext);
      var script = "data:text/plain," + encodeURIComponent(`
        var data = {};
        data.href = content.document.location.href;
        sendAsyncMessage("foobar", data);
      `);
      gBrowser.selectedBrowser.messageManager.addMessageListener("foobar", function removeMe(message) {
        gBrowser.selectedBrowser.messageManager.removeMessageListener("foobar", removeMe);
        contentPref.set(message.data.href, "spellcheck.lang", dictionary, loadContext, {
          handleResult: function (result) {},
          handleError: function (error) {},
          handleCompletion: function (completion) {
            var focusedElement = document.commandDispatcher.focusedElement;
            focusedElement.blur();
            focusedElement.focus();
          },
        });
        Services.prefs.setCharPref("spellchecker.dictionary", dictionary);
      });
      gBrowser.selectedBrowser.messageManager.loadFrameScript(script, false);
      break;
    }
  }
})();
German Dictionary (de-DE)
http://addons.mozilla.org/firefox/addon/3077

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

Test text: scratch kratzen

Similar posts
http://forums.mozillazine.org/viewtopic ... #p14478785
http://forums.mozillazine.org/viewtopic ... #p14489621

Preference spellchecker.dictionary
http://kb.mozillazine.org/Spellchecker.dictionary

Reference
http://searchfox.org/mozilla-release/so ... Engine.idl
http://searchfox.org/mozilla-release/so ... rvice2.idl
http://searchfox.org/mozilla-release/se ... dictionary
http://searchfox.org/mozilla-release/se ... check.lang

Firefox 76.0.1
Windows 7 SP1 32-bit
bege
Posts: 153
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Re: keyconfig 20110522

Post by bege »

@morat
I guess I misunderstood you. I put the function into the key bind script but that throws this error:

Code: Select all

NS_ERROR_UNEXPECTED: Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIPrefBranch.getCharPref] browser.xhtml:7
Error: Invalid window ID: -1

Code: Select all

/* Firefox userChrome.js */

(function () {

  if (location == "chrome://browser/content/browser.xhtml") {
    setTimeout(function () {
      try {

        var keyset = document.getElementById("mainKeyset");
        // bind 
        var key3 = document.createXULElement("key");
        key3.setAttribute("id", "key_dict_toggle");
        key3.setAttribute("key", "y");
		  key3.setAttribute('modifiers', 'alt');
        key3.setAttribute("oncommand", '(' + onCommand.toString() + ')()');
        keyset.appendChild(key3);

      } catch (e) {
        Components.utils.reportError(e);
      };
    }, 2000);
  }

function onCommand() {
  var spellChecker = Components.classes["@mozilla.org/spellchecker/engine;1"].
    getService(Components.interfaces.mozISpellCheckingEngine);
  var dictionaryList = spellChecker.getDictionaryList();
  for (var i = 0; i < dictionaryList.length; i++) {
    var dictionary = dictionaryList[i];
    if (dictionary != Services.prefs.getCharPref("spellchecker.dictionary")) {
      spellChecker.dictionary = dictionaryList[i];
      var contentPref = Components.classes["@mozilla.org/content-pref/service;1"].
        getService(Components.interfaces.nsIContentPrefService2);
      var target = document.commandDispatcher.focusedWindow;
      var loadContext = target.docShell.
        QueryInterface(Components.interfaces.nsIInterfaceRequestor).
          getInterface(Components.interfaces.nsIWebNavigation).
            QueryInterface(Components.interfaces.nsILoadContext);
      var script = "data:text/plain," + encodeURIComponent(`
        var data = {};
        data.href = content.document.location.href;
        sendAsyncMessage("foobar", data);
      `);
      gBrowser.selectedBrowser.messageManager.addMessageListener("foobar", function removeMe(message) {
        gBrowser.selectedBrowser.messageManager.removeMessageListener("foobar", removeMe);
        contentPref.set(message.data.href, "spellcheck.lang", dictionary, loadContext, {
          handleResult: function (result) {},
          handleError: function (error) {},
          handleCompletion: function (completion) {
            var focusedElement = document.commandDispatcher.focusedElement;
            focusedElement.blur();
            focusedElement.focus();
          },
        });
        Services.prefs.setCharPref("spellchecker.dictionary", dictionary);
      });
      gBrowser.selectedBrowser.messageManager.loadFrameScript(script, false);
      break;
    }
  }
};
})();
morat
Posts: 6403
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@bege

You need to create the spellchecker.dictionary preference. (manually or using the browser console)

Code: Select all

Services.prefs.setCharPref("spellchecker.dictionary", "en-US");
It works here with the textbox on the test page. I'm using the en-US build with the de-DE dictionary.

I tested my code using the browser console and I tested the following code using the userChrome.js file.

* <profile directory>\chrome\userChrome.js

Code: Select all

/* Firefox userChrome.js */

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

  try {

    /* unbind Find Again F3, note: key element has no id attribute */

    var keyset = document.getElementById("mainKeyset");
    var key = document.querySelector('key[keycode="VK_F3"][command="cmd_findAgain"]');
    keyset.removeChild(key);

    /* bind Dictionary Switcher F3 */

    window.__unique_identifier_dictionary_switcher = function (event) {
      var spellChecker = Components.classes["@mozilla.org/spellchecker/engine;1"].
        getService(Components.interfaces.mozISpellCheckingEngine);
      var dictionaryList = spellChecker.getDictionaryList();
      for (var i = 0; i < dictionaryList.length; i++) {
        var dictionary = dictionaryList[i];
        if (dictionary != Services.prefs.getCharPref("spellchecker.dictionary")) {
          spellChecker.dictionary = dictionaryList[i];
          var contentPref = Components.classes["@mozilla.org/content-pref/service;1"].
            getService(Components.interfaces.nsIContentPrefService2);
          var target = document.commandDispatcher.focusedWindow;
          var loadContext = target.docShell.
            QueryInterface(Components.interfaces.nsIInterfaceRequestor).
              getInterface(Components.interfaces.nsIWebNavigation).
                QueryInterface(Components.interfaces.nsILoadContext);
          var script = "data:text/plain," + encodeURIComponent(`
            var data = {};
            data.href = content.document.location.href;
            sendAsyncMessage("foobar", data);
          `);
          gBrowser.selectedBrowser.messageManager.addMessageListener("foobar", function removeMe(message) {
            gBrowser.selectedBrowser.messageManager.removeMessageListener("foobar", removeMe);
            contentPref.set(message.data.href, "spellcheck.lang", dictionary, loadContext, {
              handleResult: function (result) {},
              handleError: function (error) {},
              handleCompletion: function (completion) {
                var focusedElement = document.commandDispatcher.focusedElement;
                focusedElement.blur();
                focusedElement.focus();
              },
            });
            Services.prefs.setCharPref("spellchecker.dictionary", dictionary);
          });
          gBrowser.selectedBrowser.messageManager.loadFrameScript(script, false);
          break;
        }
      }
    };
    var keyset = document.getElementById("mainKeyset");
    var key = document.createXULElement("key");
    key.setAttribute("id", "__unique_identifier_key_dictionary_switcher");
 // key.setAttribute("key", "A"); // A
 // key.setAttribute("modifiers", "control,shift"); // Ctrl+Shift
 // key.setAttribute("modifiers", "alt"); // Alt
    key.setAttribute("keycode", "VK_F3"); // F3
 // key.setAttribute("command", "cmd_toggleOfflineStatus");
    key.setAttribute("oncommand", "__unique_identifier_dictionary_switcher(event);");
 // key.setAttribute("oncommand", "alert('Example');");
    keyset.appendChild(key);

  } catch (e) {
    Components.utils.reportError(e); // [check] Show Content Messages
  };
})();
userChrome.js hacks for Firefox
http://forums.mozillazine.org/viewtopic ... #p14854175
bege
Posts: 153
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Re: keyconfig 20110522

Post by bege »

@morat
Thank you very much! I eventually got it to work.
Oomingmak
Posts: 203
Joined: July 10th, 2004, 7:46 pm
Location: UK

Re: keyconfig 20110522

Post by Oomingmak »

Can anybody please let me know what code to use to open the current page in a new non-e10s window? (i.e. a window with multi-process disabled).

There is a command on the 'File' menu for a non-10s window, but it opens an empty page. I'd like to do the same thing, but with the currently focussed page loaded into the new non-e10s window.

Thanks in advance for any help.
morat
Posts: 6403
Joined: February 3rd, 2009, 6:29 pm

Re: keyconfig 20110522

Post by morat »

@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
Last edited by morat on September 19th, 2020, 8:56 am, edited 1 time in total.
Post Reply