Bug 291799 Implement Spell as you Type for mailnews

p=me r=neil.parkwaycc.co.uk/mnyromyr sr=bienvenu a=asa
This commit is contained in:
bugzilla%arlen.demon.co.uk 2005-05-13 22:01:44 +00:00
parent 1df45ae2f8
commit 3f4d82b8f4
8 changed files with 142 additions and 15 deletions

View File

@ -783,6 +783,8 @@
address your message.</li>
<li><strong>Check Spelling:</strong> Checks the spelling of the message text
before you send it. You can also click Spell.</li>
<li><strong>Spellcheck As You Type:</strong> Choose this option to have the
spelling of the message text checked as you type.</li>
<li><strong>Rewrap:</strong> If you are composing a message using the
plain-text editor, you can use the Rewrap command to rewrap long lines of
quoted text to fit the Compose window. This command rewraps selected quoted
@ -4524,6 +4526,9 @@ to filter unwanted mail.</p>
<li><strong>Check spelling before sending</strong>: Select this option to
have Mail &amp; Newsgroups always check the spelling of your message before
you send it.</li>
<li><strong>Check spelling as you type</strong>: Select this option to have
Mail &amp; Newsgroups always check the spelling of your message as you type
it.</li>
<li><strong>For messages that contain 8-bit characters, use &apos;quoted
printable&apos; MIME encoding</strong>: Choose to have Mail &amp;
Newsgroups use <q>quoted printable</q> MIME encoding when sending regular

View File

