Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1075 ddelon 1
////////////////////////////////////////////////////
2
// spellChecker.js
3
//
4
// spellChecker object
5
//
6
// This file is sourced on web pages that have a textarea object to evaluate
7
// for spelling. It includes the implementation for the spellCheckObject.
8
//
9
////////////////////////////////////////////////////
10
 
11
 
12
// constructor
13
function spellChecker( textObject ) {
14
 
15
	// public properties - configurable
16
//	this.popUpUrl = '/speller/spellchecker.html';							// by FredCK
17
	this.popUpUrl = 'fck_spellerpages/spellerpages/spellchecker.html';		// by FredCK
18
	this.popUpName = 'spellchecker';
19
//	this.popUpProps = "menu=no,width=440,height=350,top=70,left=120,resizable=yes,status=yes";	// by FredCK
20
	this.popUpProps = null ;																	// by FredCK
21
//	this.spellCheckScript = '/speller/server-scripts/spellchecker.php';		// by FredCK
22
	this.spellCheckScript = 'server-scripts/spellchecker.php';				// by FredCK
23
	//this.spellCheckScript = '/cgi-bin/spellchecker.pl';
24
 
25
	// values used to keep track of what happened to a word
26
	this.replWordFlag = "R";	// single replace
27
	this.ignrWordFlag = "I";	// single ignore
28
	this.replAllFlag = "RA";	// replace all occurances
29
	this.ignrAllFlag = "IA";	// ignore all occurances
30
	this.fromReplAll = "~RA";	// an occurance of a "replace all" word
31
	this.fromIgnrAll = "~IA";	// an occurance of a "ignore all" word
32
	// properties set at run time
33
	this.wordFlags = new Array();
34
	this.currentTextIndex = 0;
35
	this.currentWordIndex = 0;
36
	this.spellCheckerWin = null;
37
	this.controlWin = null;
38
	this.wordWin = null;
39
	this.textArea = textObject;	// deprecated
40
	this.textInputs = arguments;
41
 
42
	// private methods
43
	this._spellcheck = _spellcheck;
44
	this._getSuggestions = _getSuggestions;
45
	this._setAsIgnored = _setAsIgnored;
46
	this._getTotalReplaced = _getTotalReplaced;
47
	this._setWordText = _setWordText;
48
	this._getFormInputs = _getFormInputs;
49
 
50
	// public methods
51
	this.openChecker = openChecker;
52
	this.startCheck = startCheck;
53
	this.checkTextBoxes = checkTextBoxes;
54
	this.checkTextAreas = checkTextAreas;
55
	this.spellCheckAll = spellCheckAll;
56
	this.ignoreWord = ignoreWord;
57
	this.ignoreAll = ignoreAll;
58
	this.replaceWord = replaceWord;
59
	this.replaceAll = replaceAll;
60
	this.terminateSpell = terminateSpell;
61
	this.undo = undo;
62
 
63
	// set the current window's "speller" property to the instance of this class.
64
	// this object can now be referenced by child windows/frames.
65
	window.speller = this;
66
}
67
 
68
// call this method to check all text boxes (and only text boxes) in the HTML document
69
function checkTextBoxes() {
70
	this.textInputs = this._getFormInputs( "^text$" );
71
	this.openChecker();
72
}
73
 
74
// call this method to check all textareas (and only textareas ) in the HTML document
75
function checkTextAreas() {
76
	this.textInputs = this._getFormInputs( "^textarea$" );
77
	this.openChecker();
78
}
79
 
80
// call this method to check all text boxes and textareas in the HTML document
81
function spellCheckAll() {
82
	this.textInputs = this._getFormInputs( "^text(area)?$" );
83
	this.openChecker();
84
}
85
 
86
// call this method to check text boxe(s) and/or textarea(s) that were passed in to the
87
// object's constructor or to the textInputs property
88
function openChecker() {
89
	this.spellCheckerWin = window.open( this.popUpUrl, this.popUpName, this.popUpProps );
90
	if( !this.spellCheckerWin.opener ) {
91
		this.spellCheckerWin.opener = window;
92
	}
93
}
94
 
95
function startCheck( wordWindowObj, controlWindowObj ) {
96
 
97
	// set properties from args
98
	this.wordWin = wordWindowObj;
99
	this.controlWin = controlWindowObj;
100
 
101
	// reset properties
102
	this.wordWin.resetForm();
103
	this.controlWin.resetForm();
104
	this.currentTextIndex = 0;
105
	this.currentWordIndex = 0;
106
	// initialize the flags to an array - one element for each text input
107
	this.wordFlags = new Array( this.wordWin.textInputs.length );
108
	// each element will be an array that keeps track of each word in the text
109
	for( var i=0; i<this.wordFlags.length; i++ ) {
110
		this.wordFlags[i] = [];
111
	}
112
 
113
	// start
114
	this._spellcheck();
115
 
116
	return true;
117
}
118
 
