Mercurial > hg > vamp-website
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, "<"); | |
283 thetext = thetext.replace(/\>/g, ">"); | |
284 thetext = thetext.replace(/\n/g, "<br />"); | |
285 thetext = thetext.replace(/\ \ /g, " "); | |
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 } |