weekly release 1.9.12+
[moodle.git] / lib / speller / wordWindow.js
blob553b9c49ebf55e233495cfd4da9ee71278fe5088
1 ////////////////////////////////////////////////////
2 // wordWindow object
3 ////////////////////////////////////////////////////
4 function wordWindow() {
5         // private properties
6         this._forms = [];
8         // private methods
9         this._getWordObject = _getWordObject;
10         //this._getSpellerObject = _getSpellerObject;
11         this._wordInputStr = _wordInputStr;
12         this._adjustIndexes = _adjustIndexes;
13         this._isWordChar = _isWordChar;
14         this._lastPos = _lastPos;
15         
16         // public properties
17         this.wordChar = /[a-zA-Z]/;
18         this.windowType = "wordWindow";
19         this.originalSpellings = new Array();
20         this.suggestions = new Array();
21         this.checkWordBgColor = "pink";
22         this.normWordBgColor = "white";
23         this.text = "";
24         this.textInputs = new Array();
25         this.indexes = new Array();
26         //this.speller = this._getSpellerObject();
28         // public methods
29         this.resetForm = resetForm;
30         this.totalMisspellings = totalMisspellings;
31         this.totalWords = totalWords;
32         this.totalPreviousWords = totalPreviousWords;
33         //this.getTextObjectArray = getTextObjectArray;
34         this.getTextVal = getTextVal;
35         this.setFocus = setFocus;
36         this.removeFocus = removeFocus;
37         this.setText = setText;
38         //this.getTotalWords = getTotalWords;
39         this.writeBody = writeBody;
40         this.printForHtml = printForHtml;
43 function resetForm() {
44         if( this._forms ) {
45                 for( var i = 0; i < this._forms.length; i++ ) {
46                         this._forms[i].reset();
47                 }
48         }
49         return true;
52 function totalMisspellings() {
53         var total_words = 0;
54         for( var i = 0; i < this.textInputs.length; i++ ) {
55                 total_words += this.totalWords( i );
56         }
57         return total_words;
60 function totalWords( textIndex ) {
61         return this.originalSpellings[textIndex].length;
64 function totalPreviousWords( textIndex, wordIndex ) {
65         var total_words = 0;
66         for( var i = 0; i <= textIndex; i++ ) {
67                 for( var j = 0; j < this.totalWords( i ); j++ ) {
68                         if( i == textIndex && j == wordIndex ) {
69                                 break;
70                         } else {
71                                 total_words++;
72                         }       
73                 }
74         }
75         return total_words;
78 //function getTextObjectArray() {
79 //      return this._form.elements;
80 //}
82 function getTextVal( textIndex, wordIndex ) {
83         var word = this._getWordObject( textIndex, wordIndex );
84         if( word ) {
85                 return word.value;
86         }
89 function setFocus( textIndex, wordIndex ) {
90         var word = this._getWordObject( textIndex, wordIndex );
91         if( word ) {
92                 if( word.type == "text" ) {
93                         word.focus();
94                         word.style.backgroundColor = this.checkWordBgColor;
95                 }
96         }
99 function removeFocus( textIndex, wordIndex ) {
100         var word = this._getWordObject( textIndex, wordIndex );
101         if( word ) {
102                 if( word.type == "text" ) {
103                         word.blur();
104                         word.style.backgroundColor = this.normWordBgColor;
105                 }
106         }
109 function setText( textIndex, wordIndex, newText ) {
110         var word = this._getWordObject( textIndex, wordIndex );
111         var beginStr;
112         var endStr;
113         if( word ) {
114                 var pos = this.indexes[textIndex][wordIndex];
115                 var oldText = word.value;
116                 // update the text given the index of the string
117                 beginStr = this.textInputs[textIndex].substring( 0, pos );
118                 endStr = this.textInputs[textIndex].substring( 
119                         pos + oldText.length, 
120                         this.textInputs[textIndex].length 
121                 );
122                 this.textInputs[textIndex] = beginStr + newText + endStr;
123                 
124                 // adjust the indexes on the stack given the differences in 
125                 // length between the new word and old word. 
126                 var lengthDiff = newText.length - oldText.length;
127                 this._adjustIndexes( textIndex, wordIndex, lengthDiff );
128                 
129                 word.size = newText.length;
130                 word.value = newText;
131                 this.removeFocus( textIndex, wordIndex );
132         }
136 function writeBody() {
137         var d = window.document;
138         var is_html = false;
140         d.open();
142         // iterate through each text input.
143         for( var txtid = 0; txtid < this.textInputs.length; txtid++ ) { 
144                 var end_idx = 0;
145                 var begin_idx = 0;      
146                 d.writeln( '<form name="textInput'+txtid+'">' );
147                 var wordtxt = this.textInputs[txtid];
148                 this.indexes[txtid] = [];
150                 if( wordtxt ) {                 
151                         var orig = this.originalSpellings[txtid];
152                         if( !orig ) break;
154                         //!!! plain text, or HTML mode?
155                         d.writeln( '<div class="plainText">' );
156                         // iterate through each occurrence of a misspelled word. 
157                         for( var i = 0; i < orig.length; i++ ) {
158                                 // find the position of the current misspelled word,
159                                 // starting at the last misspelled word. 
160                                 // and keep looking if it's a substring of another word
161                                 do {
162                                         begin_idx = wordtxt.indexOf( orig[i], end_idx );
163                                         end_idx = begin_idx + orig[i].length;
164                                         // word not found? messed up!
165                                         if( begin_idx == -1 ) break; 
166                                         // look at the characters immediately before and after 
167                                         // the word. If they are word characters we'll keep looking.
168                                         var before_char = wordtxt.charAt( begin_idx - 1 );
169                                         var after_char = wordtxt.charAt( end_idx );
170                                 } while ( 
171                                         this._isWordChar( before_char ) 
172                                         || this._isWordChar( after_char )
173                                 );
175                                 // keep track of its position in the original text. 
176                                 this.indexes[txtid][i] = begin_idx;
178                                 // write out the characters before the current misspelled word
179                                 for( var j = this._lastPos( txtid, i ); j < begin_idx; j++ ) {
180                                         // !!! html mode? make it html compatible
181                                         d.write( this.printForHtml( wordtxt.charAt( j )));
182                                 }
184                                 // write out the misspelled word. 
185                                 d.write( this._wordInputStr( orig[i] ));
187                                 // if it's the last word, write out the rest of the text
188                                 if( i == orig.length-1 ){
189                                         d.write( printForHtml( wordtxt.substr( end_idx )));
190                                 }                       
191                         }
193                         d.writeln( '</div>' );
194                         
195                 }
196                 d.writeln( '</form>' );
197         }
198         //for ( var j = 0; j < d.forms.length; j++ ) {
199         //      alert( d.forms[j].name );
200         //      for( var k = 0; k < d.forms[j].elements.length; k++ ) {
201         //              alert( d.forms[j].elements[k].name + ": " + d.forms[j].elements[k].value );
202         //      }
203         //}     
204         
205         // set the _forms property
206         this._forms = d.forms;
207         d.close();
210 // return the character index in the full text after the last word we evaluated
211 function _lastPos( txtid, idx ) {
212         if( idx > 0 )
213                 return this.indexes[txtid][idx-1] + this.originalSpellings[txtid][idx-1].length;
214         else
215                 return 0;
218 function printForHtml( n ) {
219         var htmlstr = n;
220         if( htmlstr.length == 1 ) {
221                 // do simple case statement if it's just one character
222                 switch ( n ) {
223                         case "\n":
224                                 htmlstr = '<br/>';
225                                 break;
226                         case "<":
227                                 htmlstr = '&lt;';
228                                 break;
229                         case ">":
230                                 htmlstr = '&gt;';
231                                 break;
232                 }
233                 return htmlstr;
234         } else {
235                 htmlstr = htmlstr.replace( /</g, '&lt' );
236                 htmlstr = htmlstr.replace( />/g, '&gt' );
237                 htmlstr = htmlstr.replace( /\n/g, '<br/>' );
238                 return htmlstr;
239         }
242 function _isWordChar( letter ) {
243         if( letter.search( this.wordChar ) == -1 ) {
244                 return false;
245         } else {
246                 return true;
247         }
250 function _getWordObject( textIndex, wordIndex ) {
251         if( this._forms[textIndex] ) {
252                 if( this._forms[textIndex].elements[wordIndex] ) {
253                         return this._forms[textIndex].elements[wordIndex];
254                 }
255         }
256         return null;
259 function _wordInputStr( word ) {
260         var str = '<input readonly ';
261         str += 'class="blend" type="text" value="' + word + '" size="' + word.length + '" />';
262         return str;
265 function _adjustIndexes( textIndex, wordIndex, lengthDiff ) {
266         for( var i = wordIndex + 1; i < this.originalSpellings[textIndex].length; i++ ) {
267                 this.indexes[textIndex][i] = this.indexes[textIndex][i] + lengthDiff;
268         }