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. ;))
10 var CurrentLocation
=0;
14 var ChangesMade
=false;
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) {
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
];
34 if (CurrentSymbol
> 40){
35 StartWith
=CurrentSymbol
-40;
38 EndWith
=LineValue
.length
;
40 if (EndWith
> CurrentSymbol
+ 40){
41 EndWith
=CurrentSymbol
+40;
44 NewLineValue
+=LineValue
.substring(StartWith
, CurrentSymbol
) + "*" + Word
+ "*" + LineValue
.substring(CurrentSymbol
+ Word
.length
, EndWith
) + EndLine
;
45 document
.forms
[0].sqspell_line_area
.value
=NewLineValue
;
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
]);
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();
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
;
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;
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
;
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
);
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.
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(", ");
115 function sqspellIgnore(){
116 // Only here for consistency. Called when pressed the "Ignore" button
120 function sqspellIgnoreAll(){
121 // Called when pressed the "Ignore All" button
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;
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... ;)
139 document
.forms
[0].sqspell_oruse
.value
="";
143 // Goes on to the next error if any, or finishes.
144 if (!CurrentLocation
) CurrentError
++;
145 if (misses
[CurrentError
]){
147 populateSqspellForm();
149 if (ChangesMade
|| document
.forms
[0].words
.value
){
150 if (confirm("SpellCheck complete. Commit Changes?"))
151 sqspellCommitChanges();
154 confirm ("No changes were made.");
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... ;)
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.
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(":");
188 locations
[i
] = allLoc
.join(", ");
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];
199 for (i
=1; i
<sqspell_lines
.length
; i
++){
200 if (i
!=1) newBody
+="\r\n";
201 newBody
+= sqspell_lines
[i
];
204 newSubject
= sqspell_lines
.shift();
205 newBody
= sqspell_lines
.join("\n");
208 opener
.document
.forms
[0].subject
.value
=newSubject
;
209 opener
.document
.forms
[0].body
.value
=newBody
;
211 // See if any words were added to the dictionary.
212 if (document
.forms
[0].words
.value
){
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();