Chris@76: // These are variables the popup is going to want to access...
Chris@76: var spell_formname, spell_fieldname;
Chris@76:
Chris@76: // Spell check the specified field in the specified form.
Chris@76: function spellCheck(formName, fieldName)
Chris@76: {
Chris@76: // Grab the (hidden) spell checking form.
Chris@76: var spellform = document.forms.spell_form;
Chris@76:
Chris@76: // Register the name of the editing form for future reference.
Chris@76: spell_formname = formName;
Chris@76: spell_fieldname = fieldName;
Chris@76:
Chris@76: // This should match a word (most of the time).
Chris@76: var regexpWordMatch = /(?:<[^>]+>)|(?:\[[^ ][^\]]*\])|(?:&[^; ]+;)|(?:[^0-9\s\]\[{};:"\\|,<.>\/?`~!@#$%^&*()_+=]+)/g;
Chris@76:
Chris@76: // These characters can appear within words.
Chris@76: var aWordCharacters = ['-', '\''];
Chris@76:
Chris@76: var aWords = new Array(), aResult = new Array();
Chris@76: var sText = document.forms[formName][fieldName].value;
Chris@76: var bInCode = false;
Chris@76: var iOffset1, iOffset2;
Chris@76:
Chris@76: // Loop through all words.
Chris@76: while ((aResult = regexpWordMatch.exec(sText)) && typeof(aResult) != 'undefined')
Chris@76: {
Chris@76: iOffset1 = 0;
Chris@76: iOffset2 = aResult[0].length - 1;
Chris@76:
Chris@76: // Strip the dashes and hyphens from the begin of the word.
Chris@76: while (in_array(aResult[0].charAt(iOffset1), aWordCharacters) && iOffset1 < iOffset2)
Chris@76: iOffset1++;
Chris@76:
Chris@76: // Strip the dashes and hyphens from the end of the word.
Chris@76: while (in_array(aResult[0].charAt(iOffset2), aWordCharacters) && iOffset1 < iOffset2)
Chris@76: iOffset2--;
Chris@76:
Chris@76: // I guess there's only dashes and hyphens in this word...
Chris@76: if (iOffset1 == iOffset2)
Chris@76: continue;
Chris@76:
Chris@76: // Ignore code blocks.
Chris@76: if (aResult[0].substr(0, 5).toLowerCase() == '[code')
Chris@76: bInCode = true;
Chris@76:
Chris@76: // Glad we're out of that code block!
Chris@76: else if (bInCode && aResult[0].substr(0, 7).toLowerCase() == '[/code]')
Chris@76: bInCode = false;
Chris@76:
Chris@76: // Now let's get to business.
Chris@76: else if (!bInCode && !in_array(aResult[0].charAt(0), ['[', '<']) && aResult[0].toUpperCase() != aResult[0])
Chris@76: aWords[aWords.length] = aResult[0].substr(iOffset1, iOffset2 - iOffset1 + 1) + '|' + (iOffset1 + sText.substr(0, aResult.index).length) + '|' + (iOffset2 + sText.substr(0, aResult.index).length);
Chris@76: }
Chris@76:
Chris@76: // Open the window...
Chris@76: openSpellWin(640, 480);
Chris@76:
Chris@76: // Pass the data to a form...
Chris@76: spellform.spellstring.value = aWords.join('\n');
Chris@76:
Chris@76: // and go!
Chris@76: spellform.submit();
Chris@76:
Chris@76: return true;
Chris@76: }
Chris@76:
Chris@76: // Private functions -------------------------------
Chris@76:
Chris@76: // Globals...
Chris@76: var wordindex = -1, offsetindex = 0;
Chris@76: var ignoredWords = [];
Chris@76:
Chris@76: // A "misspelled word" object.
Chris@76: function misp(word, start, end, suggestions)
Chris@76: {
Chris@76: // The word, start index, end index, and array of suggestions.
Chris@76: this.word = word;
Chris@76: this.start = start;
Chris@76: this.end = end;
Chris@76: this.suggestions = suggestions;
Chris@76: }
Chris@76:
Chris@76: // Replace the word in the misps array at the "wordindex" index. The
Chris@76: // misps array is generated by a PHP script after the string to be spell
Chris@76: // checked is evaluated with pspell.
Chris@76: function replaceWord()
Chris@76: {
Chris@76: var strstart = "";
Chris@76: var strend;
Chris@76:
Chris@76: // If this isn't the beginning of the string then get all of the string
Chris@76: // that is before the word we are replacing.
Chris@76: if (misps[wordindex].start != 0)
Chris@76: strstart = mispstr.slice(0, misps[wordindex].start + offsetindex);
Chris@76:
Chris@76: // Get the end of the string after the word we are replacing.
Chris@76: strend = mispstr.slice(misps[wordindex].end + 1 + offsetindex);
Chris@76:
Chris@76: // Rebuild the string with the new word.
Chris@76: mispstr = strstart + document.forms.spellingForm.changeto.value + strend;
Chris@76:
Chris@76: // Update offsetindex to compensate for replacing a word with a word
Chris@76: // of a different length.
Chris@76: offsetindex += document.forms.spellingForm.changeto.value.length - misps[wordindex].word.length;
Chris@76:
Chris@76: // Update the word so future replaceAll calls don't change it.
Chris@76: misps[wordindex].word = document.forms.spellingForm.changeto.value;
Chris@76:
Chris@76: nextWord(false);
Chris@76: }
Chris@76:
Chris@76: // Replaces all instances of currently selected word with contents chosen by user.
Chris@76: // Note: currently only replaces words after highlighted word. I think we can re-index
Chris@76: // all words at replacement or ignore time to have it wrap to the beginning if we want
Chris@76: // to.
Chris@76: function replaceAll()
Chris@76: {
Chris@76: var strend;
Chris@76: var idx;
Chris@76: var origword;
Chris@76: var localoffsetindex = offsetindex;
Chris@76:
Chris@76: origword = misps[wordindex].word;
Chris@76:
Chris@76: // Re-index everything past the current word.
Chris@76: for (idx = wordindex; idx < misps.length; idx++)
Chris@76: {
Chris@76: misps[idx].start += localoffsetindex;
Chris@76: misps[idx].end += localoffsetindex;
Chris@76: }
Chris@76:
Chris@76: localoffsetindex = 0;
Chris@76:
Chris@76: for (idx = 0; idx < misps.length; idx++)
Chris@76: {
Chris@76: if (misps[idx].word == origword)
Chris@76: {
Chris@76: var strstart = "";
Chris@76: if (misps[idx].start != 0)
Chris@76: strstart = mispstr.slice(0, misps[idx].start + localoffsetindex);
Chris@76:
Chris@76: // Get the end of the string after the word we are replacing.
Chris@76: strend = mispstr.slice(misps[idx].end + 1 + localoffsetindex);
Chris@76:
Chris@76: // Rebuild the string with the new word.
Chris@76: mispstr = strstart + document.forms.spellingForm.changeto.value + strend;
Chris@76:
Chris@76: // Update offsetindex to compensate for replacing a word with a word
Chris@76: // of a different length.
Chris@76: localoffsetindex += document.forms.spellingForm.changeto.value.length - misps[idx].word.length;
Chris@76: }
Chris@76:
Chris@76: // We have to re-index everything after replacements.
Chris@76: misps[idx].start += localoffsetindex;
Chris@76: misps[idx].end += localoffsetindex;
Chris@76: }
Chris@76:
Chris@76: // Add the word to the ignore array.
Chris@76: ignoredWords[origword] = true;
Chris@76:
Chris@76: // Reset offsetindex since we re-indexed.
Chris@76: offsetindex = 0;
Chris@76:
Chris@76: nextWord(false);
Chris@76: }
Chris@76:
Chris@76: // Highlight the word that was selected using the nextWord function.
Chris@76: function highlightWord()
Chris@76: {
Chris@76: var strstart = "";
Chris@76: var strend;
Chris@76:
Chris@76: // If this isn't the beginning of the string then get all of the string
Chris@76: // that is before the word we are replacing.
Chris@76: if (misps[wordindex].start != 0)
Chris@76: strstart = mispstr.slice(0, misps[wordindex].start + offsetindex);
Chris@76:
Chris@76: // Get the end of the string after the word we are replacing.
Chris@76: strend = mispstr.slice(misps[wordindex].end + 1 + offsetindex);
Chris@76:
Chris@76: // Rebuild the string with a span wrapped around the misspelled word
Chris@76: // so we can highlight it in the div the user is viewing the string in.
Chris@76: var divptr, newValue;
Chris@76: divptr = document.getElementById("spellview");
Chris@76:
Chris@76: newValue = htmlspecialchars(strstart) + '' + misps[wordindex].word + '' + htmlspecialchars(strend);
Chris@76: setInnerHTML(divptr, newValue.replace(/_\|_/g, '
'));
Chris@76:
Chris@76: // We could use scrollIntoView, but it's just not that great anyway.
Chris@76: var spellview_height = typeof(document.getElementById("spellview").currentStyle) != "undefined" ? parseInt(document.getElementById("spellview").currentStyle.height) : document.getElementById("spellview").offsetHeight;
Chris@76: var word_position = document.getElementById("h1").offsetTop;
Chris@76: var current_position = document.getElementById("spellview").scrollTop;
Chris@76:
Chris@76: // The spellview is not tall enough! Scroll down!
Chris@76: if (spellview_height <= (word_position + current_position))
Chris@76: document.getElementById("spellview").scrollTop = word_position + current_position - spellview_height + 32;
Chris@76: }
Chris@76:
Chris@76: // Display the next misspelled word to the user and populate the suggested spellings box.
Chris@76: function nextWord(ignoreall)
Chris@76: {
Chris@76: // Push ignored word onto ignoredWords array.
Chris@76: if (ignoreall)
Chris@76: ignoredWords[misps[wordindex].word] = true;
Chris@76:
Chris@76: // Update the index of all words we have processed...
Chris@76: // This must be done to accomodate the replaceAll function.
Chris@76: if (wordindex >= 0)
Chris@76: {
Chris@76: misps[wordindex].start += offsetindex;
Chris@76: misps[wordindex].end += offsetindex;
Chris@76: }
Chris@76:
Chris@76: // Increment the counter for the array of misspelled words.
Chris@76: wordindex++;
Chris@76:
Chris@76: // Draw it and quit if there are no more misspelled words to evaluate.
Chris@76: if (misps.length <= wordindex)
Chris@76: {
Chris@76: var divptr;
Chris@76: divptr = document.getElementById("spellview");
Chris@76: setInnerHTML(divptr, htmlspecialchars(mispstr).replace(/_\|_/g, "
"));
Chris@76:
Chris@76: while (document.forms.spellingForm.suggestions.options.length > 0)
Chris@76: document.forms.spellingForm.suggestions.options[0] = null;
Chris@76:
Chris@76: alert(txt['done']);
Chris@76: document.forms.spellingForm.change.disabled = true;
Chris@76: document.forms.spellingForm.changeall.disabled = true;
Chris@76: document.forms.spellingForm.ignore.disabled = true;
Chris@76: document.forms.spellingForm.ignoreall.disabled = true;
Chris@76:
Chris@76: // Put line feeds back...
Chris@76: mispstr = mispstr.replace(/_\|_/g, "\n");
Chris@76:
Chris@76: // Get a handle to the field we need to re-populate.
Chris@76: window.opener.document.forms[spell_formname][spell_fieldname].value = mispstr;
Chris@76: if (!window.opener.spellCheckDone)
Chris@76: window.opener.document.forms[spell_formname][spell_fieldname].focus();
Chris@76: else
Chris@76: window.opener.spellCheckDone();
Chris@76:
Chris@76: window.close();
Chris@76: return true;
Chris@76: }
Chris@76:
Chris@76: // Check to see if word is supposed to be ignored.
Chris@76: if (typeof(ignoredWords[misps[wordindex].word]) != "undefined")
Chris@76: {
Chris@76: nextWord(false);
Chris@76: return false;
Chris@76: }
Chris@76:
Chris@76: // Clear out the suggestions box!
Chris@76: while (document.forms.spellingForm.suggestions.options.length > 0)
Chris@76: document.forms.spellingForm.suggestions.options[0] = null;
Chris@76:
Chris@76: // Re-populate the suggestions box if there are any suggested spellings for the word.
Chris@76: if (misps[wordindex].suggestions.length)
Chris@76: {
Chris@76: for (var sugidx = 0; sugidx < misps[wordindex].suggestions.length; sugidx++)
Chris@76: {
Chris@76: var newopt = new Option(misps[wordindex].suggestions[sugidx], misps[wordindex].suggestions[sugidx]);
Chris@76: document.forms.spellingForm.suggestions.options[sugidx] = newopt;
Chris@76:
Chris@76: if (sugidx == 0)
Chris@76: {
Chris@76: newopt.selected = true;
Chris@76: document.forms.spellingForm.changeto.value = newopt.value;
Chris@76: document.forms.spellingForm.changeto.select();
Chris@76: }
Chris@76: }
Chris@76: }
Chris@76:
Chris@76: if (document.forms.spellingForm.suggestions.options.length == 0)
Chris@76: document.forms.spellingForm.changeto.value = "";
Chris@76:
Chris@76: highlightWord();
Chris@76:
Chris@76: return false;
Chris@76: }
Chris@76:
Chris@76: function htmlspecialchars(thetext)
Chris@76: {
Chris@76: thetext = thetext.replace(/\/g, ">");
Chris@76: thetext = thetext.replace(/\n/g, "
");
Chris@76: thetext = thetext.replace(/\ \ /g, " ");
Chris@76:
Chris@76: return thetext;
Chris@76: }
Chris@76:
Chris@76: function openSpellWin(width, height)
Chris@76: {
Chris@76: window.open("", "spellWindow", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=" + width + ",height=" + height);
Chris@76: }