Annotation of loncom/html/htmlarea/plugins/SpellChecker/spell-check-ui.js, revision 1.2
1.1 www 1: // Spell Checker Plugin for HTMLArea-3.0
1.2 ! www 2: // Sponsored by www.americanbible.org
! 3: // Implementation by Mihai Bazon, http://dynarch.com/mishoo/
1.1 www 4: //
1.2 ! www 5: // (c) dynarch.com 2003.
! 6: // Distributed under the same terms as HTMLArea itself.
1.1 www 7: // This notice MUST stay intact for use (see license.txt).
8: //
1.2 ! www 9: // $Id: spell-check-ui.js,v 1.9 2004/01/31 13:47:05 mishoo Exp $
1.1 www 10:
11: // internationalization file was already loaded in parent ;-)
12: var SpellChecker = window.opener.SpellChecker;
13: var i18n = SpellChecker.I18N;
14:
1.2 ! www 15: var HTMLArea = window.opener.HTMLArea;
! 16: var is_ie = HTMLArea.is_ie;
1.1 www 17: var editor = SpellChecker.editor;
18: var frame = null;
19: var currentElement = null;
20: var wrongWords = null;
21: var modified = false;
22: var allWords = {};
1.2 ! www 23: var fixedWords = [];
! 24: var suggested_words = {};
1.1 www 25:
26: function makeCleanDoc(leaveFixed) {
27: // document.getElementById("status").innerHTML = 'Please wait: rendering valid HTML';
1.2 ! www 28: var words = wrongWords.concat(fixedWords);
! 29: for (var i = words.length; --i >= 0;) {
! 30: var el = words[i];
1.1 www 31: if (!(leaveFixed && /HA-spellcheck-fixed/.test(el.className))) {
32: el.parentNode.insertBefore(el.firstChild, el);
33: el.parentNode.removeChild(el);
1.2 ! www 34: } else
1.1 www 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.
1.2 ! www 40: return window.opener.HTMLArea.getHTML(frame.contentWindow.document.body, false, editor);
1.1 www 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;
1.2 ! www 71: var this_word_modified = (el.innerHTML != replacement);
! 72: if (this_word_modified)
! 73: modified = true;
1.1 www 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;
1.2 ! www 79: if (!this_word_modified) {
1.1 www 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: }
1.2 ! www 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";
1.1 www 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");
1.2 ! www 179: field.value = HTMLArea.getHTML(editor._doc.body, false, editor);
1.1 www 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;
1.2 ! www 201: document.getElementById("b_revert").onclick = revertClicked;
! 202: document.getElementById("b_info").onclick = displayInfo;
1.1 www 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:
1.2 ! www 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: })();
1.1 www 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: }
1.2 ! www 256: // document.getElementById("b_replall").disabled = (a.length <= 1);
! 257: // document.getElementById("b_ignall").disabled = (a.length <= 1);
1.1 www 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: }
1.2 ! www 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");
1.1 www 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: }
1.2 ! www 291: select.style.display = "none";
! 292: select.style.display = "block";
1.1 www 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:
1.2 ! www 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:
1.1 www 318: function finishedSpellChecking() {
319: // initialization of global variables
320: currentElement = null;
321: wrongWords = null;
322: allWords = {};
1.2 ! www 323: fixedWords = [];
! 324: suggested_words = frame.contentWindow.suggested_words;
1.1 www 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);
1.2 ! www 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: };
1.1 www 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: }
1.2 ! www 351: } else if (/HA-spellcheck-fixed/.test(el.className)) {
! 352: fixedWords.push(el);
! 353: }
1.1 www 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: }
1.2 ! www 365: (currentElement = sps[0]).__msh_wordClicked(true);
1.1 www 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");
1.2 ! www 388: if (/^@(.*)$/.test(txt)) {
! 389: txt = RegExp.$1;
! 390: option.selected = true;
! 391: }
1.1 www 392: option.value = txt;
393: option.appendChild(document.createTextNode(txt));
394: select.appendChild(option);
395: }
396: }
397: };
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>