119
function ignoreWord() {
120
	var wi = this.currentWordIndex;
121
	var ti = this.currentTextIndex;
122
	if( !this.wordWin ) {
123
		alert( 'Error: Word frame not available.' );
124
		return false;
125
	}
126
	if( !this.wordWin.getTextVal( ti, wi )) {
127
		alert( 'Error: "Not in dictionary" text is missing.' );
128
		return false;
129
	}
130
	// set as ignored
131
	if( this._setAsIgnored( ti, wi, this.ignrWordFlag )) {
132
		this.currentWordIndex++;
133
		this._spellcheck();
134
	}
135
}
136
 
137
function ignoreAll() {
138
	var wi = this.currentWordIndex;
139
	var ti = this.currentTextIndex;
140
	if( !this.wordWin ) {
141
		alert( 'Error: Word frame not available.' );
142
		return false;
143
	}
144
	// get the word that is currently being evaluated.
145
	var s_word_to_repl = this.wordWin.getTextVal( ti, wi );
146
	if( !s_word_to_repl ) {
147
		alert( 'Error: "Not in dictionary" text is missing' );
148
		return false;
149
	}
150
 
151
	// set this word as an "ignore all" word.
152
	this._setAsIgnored( ti, wi, this.ignrAllFlag );
153
 
154
	// loop through all the words after this word
155
	for( var i = ti; i < this.wordWin.textInputs.length; i++ ) {
156
		for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
157
			if(( i == ti && j > wi ) || i > ti ) {
158
				// future word: set as "from ignore all" if
159
				// 1) do not already have a flag and
160
				// 2) have the same value as current word
161
				if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl )
162
				&& ( !this.wordFlags[i][j] )) {
163
					this._setAsIgnored( i, j, this.fromIgnrAll );
164
				}
165
			}
166
		}
167
	}
168
 
169
	// finally, move on
170
	this.currentWordIndex++;
171
	this._spellcheck();
172
}
173
 
174
function replaceWord() {
175
	var wi = this.currentWordIndex;
176
	var ti = this.currentTextIndex;
177
	if( !this.wordWin ) {
178
		alert( 'Error: Word frame not available.' );
179
		return false;
180
	}
181
	if( !this.wordWin.getTextVal( ti, wi )) {
182
		alert( 'Error: "Not in dictionary" text is missing' );
183
		return false;
184
	}
185
	if( !this.controlWin.replacementText ) {
186
		return;
187
	}
188
	var txt = this.controlWin.replacementText;
189
	if( txt.value ) {
190
		var newspell = new String( txt.value );
191
		if( this._setWordText( ti, wi, newspell, this.replWordFlag )) {
192
			this.currentWordIndex++;
193
			this._spellcheck();
194
		}
195
	}
196
}
197
 
198
function replaceAll() {
199
	var ti = this.currentTextIndex;
200
	var wi = this.currentWordIndex;
201
	if( !this.wordWin ) {
202
		alert( 'Error: Word frame not available.' );
203
		return false;
204
	}
205
	var s_word_to_repl = this.wordWin.getTextVal( ti, wi );
206
	if( !s_word_to_repl ) {
207
		alert( 'Error: "Not in dictionary" text is missing' );
208
		return false;
209
	}
210
	var txt = this.controlWin.replacementText;
211
	if( !txt.value ) return;
212
	var newspell = new String( txt.value );
213
 
214
	// set this word as a "replace all" word.
215
	this._setWordText( ti, wi, newspell, this.replAllFlag );
216
 
217
	// loop through all the words after this word
218
	for( var i = ti; i < this.wordWin.textInputs.length; i++ ) {
219
		for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
220
			if(( i == ti && j > wi ) || i > ti ) {
221
				// future word: set word text to s_word_to_repl if
222
				// 1) do not already have a flag and
223
				// 2) have the same value as s_word_to_repl
224
				if(( this.wordWin.getTextVal( i, j ) == s_word_to_repl )
225
				&& ( !this.wordFlags[i][j] )) {
226
					this._setWordText( i, j, newspell, this.fromReplAll );
227
				}
228
			}
229
		}
230
	}
