From 526b5a512aa3e21bf843859eff7a7ee618e51687 Mon Sep 17 00:00:00 2001
From: "bugzilla%arlen.demon.co.uk"
Date: Thu, 29 Jun 2006 23:10:04 +0000
Subject: [PATCH] Bug 337155 SeaMonkey missing spellcheck language selector in
mail compose window and preferences also backporting enhancements to
Thunderbird p=me r=mnyromyr(SM)/mscott(TB) sr=neil
git-svn-id: svn://10.0.0.236/trunk@201311 18797224-902f-48f8-a5cc-f745e15eee43
---
.../editor/ui/dialogs/content/EdSpellCheck.js | 124 ++++++++++------
.../ui/dialogs/content/EdSpellCheck.xul | 6 +-
.../en-US/chrome/dialogs/EditorSpellCheck.dtd | 2 +-
.../resources/locale/en-US/mail_help.xhtml | 15 +-
.../compose/content/EdSpellCheck.js | 123 +++++++++------
.../compose/content/MsgComposeCommands.js | 114 ++++++++------
.../compose/content/messengercompose.xul | 6 +-
.../mail/components/preferences/compose.js | 57 ++++---
.../mail/components/preferences/compose.xul | 6 +-
.../content/pref-composing_messages.js | 140 ++++++++++++++++++
.../content/pref-composing_messages.xul | 118 +++++++--------
.../locale/en-US/pref-composing_messages.dtd | 17 ++-
.../resources/content/MsgComposeCommands.js | 132 ++++++++++++++++-
.../resources/content/messengercompose.xul | 9 +-
mozilla/mailnews/jar.mn | 1 +
15 files changed, 612 insertions(+), 258 deletions(-)
create mode 100644 mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.js
diff --git a/mozilla/editor/ui/dialogs/content/EdSpellCheck.js b/mozilla/editor/ui/dialogs/content/EdSpellCheck.js
index 33d9ccfa1d1..09e107e1391 100644
--- a/mozilla/editor/ui/dialogs/content/EdSpellCheck.js
+++ b/mozilla/editor/ui/dialogs/content/EdSpellCheck.js
@@ -44,12 +44,14 @@ var gAllowSelectWord = true;
var gPreviousReplaceWord = "";
var gFirstTime = true;
var gLastSelectedLang = null;
+var gDictCount = 0;
function Startup()
{
var sendMailMessageMode = false;
- if (!GetCurrentEditor())
+ var editor = GetCurrentEditor();
+ if (!editor)
{
window.close();
return;
@@ -78,11 +80,8 @@ function Startup()
filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
gSpellChecker.setFilter(Components.classes[filterContractId].createInstance(Components.interfaces.nsITextServicesFilter));
- gSpellChecker.InitSpellChecker(GetCurrentEditor(), enableSelectionChecking);
+ gSpellChecker.InitSpellChecker(editor, enableSelectionChecking);
- // XXX: We need to read in a pref here so we can set the
- // default language for the spellchecker!
- // gSpellChecker.SetCurrentDictionary();
}
catch(ex) {
dump("*** Exception error: InitSpellChecker\n");
@@ -146,7 +145,7 @@ function Startup()
gFirstTime = false;
}
-function InitLanguageMenu(curLang)
+function InitLanguageMenu(aCurLang)
{
var o1 = {};
@@ -155,9 +154,12 @@ function InitLanguageMenu(curLang)
// Get the list of dictionaries from
// the spellchecker.
- try {
+ try
+ {
gSpellChecker.GetDictionaryList(o1, o2);
- } catch(ex) {
+ }
+ catch(ex)
+ {
dump("Failed to get DictionaryList!\n");
return;
}
@@ -165,65 +167,84 @@ function InitLanguageMenu(curLang)
var dictList = o1.value;
var count = o2.value;
+ // If we're not just starting up and dictionary count
+ // hasn't changed then no need to update the menu.
+ if (gDictCount == count)
+ return;
+
+ // Store current dictionary count.
+ gDictCount = count;
+
// Load the string bundles that will help us map
// RFC 1766 strings to UI strings.
// Load the language string bundle.
var languageBundle = document.getElementById("languageBundle");
- var regionBundle;
+ var regionBundle = null;
// If we have a language string bundle, load the region string bundle.
if (languageBundle)
regionBundle = document.getElementById("regionBundle");
var menuStr2;
var isoStrArray;
- var defaultItem = null;
var langId;
+ var langLabel;
var i;
- for (i = 0; i < dictList.length; i++)
+
+ for (i = 0; i < count; i++)
{
- try {
+ try
+ {
langId = dictList[i];
isoStrArray = dictList[i].split("-");
- dictList[i] = new Array(2); // first subarray element - pretty name
- dictList[i][1] = langId; // second subarray element - language ID
-
if (languageBundle && isoStrArray[0])
- dictList[i][0] = languageBundle.getString(isoStrArray[0].toLowerCase());
+ langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
- if (regionBundle && dictList[i][0] && isoStrArray.length > 1 && isoStrArray[1])
+ if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1])
{
menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
if (menuStr2)
- dictList[i][0] = dictList[i][0] + "/" + menuStr2;
+ langLabel += "/" + menuStr2;
}
- if (!dictList[i][0])
- dictList[i][0] = dictList[i][1];
- } catch (ex) {
- // GetString throws an exception when
- // a key is not found in the bundle. In that
- // case, just use the original dictList string.
-
- dictList[i][0] = dictList[i][1];
+ if (!langLabel)
+ langLabel = langId;
}
+ catch (ex)
+ {
+ // getString throws an exception when a key is not found in the
+ // bundle. In that case, just use the original dictList string.
+ langLabel = langId;
+ }
+ dictList[i] = [langLabel, langId];
}
- // note this is not locale-aware collation, just simple ASCII-based sorting
- // we really need to add loacel-aware JS collation, see bug XXXXX
- dictList.sort();
+ // sort by locale-aware collation
+ dictList.sort(
+ function compareFn(a, b)
+ {
+ return a[0].localeCompare(b[0]);
+ }
+ );
- for (i = 0; i < dictList.length; i++)
+ // Remove any languages from the list.
+ var languageMenuPopup = gDialog.LanguageMenulist.firstChild;
+ while (languageMenuPopup.firstChild.localName != "menuseparator")
+ languageMenuPopup.removeChild(languageMenuPopup.firstChild);
+
+ var defaultItem = null;
+
+ for (i = 0; i < count; i++)
{
- var item = gDialog.LanguageMenulist.appendItem(dictList[i][0], dictList[i][1]);
- if (curLang && dictList[i][1] == curLang)
+ var item = gDialog.LanguageMenulist.insertItemAt(i, dictList[i][0], dictList[i][1]);
+ if (aCurLang && dictList[i][1] == aCurLang)
defaultItem = item;
}
// Now make sure the correct item in the menu list is selected.
-
- if (defaultItem) {
+ if (defaultItem)
+ {
gDialog.LanguageMenulist.selectedItem = defaultItem;
gLastSelectedLang = defaultItem;
}
@@ -448,7 +469,6 @@ function Recheck()
//TODO: Should we bother to add a "Recheck" method to interface?
try {
var curLang = gSpellChecker.GetCurrentDictionary();
-
gSpellChecker.UninitSpellChecker();
gSpellChecker.InitSpellChecker(GetCurrentEditor(), false);
gSpellChecker.SetCurrentDictionary(curLang);
@@ -535,14 +555,34 @@ function doDefault()
return false;
}
-function CancelSpellCheck()
+function ExitSpellChecker()
{
if (gSpellChecker)
{
- try {
+ try
+ {
+ var curLang = gSpellChecker.GetCurrentDictionary();
gSpellChecker.UninitSpellChecker();
- } finally { gSpellChecker = null; }
+ if ("@mozilla.org/spellchecker;1" in Components.classes) {
+ var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
+ .getService(Components.interfaces.mozISpellCheckingEngine);
+ spellChecker.dictionary = curLang;
+ }
+ // now check the document over again with the new dictionary
+ if ("inlineSpellChecker" in window.opener.InlineSpellChecker)
+ if (window.opener.InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
+ window.opener.InlineSpellChecker.checkDocument(window.opener.content.document);
+ }
+ finally
+ {
+ gSpellChecker = null;
+ }
}
+}
+
+function CancelSpellCheck()
+{
+ ExitSpellChecker();
// Signal to calling window that we canceled
window.opener.cancelSendMessage = true;
@@ -551,12 +591,8 @@ function CancelSpellCheck()
function onClose()
{
- if (gSpellChecker)
- {
- try {
- gSpellChecker.UninitSpellChecker();
- } finally { gSpellChecker = null; }
- }
+ ExitSpellChecker();
+
window.opener.cancelSendMessage = false;
window.close();
}
diff --git a/mozilla/editor/ui/dialogs/content/EdSpellCheck.xul b/mozilla/editor/ui/dialogs/content/EdSpellCheck.xul
index 4e2f72e2cf0..5cf5abfe71c 100644
--- a/mozilla/editor/ui/dialogs/content/EdSpellCheck.xul
+++ b/mozilla/editor/ui/dialogs/content/EdSpellCheck.xul
@@ -127,10 +127,10 @@
accesskey="&languagePopup.accessKey;"/>
-
-
-
+
+
+
diff --git a/mozilla/editor/ui/locales/en-US/chrome/dialogs/EditorSpellCheck.dtd b/mozilla/editor/ui/locales/en-US/chrome/dialogs/EditorSpellCheck.dtd
index ac9b9fae85e..9e17ff2ad39 100644
--- a/mozilla/editor/ui/locales/en-US/chrome/dialogs/EditorSpellCheck.dtd
+++ b/mozilla/editor/ui/locales/en-US/chrome/dialogs/EditorSpellCheck.dtd
@@ -56,7 +56,7 @@
-
+
diff --git a/mozilla/extensions/help/resources/locale/en-US/mail_help.xhtml b/mozilla/extensions/help/resources/locale/en-US/mail_help.xhtml
index 075bbf3fc71..46846ad99a7 100644
--- a/mozilla/extensions/help/resources/locale/en-US/mail_help.xhtml
+++ b/mozilla/extensions/help/resources/locale/en-US/mail_help.xhtml
@@ -4559,12 +4559,6 @@ to filter unwanted mail.
Forward Messages: Choose how you want forwarded
message text to appear: as an attachment or inline (in the body
of your message).
-
Check spelling before sending: Select this option to
- have Mail & Newsgroups always check the spelling of your message before
- you send it.
-
Check spelling as you type: Select this option to have
- Mail & Newsgroups always check the spelling of your message as you type
- it.
Automatically save the message every ___ minutes: Choose
this option if you want Mail & Newsgroups to save the message you are
currently composing automatically at the given interval. After a computer
@@ -4577,6 +4571,15 @@ to filter unwanted mail.
keyboard shortcut by mistake when composing a message.
Wrap plain text messages at ___ characters: Enter a
number to set the right margin for text in the message area.
+
Check spelling before sending: Select this option to
+ have Mail & Newsgroups always check the spelling of your message before
+ you send it.
+
Check spelling as you type: Select this option to have
+ Mail & Newsgroups always check the spelling of your message as you type
+ it.
+
Language: Use the drop-down list to select the language
+ you want to use to check the spelling in your messages or to download more
+ dictionaries.
Defaults for HTML Messages: Here you can define what the
defaults are for font, size, text and background color if you choose to
send mails in HTML format.
diff --git a/mozilla/mail/components/compose/content/EdSpellCheck.js b/mozilla/mail/components/compose/content/EdSpellCheck.js
index c0de052cc0c..33cf8c836a4 100644
--- a/mozilla/mail/components/compose/content/EdSpellCheck.js
+++ b/mozilla/mail/components/compose/content/EdSpellCheck.js
@@ -44,12 +44,14 @@ var gAllowSelectWord = true;
var gPreviousReplaceWord = "";
var gFirstTime = true;
var gLastSelectedLang = null;
+var gDictCount = 0;
function Startup()
{
var sendMailMessageMode = false;
- if (!GetCurrentEditor())
+ var editor = GetCurrentEditor();
+ if (!editor)
{
window.close();
return;
@@ -78,11 +80,8 @@ function Startup()
filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
gSpellChecker.setFilter(Components.classes[filterContractId].createInstance(Components.interfaces.nsITextServicesFilter));
- gSpellChecker.InitSpellChecker(GetCurrentEditor(), enableSelectionChecking);
+ gSpellChecker.InitSpellChecker(editor, enableSelectionChecking);
- // XXX: We need to read in a pref here so we can set the
- // default language for the spellchecker!
- // gSpellChecker.SetCurrentDictionary();
}
catch(ex) {
dump("*** Exception error: InitSpellChecker\n");
@@ -146,7 +145,7 @@ function Startup()
gFirstTime = false;
}
-function InitLanguageMenu(curLang)
+function InitLanguageMenu(aCurLang)
{
var o1 = {};
@@ -155,9 +154,12 @@ function InitLanguageMenu(curLang)
// Get the list of dictionaries from
// the spellchecker.
- try {
+ try
+ {
gSpellChecker.GetDictionaryList(o1, o2);
- } catch(ex) {
+ }
+ catch(ex)
+ {
dump("Failed to get DictionaryList!\n");
return;
}
@@ -165,65 +167,83 @@ function InitLanguageMenu(curLang)
var dictList = o1.value;
var count = o2.value;
+ // If dictionary count hasn't changed then no need to update the menu.
+ if (gDictCount == count)
+ return;
+
+ // Store current dictionary count.
+ gDictCount = count;
+
// Load the string bundles that will help us map
// RFC 1766 strings to UI strings.
// Load the language string bundle.
var languageBundle = document.getElementById("languageBundle");
- var regionBundle;
+ var regionBundle = null;
// If we have a language string bundle, load the region string bundle.
if (languageBundle)
regionBundle = document.getElementById("regionBundle");
var menuStr2;
var isoStrArray;
- var defaultItem = null;
var langId;
+ var langLabel;
var i;
- for (i = 0; i < dictList.length; i++)
+
+ for (i = 0; i < count; i++)
{
- try {
+ try
+ {
langId = dictList[i];
isoStrArray = dictList[i].split("-");
- dictList[i] = new Array(2); // first subarray element - pretty name
- dictList[i][1] = langId; // second subarray element - language ID
-
if (languageBundle && isoStrArray[0])
- dictList[i][0] = languageBundle.getString(isoStrArray[0].toLowerCase());
+ langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
- if (regionBundle && dictList[i][0] && isoStrArray.length > 1 && isoStrArray[1])
+ if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1])
{
menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
if (menuStr2)
- dictList[i][0] = dictList[i][0] + "/" + menuStr2;
+ langLabel += "/" + menuStr2;
}
- if (!dictList[i][0])
- dictList[i][0] = dictList[i][1];
- } catch (ex) {
- // GetString throws an exception when
- // a key is not found in the bundle. In that
- // case, just use the original dictList string.
-
- dictList[i][0] = dictList[i][1];
+ if (!langLabel)
+ langLabel = langId;
}
+ catch (ex)
+ {
+ // getString throws an exception when a key is not found in the
+ // bundle. In that case, just use the original dictList string.
+ langLabel = langId;
+ }
+ dictList[i] = [langLabel, langId];
}
- // note this is not locale-aware collation, just simple ASCII-based sorting
- // we really need to add loacel-aware JS collation, see bug XXXXX
- dictList.sort();
+ // sort by locale-aware collation
+ dictList.sort(
+ function compareFn(a, b)
+ {
+ return a[0].localeCompare(b[0]);
+ }
+ );
- for (i = 0; i < dictList.length; i++)
+ // Remove any languages from the list.
+ var languageMenuPopup = gDialog.LanguageMenulist.firstChild;
+ while (languageMenuPopup.firstChild.localName != "menuseparator")
+ languageMenuPopup.removeChild(languageMenuPopup.firstChild);
+
+ var defaultItem = null;
+
+ for (i = 0; i < count; i++)
{
- var item = gDialog.LanguageMenulist.appendItem(dictList[i][0], dictList[i][1]);
- if (curLang && dictList[i][1] == curLang)
+ var item = gDialog.LanguageMenulist.insertItemAt(i, dictList[i][0], dictList[i][1]);
+ if (aCurLang && dictList[i][1] == aCurLang)
defaultItem = item;
}
// Now make sure the correct item in the menu list is selected.
-
- if (defaultItem) {
+ if (defaultItem)
+ {
gDialog.LanguageMenulist.selectedItem = defaultItem;
gLastSelectedLang = defaultItem;
}
@@ -452,7 +472,6 @@ function Recheck()
//TODO: Should we bother to add a "Recheck" method to interface?
try {
var curLang = gSpellChecker.GetCurrentDictionary();
-
gSpellChecker.UninitSpellChecker();
gSpellChecker.InitSpellChecker(GetCurrentEditor(), false);
gSpellChecker.SetCurrentDictionary(curLang);
@@ -539,14 +558,34 @@ function doDefault()
return false;
}
-function CancelSpellCheck()
+function ExitSpellChecker()
{
if (gSpellChecker)
{
- try {
+ try
+ {
+ var curLang = gSpellChecker.GetCurrentDictionary();
gSpellChecker.UninitSpellChecker();
- } finally { gSpellChecker = null; }
+ if ("@mozilla.org/spellchecker;1" in Components.classes) {
+ var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
+ .getService(Components.interfaces.mozISpellCheckingEngine);
+ spellChecker.dictionary = curLang;
+ }
+ // now check the document over again with the new dictionary
+ if ("inlineSpellChecker" in window.opener.InlineSpellChecker)
+ if (window.opener.InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
+ window.opener.InlineSpellChecker.checkDocument(window.opener.content.document);
+ }
+ finally
+ {
+ gSpellChecker = null;
+ }
}
+}
+
+function CancelSpellCheck()
+{
+ ExitSpellChecker();
// Signal to calling window that we canceled
window.opener.cancelSendMessage = true;
@@ -555,12 +594,8 @@ function CancelSpellCheck()
function onClose()
{
- if (gSpellChecker)
- {
- try {
- gSpellChecker.UninitSpellChecker();
- } finally { gSpellChecker = null; }
- }
+ ExitSpellChecker();
+
window.opener.cancelSendMessage = false;
window.close();
}
diff --git a/mozilla/mail/components/compose/content/MsgComposeCommands.js b/mozilla/mail/components/compose/content/MsgComposeCommands.js
index 5f0b0559ff5..710b32fff24 100644
--- a/mozilla/mail/components/compose/content/MsgComposeCommands.js
+++ b/mozilla/mail/components/compose/content/MsgComposeCommands.js
@@ -39,14 +39,15 @@
/**
* interfaces
*/
-var nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
-var nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
-var nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
-var nsIMsgCompType = Components.interfaces.nsIMsgCompType;
-var nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
-var nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
-var nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
-
+const nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
+const nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
+const nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
+const nsIMsgCompType = Components.interfaces.nsIMsgCompType;
+const nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
+const nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
+const nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
+const nsISupportsString = Components.interfaces.nsISupportsString;
+const mozISpellCheckingEngine = Components.interfaces.mozISpellCheckingEngine;
/**
* In order to distinguish clearly globals that are initialized once when js load (static globals) and those that need to be
@@ -66,6 +67,7 @@ var sOther_headers = "";
var sAccountManagerDataSource = null;
var sRDF = null;
var sNameProperty = null;
+var sDictCount = 0;
/* Create message window object. This is use by mail-offline.js and therefore should not be renamed. We need to avoid doing
this kind of cross file global stuff in the future and instead pass this object as parameter when needed by function
@@ -1361,7 +1363,6 @@ function ComposeStartup(recycled, aParams)
// Do setup common to Message Composer and Web Composer
EditorSharedStartup();
- initLanguageMenu();
}
var msgCompFields = gMsgCompose.compFields;
@@ -2188,12 +2189,14 @@ function ToggleInlineSpellChecker(target)
}
}
-function initLanguageMenu()
+function InitLanguageMenu()
{
- var languageMenuList = document.getElementById('LanguageMenulist');
- if (!languageMenuList) return;
+ var languageMenuList = document.getElementById('languageMenuList');
+ if (!languageMenuList)
+ return;
- var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1'].getService(Components.interfaces.mozISpellCheckingEngine);
+ var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1']
+ .getService(mozISpellCheckingEngine);
var o1 = {};
var o2 = {};
@@ -2205,87 +2208,100 @@ function initLanguageMenu()
var dictList = o1.value;
var count = o2.value;
- // Load the string bundles that will help us map
- // RFC 1766 strings to UI strings.
+ // If dictionary count hasn't changed then no need to update the menu.
+ if (sDictCount == count)
+ return;
- // Load the language string bundle.
+ // Store current dictionary count.
+ sDictCount = count;
+
+ // Load the string bundle that will help us map
+ // RFC 1766 strings to UI strings.
var languageBundle = document.getElementById("languageBundle");
var isoStrArray;
var langId;
+ var langLabel;
var i;
- for (i = 0; i < dictList.length; i++)
+ for (i = 0; i < count; i++)
{
- try {
+ try
+ {
langId = dictList[i];
isoStrArray = dictList[i].split("-");
- dictList[i] = new Array(2); // first subarray element - pretty name
- dictList[i][1] = langId; // second subarray element - language ID
-
if (languageBundle && isoStrArray[0])
- dictList[i][0] = languageBundle.getString(isoStrArray[0].toLowerCase());
+ langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
// the user needs to be able to distinguish between the UK English dictionary
// and say the United States English Dictionary. If we have a isoStr value then
// wrap it in parentheses and append it to the menu item string. i.e.
// English (US) and English (UK)
- if (!dictList[i][0])
- dictList[i][0] = dictList[i][1];
+ if (!langLabel)
+ langLabel = langId;
else if (isoStrArray.length > 1 && isoStrArray[1]) // if we have a language ID like US or UK, append it to the menu item
- dictList[i][0] += ' (' + isoStrArray[1] + ')';
- } catch (ex) {
- // GetString throws an exception when
- // a key is not found in the bundle. In that
- // case, just use the original dictList string.
-
- dictList[i][0] = dictList[i][1];
+ langLabel += ' (' + isoStrArray[1] + ')';
}
+ catch (ex)
+ {
+ // getString throws an exception when a key is not found in the
+ // bundle. In that case, just use the original dictList string.
+ langLabel = langId;
+ }
+ dictList[i] = [langLabel, langId];
}
- // note this is not locale-aware collation, just simple ASCII-based sorting
- // we really need to add locale-aware JS collation
- dictList.sort();
+ // sort by locale-aware collation
+ dictList.sort(
+ function compareFn(a, b)
+ {
+ return a[0].localeCompare(b[0]);
+ }
+ );
- // now select the dictionary we are currently using
- for (i = 0; i < dictList.length; i++)
+ // Remove any languages from the list.
+ while (languageMenuList.hasChildNodes())
+ languageMenuList.removeChild(languageMenuList.firstChild);
+
+ for (i = 0; i < count; i++)
{
var item = document.createElement("menuitem");
item.setAttribute("label", dictList[i][0]);
item.setAttribute("value", dictList[i][1]);
item.setAttribute('type', 'radio');
- item.setAttribute('oncommand', "changeLanguage(event)");
languageMenuList.appendChild(item);
}
}
-function onShowDictionaryMenu()
+function OnShowDictionaryMenu(aTarget)
{
- var curLang = sPrefs.getComplexValue("spellchecker.dictionary", Components.interfaces.nsISupportsString).data;
- var languageMenuList = document.getElementById('LanguageMenulist');
-
- var languages = languageMenuList.getElementsByAttribute('value', curLang);
- languages[0].setAttribute('checked', true);
+ InitLanguageMenu();
+ var curLang = sPrefs.getComplexValue("spellchecker.dictionary", nsISupportsString).data;
+ var languages = aTarget.getElementsByAttribute("value", curLang);
+ if (languages.length > 0)
+ languages[0].setAttribute("checked", true);
}
-function changeLanguage(event)
+function ChangeLanguage(event)
{
// We need to change the dictionary language and if we are using inline spell check,
// recheck the message
- var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1'].getService(Components.interfaces.mozISpellCheckingEngine);
+ var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1']
+ .getService(mozISpellCheckingEngine);
if (spellChecker.dictionary != event.target.value)
{
spellChecker.dictionary = event.target.value;
var str = Components.classes["@mozilla.org/supports-string;1"]
- .createInstance(Components.interfaces.nsISupportsString);
+ .createInstance(nsISupportsString);
str.data = event.target.value;
- sPrefs.setComplexValue("spellchecker.dictionary", Components.interfaces.nsISupportsString, str);
+ sPrefs.setComplexValue("spellchecker.dictionary", nsISupportsString, str);
// now check the document over again with the new dictionary
- InlineSpellChecker.checkDocument(window.content.document);
+ if (InlineSpellChecker.inlineSpellChecker)
+ if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
+ InlineSpellChecker.checkDocument(window.content.document);
}
-
event.stopPropagation();
}
diff --git a/mozilla/mail/components/compose/content/messengercompose.xul b/mozilla/mail/components/compose/content/messengercompose.xul
index e0fa99fffa1..d4ae9657aeb 100644
--- a/mozilla/mail/components/compose/content/messengercompose.xul
+++ b/mozilla/mail/components/compose/content/messengercompose.xul
@@ -610,9 +610,9 @@
-
-
-
+
+ 1 && isoStrArray[1])
+ if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1])
{
menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
if (menuStr2)
- dictList[i][0] = dictList[i][0] + "/" + menuStr2;
+ langLabel += "/" + menuStr2;
}
- if (!dictList[i][0])
- dictList[i][0] = dictList[i][1];
+ if (!langLabel)
+ langLabel = langId;
} catch (ex) {
- // GetString throws an exception when
- // a key is not found in the bundle. In that
- // case, just use the original dictList string.
-
- dictList[i][0] = dictList[i][1];
+ // getString throws an exception when a key is not found in the
+ // bundle. In that case, just use the original dictList string.
+ langLabel = langId;
}
+ dictList[i] = [langLabel, langId];
}
- // note this is not locale-aware collation, just simple ASCII-based sorting
- // we really need to add loacel-aware JS collation, see bug XXXXX
- dictList.sort();
+ // sort by locale-aware collation
+ dictList.sort(
+ function compareFn(a, b)
+ {
+ return a[0].localeCompare(b[0]);
+ }
+ );
+
+ var languageMenuList = document.getElementById("languageMenuList");
+ // Remove any languages from the list.
+ var languageMenuPopup = languageMenuList.firstChild;
+ while (languageMenuPopup.hasChildNodes())
+ languageMenuPopup.removeChild(languageMenuPopup.firstChild);
var curLang = languageMenuList.value;
+ var defaultItem = null;
- // now select the dictionary we are currently using
- for (i = 0; i < dictList.length; i++)
+ for (i = 0; i < count; i++)
{
var item = languageMenuList.appendItem(dictList[i][0], dictList[i][1]);
if (curLang && dictList[i][1] == curLang)
diff --git a/mozilla/mail/components/preferences/compose.xul b/mozilla/mail/components/preferences/compose.xul
index c88f651139e..f13d10efc6b 100644
--- a/mozilla/mail/components/preferences/compose.xul
+++ b/mozilla/mail/components/preferences/compose.xul
@@ -192,9 +192,9 @@
-
-
-
+
+
+
diff --git a/mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.js b/mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.js
new file mode 100644
index 00000000000..0ce92256de8
--- /dev/null
+++ b/mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.js
@@ -0,0 +1,140 @@
+var gAutoSaveInterval;
+var gLastSelectedLang;
+var gDictCount = 0;
+
+function Startup() {
+ if ("@mozilla.org/spellchecker;1" in Components.classes)
+ InitLanguageMenu();
+ else
+ document.getElementById("spellingGroup").hidden = true;
+
+ gAutoSaveInterval = document.getElementById("autoSaveInterval");
+ EnableTextbox(document.getElementById("autoSave"), gAutoSaveInterval, true);
+}
+
+function EnableTextbox(aCheckbox, aTextbox, aStartingUp) {
+ aTextbox.disabled = (!aCheckbox.checked ||
+ parent.hPrefWindow.getPrefIsLocked(aTextbox.getAttribute("prefstring")));
+
+ if (!aTextbox.disabled && !aStartingUp)
+ aTextbox.focus();
+}
+
+function PopulateFonts() {
+ var fontsList = document.getElementById("fontSelect");
+ try {
+ var enumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"]
+ .getService(Components.interfaces.nsIFontEnumerator);
+ var localFontCount = { value: 0 }
+ var localFonts = enumerator.EnumerateAllFonts(localFontCount);
+ for (var i = 0; i < localFonts.length; ++i) {
+ if (localFonts[i] != "") {
+ fontsList.appendItem(localFonts[i], localFonts[i]);
+ }
+ }
+ } catch (ex) { }
+}
+
+function InitLanguageMenu() {
+ var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
+ .getService(Components.interfaces.mozISpellCheckingEngine);
+
+ var o1 = {};
+ var o2 = {};
+
+ // Get the list of dictionaries from the spellchecker.
+ spellChecker.getDictionaryList(o1, o2);
+
+ var dictList = o1.value;
+ var count = o2.value;
+
+ // If dictionary count hasn't changed then no need to update the menu.
+ if (gDictCount == count)
+ return;
+
+ // Store current dictionary count.
+ gDictCount = count;
+
+ // Load the string bundles that will help us map
+ // RFC 1766 strings to UI strings.
+
+ // Load the language string bundle.
+ var languageBundle = document.getElementById("languageBundle");
+ var regionBundle = null;
+ // If we have a language string bundle, load the region string bundle.
+ if (languageBundle)
+ regionBundle = document.getElementById("regionBundle");
+
+ var menuStr2;
+ var isoStrArray;
+ var langId;
+ var langLabel;
+ var i;
+
+ for (i = 0; i < count; i++) {
+ try {
+ langId = dictList[i];
+ isoStrArray = dictList[i].split("-");
+
+ if (languageBundle && isoStrArray[0])
+ langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
+
+ if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1]) {
+ menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
+ if (menuStr2)
+ langLabel += "/" + menuStr2;
+ }
+
+ if (!langLabel)
+ langLabel = langId;
+ } catch (ex) {
+ // getString throws an exception when a key is not found in the
+ // bundle. In that case, just use the original dictList string.
+ langLabel = langId;
+ }
+ dictList[i] = [langLabel, langId];
+ }
+
+ // sort by locale-aware collation
+ dictList.sort(
+ function compareFn(a, b) {
+ return a[0].localeCompare(b[0]);
+ }
+ );
+
+ var languageMenuList = document.getElementById("languageMenuList");
+ // Remove any languages from the list.
+ var languageMenuPopup = languageMenuList.firstChild;
+ while (languageMenuPopup.firstChild.localName != "menuseparator")
+ languageMenuPopup.removeChild(languageMenuPopup.firstChild);
+
+ var curLang = languageMenuList.value;
+ var defaultItem = null;
+
+ for (i = 0; i < count; i++) {
+ var item = languageMenuList.insertItemAt(i, dictList[i][0], dictList[i][1]);
+ if (curLang && dictList[i][1] == curLang)
+ defaultItem = item;
+ }
+
+ // Now make sure the correct item in the menu list is selected.
+ if (defaultItem) {
+ languageMenuList.selectedItem = defaultItem;
+ gLastSelectedLang = defaultItem;
+ }
+}
+
+function SelectLanguage(aTarget) {
+ try {
+ if (aTarget.value != "more-cmd")
+ gLastSelectedLang = aTarget;
+ else {
+ window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no",
+ xlateURL('urn:clienturl:composer:spellcheckers'));
+ if (gLastSelectedLang)
+ document.getElementById("languageMenuList").selectedItem = gLastSelectedLang;
+ }
+ } catch (ex) {
+ dump(ex);
+ }
+}
diff --git a/mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.xul b/mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.xul
index d3482c9161e..aee59340656 100644
--- a/mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.xul
+++ b/mozilla/mailnews/compose/prefs/resources/content/pref-composing_messages.xul
@@ -2,6 +2,8 @@
+
+
%pref-composing_messagesDTD;
@@ -10,56 +12,25 @@
]>
-
+
+
+
+
+
-
-
-
+
+
@@ -120,7 +106,7 @@
-
+
@@ -136,10 +122,10 @@
-
+
-
+
diff --git a/mozilla/mailnews/compose/prefs/resources/locale/en-US/pref-composing_messages.dtd b/mozilla/mailnews/compose/prefs/resources/locale/en-US/pref-composing_messages.dtd
index 8e69dde89b6..122fd95d170 100644
--- a/mozilla/mailnews/compose/prefs/resources/locale/en-US/pref-composing_messages.dtd
+++ b/mozilla/mailnews/compose/prefs/resources/locale/en-US/pref-composing_messages.dtd
@@ -37,7 +37,7 @@
***** END LICENSE BLOCK ***** -->
-
+
@@ -46,22 +46,25 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js b/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js
index 3acfc55d2e8..9f928773c74 100644
--- a/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js
+++ b/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js
@@ -40,14 +40,15 @@
/**
* interfaces
*/
-var nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
-var nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
-var nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
-var nsIMsgCompType = Components.interfaces.nsIMsgCompType;
-var nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
-var nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
-var nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
-
+const nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
+const nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
+const nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
+const nsIMsgCompType = Components.interfaces.nsIMsgCompType;
+const nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
+const nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
+const nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
+const nsISupportsString = Components.interfaces.nsISupportsString;
+const mozISpellCheckingEngine = Components.interfaces.mozISpellCheckingEngine;
/**
* In order to distinguish clearly globals that are initialized once when js load (static globals) and those that need to be
@@ -67,6 +68,7 @@ var sOther_headers = "";
var sAccountManagerDataSource = null;
var sRDF = null;
var sNameProperty = null;
+var sDictCount = 0;
/* Create message window object. This is use by mail-offline.js and therefore should not be renamed. We need to avoid doing
this kind of cross file global stuff in the future and instead pass this object as parameter when needed by function
@@ -2114,6 +2116,120 @@ function ToggleInlineSpellChecker(target)
}
}
+function InitLanguageMenu()
+{
+ var languageMenuList = document.getElementById("languageMenuList");
+ if (!languageMenuList)
+ return;
+
+ var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
+ .getService(mozISpellCheckingEngine);
+ var o1 = {};
+ var o2 = {};
+
+ // Get the list of dictionaries from the spellchecker.
+ spellChecker.getDictionaryList(o1, o2);
+
+ var dictList = o1.value;
+ var count = o2.value;
+
+ // If dictionary count hasn't changed then no need to update the menu.
+ if (sDictCount == count)
+ return;
+
+ // Store current dictionary count.
+ sDictCount = count;
+
+ // Load the language string bundle that will help us map
+ // RFC 1766 strings to UI strings.
+ var languageBundle = document.getElementById("languageBundle");
+ var isoStrArray;
+ var langId;
+ var langLabel;
+ var i;
+
+ for (i = 0; i < count; i++)
+ {
+ try
+ {
+ langId = dictList[i];
+ isoStrArray = dictList[i].split("-");
+
+ if (languageBundle && isoStrArray[0])
+ langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
+
+ // the user needs to be able to distinguish between the UK English dictionary
+ // and say the United States English Dictionary. If we have a isoStr value then
+ // wrap it in parentheses and append it to the menu item string. i.e.
+ // English (US) and English (UK)
+ if (!langLabel)
+ langLabel = langId;
+ else if (isoStrArray.length > 1 && isoStrArray[1]) // if we have a language ID like US or UK, append it to the menu item
+ langLabel += ' (' + isoStrArray[1] + ')';
+ }
+ catch (ex)
+ {
+ // getString throws an exception when a key is not found in the
+ // bundle. In that case, just use the original dictList string.
+ langLabel = langId;
+ }
+ dictList[i] = [langLabel, langId];
+ }
+
+ // sort by locale-aware collation
+ dictList.sort(
+ function compareFn(a, b)
+ {
+ return a[0].localeCompare(b[0]);
+ }
+ );
+
+ // Remove any languages from the list.
+ while (languageMenuList.hasChildNodes())
+ languageMenuList.removeChild(languageMenuList.firstChild);
+
+ for (i = 0; i < count; i++)
+ {
+ var item = document.createElement("menuitem");
+ item.setAttribute("label", dictList[i][0]);
+ item.setAttribute("value", dictList[i][1]);
+ item.setAttribute("type", "radio");
+ languageMenuList.appendChild(item);
+ }
+}
+
+function OnShowDictionaryMenu(aTarget)
+{
+ InitLanguageMenu();
+ var curLang = sPrefs.getComplexValue("spellchecker.dictionary", nsISupportsString).data;
+ var languages = aTarget.getElementsByAttribute("value", curLang);
+ if (languages.length > 0)
+ languages[0].setAttribute("checked", true);
+}
+
+function ChangeLanguage(event)
+{
+ // We need to change the dictionary language and if we are using inline spell check,
+ // recheck the message
+
+ var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
+ .getService(mozISpellCheckingEngine);
+ if (spellChecker.dictionary != event.target.value)
+ {
+ spellChecker.dictionary = event.target.value;
+ var str = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(nsISupportsString);
+ str.data = event.target.value;
+ sPrefs.setComplexValue("spellchecker.dictionary", nsISupportsString, str);
+
+ // now check the document over again with the new dictionary
+ if (InlineSpellChecker.inlineSpellChecker)
+ if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
+ InlineSpellChecker.checkDocument(window.content.document);
+ }
+ event.stopPropagation();
+}
+
function ToggleReturnReceipt(target)
{
var msgCompFields = gMsgCompose.compFields;
diff --git a/mozilla/mailnews/compose/resources/content/messengercompose.xul b/mozilla/mailnews/compose/resources/content/messengercompose.xul
index 88f86ed9446..36fb3cd58d8 100644
--- a/mozilla/mailnews/compose/resources/content/messengercompose.xul
+++ b/mozilla/mailnews/compose/resources/content/messengercompose.xul
@@ -85,6 +85,7 @@
+
@@ -457,9 +458,13 @@
-
+ command="cmd_spelling">
+
+
+