home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / 01_02.iso / software / netscape62win / browser.xpi / bin / chrome / comm.jar / content / editor / EdSpellCheck.js < prev    next >
Encoding:
JavaScript  |  2001-09-20  |  13.7 KB  |  508 lines

  1. /*
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  *
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  *
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  */
  22.  
  23. var gMisspelledWord;
  24. var spellChecker;
  25. var allowSelectWord = true;
  26. var PreviousReplaceWord = "";
  27. var firstTime = true;
  28.  
  29. // dialog initialization code
  30. function Startup()
  31. {
  32.   if (!InitEditorShell())
  33.     return;
  34.  
  35.   // Get the spellChecker shell
  36.   spellChecker = editorShell.QueryInterface(Components.interfaces.nsIEditorSpellCheck);
  37.   if (!spellChecker) {
  38.     dump("SpellChecker not found!!!\n");
  39.     window.close();
  40.     return;
  41.   }
  42.  
  43.   // Start the spell checker module.
  44.   try {
  45.    spellChecker.InitSpellChecker();
  46.  
  47.    // XXX: We need to read in a pref here so we can set the
  48.    //      default language for the spellchecker!
  49.    // spellChecker.SetCurrentDictionary();
  50.   }
  51.   catch(ex) {
  52.    dump("*** Exception error: InitSpellChecker\n");
  53.     window.close();
  54.     return;
  55.   }
  56.  
  57.   // Create dialog object to store controls for easy access
  58.   dialog = new Object;
  59.   if (!dialog)
  60.   {
  61.     dump("Failed to create dialog object!!!\n");
  62.     Close();
  63.   }
  64.   dialog.MisspelledWordLabel = document.getElementById("MisspelledWordLabel");
  65.   dialog.MisspelledWord      = document.getElementById("MisspelledWord");
  66.   dialog.ReplaceButton       = document.getElementById("Replace");
  67.   dialog.IgnoreButton        = document.getElementById("Ignore");
  68.   dialog.CloseButton         = document.getElementById("Close");
  69.   dialog.ReplaceWordInput    = document.getElementById("ReplaceWordInput");
  70.   dialog.SuggestedList       = document.getElementById("SuggestedList");
  71.   dialog.LanguageMenulist    = document.getElementById("LanguageMenulist");
  72.  
  73.   if (!dialog.MisspelledWord ||
  74.       !dialog.ReplaceWordInput ||
  75.       !dialog.SuggestedList  ||
  76.       !dialog.LanguageMenulist )
  77.   {
  78.     return;
  79.   }
  80.  
  81.   if (dialog.LanguageMenulist)
  82.   {
  83.     // Fill in the language menulist and sync it up
  84.     // with the spellchecker's current language.
  85.  
  86.     var curLang;
  87.  
  88.     try {
  89.       curLang = spellChecker.GetCurrentDictionary();
  90.     } catch(ex) {
  91.       curLang = "";
  92.     }
  93.  
  94.     InitLanguageMenu(curLang);
  95.   }
  96.  
  97.   SetWindowLocation();
  98.  
  99.   // Get the first misspelled word and setup all UI
  100.   NextWord();
  101.  
  102.   // Clear flag that determines message when
  103.   //  no misspelled word is found
  104.   //  (different message when used for the first time)
  105.   firstTime = false;
  106. }
  107.  
  108. function InitLanguageMenu(curLang)
  109. {
  110.  
  111.   var o1 = {};
  112.   var o2 = {};
  113.  
  114.   // Get the list of dictionaries from
  115.   // the spellchecker.
  116.  
  117.   try {
  118.     spellChecker.GetDictionaryList(o1, o2);
  119.   } catch(ex) {
  120.     dump("Failed to get DictionaryList!\n");
  121.     return;
  122.   }
  123.  
  124.   var dictList = o1.value;
  125.   var count    = o2.value;
  126.  
  127.   // Load the string bundles that will help us map
  128.   // RFC 1766 strings to UI strings.
  129.  
  130.   var languageBundle;
  131.   var regionBundle;
  132.   var menuStr2;
  133.   var isoStrArray;
  134.   var defaultIndex = 0;
  135.   var langId;
  136.  
  137.   // Try to load the language string bundle.
  138.  
  139.   try {
  140.     languageBundle = srGetStrBundle("chrome://global/locale/languageNames.properties");
  141.   } catch(ex) {
  142.     languageBundle = null;
  143.   }
  144.  
  145.   // If we have a language string bundle, try to load the region string bundle.
  146.  
  147.   if (languageBundle)
  148.   {
  149.     try {
  150.       regionBundle = srGetStrBundle("chrome://global/locale/regionNames.properties");
  151.     } catch(ex) {
  152.       regionBundle = null;
  153.     }
  154.   }
  155.  
  156.   for (var i = 0; i < dictList.length; i++)
  157.   {
  158.     try {
  159.       langId = dictList[i];
  160.       isoStrArray = dictList[i].split("-");
  161.  
  162.       dictList[i] = new Array(2); // first subarray element - pretty name
  163.       dictList[i][1] = langId;    // second subarray element - language ID
  164.  
  165.       if (languageBundle && isoStrArray[0])
  166.         dictList[i][0] = languageBundle.GetStringFromName(isoStrArray[0].toLowerCase());
  167.  
  168.       if (regionBundle && dictList[i][0] && isoStrArray.length > 1 && isoStrArray[1])
  169.       {
  170.         menuStr2 = regionBundle.GetStringFromName(isoStrArray[1].toLowerCase());
  171.         if (menuStr2)
  172.           dictList[i][0] = dictList[i][0] + "/" + menuStr2;
  173.       }
  174.  
  175.       if (!dictList[i][0])
  176.         dictList[i][0] = dictList[i][1];
  177.     } catch (ex) {
  178.       // GetStringFromName throws an exception when
  179.       // a key is not found in the bundle. In that
  180.       // case, just use the original dictList string.
  181.  
  182.       dictList[i][0] = dictList[i][1];
  183.     }
  184.   }
  185.   
  186.   // note this is not locale-aware collation, just simple ASCII-based sorting
  187.   // we really need to add loacel-aware JS collation, see bug XXXXX
  188.   dictList.sort();
  189.  
  190.   for (var i = 0; i < dictList.length; i++)
  191.   {
  192.     AppendLabelAndValueToMenulist(dialog.LanguageMenulist, dictList[i][0], dictList[i][1]);
  193.     if (curLang && dictList[i][1] == curLang)
  194.       defaultIndex = i+2; //first two items are pre-populated and fixed
  195.   }
  196.  
  197.   // Now make sure the correct item in the menu list is selected.
  198.  
  199.   if (dictList.length > 0)
  200.     dialog.LanguageMenulist.selectedIndex = defaultIndex;
  201. }
  202.  
  203. function DoEnabling()
  204. {
  205.   if (!gMisspelledWord)
  206.   {
  207.     // No more misspelled words
  208.     dialog.MisspelledWord.setAttribute("value",GetString( firstTime ? "NoMisspelledWord" : "CheckSpellingDone"));
  209.  
  210.     dialog.ReplaceButton.removeAttribute("default");
  211.     dialog.IgnoreButton.removeAttribute("default");
  212.  
  213.     dialog.CloseButton.setAttribute("default","true");
  214.     // Shouldn't have to do this if "default" is true?
  215.     dialog.CloseButton.focus();
  216.  
  217.     SetElementEnabledById("MisspelledWordLabel", false);
  218.     SetElementEnabledById("ReplaceWordLabel", false);
  219.     SetElementEnabledById("ReplaceWordInput", false);
  220.     SetElementEnabledById("CheckWord", false);
  221.     SetElementEnabledById("SuggestedListLabel", false);
  222.     SetElementEnabledById("SuggestedList", false);
  223.     SetElementEnabledById("Ignore", false);
  224.     SetElementEnabledById("IgnoreAll", false);
  225.     SetElementEnabledById("Replace", false);
  226.     SetElementEnabledById("ReplaceAll", false);
  227.     SetElementEnabledById("AddToDictionary", false);
  228.   } else {
  229.     SetElementEnabledById("MisspelledWordLabel", true);
  230.     SetElementEnabledById("ReplaceWordLabel", true);
  231.     SetElementEnabledById("ReplaceWordInput", true);
  232.     SetElementEnabledById("CheckWord", true);
  233.     SetElementEnabledById("SuggestedListLabel", true);
  234.     SetElementEnabledById("SuggestedList", true);
  235.     SetElementEnabledById("Ignore", true);
  236.     SetElementEnabledById("IgnoreAll", true);
  237.     SetElementEnabledById("AddToDictionary", true);
  238.  
  239.     dialog.CloseButton.removeAttribute("default");
  240.     SetReplaceEnable();
  241.   }
  242. }
  243.  
  244. function NextWord()
  245. {
  246.   gMisspelledWord = spellChecker.GetNextMisspelledWord();
  247.   SetWidgetsForMisspelledWord();
  248. }
  249.  
  250. function SetWidgetsForMisspelledWord()
  251. {
  252.   dialog.MisspelledWord.setAttribute("value", gMisspelledWord);
  253.  
  254.  
  255.   // Initial replace word is misspelled word
  256.   dialog.ReplaceWordInput.value = gMisspelledWord;
  257.   PreviousReplaceWord = gMisspelledWord;
  258.  
  259.   // This sets dialog.ReplaceWordInput to first suggested word in list
  260.   FillSuggestedList(gMisspelledWord);
  261.  
  262.   DoEnabling();
  263.  
  264.   if (gMisspelledWord)
  265.     SetTextboxFocus(dialog.ReplaceWordInput);
  266. }
  267.  
  268. function CheckWord()
  269. {
  270.   word = dialog.ReplaceWordInput.value;
  271.   if (word) 
  272.   {
  273.     isMisspelled = spellChecker.CheckCurrentWord(word);
  274.     if (isMisspelled)
  275.     {
  276.       FillSuggestedList(word);
  277.       SetReplaceEnable();
  278.     } 
  279.     else 
  280.     {
  281.       ClearTreelist(dialog.SuggestedList);
  282.       var item = AppendStringToTreelistById(dialog.SuggestedList, "CorrectSpelling");
  283.       if (item) item.setAttribute("disabled", "true");
  284.       // Suppress being able to select the message text
  285.       allowSelectWord = false;
  286.     }
  287.   }
  288. }
  289.  
  290. function SelectSuggestedWord()
  291. {
  292.   if (allowSelectWord)
  293.   {
  294.     var index = dialog.SuggestedList.selectedIndex;
  295.     if (index == -1)
  296.     {
  297.       dialog.ReplaceWordInput.value = PreviousReplaceWord;
  298.     }
  299.     else
  300.     {
  301.       var selValue = GetSelectedTreelistValue(dialog.SuggestedList);
  302.       dialog.ReplaceWordInput.value = selValue;
  303.       PreviousReplaceWord = selValue;
  304.     }
  305.     SetReplaceEnable();
  306.   }
  307. }
  308.  
  309. function ChangeReplaceWord()
  310. {
  311.   // Calling this triggers SelectSuggestedWord(),
  312.   //  so temporarily suppress the effect of that
  313.   var saveAllow = allowSelectWord;
  314.   allowSelectWord = false;
  315.  
  316.   // Select matching word in list
  317.   var newIndex = -1;
  318.   var replaceWord = TrimString(dialog.ReplaceWordInput.value);
  319.   if (replaceWord)
  320.   {
  321.     var count = 0;
  322.     var treeChildren = dialog.SuggestedList.firstChild.nextSibling;
  323.     if (treeChildren && treeChildren.childNodes)
  324.       count = treeChildren.childNodes.length;
  325.  
  326.     for (var i = 0; i < count; i++)
  327.     {
  328.       var wordInList = GetTreelistValueAt(dialog.SuggestedList, i);
  329.       if (wordInList == replaceWord)
  330.       {
  331.         newIndex = i;
  332.         break;
  333.       }
  334.     }
  335.   }
  336.   dialog.SuggestedList.selectedIndex = newIndex;
  337.  
  338.   allowSelectWord = saveAllow;
  339.  
  340.   // Remember the new word
  341.   PreviousReplaceWord = dialog.ReplaceWordInput.value;
  342.  
  343.   SetReplaceEnable();
  344. }
  345.  
  346. function Ignore()
  347. {
  348.   NextWord();
  349. }
  350.  
  351. function IgnoreAll()
  352. {
  353.   if (gMisspelledWord) {
  354.     spellChecker.IgnoreWordAllOccurrences(gMisspelledWord);
  355.   }
  356.   NextWord();
  357. }
  358.  
  359. function Replace()
  360. {
  361.   newWord = dialog.ReplaceWordInput.value;
  362.   if (gMisspelledWord && gMisspelledWord != newWord)
  363.   {
  364.     editorShell.BeginBatchChanges();
  365.     isMisspelled = spellChecker.ReplaceWord(gMisspelledWord, newWord, false);
  366.     editorShell.EndBatchChanges();
  367.   }
  368.   NextWord();
  369. }
  370.  
  371. function ReplaceAll()
  372. {
  373.   newWord = dialog.ReplaceWordInput.value;
  374.   if (gMisspelledWord && gMisspelledWord != newWord)
  375.   {
  376.     editorShell.BeginBatchChanges();
  377.     isMisspelled = spellChecker.ReplaceWord(gMisspelledWord, newWord, true);
  378.     editorShell.EndBatchChanges();
  379.   }
  380.   NextWord();
  381. }
  382.  
  383. function AddToDictionary()
  384. {
  385.   if (gMisspelledWord) {
  386.     spellChecker.AddWordToDictionary(gMisspelledWord);
  387.   }
  388.   NextWord();
  389. }
  390.  
  391. function EditDictionary()
  392. {
  393.   window.openDialog("chrome://editor/content/EdDictionary.xul", "_blank", "chrome,close,titlebar,modal", "", gMisspelledWord);
  394. }
  395.  
  396. function SelectLanguage()
  397. {
  398.   try {
  399.     var item = dialog.LanguageMenulist.selectedItem;
  400.     if (item.value != "more-cmd")
  401.       spellChecker.SetCurrentDictionary(item.value);
  402.     else
  403.       window.openDialog( getBrowserURL(), "_blank", "chrome,all,dialog=no,modal", xlateURL('urn:clienturl:composer:spellcheckers'));
  404.   } catch (ex) {
  405.     dump(ex);
  406.   }
  407. }
  408.  
  409. function Recheck()
  410. {
  411.   //TODO: Should we bother to add a "Recheck" method to interface?
  412.   try {
  413.     var curLang = spellChecker.GetCurrentDictionary();
  414.  
  415.     spellChecker.UninitSpellChecker();
  416.     spellChecker.InitSpellChecker();
  417.     spellChecker.SetCurrentDictionary(curLang);
  418.     gMisspelledWord = spellChecker.GetNextMisspelledWord();
  419.     SetWidgetsForMisspelledWord();
  420.   } catch(ex) {
  421.     dump(ex);
  422.   }
  423. }
  424.  
  425. function FillSuggestedList(misspelledWord)
  426. {
  427.   var list = dialog.SuggestedList;
  428.  
  429.   // Clear the current contents of the list
  430.   allowSelectWord = false;
  431.   ClearTreelist(list);
  432.  
  433.   if (misspelledWord.length > 0)
  434.   {
  435.     // Get suggested words until an empty string is returned
  436.     var count = 0;
  437.     var firstWord = 0;
  438.     do {
  439.       word = spellChecker.GetSuggestedWord();
  440.       if (count==0)
  441.         firstWord = word;
  442.       if (word.length > 0) {
  443.         AppendStringToTreelist(list, word);
  444.         count++;
  445.       }
  446.     } while (word.length > 0);
  447.  
  448.     var len = list.getAttribute("length");
  449.  
  450.     if (count == 0)
  451.     {
  452.       // No suggestions - show a message but don't let user select it
  453.       var item = AppendStringToTreelistById(list, "NoSuggestedWords");
  454.       if (item) item.setAttribute("disabled", "true");
  455.       allowSelectWord = false;
  456.     } else {
  457.       allowSelectWord = true;
  458.       // Initialize with first suggested list by selecting it
  459.       dialog.SuggestedList.selectedIndex = 0;
  460.     }
  461.   } 
  462.   else
  463.   {
  464.     var item = AppendStringToTreelist(list, "");
  465.     if (item)
  466.       item.setAttribute("disabled", "true");
  467.   }
  468. }
  469.  
  470. function SetReplaceEnable()
  471. {
  472.   // Enable "Change..." buttons only if new word is different than misspelled
  473.   var newWord = dialog.ReplaceWordInput.value;
  474.   var enable = newWord.length > 0 && newWord != gMisspelledWord;
  475.   SetElementEnabledById("Replace", enable);
  476.   SetElementEnabledById("ReplaceAll", enable);
  477.   if (enable)
  478.   {
  479.     dialog.ReplaceButton.setAttribute("default","true");
  480.     dialog.IgnoreButton.removeAttribute("default");
  481.   }
  482.   else
  483.   {
  484.     dialog.IgnoreButton.setAttribute("default","true");
  485.     dialog.ReplaceButton.removeAttribute("default");
  486.   }
  487. }
  488.  
  489. function doDefault()
  490. {
  491.   if (dialog.ReplaceButton.getAttribute("default") == "true")
  492.     Replace();
  493.   else if (dialog.IgnoreButton.getAttribute("default") == "true")
  494.     Ignore();
  495.   else if (dialog.CloseButton.getAttribute("default") == "true")
  496.     onClose();
  497. }
  498.  
  499. function onClose()
  500. {
  501.   // Shutdown the spell check and close the dialog
  502.   spellChecker.UninitSpellChecker();
  503.   SaveWindowLocation();
  504.   window.close();
  505.   return true;
  506. }
  507.  
  508.