@ -16,7 +16,7 @@
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["forwardMessageMode", "autoSave",
"autoSaveInterval","spellCheckBeforeSend",
"autoSaveInterval","spellCheckBeforeSend", "inlineSpellCheck",
"strictlyMime", "mailWarnOnSendAccelKey",
"wrapLength", "sendDefaultCharsetList",
"replyInDefaultCharset", "FontSelect",
@ -28,8 +28,9 @@
function Startup()
{
document.getElementById("spellCheckBeforeSend").hidden =
!("@mozilla.org/spellchecker;1" in Components.classes);
var hideSpellCheck = !("@mozilla.org/spellchecker;1" in Components.classes);
document.getElementById("spellCheckBeforeSend").hidden = hideSpellCheck;
document.getElementById("inlineSpellCheck").hidden = hideSpellCheck;
gAutoSaveInterval = document.getElementById("autoSaveInterval");
enableTextbox(document.getElementById("autoSave"), gAutoSaveInterval, true);
}
@ -86,11 +87,17 @@
prefstring="mail.compose.autosaveinterval"/>
<label value="&autoSaveEnd.label;"/>
</hbox>
<checkbox id="spellCheckBeforeSend" label="&spellCheck.label;"
prefstring="mail.SpellCheckBeforeSend"
accesskey="&spellCheck.accesskey;"/>
<hbox align="center">
<checkbox id="spellCheckBeforeSend" label="&spellCheck.label;"
prefstring="mail.SpellCheckBeforeSend"
accesskey="&spellCheck.accesskey;"/>
<checkbox id="inlineSpellCheck" label="&spellCheckInline.label;"
prefstring="mail.spellcheck.inline"
accesskey="&spellCheckInline.accesskey;"/>
</hbox>
<checkbox id="strictlyMime" label="&useMIME.label;"
prefstring="mail.strictly_mime"
accesskey="&useMIME.accesskey;"/>
@ -100,7 +107,7 @@
prefstring="mail.warn_on_send_accel_key"
accesskey="&warnOnSendAccelKey.accesskey;" />
</hbox>
<hbox align="center">
<label value="&wrapOutMsg.label;" accesskey="&wrapOutMsg.accesskey;" control="wrapLength"/>
<textbox id="wrapLength" size="3" preftype="int"

View File

@ -55,6 +55,8 @@
<!ENTITY autoSaveEnd.label "minutes">
<!ENTITY spellCheck.label "Check spelling before sending">
<!ENTITY spellCheck.accesskey "C">
<!ENTITY spellCheckInline.label "Check spelling as you type">
<!ENTITY spellCheckInline.accesskey "e">
<!-- LOCALIZATION NOTE (wrapOutMsg.label): This will concatenate with "xxx characters", using a number and (char.label). -->
<!ENTITY wrapOutMsg.label "Wrap plain text messages at">
<!ENTITY wrapOutMsg.accesskey "W">

View File

@ -21,6 +21,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ian Neal <bugzilla@arlen.demon.co.uk>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -606,6 +607,25 @@ function updateComposeItems() {
} catch(e) {}
}
function openEditorContextMenu()
{
// if we have a mispelled word, show spellchecker context
// menuitems as well as the usual context menu
var spellCheckNoSuggestionsItem = document.getElementById('spellCheckNoSuggestions');
var word;
var misspelledWordStatus = InlineSpellChecker.updateSuggestionsMenu(document.getElementById('msgComposeContext'),
spellCheckNoSuggestionsItem, word);
var hideSpellingItems = (misspelledWordStatus == kSpellNoMispelling);
spellCheckNoSuggestionsItem.hidden = hideSpellingItems || misspelledWordStatus != kSpellNoSuggestionsFound;
document.getElementById('spellCheckAddToDictionary').hidden = hideSpellingItems;
document.getElementById('spellCheckIgnoreWord').hidden = hideSpellingItems;
document.getElementById('spellCheckAddSep').hidden = hideSpellingItems;
document.getElementById('spellCheckSuggestionsSeparator').hidden = hideSpellingItems;
updateEditItems();
}
function updateEditItems() {
goUpdateCommand("cmd_pasteNoFormatting");
goUpdateCommand("cmd_pasteQuote");
@ -1285,6 +1305,8 @@ function ComposeStartup(recycled, aParams)
gMsgCompose.compFields.returnReceipt);
document.getElementById("cmd_attachVCard").setAttribute('checked',
gMsgCompose.compFields.attachVCard);
document.getElementById("menu_inlineSpellCheck").setAttribute('checked',
sPrefs.getBoolPref("mail.spellcheck.inline"));
// If recycle, editor is already created
if (!recycled)
@ -1347,8 +1369,7 @@ function ComposeStartup(recycled, aParams)
if (recycled)
{
// This sets charset and does reply quote insertion
gMsgCompose.initEditor(GetCurrentEditor(), window.content);
InitEditor(GetCurrentEditor());
if (gMsgCompose.composeHTML)
{
@ -1395,7 +1416,7 @@ var gMsgEditorCreationObserver =
{
var editor = GetCurrentEditor();
if (editor && GetCurrentCommandManager() == aSubject)
gMsgCompose.initEditor(editor, window.content);
InitEditor(editor);
}
}
}
@ -1998,6 +2019,43 @@ function SelectAddress()
AdjustFocus();
}
// walk through the recipients list and add them to the inline spell checker ignore list
function addRecipientsToIgnoreList(aAddressesToAdd)
{
if (InlineSpellChecker.inlineSpellChecker && InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
{
// break the list of potentially many recipients back into individual names
var hdrParser = Components.classes["@mozilla.org/messenger/headerparser;1"].getService(Components.interfaces.nsIMsgHeaderParser);
var emailAddresses = {};
var names = {};
var fullNames = {};
var numAddresses = hdrParser.parseHeadersWithArray(aAddressesToAdd, emailAddresses, names, fullNames);
var tokenizedNames = [];
// each name could consist of multiple words delimited by commas and/or spaces.
// i.e. Green Lantern or Lantern,Green.
for (var i = 0; i < names.value.length; i++)
{
var splitNames = names.value[i].match(/[^\s,]+/g);
if (splitNames)
tokenizedNames = tokenizedNames.concat(splitNames);
}
InlineSpellChecker.inlineSpellChecker.ignoreWords(tokenizedNames, tokenizedNames.length);
}
}
function ToggleInlineSpellChecker(target)
{
if (InlineSpellChecker.inlineSpellChecker)
{
InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell = !InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell;
if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
InlineSpellChecker.checkDocument(window.content.document);
}
}
function ToggleReturnReceipt(target)
{
var msgCompFields = gMsgCompose.compFields;
@ -2644,6 +2702,9 @@ function LoadIdentity(startup)
// catch the exception and ignore it, so that if LDAP setup
// fails, the entire compose window doesn't end up horked
}
// only do this if we aren't starting up....it gets done as part of startup already
addRecipientsToIgnoreList(gCurrentIdentity.identityName);
}
}
}
@ -3061,3 +3122,16 @@ function AutoSave()
gAutoSaveTimeout = setTimeout(AutoSave, gAutoSaveInterval);
}
function InitEditor(editor)
{
gMsgCompose.initEditor(editor, window.content);
try {
InlineSpellChecker.Init(editor, sPrefs.getBoolPref("mail.spellcheck.inline"));
// Following line works round bug 292520, look at removing after that is fixed
InlineSpellChecker.checkDocument(window.content.document);
} catch (e) {
// InlineSpellChecker.Init throws if there is no inline spellchecker
// so disable menuitem.
document.getElementById('menu_inlineSpellCheck').setAttribute('disabled', true);
}
}

