Subversion Repositories Applications.papyrus

Rev

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