231
 
232
	// finally, move on
233
	this.currentWordIndex++;
234
	this._spellcheck();
235
}
236
 
237
function terminateSpell() {
238
	// called when we have reached the end of the spell checking.
239
	var msg = "";		// by FredCK
240
	var numrepl = this._getTotalReplaced();
241
	if( numrepl == 0 ) {
242
		// see if there were no misspellings to begin with
243
		if( !this.wordWin ) {
244
			msg = "";
245
		} else {
246
			if( this.wordWin.totalMisspellings() ) {
247
//				msg += "No words changed.";			// by FredCK
248
				msg += FCKLang.DlgSpellNoChanges ;	// by FredCK
249
			} else {
250
//				msg += "No misspellings found.";	// by FredCK
251
				msg += FCKLang.DlgSpellNoMispell ;	// by FredCK
252
			}
253
		}
254
	} else if( numrepl == 1 ) {
255
//		msg += "One word changed.";			// by FredCK
256
		msg += FCKLang.DlgSpellOneChange ;	// by FredCK
257
	} else {
258
//		msg += numrepl + " words changed.";	// by FredCK
259
		msg += FCKLang.DlgSpellManyChanges.replace( /%1/g, numrepl ) ;
260
	}
261
	if( msg ) {
262
//		msg += "\n";	// by FredCK
263
		alert( msg );
264
	}
265
 
266
	if( numrepl > 0 ) {
267
		// update the text field(s) on the opener window
268
		for( var i = 0; i < this.textInputs.length; i++ ) {
269
			// this.textArea.value = this.wordWin.text;
270
			if( this.wordWin ) {
271
				if( this.wordWin.textInputs[i] ) {
272
					this.textInputs[i].value = this.wordWin.textInputs[i];
273
				}
274
			}
275
		}
276
	}
277
 
278
	// return back to the calling window
279
//	this.spellCheckerWin.close();					// by FredCK
280
	if ( typeof( this.OnFinished ) == 'function' )	// by FredCK
281
		this.OnFinished(numrepl) ;					// by FredCK
282
 
283
	return true;
284
}
285
 
286
function undo() {
287
	// skip if this is the first word!
288
	var ti = this.currentTextIndex;
289
	var wi = this.currentWordIndex
290
 
291
	if( this.wordWin.totalPreviousWords( ti, wi ) > 0 ) {
292
		this.wordWin.removeFocus( ti, wi );
293
 
294
		// go back to the last word index that was acted upon
295
		do {
296
			// if the current word index is zero then reset the seed
297
			if( this.currentWordIndex == 0 && this.currentTextIndex > 0 ) {
298
				this.currentTextIndex--;
299
				this.currentWordIndex = this.wordWin.totalWords( this.currentTextIndex )-1;
300
				if( this.currentWordIndex < 0 ) this.currentWordIndex = 0;
301
			} else {
302
				if( this.currentWordIndex > 0 ) {
303
					this.currentWordIndex--;
304
				}
305
			}
306
		} while (
307
			this.wordWin.totalWords( this.currentTextIndex ) == 0
308
			|| this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromIgnrAll
309
			|| this.wordFlags[this.currentTextIndex][this.currentWordIndex] == this.fromReplAll
310
		);
311
 
312
		var text_idx = this.currentTextIndex;
313
		var idx = this.currentWordIndex;
314
		var preReplSpell = this.wordWin.originalSpellings[text_idx][idx];
315
 
316
		// if we got back to the first word then set the Undo button back to disabled
317
		if( this.wordWin.totalPreviousWords( text_idx, idx ) == 0 ) {
318
			this.controlWin.disableUndo();
319
		}
320
 
321
		// examine what happened to this current word.
322
		switch( this.wordFlags[text_idx][idx] ) {
323
			// replace all: go through this and all the future occurances of the word
324
			// and revert them all to the original spelling and clear their flags
325
			case this.replAllFlag :
326
				for( var i = text_idx; i < this.wordWin.textInputs.length; i++ ) {
327
					for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
328
						if(( i == text_idx && j >= idx ) || i > text_idx ) {
329
							var origSpell = this.wordWin.originalSpellings[i][j];
330
							if( origSpell == preReplSpell ) {
331
								this._setWordText ( i, j, origSpell, undefined );
332
							}
333
						}
334
					}
335
				}
336
				break;
337
 
338
			// ignore all: go through all the future occurances of the word
339
			// and clear their flags
340
			case this.ignrAllFlag :
341
				for( var i = text_idx; i < this.wordWin.textInputs.length; i++ ) {
342
					for( var j = 0; j < this.wordWin.totalWords( i ); j++ ) {
343
						if(( i == text_idx && j >= idx ) || i > text_idx ) {
344
							var origSpell = this.wordWin.originalSpellings[i][j];
345
							if( origSpell == preReplSpell ) {
346
								this.wordFlags[i][j] = undefined;
347
							}
348
						}
349
					}
350
				}
351
				break;
352
 
353
			// replace: revert the word to its original spelling
354
			case this.replWordFlag :
355
				this._setWordText ( text_idx, idx, preReplSpell, undefined );
356
				break;
357
		}
358
 
359
		// For all four cases, clear the wordFlag of this word. re-start the process
360
		this.wordFlags[text_idx][idx] = undefined;
361
		this._spellcheck();
362
	}
