MozillaZine

keyconfig 20110522

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

Post Posted March 23rd, 2020, 8:05 am

You're welcome.

bege
 
Posts: 128
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Post Posted March 23rd, 2020, 3:35 pm

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

Post Posted March 25th, 2020, 6:21 pm

@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: viewtopic.php?f=23&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: 128
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Post Posted March 26th, 2020, 9:50 am

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

Post Posted March 26th, 2020, 11:23 am

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/Browser_Toolbox#Targeting_a_document

The lang attribute code snippet is in the ComposeChangeLanguage function.

bege
 
Posts: 128
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Post Posted March 26th, 2020, 11:54 am

@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: 196
Joined: July 10th, 2004, 7:46 pm
Location: UK

Post Posted May 12th, 2020, 8:57 pm

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

1. I'm using this code in KeyConfig: viewtopic.php?p=13105961#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: 3929
Joined: February 3rd, 2009, 6:29 pm

Post Posted May 13th, 2020, 7:24 am

@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: 128
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Post Posted May 15th, 2020, 10:18 am

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

Post Posted May 15th, 2020, 1:54 pm

@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.php?p=14478785#p14478785
http://forums.mozillazine.org/viewtopic.php?p=14489621#p14489621

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

Reference
http://searchfox.org/mozilla-release/source/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
http://searchfox.org/mozilla-release/source/dom/interfaces/base/nsIContentPrefService2.idl
http://searchfox.org/mozilla-release/search?q=spellchecker.dictionary
http://searchfox.org/mozilla-release/search?q=spellcheck.lang

Firefox 76.0.1
Windows 7 SP1 32-bit

bege
 
Posts: 128
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Post Posted May 17th, 2020, 8:53 am

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

Post Posted May 17th, 2020, 9:26 am

@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.php?p=14854175#p14854175

bege
 
Posts: 128
Joined: January 23rd, 2009, 9:14 pm
Location: Germany

Post Posted May 28th, 2020, 11:08 am

@morat
Thank you very much! I eventually got it to work.

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

Post Posted September 18th, 2020, 12:00 pm

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

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

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

Return to Extension/Theme Releases


Who is online

Users browsing this forum: No registered users and 2 guests