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>