annotate forum/Themes/Vamp/scripts/spellcheck.js @ 94:e43e2f72254a rdfquery

Add some resources for the dynamic plugin list
author Chris Cannam
date Sun, 22 Jun 2014 13:25:59 +0100
parents e3e11437ecea
children
rev   line source
Chris@76 1 // These are variables the popup is going to want to access...
Chris@76 2 var spell_formname, spell_fieldname;
Chris@76 3
Chris@76 4 // Spell check the specified field in the specified form.
Chris@76 5 function spellCheck(formName, fieldName)
Chris@76 6 {
Chris@76 7 // Grab the (hidden) spell checking form.
Chris@76 8 var spellform = document.forms.spell_form;
Chris@76 9
Chris@76 10 // Register the name of the editing form for future reference.
Chris@76 11 spell_formname = formName;
Chris@76 12 spell_fieldname = fieldName;
Chris@76 13
Chris@76 14 // This should match a word (most of the time).
Chris@76 15 var regexpWordMatch = /(?:<[^>]+>)|(?:\[[^ ][^\]]*\])|(?:&[^; ]+;)|(?:[^0-9\s\]\[{};:"\\|,<.>\/?`~!@#$%^&*()_+=]+)/g;
Chris@76 16
Chris@76 17 // These characters can appear within words.
Chris@76 18 var aWordCharacters = ['-', '\''];
Chris@76 19
Chris@76 20 var aWords = new Array(), aResult = new Array();
Chris@76 21 var sText = document.forms[formName][fieldName].value;
Chris@76 22 var bInCode = false;
Chris@76 23 var iOffset1, iOffset2;
Chris@76 24
Chris@76 25 // Loop through all words.
Chris@76 26 while ((aResult = regexpWordMatch.exec(sText)) && typeof(aResult) != 'undefined')
Chris@76 27 {
Chris@76 28 iOffset1 = 0;
Chris@76 29 iOffset2 = aResult[0].length - 1;
Chris@76 30
Chris@76 31 // Strip the dashes and hyphens from the begin of the word.
Chris@76 32 while (in_array(aResult[0].charAt(iOffset1), aWordCharacters) && iOffset1 < iOffset2)
Chris@76 33 iOffset1++;
Chris@76 34
Chris@76 35 // Strip the dashes and hyphens from the end of the word.
Chris@76 36 while (in_array(aResult[0].charAt(iOffset2), aWordCharacters) && iOffset1 < iOffset2)
Chris@76 37 iOffset2--;
Chris@76 38
Chris@76 39 // I guess there's only dashes and hyphens in this word...
Chris@76 40 if (iOffset1 == iOffset2)
Chris@76 41 continue;
Chris@76 42
Chris@76 43 // Ignore code blocks.
Chris@76 44 if (aResult[0].substr(0, 5).toLowerCase() == '[code')
Chris@76 45 bInCode = true;
Chris@76 46
Chris@76 47 // Glad we're out of that code block!
Chris@76 48 else if (bInCode && aResult[0].substr(0, 7).toLowerCase() == '[/code]')
Chris@76 49 bInCode = false;
Chris@76 50
Chris@76 51 // Now let's get to business.
Chris@76 52 else if (!bInCode && !in_array(aResult[0].charAt(0), ['[', '<']) && aResult[0].toUpperCase() != aResult[0])
Chris@76 53 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 54 }
Chris@76 55
Chris@76 56 // Open the window...
Chris@76 57 openSpellWin(640, 480);
Chris@76 58
Chris@76 59 // Pass the data to a form...
Chris@76 60 spellform.spellstring.value = aWords.join('\n');
Chris@76 61
Chris@76 62 // and go!
Chris@76 63 spellform.submit();
Chris@76 64
Chris@76 65 return true;
Chris@76 66 }
Chris@76 67
Chris@76 68 // Private functions -------------------------------
Chris@76 69
Chris@76 70 // Globals...
Chris@76 71 var wordindex = -1, offsetindex = 0;
Chris@76 72 var ignoredWords = [];
Chris@76 73
Chris@76 74 // A "misspelled word" object.
Chris@76 75 function misp(word, start, end, suggestions)
Chris@76 76 {
Chris@76 77 // The word, start index, end index, and array of suggestions.
Chris@76 78 this.word = word;
Chris@76 79 this.start = start;
Chris@76 80 this.end = end;
Chris@76 81 this.suggestions = suggestions;
Chris@76 82 }
Chris@76 83
Chris@76 84 // Replace the word in the misps array at the "wordindex" index. The
Chris@76 85 // misps array is generated by a PHP script after the string to be spell
Chris@76 86 // checked is evaluated with pspell.
Chris@76 87 function replaceWord()
Chris@76 88 {
Chris@76 89 var strstart = "";
Chris@76 90 var strend;
Chris@76 91
Chris@76 92 // If this isn't the beginning of the string then get all of the string
Chris@76 93 // that is before the word we are replacing.
Chris@76 94 if (misps[wordindex].start != 0)
Chris@76 95 strstart = mispstr.slice(0, misps[wordindex].start + offsetindex);
Chris@76 96
Chris@76 97 // Get the end of the string after the word we are replacing.
Chris@76 98 strend = mispstr.slice(misps[wordindex].end + 1 + offsetindex);
Chris@76 99
Chris@76 100 // Rebuild the string with the new word.
Chris@76 101 mispstr = strstart + document.forms.spellingForm.changeto.value + strend;
Chris@76 102
Chris@76 103 // Update offsetindex to compensate for replacing a word with a word
Chris@76 104 // of a different length.
Chris@76 105 offsetindex += document.forms.spellingForm.changeto.value.length - misps[wordindex].word.length;
Chris@76 106
Chris@76 107 // Update the word so future replaceAll calls don't change it.
Chris@76 108 misps[wordindex].word = document.forms.spellingForm.changeto.value;
Chris@76 109
Chris@76 110 nextWord(false);
Chris@76 111 }
Chris@76 112
Chris@76 113 // Replaces all instances of currently selected word with contents chosen by user.
Chris@76 114 // Note: currently only replaces words after highlighted word. I think we can re-index
Chris@76 115 // all words at replacement or ignore time to have it wrap to the beginning if we want
Chris@76 116 // to.
Chris@76 117 function replaceAll()
Chris@76 118 {
Chris@76 119 var strend;
Chris@76 120 var idx;
Chris@76 121 var origword;
Chris@76 122 var localoffsetindex = offsetindex;
Chris@76 123
Chris@76 124 origword = misps[wordindex].word;
Chris@76 125
Chris@76 126 // Re-index everything past the current word.
Chris@76 127 for (idx = wordindex; idx < misps.length; idx++)
Chris@76 128 {
Chris@76 129 misps[idx].start += localoffsetindex;
Chris@76 130 misps[idx].end += localoffsetindex;
Chris@76 131 }
Chris@76 132
Chris@76 133 localoffsetindex = 0;
Chris@76 134
Chris@76 135 for (idx = 0; idx < misps.length; idx++)
Chris@76 136 {
Chris@76 137 if (misps[idx].word == origword)
Chris@76 138 {
Chris@76 139 var strstart = "";
Chris@76 140 if (misps[idx].start != 0)
Chris@76 141 strstart = mispstr.slice(0, misps[idx].start + localoffsetindex);
Chris@76 142
Chris@76 143 // Get the end of the string after the word we are replacing.
Chris@76 144 strend = mispstr.slice(misps[idx].end + 1 + localoffsetindex);
Chris@76 145
Chris@76 146 // Rebuild the string with the new word.
Chris@76 147 mispstr = strstart + document.forms.spellingForm.changeto.value + strend;
Chris@76 148
Chris@76 149 // Update offsetindex to compensate for replacing a word with a word
Chris@76 150 // of a different length.
Chris@76 151 localoffsetindex += document.forms.spellingForm.changeto.value.length - misps[idx].word.length;
Chris@76 152 }
Chris@76 153
Chris@76 154 // We have to re-index everything after replacements.
Chris@76 155 misps[idx].start += localoffsetindex;
Chris@76 156 misps[idx].end += localoffsetindex;
Chris@76 157 }
Chris@76 158
Chris@76 159 // Add the word to the ignore array.
Chris@76 160 ignoredWords[origword] = true;
Chris@76 161
Chris@76 162 // Reset offsetindex since we re-indexed.
Chris@76 163 offsetindex = 0;
Chris@76 164
Chris@76 165 nextWord(false);
Chris@76 166 }
Chris@76 167
Chris@76 168 // Highlight the word that was selected using the nextWord function.
Chris@76 169 function highlightWord()
Chris@76 170 {
Chris@76 171 var strstart = "";
Chris@76 172 var strend;
Chris@76 173
Chris@76 174 // If this isn't the beginning of the string then get all of the string
Chris@76 175 // that is before the word we are replacing.
Chris@76 176 if (misps[wordindex].start != 0)
Chris@76 177 strstart = mispstr.slice(0, misps[wordindex].start + offsetindex);
Chris@76 178
Chris@76 179 // Get the end of the string after the word we are replacing.
Chris@76 180 strend = mispstr.slice(misps[wordindex].end + 1 + offsetindex);
Chris@76 181
Chris@76 182 // Rebuild the string with a span wrapped around the misspelled word
Chris@76 183 // so we can highlight it in the div the user is viewing the string in.
Chris@76 184 var divptr, newValue;
Chris@76 185 divptr = document.getElementById("spellview");
Chris@76 186
Chris@76 187 newValue = htmlspecialchars(strstart) + '<span class="highlight" id="h1">' + misps[wordindex].word + '</span>' + htmlspecialchars(strend);
Chris@76 188 setInnerHTML(divptr, newValue.replace(/_\|_/g, '<br />'));
Chris@76 189
Chris@76 190 // We could use scrollIntoView, but it's just not that great anyway.
Chris@76 191 var spellview_height = typeof(document.getElementById("spellview").currentStyle) != "undefined" ? parseInt(document.getElementById("spellview").currentStyle.height) : document.getElementById("spellview").offsetHeight;
Chris@76 192 var word_position = document.getElementById("h1").offsetTop;
Chris@76 193 var current_position = document.getElementById("spellview").scrollTop;
Chris@76 194
Chris@76 195 // The spellview is not tall enough! Scroll down!
Chris@76 196 if (spellview_height <= (word_position + current_position))
Chris@76 197 document.getElementById("spellview").scrollTop = word_position + current_position - spellview_height + 32;
Chris@76 198 }
Chris@76 199
Chris@76 200 // Display the next misspelled word to the user and populate the suggested spellings box.
Chris@76 201 function nextWord(ignoreall)
Chris@76 202 {
Chris@76 203 // Push ignored word onto ignoredWords array.
Chris@76 204 if (ignoreall)
Chris@76 205 ignoredWords[misps[wordindex].word] = true;
Chris@76 206
Chris@76 207 // Update the index of all words we have processed...
Chris@76 208 // This must be done to accomodate the replaceAll function.
Chris@76 209 if (wordindex >= 0)
Chris@76 210 {
Chris@76 211 misps[wordindex].start += offsetindex;
Chris@76 212 misps[wordindex].end += offsetindex;
Chris@76 213 }
Chris@76 214
Chris@76 215 // Increment the counter for the array of misspelled words.
Chris@76 216 wordindex++;
Chris@76 217
Chris@76 218 // Draw it and quit if there are no more misspelled words to evaluate.
Chris@76 219 if (misps.length <= wordindex)
Chris@76 220 {
Chris@76 221 var divptr;
Chris@76 222 divptr = document.getElementById("spellview");
Chris@76 223 setInnerHTML(divptr, htmlspecialchars(mispstr).replace(/_\|_/g, "<br />"));
Chris@76 224
Chris@76 225 while (document.forms.spellingForm.suggestions.options.length > 0)
Chris@76 226 document.forms.spellingForm.suggestions.options[0] = null;
Chris@76 227
Chris@76 228 alert(txt['done']);
Chris@76 229 document.forms.spellingForm.change.disabled = true;
Chris@76 230 document.forms.spellingForm.changeall.disabled = true;
Chris@76 231 document.forms.spellingForm.ignore.disabled = true;
Chris@76 232 document.forms.spellingForm.ignoreall.disabled = true;
Chris@76 233
Chris@76 234 // Put line feeds back...
Chris@76 235 mispstr = mispstr.replace(/_\|_/g, "\n");
Chris@76 236
Chris@76 237 // Get a handle to the field we need to re-populate.
Chris@76 238 window.opener.document.forms[spell_formname][spell_fieldname].value = mispstr;
Chris@76 239 if (!window.opener.spellCheckDone)
Chris@76 240 window.opener.document.forms[spell_formname][spell_fieldname].focus();
Chris@76 241 else
Chris@76 242 window.opener.spellCheckDone();
Chris@76 243
Chris@76 244 window.close();
Chris@76 245 return true;
Chris@76 246 }
Chris@76 247
Chris@76 248 // Check to see if word is supposed to be ignored.
Chris@76 249 if (typeof(ignoredWords[misps[wordindex].word]) != "undefined")
Chris@76 250 {
Chris@76 251 nextWord(false);
Chris@76 252 return false;
Chris@76 253 }
Chris@76 254
Chris@76 255 // Clear out the suggestions box!
Chris@76 256 while (document.forms.spellingForm.suggestions.options.length > 0)
Chris@76 257 document.forms.spellingForm.suggestions.options[0] = null;
Chris@76 258
Chris@76 259 // Re-populate the suggestions box if there are any suggested spellings for the word.
Chris@76 260 if (misps[wordindex].suggestions.length)
Chris@76 261 {
Chris@76 262 for (var sugidx = 0; sugidx < misps[wordindex].suggestions.length; sugidx++)
Chris@76 263 {
Chris@76 264 var newopt = new Option(misps[wordindex].suggestions[sugidx], misps[wordindex].suggestions[sugidx]);
Chris@76 265 document.forms.spellingForm.suggestions.options[sugidx] = newopt;
Chris@76 266
Chris@76 267 if (sugidx == 0)
Chris@76 268 {
Chris@76 269 newopt.selected = true;
Chris@76 270 document.forms.spellingForm.changeto.value = newopt.value;
Chris@76 271 document.forms.spellingForm.changeto.select();
Chris@76 272 }
Chris@76 273 }
Chris@76 274 }
Chris@76 275
Chris@76 276 if (document.forms.spellingForm.suggestions.options.length == 0)
Chris@76 277 document.forms.spellingForm.changeto.value = "";
Chris@76 278
Chris@76 279 highlightWord();
Chris@76 280
Chris@76 281 return false;
Chris@76 282 }
Chris@76 283
Chris@76 284 function htmlspecialchars(thetext)
Chris@76 285 {
Chris@76 286 thetext = thetext.replace(/\</g, "&lt;");
Chris@76 287 thetext = thetext.replace(/\>/g, "&gt;");
Chris@76 288 thetext = thetext.replace(/\n/g, "<br />");
Chris@76 289 thetext = thetext.replace(/\ \ /g, " &nbsp;");
Chris@76 290
Chris@76 291 return thetext;
Chris@76 292 }
Chris@76 293
Chris@76 294 function openSpellWin(width, height)
Chris@76 295 {
Chris@76 296 window.open("", "spellWindow", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=" + width + ",height=" + height);
Chris@76 297 }