View File

@ -19,6 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ian Neal <bugzilla@arlen.demon.co.uk>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -57,6 +58,7 @@ var gMimeHeaderParser = null;
*/
var test_addresses_sequence = false;
try {
if (sPrefs)
test_addresses_sequence = sPrefs.getBoolPref("mail.debug.test_addresses_sequence");
@ -238,6 +240,10 @@ function CompFields2Recipients(msgCompFields, msgType)
parent.replaceChild(newListBoxNode, listbox);
awFitDummyRows(2);
// CompFields2Recipients is called whenever a user replies or edits an existing message.
// We want to add all of the recipients for this message to the ignore list for spell check
addRecipientsToIgnoreList((gCurrentIdentity ? gCurrentIdentity.identityName + ', ' : '') + msgTo + ', ' + msgCC + ', ' + msgBCC);
gMimeHeaderParser = null; //Release the mime parser
}
}
@ -365,6 +371,9 @@ function awAddRecipient(recipientType, address)
awAppendNewRow(true);
awSetInputAndPopupValue(awGetInputElement(top.MAX_RECIPIENTS), "", awGetPopupElement(top.MAX_RECIPIENTS), "addr_to", top.MAX_RECIPIENTS);
}
// add the recipient to our spell check ignore list
addRecipientsToIgnoreList(address);
}
function awTestRowSequence()
@ -491,6 +500,10 @@ function awReturnHit(inputElement)
nextInput.select();
awSetFocus(row+1, nextInput);
}
// be sure to add the recipient to our ignore list
// when the user hits enter in an autocomplete widget...
addRecipientsToIgnoreList(inputElement.value);
}
function awDeleteHit(inputElement)
@ -725,7 +738,7 @@ function _awSetFocus()
function awTabFromRecipient(element, event)
{
//If we are le last element in the listbox, we don't want to create a new row.
//If we are the last element in the listbox, we don't want to create a new row.
if (element == awGetInputElement(top.MAX_RECIPIENTS))
top.doNotCreateANewRow = true;
@ -735,6 +748,10 @@ function awTabFromRecipient(element, event)
var listBox = document.getElementById("addressingWidget");
listBox.listBoxObject.ensureIndexIsVisible(listBoxRow + 1);
}
// be sure to add the recipient to our ignore list
// when the user tabs out of an autocomplete line...
addRecipientsToIgnoreList(element.value);
}
function awTabFromMenulist(element, event)

View File

