Bug #280826 --> automatically add email recipients to the inline spell checker ignore list.

sr=bienvenu


git-svn-id: svn://10.0.0.236/trunk@168782 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
scott%scott-macgregor.org
2005-02-04 01:39:02 +00:00
parent eb57034808
commit 4203323371
6 changed files with 199 additions and 140 deletions

View File

@@ -54,21 +54,23 @@ interface nsIInlineSpellChecker : nsISupports
attribute boolean enableRealTimeSpell;
void spellCheckAfterEditorChange(in PRInt32 aAction,
void spellCheckAfterEditorChange(in long aAction,
in nsISelection aSelection,
in nsIDOMNode aPreviousSelectedNode,
in PRInt32 aPreviousSelectedOffset,
in long aPreviousSelectedOffset,
in nsIDOMNode aStartNode,
in PRInt32 aStartOffset,
in long aStartOffset,
in nsIDOMNode aEndNode,
in PRInt32 aEndOffset);
in long aEndOffset);
void spellCheckRange(in nsIDOMRange aSelection);
nsIDOMRange getMispelledWord(in nsIDOMNode aNode, in PRInt32 aOffset);
void replaceWord(in nsIDOMNode aNode, in PRInt32 aOffset, in AString aNewword);
nsIDOMRange getMispelledWord(in nsIDOMNode aNode, in long aOffset);
void replaceWord(in nsIDOMNode aNode, in long aOffset, in AString aNewword);
void addWordToDictionary(in AString aWord);
void ignoreWord(in AString aWord);
void ignoreWords([array, size_is(aCount)] in wstring aWordsToIgnore, in unsigned long aCount);
};
%{C++

View File

@@ -438,6 +438,22 @@ NS_IMETHODIMP mozInlineSpellChecker::IgnoreWord(const nsAString &word)
res = editor->GetRootElement(getter_AddRefs(rootElem));
NS_ENSURE_SUCCESS(res, res);
return SpellCheckBetweenNodes(rootElem, 0, rootElem, -1, NULL);
}
NS_IMETHODIMP mozInlineSpellChecker::IgnoreWords(const PRUnichar **aWordsToIgnore, PRUint32 aCount)
{
// add each word to the ignore list and then recheck the document
for (PRInt32 index = 0; index < aCount; index++)
mSpellCheck->IgnoreWordAllOccurrences(aWordsToIgnore[index]);
nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMElement> rootElem;
nsresult res = editor->GetRootElement(getter_AddRefs(rootElem));
NS_ENSURE_SUCCESS(res, res);
return SpellCheckBetweenNodes(rootElem, 0, rootElem, -1, NULL);
}

View File

@@ -244,7 +244,9 @@ NS_IMETHODIMP mozPersonalDictionary::RemoveWord(const PRUnichar *aWord, const PR
/* void IgnoreWord (in wstring word); */
NS_IMETHODIMP mozPersonalDictionary::IgnoreWord(const PRUnichar *aWord)
{
mIgnoreTable.PutEntry(aWord);
// avoid adding duplicate words to the ignore list
if (aWord && !mIgnoreTable.GetEntry(aWord))
mIgnoreTable.PutEntry(aWord);
return NS_OK;
}

View File

@@ -2054,6 +2054,38 @@ 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 = new Array();
// each name could consist of multiple word delimited by either commas or spaces. i.e. Green Lantern
// or Lantern,Green. Tokenize on comma first, then tokenize again on spaces.
for (name in names.value)
{
var splitNames = names.value[name].split(',');
for (var i=0; i < splitNames.length; i++)
{
// now tokenize off of white space
var splitNamesFromWhiteSpaceArray = splitNames[i].split(' ');
for (var whiteSpaceIndex = 0; whiteSpaceIndex < splitNamesFromWhiteSpaceArray.length; whiteSpaceIndex++)
if (splitNamesFromWhiteSpaceArray[whiteSpaceIndex])
tokenizedNames.push(splitNamesFromWhiteSpaceArray[whiteSpaceIndex]);
}
}
InlineSpellChecker.inlineSpellChecker.ignoreWords(tokenizedNames, tokenizedNames.length);
}
}
function ToggleInlineSpellChecker(target)
{
if (InlineSpellChecker.inlineSpellChecker)
@@ -2856,6 +2888,8 @@ function LoadIdentity(startup)
// catch the exception and ignore it, so that if LDAP setup
// fails, the entire compose window doesn't end up horked
}
addRecipientsToIgnoreList(gCurrentIdentity.identityName); // only do this if we aren't starting up....it gets done as part of startup already
}
}
}
@@ -3341,3 +3375,4 @@ function InitEditor()
InlineSpellChecker.Init(editor, sPrefs.getBoolPref("mail.spellcheck.inline"));
InlineSpellChecker.checkDocument(window.content.document);
}

View File

