498 lines
13 KiB
JavaScript
498 lines
13 KiB
JavaScript
/*
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
|
*
|
|
* 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 Netscape are
|
|
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
var gMisspelledWord;
|
|
var spellChecker;
|
|
var allowSelectWord = true;
|
|
var PreviousReplaceWord = "";
|
|
var firstTime = true;
|
|
|
|
// dialog initialization code
|
|
function Startup()
|
|
{
|
|
if (!InitEditorShell())
|
|
return;
|
|
|
|
// Get the spellChecker shell
|
|
spellChecker = editorShell.QueryInterface(Components.interfaces.nsIEditorSpellCheck);
|
|
if (!spellChecker) {
|
|
dump("SpellChecker not found!!!\n");
|
|
window.close();
|
|
return;
|
|
}
|
|
|
|
// Start the spell checker module.
|
|
try {
|
|
spellChecker.InitSpellChecker();
|
|
|
|
// XXX: We need to read in a pref here so we can set the
|
|
// default language for the spellchecker!
|
|
// spellChecker.SetCurrentDictionary();
|
|
}
|
|
catch(ex) {
|
|
dump("*** Exception error: InitSpellChecker\n");
|
|
window.close();
|
|
return;
|
|
}
|
|
|
|
gDialog.MisspelledWordLabel = document.getElementById("MisspelledWordLabel");
|
|
gDialog.MisspelledWord = document.getElementById("MisspelledWord");
|
|
gDialog.ReplaceButton = document.getElementById("Replace");
|
|
gDialog.IgnoreButton = document.getElementById("Ignore");
|
|
gDialog.CloseButton = document.getElementById("Close");
|
|
gDialog.ReplaceWordInput = document.getElementById("ReplaceWordInput");
|
|
gDialog.SuggestedList = document.getElementById("SuggestedList");
|
|
gDialog.LanguageMenulist = document.getElementById("LanguageMenulist");
|
|
|
|
// Fill in the language menulist and sync it up
|
|
// with the spellchecker's current language.
|
|
|
|
var curLang;
|
|
|
|
try {
|
|
curLang = spellChecker.GetCurrentDictionary();
|
|
} catch(ex) {
|
|
curLang = "";
|
|
}
|
|
|
|
InitLanguageMenu(curLang);
|
|
|
|
SetWindowLocation();
|
|
|
|
// Get the first misspelled word and setup all UI
|
|
NextWord();
|
|
|
|
// Clear flag that determines message when
|
|
// no misspelled word is found
|
|
// (different message when used for the first time)
|
|
firstTime = false;
|
|
}
|
|
|
|
function InitLanguageMenu(curLang)
|
|
{
|
|
|
|
var o1 = {};
|
|
var o2 = {};
|
|
|
|
// Get the list of dictionaries from
|
|
// the spellchecker.
|
|
|
|
try {
|
|
spellChecker.GetDictionaryList(o1, o2);
|
|
} catch(ex) {
|
|
dump("Failed to get DictionaryList!\n");
|
|
return;
|
|
}
|
|
|
|
var dictList = o1.value;
|
|
var count = o2.value;
|
|
|
|
// Load the string bundles that will help us map
|
|
// RFC 1766 strings to UI strings.
|
|
|
|
var languageBundle;
|
|
var regionBundle;
|
|
var menuStr2;
|
|
var isoStrArray;
|
|
var defaultIndex = 0;
|
|
var langId;
|
|
|
|
// Try to load the language string bundle.
|
|
|
|
try {
|
|
languageBundle = srGetStrBundle("chrome://global/locale/languageNames.properties");
|
|
} catch(ex) {
|
|
languageBundle = null;
|
|
}
|
|
|
|
// If we have a language string bundle, try to load the region string bundle.
|
|
|
|
if (languageBundle)
|
|
{
|
|
try {
|
|
regionBundle = srGetStrBundle("chrome://global/locale/regionNames.properties");
|
|
} catch(ex) {
|
|
regionBundle = null;
|
|
}
|
|
}
|
|
var i;
|
|
for (i = 0; i < dictList.length; i++)
|
|
{
|
|
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.GetStringFromName(isoStrArray[0].toLowerCase());
|
|
|
|
if (regionBundle && dictList[i][0] && isoStrArray.length > 1 && isoStrArray[1])
|
|
{
|
|
menuStr2 = regionBundle.GetStringFromName(isoStrArray[1].toLowerCase());
|
|
if (menuStr2)
|
|
dictList[i][0] = dictList[i][0] + "/" + menuStr2;
|
|
}
|
|
|
|
if (!dictList[i][0])
|
|
dictList[i][0] = dictList[i][1];
|
|
} catch (ex) {
|
|
// GetStringFromName 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];
|
|
}
|
|
}
|
|
|
|
// 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();
|
|
|
|
for (i = 0; i < dictList.length; i++)
|
|
{
|
|
AppendLabelAndValueToMenulist(gDialog.LanguageMenulist, dictList[i][0], dictList[i][1]);
|
|
if (curLang && dictList[i][1] == curLang)
|
|
defaultIndex = i+2; //first two items are pre-populated and fixed
|
|
}
|
|
|
|
// Now make sure the correct item in the menu list is selected.
|
|
|
|
if (dictList.length > 0)
|
|
gDialog.LanguageMenulist.selectedIndex = defaultIndex;
|
|
}
|
|
|
|
function DoEnabling()
|
|
{
|
|
if (!gMisspelledWord)
|
|
{
|
|
// No more misspelled words
|
|
gDialog.MisspelledWord.setAttribute("value",GetString( firstTime ? "NoMisspelledWord" : "CheckSpellingDone"));
|
|
|
|
gDialog.ReplaceButton.removeAttribute("default");
|
|
gDialog.IgnoreButton.removeAttribute("default");
|
|
|
|
gDialog.CloseButton.setAttribute("default","true");
|
|
// Shouldn't have to do this if "default" is true?
|
|
gDialog.CloseButton.focus();
|
|
|
|
SetElementEnabledById("MisspelledWordLabel", false);
|
|
SetElementEnabledById("ReplaceWordLabel", false);
|
|
SetElementEnabledById("ReplaceWordInput", false);
|
|
SetElementEnabledById("CheckWord", false);
|
|
SetElementEnabledById("SuggestedListLabel", false);
|
|
SetElementEnabledById("SuggestedList", false);
|
|
SetElementEnabledById("Ignore", false);
|
|
SetElementEnabledById("IgnoreAll", false);
|
|
SetElementEnabledById("Replace", false);
|
|
SetElementEnabledById("ReplaceAll", false);
|
|
SetElementEnabledById("AddToDictionary", false);
|
|
|
|
// Signal to calling window that we're done
|
|
window.opener.spellCheckCompleted = true;
|
|
} else {
|
|
SetElementEnabledById("MisspelledWordLabel", true);
|
|
SetElementEnabledById("ReplaceWordLabel", true);
|
|
SetElementEnabledById("ReplaceWordInput", true);
|
|
SetElementEnabledById("CheckWord", true);
|
|
SetElementEnabledById("SuggestedListLabel", true);
|
|
SetElementEnabledById("SuggestedList", true);
|
|
SetElementEnabledById("Ignore", true);
|
|
SetElementEnabledById("IgnoreAll", true);
|
|
SetElementEnabledById("AddToDictionary", true);
|
|
|
|
gDialog.CloseButton.removeAttribute("default");
|
|
SetReplaceEnable();
|
|
|
|
// Signal to calling window that we're not done
|
|
window.opener.spellCheckCompleted = false;
|
|
}
|
|
}
|
|
|
|
function NextWord()
|
|
{
|
|
gMisspelledWord = spellChecker.GetNextMisspelledWord();
|
|
SetWidgetsForMisspelledWord();
|
|
}
|
|
|
|
function SetWidgetsForMisspelledWord()
|
|
{
|
|
gDialog.MisspelledWord.setAttribute("value", gMisspelledWord);
|
|
|
|
|
|
// Initial replace word is misspelled word
|
|
gDialog.ReplaceWordInput.value = gMisspelledWord;
|
|
PreviousReplaceWord = gMisspelledWord;
|
|
|
|
// This sets gDialog.ReplaceWordInput to first suggested word in list
|
|
FillSuggestedList(gMisspelledWord);
|
|
|
|
DoEnabling();
|
|
|
|
if (gMisspelledWord)
|
|
SetTextboxFocus(gDialog.ReplaceWordInput);
|
|
}
|
|
|
|
function CheckWord()
|
|
{
|
|
word = gDialog.ReplaceWordInput.value;
|
|
if (word)
|
|
{
|
|
isMisspelled = spellChecker.CheckCurrentWord(word);
|
|
if (isMisspelled)
|
|
{
|
|
FillSuggestedList(word);
|
|
SetReplaceEnable();
|
|
}
|
|
else
|
|
{
|
|
ClearTreelist(gDialog.SuggestedList);
|
|
var item = AppendStringToTreelistById(gDialog.SuggestedList, "CorrectSpelling");
|
|
if (item) item.setAttribute("disabled", "true");
|
|
// Suppress being able to select the message text
|
|
allowSelectWord = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
function SelectSuggestedWord()
|
|
{
|
|
if (allowSelectWord)
|
|
{
|
|
var index = gDialog.SuggestedList.selectedIndex;
|
|
if (index == -1)
|
|
{
|
|
gDialog.ReplaceWordInput.value = PreviousReplaceWord;
|
|
}
|
|
else
|
|
{
|
|
var selValue = GetSelectedTreelistValue(gDialog.SuggestedList);
|
|
gDialog.ReplaceWordInput.value = selValue;
|
|
PreviousReplaceWord = selValue;
|
|
}
|
|
SetReplaceEnable();
|
|
}
|
|
}
|
|
|
|
function ChangeReplaceWord()
|
|
{
|
|
// Calling this triggers SelectSuggestedWord(),
|
|
// so temporarily suppress the effect of that
|
|
var saveAllow = allowSelectWord;
|
|
allowSelectWord = false;
|
|
|
|
// Select matching word in list
|
|
var newIndex = -1;
|
|
var replaceWord = TrimString(gDialog.ReplaceWordInput.value);
|
|
if (replaceWord)
|
|
{
|
|
var count = 0;
|
|
var treeChildren = gDialog.SuggestedList.firstChild.nextSibling;
|
|
if (treeChildren && treeChildren.childNodes)
|
|
count = treeChildren.childNodes.length;
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var wordInList = GetTreelistValueAt(gDialog.SuggestedList, i);
|
|
if (wordInList == replaceWord)
|
|
{
|
|
newIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
gDialog.SuggestedList.selectedIndex = newIndex;
|
|
|
|
allowSelectWord = saveAllow;
|
|
|
|
// Remember the new word
|
|
PreviousReplaceWord = gDialog.ReplaceWordInput.value;
|
|
|
|
SetReplaceEnable();
|
|
}
|
|
|
|
function Ignore()
|
|
{
|
|
NextWord();
|
|
}
|
|
|
|
function IgnoreAll()
|
|
{
|
|
if (gMisspelledWord) {
|
|
spellChecker.IgnoreWordAllOccurrences(gMisspelledWord);
|
|
}
|
|
NextWord();
|
|
}
|
|
|
|
function Replace()
|
|
{
|
|
var newWord = gDialog.ReplaceWordInput.value;
|
|
if (gMisspelledWord && gMisspelledWord != newWord)
|
|
{
|
|
editorShell.BeginBatchChanges();
|
|
var isMisspelled = spellChecker.ReplaceWord(gMisspelledWord, newWord, false);
|
|
editorShell.EndBatchChanges();
|
|
}
|
|
NextWord();
|
|
}
|
|
|
|
function ReplaceAll()
|
|
{
|
|
var newWord = gDialog.ReplaceWordInput.value;
|
|
if (gMisspelledWord && gMisspelledWord != newWord)
|
|
{
|
|
editorShell.BeginBatchChanges();
|
|
isMisspelled = spellChecker.ReplaceWord(gMisspelledWord, newWord, true);
|
|
editorShell.EndBatchChanges();
|
|
}
|
|
NextWord();
|
|
}
|
|
|
|
function AddToDictionary()
|
|
{
|
|
if (gMisspelledWord) {
|
|
spellChecker.AddWordToDictionary(gMisspelledWord);
|
|
}
|
|
NextWord();
|
|
}
|
|
|
|
function EditDictionary()
|
|
{
|
|
window.openDialog("chrome://editor/content/EdDictionary.xul", "_blank", "chrome,close,titlebar,modal", "", gMisspelledWord);
|
|
}
|
|
|
|
function SelectLanguage()
|
|
{
|
|
try {
|
|
var item = gDialog.LanguageMenulist.selectedItem;
|
|
if (item.value != "more-cmd")
|
|
spellChecker.SetCurrentDictionary(item.value);
|
|
else
|
|
window.openDialog( getBrowserURL(), "_blank", "chrome,all,dialog=no,modal", xlateURL('urn:clienturl:composer:spellcheckers'));
|
|
} catch (ex) {
|
|
dump(ex);
|
|
}
|
|
}
|
|
|
|
function Recheck()
|
|
{
|
|
//TODO: Should we bother to add a "Recheck" method to interface?
|
|
try {
|
|
var curLang = spellChecker.GetCurrentDictionary();
|
|
|
|
spellChecker.UninitSpellChecker();
|
|
spellChecker.InitSpellChecker();
|
|
spellChecker.SetCurrentDictionary(curLang);
|
|
gMisspelledWord = spellChecker.GetNextMisspelledWord();
|
|
SetWidgetsForMisspelledWord();
|
|
} catch(ex) {
|
|
dump(ex);
|
|
}
|
|
}
|
|
|
|
function FillSuggestedList(misspelledWord)
|
|
{
|
|
var list = gDialog.SuggestedList;
|
|
|
|
// Clear the current contents of the list
|
|
allowSelectWord = false;
|
|
ClearTreelist(list);
|
|
var item;
|
|
|
|
if (misspelledWord.length > 0)
|
|
{
|
|
// Get suggested words until an empty string is returned
|
|
var count = 0;
|
|
var firstWord = 0;
|
|
do {
|
|
var word = spellChecker.GetSuggestedWord();
|
|
if (count==0)
|
|
firstWord = word;
|
|
if (word.length > 0) {
|
|
AppendStringToTreelist(list, word);
|
|
count++;
|
|
}
|
|
} while (word.length > 0);
|
|
|
|
var len = list.getAttribute("length");
|
|
|
|
if (count == 0)
|
|
{
|
|
// No suggestions - show a message but don't let user select it
|
|
item = AppendStringToTreelistById(list, "NoSuggestedWords");
|
|
if (item) item.setAttribute("disabled", "true");
|
|
allowSelectWord = false;
|
|
} else {
|
|
allowSelectWord = true;
|
|
// Initialize with first suggested list by selecting it
|
|
gDialog.SuggestedList.selectedIndex = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item = AppendStringToTreelist(list, "");
|
|
if (item)
|
|
item.setAttribute("disabled", "true");
|
|
}
|
|
}
|
|
|
|
function SetReplaceEnable()
|
|
{
|
|
// Enable "Change..." buttons only if new word is different than misspelled
|
|
var newWord = gDialog.ReplaceWordInput.value;
|
|
var enable = newWord.length > 0 && newWord != gMisspelledWord;
|
|
SetElementEnabledById("Replace", enable);
|
|
SetElementEnabledById("ReplaceAll", enable);
|
|
if (enable)
|
|
{
|
|
gDialog.ReplaceButton.setAttribute("default","true");
|
|
gDialog.IgnoreButton.removeAttribute("default");
|
|
}
|
|
else
|
|
{
|
|
gDialog.IgnoreButton.setAttribute("default","true");
|
|
gDialog.ReplaceButton.removeAttribute("default");
|
|
}
|
|
}
|
|
|
|
function doDefault()
|
|
{
|
|
if (gDialog.ReplaceButton.getAttribute("default") == "true")
|
|
Replace();
|
|
else if (gDialog.IgnoreButton.getAttribute("default") == "true")
|
|
Ignore();
|
|
else if (gDialog.CloseButton.getAttribute("default") == "true")
|
|
return onClose();
|
|
|
|
// Don't close the dialog
|
|
return false;
|
|
}
|
|
|
|
function onClose()
|
|
{
|
|
// Shutdown the spell check and close the dialog
|
|
spellChecker.UninitSpellChecker();
|
|
return onCancel();
|
|
}
|
|
|