@ -24,6 +24,7 @@
- Ben Goodger <ben@netscape.com> (ass'td polish fixes)
- Håkan Waara <hwaara@chello.se>
- Neil Rashbrook <neil@parkwaycc.co.uk> (ass'td polish fix)
- Ian Neal <bugzilla@arlen.demon.co.uk>
-
- Alternatively, the contents of this file may be used under the terms of
- either of the GNU General Public License Version 2 or later (the "GPL"),
@ -93,6 +94,7 @@
<script type="application/x-javascript" src="chrome://messenger/content/widgetglue.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/mail-offline.js"/>
<script type="application/x-javascript" src="chrome://editor/content/editor.js"/>
<script type="application/x-javascript" src="chrome://editor/content/editorInlineSpellCheck.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/messengercompose/MsgComposeCommands.js"/>
<!-- drag and drop -->
@ -208,7 +210,16 @@
<keyset id="editorKeys"/>
<popup id="sidebarPopup"/>
<popup id="msgComposeContext" onpopupshowing="updateEditItems();">
<popup id="msgComposeContext" onpopupshowing="openEditorContextMenu();">
<menuitem id="spellCheckNoSuggestions" label="&spellCheckNoSuggestions.label;" disabled="true"/>
<menuseparator id="spellCheckAddSep"/>
<menuitem id="spellCheckAddToDictionary" label="&spellCheckAddToDictionary.label;" accesskey="&spellCheckAddToDictionary.accesskey;"
oncommand="InlineSpellChecker.addToDictionary(null,null);"/>
<menuitem id="spellCheckIgnoreWord" label="&spellCheckIgnoreWord.label;" accesskey="&spellCheckIgnoreWord.accesskey;"
oncommand="InlineSpellChecker.ignoreWord(null, null)"/>
<menuseparator id="spellCheckSuggestionsSeparator"/>
<menuitem label="&undo.label;" accesskey="&undo.accesskey;" command="cmd_undo"/>
<menuseparator/>
<menuitem label="&cut.label;" accesskey="&cut.accesskey;" command="cmd_cut"/>
@ -329,6 +340,9 @@
<menupopup id="optionsMenuPopup" onpopupshowing="updateOptionItems();">
<menuitem label="&selectAddressCmd.label;" accesskey="&selectAddressCmd.accesskey;" command="cmd_selectAddress"/>
<menuitem label="&checkSpellingCmd.label;" id="menu_checkspelling" accesskey="&checkSpellingCmd.accesskey;" key="key_checkspelling" command="cmd_spelling"/>
<menuitem label="&enableInlineSpellChecker.label;" id="menu_inlineSpellCheck"
accesskey="&enableInlineSpellChecker.accesskey;" type="checkbox"
oncommand="ToggleInlineSpellChecker(event.target)"/>
<menuitem label="&quoteCmd.label;" accesskey="&quoteCmd.accesskey;" command="cmd_quoteMessage"/>
<menuseparator/>
<menuitem id="returnReceiptMenu" type="checkbox" label="&returnReceiptMenu.label;" accesskey="&returnReceiptMenu.accesskey;" checked="false" oncommand="ToggleReturnReceipt(event.target)"/>

View File

@ -117,7 +117,9 @@
<!ENTITY checkSpellingCmd.label "Check Spelling...">
<!ENTITY checkSpellingCmd.key "K">
<!ENTITY checkSpellingCmd.accesskey "S">
<!ENTITY checkSpellingCmd.accesskey "h">
<!ENTITY enableInlineSpellChecker.label "Spellcheck As You Type">
<!ENTITY enableInlineSpellChecker.accesskey "S">
<!ENTITY priorityMenu.label "Priority">
<!ENTITY priorityMenu.accesskey "p">
@ -197,6 +199,11 @@
<!ENTITY formatToolbar.underlineChar "U">
<!-- context menu items -->
<!ENTITY spellCheckNoSuggestions.label "(No Suggestions Found)">
<!ENTITY spellCheckIgnoreWord.label "Ignore Word">
<!ENTITY spellCheckIgnoreWord.accesskey "I">
<!ENTITY spellCheckAddToDictionary.label "Add to Dictionary">
<!ENTITY spellCheckAddToDictionary.accesskey "n">
<!ENTITY undo.label "Undo">
<!ENTITY undo.accesskey "U">
<!ENTITY cut.label "Cut">

View File

@ -510,6 +510,7 @@ pref("mailnews.nav_crosses_folders", 1); // prompt user when crossing folders
pref("news.cancel.confirm",true);
pref("news.cancel.alert_on_success",true);
pref("mail.SpellCheckBeforeSend",false);
pref("mail.spellcheck.inline",true);
pref("mail.warn_on_send_accel_key", true);
pref("mail.enable_autocomplete",true);
pref("mailnews.html_domains","");