comparison forum/Themes/default/spellcheck.js @ 76:e3e11437ecea website

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