363
}
364
 
365
function _spellcheck() {
366
	var ww = this.wordWin;
367
 
368
	// check if this is the last word in the current text element
369
	if( this.currentWordIndex == ww.totalWords( this.currentTextIndex) ) {
370
		this.currentTextIndex++;
371
		this.currentWordIndex = 0;
372
		// keep going if we're not yet past the last text element
373
		if( this.currentTextIndex < this.wordWin.textInputs.length ) {
374
			this._spellcheck();
375
			return;
376
		} else {
377
			this.terminateSpell();
378
			return;
379
		}
380
	}
381
 
382
	// if this is after the first one make sure the Undo button is enabled
383
	if( this.currentWordIndex > 0 ) {
384
		this.controlWin.enableUndo();
385
	}
386
 
387
	// skip the current word if it has already been worked on
388
	if( this.wordFlags[this.currentTextIndex][this.currentWordIndex] ) {
389
		// increment the global current word index and move on.
390
		this.currentWordIndex++;
391
		this._spellcheck();
392
	} else {
393
		var evalText = ww.getTextVal( this.currentTextIndex, this.currentWordIndex );
394
		if( evalText ) {
395
			this.controlWin.evaluatedText.value = evalText;
396
			ww.setFocus( this.currentTextIndex, this.currentWordIndex );
397
			this._getSuggestions( this.currentTextIndex, this.currentWordIndex );
398
		}
399
	}
400
}
401
 
402
function _getSuggestions( text_num, word_num ) {
403
	this.controlWin.clearSuggestions();
404
	// add suggestion in list for each suggested word.
405
	// get the array of suggested words out of the
406
	// three-dimensional array containing all suggestions.
407
	var a_suggests = this.wordWin.suggestions[text_num][word_num];
408
	if( a_suggests ) {
409
		// got an array of suggestions.
410
		for( var ii = 0; ii < a_suggests.length; ii++ ) {
411
			this.controlWin.addSuggestion( a_suggests[ii] );
412
		}
413
	}
414
	this.controlWin.selectDefaultSuggestion();
415
}
416
 
417
function _setAsIgnored( text_num, word_num, flag ) {
418
	// set the UI
419
	this.wordWin.removeFocus( text_num, word_num );
420
	// do the bookkeeping
421
	this.wordFlags[text_num][word_num] = flag;
422
	return true;
423
}
424
 
425
function _getTotalReplaced() {
426
	var i_replaced = 0;
427
	for( var i = 0; i < this.wordFlags.length; i++ ) {
428
		for( var j = 0; j < this.wordFlags[i].length; j++ ) {
429
			if(( this.wordFlags[i][j] == this.replWordFlag )
430
			|| ( this.wordFlags[i][j] == this.replAllFlag )
431
			|| ( this.wordFlags[i][j] == this.fromReplAll )) {
432
				i_replaced++;
433
			}
434
		}
435
	}
436
	return i_replaced;
437
}
438
 
439
function _setWordText( text_num, word_num, newText, flag ) {
440
	// set the UI and form inputs
441
	this.wordWin.setText( text_num, word_num, newText );
442
	// keep track of what happened to this word:
443
	this.wordFlags[text_num][word_num] = flag;
444
	return true;
445
}
446
 
447
function _getFormInputs( inputPattern ) {
448
	var inputs = new Array();
449
	for( var i = 0; i < document.forms.length; i++ ) {
450
		for( var j = 0; j < document.forms[i].elements.length; j++ ) {
451
			if( document.forms[i].elements[j].type.match( inputPattern )) {
452
				inputs[inputs.length] = document.forms[i].elements[j];
453
			}
454
		}
455
	}
456
	return inputs;
457
}
458