home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / groupoffice-com-2.01 / controls / htmlarea / plugins / SpellChecker / spell-check-ui.js < prev    next >
Text File  |  2004-03-08  |  12KB  |  398 lines

  1. // Spell Checker Plugin for HTMLArea-3.0
  2. // Sponsored by www.americanbible.org
  3. // Implementation by Mihai Bazon, http://dynarch.com/mishoo/
  4. //
  5. // (c) dynarch.com 2003.
  6. // Distributed under the same terms as HTMLArea itself.
  7. // This notice MUST stay intact for use (see license.txt).
  8. //
  9. // $Id: spell-check-ui.js,v 1.5 2004/03/03 11:22:41 mschering Exp $
  10.  
  11. // internationalization file was already loaded in parent ;-)
  12. var SpellChecker = window.opener.SpellChecker;
  13. var i18n = SpellChecker.I18N;
  14.  
  15. var HTMLArea = window.opener.HTMLArea;
  16. var is_ie = HTMLArea.is_ie;
  17. var editor = SpellChecker.editor;
  18. var frame = null;
  19. var currentElement = null;
  20. var wrongWords = null;
  21. var modified = false;
  22. var allWords = {};
  23. var fixedWords = [];
  24. var suggested_words = {};
  25.  
  26. function makeCleanDoc(leaveFixed) {
  27.     // document.getElementById("status").innerHTML = 'Please wait: rendering valid HTML';
  28.     var words = wrongWords.concat(fixedWords);
  29.     for (var i = words.length; --i >= 0;) {
  30.         var el = words[i];
  31.         if (!(leaveFixed && /HA-spellcheck-fixed/.test(el.className))) {
  32.             el.parentNode.insertBefore(el.firstChild, el);
  33.             el.parentNode.removeChild(el);
  34.         } else
  35.             el.className = "HA-spellcheck-fixed";
  36.     }
  37.     // we should use innerHTML here, but IE6's implementation fucks up the
  38.     // HTML to such extent that our poor Perl parser doesn't understand it
  39.     // anymore.
  40.     return window.opener.HTMLArea.getHTML(frame.contentWindow.document.body, false, editor);
  41. };
  42.  
  43. function recheckClicked() {
  44.     document.getElementById("status").innerHTML = i18n["Please wait: changing dictionary to"] + ': "' + document.getElementById("f_dictionary").value + '".';
  45.     var field = document.getElementById("f_content");
  46.     field.value = makeCleanDoc(true);
  47.     field.form.submit();
  48. };
  49.  
  50. function saveClicked() {
  51.     if (modified) {
  52.         editor.setHTML(makeCleanDoc(false));
  53.     }
  54.     window.close();
  55.     return false;
  56. };
  57.  
  58. function cancelClicked() {
  59.     var ok = true;
  60.     if (modified) {
  61.         ok = confirm(i18n["QUIT_CONFIRMATION"]);
  62.     }
  63.     if (ok) {
  64.         window.close();
  65.     }
  66.     return false;
  67. };
  68.  
  69. function replaceWord(el) {
  70.     var replacement = document.getElementById("v_replacement").value;
  71.     var this_word_modified = (el.innerHTML != replacement);
  72.     if (this_word_modified)
  73.         modified = true;
  74.     if (el) {
  75.         el.className = el.className.replace(/\s*HA-spellcheck-(hover|fixed)\s*/g, " ");
  76.     }
  77.     el.className += " HA-spellcheck-fixed";
  78.     el.__msh_fixed = true;
  79.     if (!this_word_modified) {
  80.         return false;
  81.     }
  82.     el.innerHTML = replacement;
  83. };
  84.  
  85. function replaceClicked() {
  86.     replaceWord(currentElement);
  87.     var start = currentElement.__msh_id;
  88.     var index = start;
  89.     do {
  90.         ++index;
  91.         if (index == wrongWords.length) {
  92.             index = 0;
  93.         }
  94.     } while ((index != start) && wrongWords[index].__msh_fixed);
  95.     if (index == start) {
  96.         index = 0;
  97.         alert(i18n["Finished list of mispelled words"]);
  98.     }
  99.     wrongWords[index].__msh_wordClicked(true);
  100.     return false;
  101. };
  102.  
  103. function revertClicked() {
  104.     document.getElementById("v_replacement").value = currentElement.__msh_origWord;
  105.     replaceWord(currentElement);
  106.     currentElement.className = "HA-spellcheck-error HA-spellcheck-current";
  107.     return false;
  108. };
  109.  
  110. function replaceAllClicked() {
  111.     var replacement = document.getElementById("v_replacement").value;
  112.     var ok = true;
  113.     var spans = allWords[currentElement.__msh_origWord];
  114.     if (spans.length == 0) {
  115.         alert("An impossible condition just happened.  Call FBI.  ;-)");
  116.     } else if (spans.length == 1) {
  117.         replaceClicked();
  118.         return false;
  119.     }
  120.     /*
  121.     var message = "The word \"" + currentElement.__msh_origWord + "\" occurs " + spans.length + " times.\n";
  122.     if (replacement == currentElement.__msh_origWord) {
  123.         ok = confirm(message + "Ignore all occurrences?");
  124.     } else {
  125.         ok = confirm(message + "Replace all occurrences with \"" + replacement + "\"?");
  126.     }
  127.     */
  128.     if (ok) {
  129.         for (var i in spans) {
  130.             if (spans[i] != currentElement) {
  131.                 replaceWord(spans[i]);
  132.             }
  133.         }
  134.         // replace current element the last, so that we jump to the next word ;-)
  135.         replaceClicked();
  136.     }
  137.     return false;
  138. };
  139.  
  140. function ignoreClicked() {
  141.     document.getElementById("v_replacement").value = currentElement.__msh_origWord;
  142.     replaceClicked();
  143.     return false;
  144. };
  145.  
  146. function ignoreAllClicked() {
  147.     document.getElementById("v_replacement").value = currentElement.__msh_origWord;
  148.     replaceAllClicked();
  149.     return false;
  150. };
  151.  
  152. function learnClicked() {
  153.     alert("Not [yet] implemented");
  154.     return false;
  155. };
  156.  
  157. function internationalizeWindow() {
  158.     var types = ["div", "span", "button"];
  159.     for (var i in types) {
  160.         var tag = types[i];
  161.         var els = document.getElementsByTagName(tag);
  162.         for (var j = els.length; --j >= 0;) {
  163.             var el = els[j];
  164.             if (el.childNodes.length == 1 && /\S/.test(el.innerHTML)) {
  165.                 var txt = el.innerHTML;
  166.                 if (typeof i18n[txt] != "undefined") {
  167.                     el.innerHTML = i18n[txt];
  168.                 }
  169.             }
  170.         }
  171.     }
  172. };
  173.  
  174. function initDocument() {
  175.     internationalizeWindow();
  176.     modified = false;
  177.     frame = document.getElementById("i_framecontent");
  178.     var field = document.getElementById("f_content");
  179.     field.value = HTMLArea.getHTML(editor._doc.body, false, editor);
  180.     field.form.submit();
  181.     document.getElementById("f_init").value = "0";
  182.  
  183.     // assign some global event handlers
  184.  
  185.     var select = document.getElementById("v_suggestions");
  186.     select.onchange = function() {
  187.         document.getElementById("v_replacement").value = this.value;
  188.     };
  189.     if (is_ie) {
  190.         select.attachEvent("ondblclick", replaceClicked);
  191.     } else {
  192.         select.addEventListener("dblclick", replaceClicked, true);
  193.     }
  194.  
  195.     document.getElementById("b_replace").onclick = replaceClicked;
  196.     // document.getElementById("b_learn").onclick = learnClicked;
  197.     document.getElementById("b_replall").onclick = replaceAllClicked;
  198.     document.getElementById("b_ignore").onclick = ignoreClicked;
  199.     document.getElementById("b_ignall").onclick = ignoreAllClicked;
  200.     document.getElementById("b_recheck").onclick = recheckClicked;
  201.     document.getElementById("b_revert").onclick = revertClicked;
  202.     document.getElementById("b_info").onclick = displayInfo;
  203.  
  204.     document.getElementById("b_ok").onclick = saveClicked;
  205.     document.getElementById("b_cancel").onclick = cancelClicked;
  206.  
  207.     select = document.getElementById("v_dictionaries");
  208.     select.onchange = function() {
  209.         document.getElementById("f_dictionary").value = this.value;
  210.     };
  211. };
  212.  
  213. function getAbsolutePos(el) {
  214.     var r = { x: el.offsetLeft, y: el.offsetTop };
  215.     if (el.offsetParent) {
  216.         var tmp = getAbsolutePos(el.offsetParent);
  217.         r.x += tmp.x;
  218.         r.y += tmp.y;
  219.     }
  220.     return r;
  221. };
  222.  
  223. function wordClicked(scroll) {
  224.     var self = this;
  225.     if (scroll) (function() {
  226.         var pos = getAbsolutePos(self);
  227.         var ws = { x: frame.offsetWidth - 4,
  228.                y: frame.offsetHeight - 4 };
  229.         var wp = { x: frame.contentWindow.document.body.scrollLeft,
  230.                y: frame.contentWindow.document.body.scrollTop };
  231.         pos.x -= Math.round(ws.x/2);
  232.         if (pos.x < 0) pos.x = 0;
  233.         pos.y -= Math.round(ws.y/2);
  234.         if (pos.y < 0) pos.y = 0;
  235.         frame.contentWindow.scrollTo(pos.x, pos.y);
  236.     })();
  237.     if (currentElement) {
  238.         var a = allWords[currentElement.__msh_origWord];
  239.         currentElement.className = currentElement.className.replace(/\s*HA-spellcheck-current\s*/g, " ");
  240.         for (var i in a) {
  241.             var el = a[i];
  242.             if (el != currentElement) {
  243.                 el.className = el.className.replace(/\s*HA-spellcheck-same\s*/g, " ");
  244.             }
  245.         }
  246.     }
  247.     currentElement = this;
  248.     this.className += " HA-spellcheck-current";
  249.     var a = allWords[currentElement.__msh_origWord];
  250.     for (var i in a) {
  251.         var el = a[i];
  252.         if (el != currentElement) {
  253.             el.className += " HA-spellcheck-same";
  254.         }
  255.     }
  256.     // document.getElementById("b_replall").disabled = (a.length <= 1);
  257.     // document.getElementById("b_ignall").disabled = (a.length <= 1);
  258.     var txt;
  259.     if (a.length == 1) {
  260.         txt = "one occurrence";
  261.     } else if (a.length == 2) {
  262.         txt = "two occurrences";
  263.     } else {
  264.         txt = a.length + " occurrences";
  265.     }
  266.     var suggestions = suggested_words[this.__msh_origWord];
  267.     if (suggestions)
  268.         suggestions = suggestions.split(/,/);
  269.     else
  270.         suggestions = [];
  271.     var select = document.getElementById("v_suggestions");
  272.     document.getElementById("statusbar").innerHTML = "Found " + txt +
  273.         ' for word "<b>' + currentElement.__msh_origWord + '</b>"';
  274.     for (var i = select.length; --i >= 0;) {
  275.         select.remove(i);
  276.     }
  277.     for (var i = 0; i < suggestions.length; ++i) {
  278.         var txt = suggestions[i];
  279.         var option = document.createElement("option");
  280.         option.value = txt;
  281.         option.appendChild(document.createTextNode(txt));
  282.         select.appendChild(option);
  283.     }
  284.     document.getElementById("v_currentWord").innerHTML = this.__msh_origWord;
  285.     if (suggestions.length > 0) {
  286.         select.selectedIndex = 0;
  287.         select.onchange();
  288.     } else {
  289.         document.getElementById("v_replacement").value = this.innerHTML;
  290.     }
  291.     select.style.display = "none";
  292.     select.style.display = "block";
  293.     return false;
  294. };
  295.  
  296. function wordMouseOver() {
  297.     this.className += " HA-spellcheck-hover";
  298. };
  299.  
  300. function wordMouseOut() {
  301.     this.className = this.className.replace(/\s*HA-spellcheck-hover\s*/g, " ");
  302. };
  303.  
  304. function displayInfo() {
  305.     var info = frame.contentWindow.spellcheck_info;
  306.     if (!info)
  307.         alert("No information available");
  308.     else {
  309.         var txt = "** Document information **";
  310.         for (var i in info) {
  311.             txt += "\n" + i + " : " + info[i];
  312.         }
  313.         alert(txt);
  314.     }
  315.     return false;
  316. };
  317.  
  318. function finishedSpellChecking() {
  319.     // initialization of global variables
  320.     currentElement = null;
  321.     wrongWords = null;
  322.     allWords = {};
  323.     fixedWords = [];
  324.     suggested_words = frame.contentWindow.suggested_words;
  325.  
  326.     document.getElementById("status").innerHTML = "HTMLArea Spell Checker (<a href='readme-tech.html' target='_blank' title='Technical information'>info</a>)";
  327.     var doc = frame.contentWindow.document;
  328.         var spans = doc.getElementsByTagName("span");
  329.         var sps = [];
  330.     var id = 0;
  331.         for (var i = 0; i < spans.length; ++i) {
  332.                 var el = spans[i];
  333.                 if (/HA-spellcheck-error/.test(el.className)) {
  334.                         sps.push(el);
  335.             el.__msh_wordClicked = wordClicked;
  336.             el.onclick = function(ev) {
  337.                 ev || (ev = window.event);
  338.                 ev && HTMLArea._stopEvent(ev);
  339.                 return this.__msh_wordClicked(false);
  340.             };
  341.             el.onmouseover = wordMouseOver;
  342.             el.onmouseout = wordMouseOut;
  343.             el.__msh_id = id++;
  344.             var txt = (el.__msh_origWord = el.firstChild.data);
  345.             el.__msh_fixed = false;
  346.             if (typeof allWords[txt] == "undefined") {
  347.                 allWords[txt] = [el];
  348.             } else {
  349.                 allWords[txt].push(el);
  350.             }
  351.                 } else if (/HA-spellcheck-fixed/.test(el.className)) {
  352.             fixedWords.push(el);
  353.         }
  354.         }
  355.     wrongWords = sps;
  356.     if (sps.length == 0) {
  357.         if (!modified) {
  358.             alert(i18n["NO_ERRORS_CLOSING"]);
  359.             window.close();
  360.         } else {
  361.             alert(i18n["NO_ERRORS"]);
  362.         }
  363.         return false;
  364.     }
  365.     (currentElement = sps[0]).__msh_wordClicked(true);
  366.     var as = doc.getElementsByTagName("a");
  367.     for (var i = as.length; --i >= 0;) {
  368.         var a = as[i];
  369.         a.onclick = function() {
  370.             if (confirm(i18n["CONFIRM_LINK_CLICK"] + ":\n" +
  371.                     this.href + "\n" + i18n["I will open it in a new page."])) {
  372.                 window.open(this.href);
  373.             }
  374.             return false;
  375.         };
  376.     }
  377.     var dicts = doc.getElementById("HA-spellcheck-dictionaries");
  378.     if (dicts) {
  379.         dicts.parentNode.removeChild(dicts);
  380.         dicts = dicts.innerHTML.split(/,/);
  381.         var select = document.getElementById("v_dictionaries");
  382.         for (var i = select.length; --i >= 0;) {
  383.             select.remove(i);
  384.         }
  385.         for (var i = 0; i < dicts.length; ++i) {
  386.             var txt = dicts[i];
  387.             var option = document.createElement("option");
  388.             if (/^@(.*)$/.test(txt)) {
  389.                 txt = RegExp.$1;
  390.                 option.selected = true;
  391.             }
  392.             option.value = txt;
  393.             option.appendChild(document.createTextNode(txt));
  394.             select.appendChild(option);
  395.         }
  396.     }
  397. };
  398.