852ca0e4d56b7d0dbf6554fe9ba7fbba40fc63ba
[squirrelmail.git] / plugins / squirrelspell / js / check_me.js
1 /**
2 CHECK_ME.JS
3 ------------
4 This JavaScript app is the driving power of the SquirrelSpell's
5 main spellchecker window. Hope you have as much pain figuring
6 it out as it took to write. ;))
7 **/
8
9 var CurrentError=0;
10 var CurrentLocation=0;
11
12 var CurrentLine;
13 var CurrentSymbol;
14 var ChangesMade=false;
15
16 function populateSqspellForm(){
17 // this function loads error data into the form.
18 CurrentWord=Word=misses[CurrentError];
19 WordLocations = locations[CurrentError].split(", ");
20 CurrentLoc = WordLocations[CurrentLocation];
21 if(CurrentLocation==WordLocations.length-1) {
22 CurrentLocation=0;
23 } else {
24 CurrentLocation++;
25 }
26
27 tmp = CurrentLoc.split(":");
28 CurrentLine=parseInt(tmp[0]);
29 CurrentSymbol=parseInt(tmp[1]);
30 document.forms[0].sqspell_error.value=Word;
31 LineValue=sqspell_lines[CurrentLine];
32 StartWith=0;
33 NewLineValue="";
34 if (CurrentSymbol > 40){
35 StartWith=CurrentSymbol-40;
36 NewLineValue = "...";
37 }
38 EndWith=LineValue.length;
39 EndLine="";
40 if (EndWith > CurrentSymbol + 40){
41 EndWith=CurrentSymbol+40;
42 EndLine="...";
43 }
44 NewLineValue+=LineValue.substring(StartWith, CurrentSymbol) + "*" + Word + "*" + LineValue.substring(CurrentSymbol + Word.length, EndWith) + EndLine;
45 document.forms[0].sqspell_line_area.value=NewLineValue;
46
47 if (suggestions[CurrentError]){
48 WordSuggestions = suggestions[CurrentError].split(", ");
49 for (i=0; i<WordSuggestions.length; i++){
50 document.forms[0].sqspell_suggestion.options[i] = new Option(WordSuggestions[i], WordSuggestions[i]);
51 }
52 } else {
53 document.forms[0].sqspell_suggestion.options[0] = new Option("No Suggestions", "_NONE");
54 document.forms[0].sqspell_oruse.value=Word;
55 document.forms[0].sqspell_oruse.focus();
56 document.forms[0].sqspell_oruse.select();
57 }
58
59 document.forms[0].sqspell_suggestion.selectedIndex=0;
60 if (!document.forms[0].sqspell_oruse.value)
61 document.forms[0].sqspell_oruse.value=document.forms[0].sqspell_suggestion.options[document.forms[0].sqspell_suggestion.selectedIndex].value;
62 occursTimes = WordLocations.length;
63 if (CurrentLocation) occursTimes += CurrentLocation-1;
64 document.forms[0].sqspell_likethis.value=occursTimes;
65 }
66
67 function updateLine(lLine, lSymbol, lWord, lNewWord){
68 // This function updates the line with new word value
69 sqspell_lines[lLine] = sqspell_lines[lLine].substring(0, lSymbol) + lNewWord + sqspell_lines[lLine].substring(lSymbol+lWord.length, sqspell_lines[lLine].length);
70 if (lWord.length != lNewWord.length)
71 updateSymbol(lLine, lSymbol, lNewWord.length-lWord.length);
72 if (!ChangesMade) ChangesMade=true;
73 }
74
75 function sqspellRemember(){
76 // This function adds the word to the field in the form to be later
77 // submitted and added to the user dictionary.
78 CurrentWord = misses[CurrentError] + "%";
79 document.forms[0].words.value += CurrentWord;
80 sqspellIgnoreAll();
81 }
82
83
84 function sqspellChange(){
85 // Called when pressed the "Change" button
86 CurrentWord = misses[CurrentError];
87 NewWord=document.forms[0].sqspell_oruse.value;
88 updateLine(CurrentLine, CurrentSymbol, CurrentWord, NewWord);
89 proceed();
90 }
91
92 function sqspellChangeAll(){
93 // Called when pressed the "Change All" button
94 allLoc = locations[CurrentError].split(", ");
95 if (allLoc.length==1) {
96 // There's no need to "change all", only one occurance.
97 sqspellChange();
98 return;
99 }
100
101 NewWord=document.forms[0].sqspell_oruse.value;
102 CurrentWord = misses[CurrentError];
103 for (z=CurrentLocation-1; z<allLoc.length; z++){
104 tmp = allLoc[z].split(":");
105 lLine = parseInt(tmp[0]); lSymbol = parseInt(tmp[1]);
106 updateLine(lLine, lSymbol, CurrentWord, NewWord);
107 // Load it again to reflect the changes in symbol data
108 allLoc = locations[CurrentError].split(", ");
109 }
110
111 CurrentLocation=0;
112 proceed();
113 }
114
115 function sqspellIgnore(){
116 // Only here for consistency. Called when pressed the "Ignore" button
117 proceed();
118 }
119
120 function sqspellIgnoreAll(){
121 // Called when pressed the "Ignore All" button
122 CurrentLocation=0;
123 proceed();
124 }
125
126 function clearSqspellForm(){
127 // Clears the options in selectbox "sqspell_suggestions"
128 for (i=0; i<document.forms[0].sqspell_suggestion.length; i++){
129 document.forms[0].sqspell_suggestion.options[i]=null;
130 }
131
132 // Now, I've been instructed by the Netscape Developer docs to call
133 // history.go(0) to refresh the page after I've changed the options.
134 // However, that brings so many pains with it that I just decided not
135 // to do it. It works like it is in Netscape 4.x. If there are problems
136 // in earlier versions of Netscape, then oh well. I'm not THAT anxious
137 // to have it working on all browsers... ;)
138
139 document.forms[0].sqspell_oruse.value="";
140 }
141
142 function proceed(){
143 // Goes on to the next error if any, or finishes.
144 if (!CurrentLocation) CurrentError++;
145 if (misses[CurrentError]){
146 clearSqspellForm();
147 populateSqspellForm();
148 } else {
149 if (ChangesMade || document.forms[0].words.value){
150 if (confirm("SpellCheck complete. Commit Changes?"))
151 sqspellCommitChanges();
152 else self.close();
153 } else {
154 confirm ("No changes were made.");
155 self.close();
156 }
157 }
158 }
159
160 function updateSymbol(lLine, lSymbol, difference){
161 // Now, I will admit that this is not the best way to do stuff,
162 // However that's the solution I've come up with.
163 // This function updates the symbol locations after there have been
164 // word length changes in the lines. Otherwise SquirrelSpell barfs all
165 // over your message... ;)
166 //
167 // If you are wondering why I didn't use two-dimensional arrays instead,
168 // well, sometimes there will be a long line with an error close to the
169 // end of it, so the coordinates would be something like 2,98 and
170 // some Javascript implementations will create 98 empty members of an
171 // array just to have a filled number 98. This is too resource-wasteful
172 // and I have decided to go with the below solution instead. It takes
173 // a little more processing, but it saves a lot on memory.
174
175 for (i=0; i<misses.length; i++){
176 if(locations[i].indexOf(lLine + ":") >= 0){
177 allLoc = locations[i].split(", ");
178 for (j=0; j<allLoc.length; j++){
179 if (allLoc[j].indexOf(lLine+":")==0){
180 tmp = allLoc[j].split(":");
181 tmp[0] = parseInt(tmp[0]); tmp[1] = parseInt(tmp[1]);
182 if (tmp[1] > lSymbol){
183 tmp[1] = tmp[1] + difference;
184 allLoc[j] = tmp.join(":");
185 }
186 }
187 }
188 locations[i] = allLoc.join(", ");
189 }
190 }
191 }
192
193 function sqspellCommitChanges(){
194 // Write the changes back into the compose form
195 if (navigator.appName.indexOf("Microsoft")==0){
196 // MSIE doesn't have array.shift()
197 newSubject = sqspell_lines[0];
198 newBody = "";
199 for (i=1; i<sqspell_lines.length; i++){
200 if (i!=1) newBody+="\r\n";
201 newBody += sqspell_lines[i];
202 }
203 } else {
204 newSubject = sqspell_lines.shift();
205 newBody = sqspell_lines.join("\n");
206 }
207
208 opener.document.forms[0].subject.value=newSubject;
209 opener.document.forms[0].body.value=newBody;
210
211 // See if any words were added to the dictionary.
212 if (document.forms[0].words.value){
213 // yeppers
214 document.forms[0].sqspell_line_area.value="Now saving your personal dictionary... Please wait.";
215 // pass focus to the parent so we can do background save.
216 window.opener.focus();
217 document.forms[0].submit();
218 } else {
219 self.close();
220 }
221 }