@@ -1,38 +1,40 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
# -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998-1999
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
top.MAX_RECIPIENTS = 0;
@@ -46,17 +48,8 @@ var gDragService = Components.classes["@mozilla.org/widget/dragservice;1"].getSe
gDragService = gDragService.QueryInterface(Components.interfaces.nsIDragService);
var gMimeHeaderParser = null;
/**
* global variable inherited from MsgComposeCommands.js
*
var sPrefs;
var gPromptService;
var gMsgCompose;
*/
var test_addresses_sequence = false;
try {
if (sPrefs)
test_addresses_sequence = sPrefs.getBoolPref("mail.debug.test_addresses_sequence");
@@ -84,33 +77,34 @@ function awGetNumberOfCols()
function awInputElementName()
{
if (inputElementType == "")
inputElementType = document.getElementById("addressCol2#1").localName;
return inputElementType;
if (inputElementType == "")
inputElementType = document.getElementById("addressCol2#1").localName;
return inputElementType;
}
function awSelectElementName()
{
if (selectElementType == "")
selectElementType = document.getElementById("addressCol1#1").localName;
return selectElementType;
if (selectElementType == "")
selectElementType = document.getElementById("addressCol1#1").localName;
return selectElementType;
}
// TODO: replace awGetSelectItemIndex with recipient type index constants
function awGetSelectItemIndex(itemData)
{
if (selectElementIndexTable == null)
if (selectElementIndexTable == null)
{
selectElementIndexTable = new Object();
var selectElem = document.getElementById("addressCol1#1");
for (var i = 0; i < selectElem.childNodes[0].childNodes.length; i ++)
{
selectElementIndexTable = new Object();
var selectElem = document.getElementById("addressCol1#1");
for (var i = 0; i < selectElem.childNodes[0].childNodes.length; i ++)
{
var aData = selectElem.childNodes[0].childNodes[i].getAttribute("value");
selectElementIndexTable[aData] = i;
}
var aData = selectElem.childNodes[0].childNodes[i].getAttribute("value");
selectElementIndexTable[aData] = i;
}
return selectElementIndexTable[itemData];
}
return selectElementIndexTable[itemData];
}
function Recipients2CompFields(msgCompFields)
@@ -238,6 +232,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
}
}
@@ -347,7 +345,7 @@ function awAddRecipients(msgCompFields, recipientType, recipientsList)
// this was broken out of awAddRecipients so it can be re-used...adds a new row matching recipientType and
// drops in the single address.
function awAddRecipient(recipientType, address)
{
{
for (var row = 1; row <= top.MAX_RECIPIENTS; row ++)
{
if (awGetInputElement(row).value == "")
@@ -365,6 +363,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 +492,10 @@ function awReturnHit(inputElement)
nextInput.select();
awSetFocus(row+1, nextInput);
}
// be sure to add the user add recipient to our ignore list
// when the user hits enter in an autocomplete widget...
addRecipientsToIgnoreList(inputElement.value);
}
function awDeleteHit(inputElement)
@@ -518,9 +523,6 @@ function awDeleteHit(inputElement)
function awInputChanged(inputElement)
{
dump("awInputChanged\n");
// AutoCompleteAddress(inputElement);
//Do we need to add a new row?
var lastInput = awGetInputElement(top.MAX_RECIPIENTS);
if ( lastInput && lastInput.value && !top.doNotCreateANewRow)
@@ -725,7 +727,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 +737,10 @@ function awTabFromRecipient(element, event)
var listBox = document.getElementById("addressingWidget");
listBox.listBoxObject.ensureIndexIsVisible(listBoxRow + 1);
}
// be sure to add the user add recipient to our ignore list
// when the user tabs out of an autocomplete line...
addRecipientsToIgnoreList(element.value);
}
function awTabFromMenulist(element, event)
@@ -827,39 +833,37 @@ function awRecipientTextCommand(userAction, element)
//
function awRecipientErrorCommand(errItem, element)
{
// remove the angle brackets from the general error message to construct
// the title for the alert. someday we'll pass this info using a real
// exception object, and then this code can go away.
//
var generalErrString;
if (errItem.value != "") {
generalErrString = errItem.value.slice(1, errItem.value.length-1);
} else {
generalErrString = "Unknown LDAP server problem encountered";
}
// remove the angle brackets from the general error message to construct
// the title for the alert. someday we'll pass this info using a real
// exception object, and then this code can go away.
//
var generalErrString;
if (errItem.value != "")
generalErrString = errItem.value.slice(1, errItem.value.length-1);
else
generalErrString = "Unknown LDAP server problem encountered";
// try and get the string of the specific error to contruct the complete
// err msg, otherwise fall back to something generic. This message is
// handed to us as an nsISupportsString in the param slot of the
// autocomplete error item, by agreement documented in
// nsILDAPAutoCompFormatter.idl
//
var specificErrString = "";
try {
var specificError = errItem.param.QueryInterface(
Components.interfaces.nsISupportsString);
specificErrString = specificError.data;
} catch (ex) {
}
if (specificErrString == "") {
specificErrString = "Internal error";
}
// try and get the string of the specific error to contruct the complete
// err msg, otherwise fall back to something generic. This message is
// handed to us as an nsISupportsString in the param slot of the
// autocomplete error item, by agreement documented in
// nsILDAPAutoCompFormatter.idl
//
var specificErrString = "";
try
{
var specificError = errItem.param.QueryInterface(Components.interfaces.nsISupportsString);
specificErrString = specificError.data;
} catch (ex)
{}
if (specificErrString == "")
specificErrString = "Internal error";
if (gPromptService) {
gPromptService.alert(window, generalErrString, specificErrString);
} else {
window.alert(generalErrString + ": " + specificErrString);
}
if (gPromptService)
gPromptService.alert(window, generalErrString, specificErrString);
else
window.alert(generalErrString + ": " + specificErrString);
}
function awRecipientKeyPress(event, element)

View File

@@ -1,40 +1,40 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is
Netscape Communications Corporation.
Portions created by the Initial Developer are Copyright (C) 1998-1999
the Initial Developer. All Rights Reserved.
Contributor(s):
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"),
or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
***** END LICENSE BLOCK ***** -->
<?xml version="1.0"?>
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1999
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
<!DOCTYPE overlay SYSTEM "chrome://messenger/locale/messengercompose/addressingWidgetOverlay.dtd">