Rev 4870 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4870 | bpr | 1 | /** |
2 | * Autocompletion class |
||
8476 | bpr | 3 | * |
4870 | bpr | 4 | * An auto completion box appear while you're writing. It's possible to force it to appear with Ctrl+Space short cut |
8476 | bpr | 5 | * |
4870 | bpr | 6 | * Loaded as a plugin inside editArea (everything made here could have been made in the plugin directory) |
7 | * But is definitly linked to syntax selection (no need to do 2 different files for color and auto complete for each syntax language) |
||
8 | * and add a too important feature that many people would miss if included as a plugin |
||
8476 | bpr | 9 | * |
4870 | bpr | 10 | * - init param: autocompletion_start |
11 | * - Button name: "autocompletion" |
||
8476 | bpr | 12 | */ |
4870 | bpr | 13 | |
14 | var EditArea_autocompletion= { |
||
8476 | bpr | 15 | |
4870 | bpr | 16 | /** |
17 | * Get called once this file is loaded (editArea still not initialized) |
||
18 | * |
||
8476 | bpr | 19 | * @return nothing |
20 | */ |
||
21 | init: function(){ |
||
4870 | bpr | 22 | // alert("test init: "+ this._someInternalFunction(2, 3)); |
8476 | bpr | 23 | |
4870 | bpr | 24 | if(editArea.settings["autocompletion"]) |
25 | this.enabled= true; |
||
26 | else |
||
27 | this.enabled= false; |
||
28 | this.current_word = false; |
||
29 | this.shown = false; |
||
30 | this.selectIndex = -1; |
||
31 | this.forceDisplay = false; |
||
32 | this.isInMiddleWord = false; |
||
33 | this.autoSelectIfOneResult = false; |
||
34 | this.delayBeforeDisplay = 100; |
||
35 | this.checkDelayTimer = false; |
||
36 | this.curr_syntax_str = ''; |
||
8476 | bpr | 37 | |
4870 | bpr | 38 | this.file_syntax_datas = {}; |
39 | } |
||
40 | /** |
||
41 | * Returns the HTML code for a specific control string or false if this plugin doesn't have that control. |
||
42 | * A control can be a button, select list or any other HTML item to present in the EditArea user interface. |
||
43 | * Language variables such as {$lang_somekey} will also be replaced with contents from |
||
44 | * the language packs. |
||
8476 | bpr | 45 | * |
46 | * @param {string} ctrl_name: the name of the control to add |
||
4870 | bpr | 47 | * @return HTML code for a specific control or false. |
48 | * @type string or boolean |
||
8476 | bpr | 49 | */ |
4870 | bpr | 50 | /*,get_control_html: function(ctrl_name){ |
51 | switch( ctrl_name ){ |
||
52 | case 'autocompletion': |
||
53 | // Control id, button img, command |
||
54 | return parent.editAreaLoader.get_button_html('autocompletion_but', 'autocompletion.gif', 'toggle_autocompletion', false, this.baseURL); |
||
55 | break; |
||
56 | } |
||
57 | return false; |
||
58 | }*/ |
||
59 | /** |
||
60 | * Get called once EditArea is fully loaded and initialised |
||
8476 | bpr | 61 | * |
4870 | bpr | 62 | * @return nothing |
8476 | bpr | 63 | */ |
64 | ,onload: function(){ |
||
4870 | bpr | 65 | if(this.enabled) |
66 | { |
||
67 | var icon= document.getElementById("autocompletion"); |
||
68 | if(icon) |
||
69 | editArea.switchClassSticky(icon, 'editAreaButtonSelected', true); |
||
70 | } |
||
8476 | bpr | 71 | |
4870 | bpr | 72 | this.container = document.createElement('div'); |
73 | this.container.id = "auto_completion_area"; |
||
74 | editArea.container.insertBefore( this.container, editArea.container.firstChild ); |
||
8476 | bpr | 75 | |
4870 | bpr | 76 | // add event detection for hiding suggestion box |
77 | parent.editAreaLoader.add_event( document, "click", function(){ editArea.plugins['autocompletion']._hide();} ); |
||
78 | parent.editAreaLoader.add_event( editArea.textarea, "blur", function(){ editArea.plugins['autocompletion']._hide();} ); |
||
8476 | bpr | 79 | |
4870 | bpr | 80 | } |
8476 | bpr | 81 | |
4870 | bpr | 82 | /** |
83 | * Is called each time the user touch a keyboard key. |
||
8476 | bpr | 84 | * |
4870 | bpr | 85 | * @param (event) e: the keydown event |
86 | * @return true - pass to next handler in chain, false - stop chain execution |
||
8476 | bpr | 87 | * @type boolean |
4870 | bpr | 88 | */ |
89 | ,onkeydown: function(e){ |
||
90 | if(!this.enabled) |
||
91 | return true; |
||
8476 | bpr | 92 | |
4870 | bpr | 93 | if (EA_keys[e.keyCode]) |
94 | letter=EA_keys[e.keyCode]; |
||
95 | else |
||
8476 | bpr | 96 | letter=String.fromCharCode(e.keyCode); |
4870 | bpr | 97 | // shown |
98 | if( this._isShown() ) |
||
8476 | bpr | 99 | { |
4870 | bpr | 100 | // if escape, hide the box |
101 | if(letter=="Esc") |
||
102 | { |
||
103 | this._hide(); |
||
104 | return false; |
||
105 | } |
||
106 | // Enter |
||
107 | else if( letter=="Entrer") |
||
108 | { |
||
109 | var as = this.container.getElementsByTagName('A'); |
||
110 | // select a suggested entry |
||
111 | if( this.selectIndex >= 0 && this.selectIndex < as.length ) |
||
112 | { |
||
113 | as[ this.selectIndex ].onmousedown(); |
||
114 | return false |
||
115 | } |
||
116 | // simply add an enter in the code |
||
117 | else |
||
118 | { |
||
119 | this._hide(); |
||
120 | return true; |
||
121 | } |
||
122 | } |
||
123 | else if( letter=="Tab" || letter=="Down") |
||
124 | { |
||
125 | this._selectNext(); |
||
126 | return false; |
||
127 | } |
||
128 | else if( letter=="Up") |
||
129 | { |
||
130 | this._selectBefore(); |
||
131 | return false; |
||
132 | } |
||
133 | } |
||
134 | // hidden |
||
135 | else |
||
136 | { |
||
8476 | bpr | 137 | |
4870 | bpr | 138 | } |
8476 | bpr | 139 | |
4870 | bpr | 140 | // show current suggestion list and do autoSelect if possible (no matter it's shown or hidden) |
141 | if( letter=="Space" && CtrlPressed(e) ) |
||
142 | { |
||
143 | //parent.console.log('SHOW SUGGEST'); |
||
144 | this.forceDisplay = true; |
||
145 | this.autoSelectIfOneResult = true; |
||
146 | this._checkLetter(); |
||
147 | return false; |
||
148 | } |
||
8476 | bpr | 149 | |
4870 | bpr | 150 | // wait a short period for check that the cursor isn't moving |
151 | setTimeout("editArea.plugins['autocompletion']._checkDelayAndCursorBeforeDisplay();", editArea.check_line_selection_timer +5 ); |
||
152 | this.checkDelayTimer = false; |
||
153 | return true; |
||
8476 | bpr | 154 | } |
4870 | bpr | 155 | /** |
156 | * Executes a specific command, this function handles plugin commands. |
||
157 | * |
||
158 | * @param {string} cmd: the name of the command being executed |
||
8476 | bpr | 159 | * @param {unknown} param: the parameter of the command |
4870 | bpr | 160 | * @return true - pass to next handler in chain, false - stop chain execution |
8476 | bpr | 161 | * @type boolean |
4870 | bpr | 162 | */ |
163 | ,execCommand: function(cmd, param){ |
||
164 | switch( cmd ){ |
||
165 | case 'toggle_autocompletion': |
||
166 | var icon= document.getElementById("autocompletion"); |
||
167 | if(!this.enabled) |
||
168 | { |
||
169 | if(icon != null){ |
||
170 | editArea.restoreClass(icon); |
||
171 | editArea.switchClassSticky(icon, 'editAreaButtonSelected', true); |
||
172 | } |
||
173 | this.enabled= true; |
||
174 | } |
||
175 | else |
||
176 | { |
||
177 | this.enabled= false; |
||
178 | if(icon != null) |
||
179 | editArea.switchClassSticky(icon, 'editAreaButtonNormal', false); |
||
180 | } |
||
181 | return true; |
||
182 | } |
||
183 | return true; |
||
184 | } |
||
185 | ,_checkDelayAndCursorBeforeDisplay: function() |
||
186 | { |
||
187 | this.checkDelayTimer = setTimeout("if(editArea.textarea.selectionStart == "+ editArea.textarea.selectionStart +") EditArea_autocompletion._checkLetter();", this.delayBeforeDisplay - editArea.check_line_selection_timer - 5 ); |
||
188 | } |
||
189 | // hide the suggested box |
||
190 | ,_hide: function(){ |
||
191 | this.container.style.display="none"; |
||
192 | this.selectIndex = -1; |
||
193 | this.shown = false; |
||
194 | this.forceDisplay = false; |
||
195 | this.autoSelectIfOneResult = false; |
||
196 | } |
||
197 | // display the suggested box |
||
198 | ,_show: function(){ |
||
199 | if( !this._isShown() ) |
||
200 | { |
||
201 | this.container.style.display="block"; |
||
202 | this.selectIndex = -1; |
||
203 | this.shown = true; |
||
204 | } |
||
205 | } |
||
206 | // is the suggested box displayed? |
||
207 | ,_isShown: function(){ |
||
208 | return this.shown; |
||
209 | } |
||
210 | // setter and getter |
||
211 | ,_isInMiddleWord: function( new_value ){ |
||
212 | if( typeof( new_value ) == "undefined" ) |
||
213 | return this.isInMiddleWord; |
||
214 | else |
||
215 | this.isInMiddleWord = new_value; |
||
216 | } |
||
217 | // select the next element in the suggested box |
||
218 | ,_selectNext: function() |
||
219 | { |
||
220 | var as = this.container.getElementsByTagName('A'); |
||
8476 | bpr | 221 | |
4870 | bpr | 222 | // clean existing elements |
223 | for( var i=0; i<as.length; i++ ) |
||
224 | { |
||
225 | if( as[i].className ) |
||
226 | as[i].className = as[i].className.replace(/ focus/g, ''); |
||
227 | } |
||
8476 | bpr | 228 | |
229 | this.selectIndex++; |
||
4870 | bpr | 230 | this.selectIndex = ( this.selectIndex >= as.length || this.selectIndex < 0 ) ? 0 : this.selectIndex; |
231 | as[ this.selectIndex ].className += " focus"; |
||
232 | } |
||
233 | // select the previous element in the suggested box |
||
234 | ,_selectBefore: function() |
||
235 | { |
||
236 | var as = this.container.getElementsByTagName('A'); |
||
8476 | bpr | 237 | |
4870 | bpr | 238 | // clean existing elements |
239 | for( var i=0; i<as.length; i++ ) |
||
240 | { |
||
241 | if( as[i].className ) |
||
242 | as[i].className = as[ i ].className.replace(/ focus/g, ''); |
||
243 | } |
||
8476 | bpr | 244 | |
4870 | bpr | 245 | this.selectIndex--; |
8476 | bpr | 246 | |
4870 | bpr | 247 | this.selectIndex = ( this.selectIndex >= as.length || this.selectIndex < 0 ) ? as.length-1 : this.selectIndex; |
248 | as[ this.selectIndex ].className += " focus"; |
||
249 | } |
||
250 | ,_select: function( content ) |
||
251 | { |
||
252 | cursor_forced_position = content.indexOf( '{@}' ); |
||
253 | content = content.replace(/{@}/g, '' ); |
||
8476 | bpr | 254 | editArea.getIESelection(); |
255 | |||
4870 | bpr | 256 | // retrive the number of matching characters |
257 | var start_index = Math.max( 0, editArea.textarea.selectionEnd - content.length ); |
||
8476 | bpr | 258 | |
4870 | bpr | 259 | line_string = editArea.textarea.value.substring( start_index, editArea.textarea.selectionEnd + 1); |
260 | limit = line_string.length -1; |
||
261 | nbMatch = 0; |
||
262 | for( i =0; i<limit ; i++ ) |
||
263 | { |
||
264 | if( line_string.substring( limit - i - 1, limit ) == content.substring( 0, i + 1 ) ) |
||
265 | nbMatch = i + 1; |
||
266 | } |
||
267 | // if characters match, we should include them in the selection that will be replaced |
||
268 | if( nbMatch > 0 ) |
||
269 | parent.editAreaLoader.setSelectionRange(editArea.id, editArea.textarea.selectionStart - nbMatch , editArea.textarea.selectionEnd); |
||
8476 | bpr | 270 | |
4870 | bpr | 271 | parent.editAreaLoader.setSelectedText(editArea.id, content ); |
272 | range= parent.editAreaLoader.getSelectionRange(editArea.id); |
||
8476 | bpr | 273 | |
4870 | bpr | 274 | if( cursor_forced_position != -1 ) |
275 | new_pos = range["end"] - ( content.length-cursor_forced_position ); |
||
276 | else |
||
8476 | bpr | 277 | new_pos = range["end"]; |
4870 | bpr | 278 | parent.editAreaLoader.setSelectionRange(editArea.id, new_pos, new_pos); |
279 | this._hide(); |
||
280 | } |
||
8476 | bpr | 281 | |
282 | |||
4870 | bpr | 283 | /** |
284 | * Parse the AUTO_COMPLETION part of syntax definition files |
||
285 | */ |
||
286 | ,_parseSyntaxAutoCompletionDatas: function(){ |
||
287 | //foreach syntax loaded |
||
288 | for(var lang in parent.editAreaLoader.load_syntax) |
||
289 | { |
||
290 | if(!parent.editAreaLoader.syntax[lang]['autocompletion']) // init the regexp if not already initialized |
||
291 | { |
||
292 | parent.editAreaLoader.syntax[lang]['autocompletion']= {}; |
||
293 | // the file has auto completion datas |
||
294 | if(parent.editAreaLoader.load_syntax[lang]['AUTO_COMPLETION']) |
||
295 | { |
||
296 | // parse them |
||
297 | for(var i in parent.editAreaLoader.load_syntax[lang]['AUTO_COMPLETION']) |
||
298 | { |
||
299 | datas = parent.editAreaLoader.load_syntax[lang]['AUTO_COMPLETION'][i]; |
||
300 | tmp = {}; |
||
301 | if(datas["CASE_SENSITIVE"]!="undefined" && datas["CASE_SENSITIVE"]==false) |
||
302 | tmp["modifiers"]="i"; |
||
303 | else |
||
304 | tmp["modifiers"]=""; |
||
305 | tmp["prefix_separator"]= datas["REGEXP"]["prefix_separator"]; |
||
306 | tmp["match_prefix_separator"]= new RegExp( datas["REGEXP"]["prefix_separator"] +"$", tmp["modifiers"]); |
||
307 | tmp["match_word"]= new RegExp("(?:"+ datas["REGEXP"]["before_word"] +")("+ datas["REGEXP"]["possible_words_letters"] +")$", tmp["modifiers"]); |
||
308 | tmp["match_next_letter"]= new RegExp("^("+ datas["REGEXP"]["letter_after_word_must_match"] +")$", tmp["modifiers"]); |
||
309 | tmp["keywords"]= {}; |
||
310 | //console.log( datas["KEYWORDS"] ); |
||
311 | for( var prefix in datas["KEYWORDS"] ) |
||
312 | { |
||
313 | tmp["keywords"][prefix]= { |
||
314 | prefix: prefix, |
||
315 | prefix_name: prefix, |
||
316 | prefix_reg: new RegExp("(?:"+ parent.editAreaLoader.get_escaped_regexp( prefix ) +")(?:"+ tmp["prefix_separator"] +")$", tmp["modifiers"] ), |
||
317 | datas: [] |
||
318 | }; |
||
319 | for( var j=0; j<datas["KEYWORDS"][prefix].length; j++ ) |
||
320 | { |
||
321 | tmp["keywords"][prefix]['datas'][j]= { |
||
322 | is_typing: datas["KEYWORDS"][prefix][j][0], |
||
323 | // if replace with is empty, replace with the is_typing value |
||
324 | replace_with: datas["KEYWORDS"][prefix][j][1] ? datas["KEYWORDS"][prefix][j][1].replace('§', datas["KEYWORDS"][prefix][j][0] ) : '', |
||
8476 | bpr | 325 | comment: datas["KEYWORDS"][prefix][j][2] ? datas["KEYWORDS"][prefix][j][2] : '' |
4870 | bpr | 326 | }; |
8476 | bpr | 327 | |
4870 | bpr | 328 | // the replace with shouldn't be empty |
329 | if( tmp["keywords"][prefix]['datas'][j]['replace_with'].length == 0 ) |
||
330 | tmp["keywords"][prefix]['datas'][j]['replace_with'] = tmp["keywords"][prefix]['datas'][j]['is_typing']; |
||
8476 | bpr | 331 | |
4870 | bpr | 332 | // if the comment is empty, display the replace_with value |
333 | if( tmp["keywords"][prefix]['datas'][j]['comment'].length == 0 ) |
||
334 | tmp["keywords"][prefix]['datas'][j]['comment'] = tmp["keywords"][prefix]['datas'][j]['replace_with'].replace(/{@}/g, '' ); |
||
335 | } |
||
8476 | bpr | 336 | |
4870 | bpr | 337 | } |
338 | tmp["max_text_length"]= datas["MAX_TEXT_LENGTH"]; |
||
339 | parent.editAreaLoader.syntax[lang]['autocompletion'][i] = tmp; |
||
340 | } |
||
341 | } |
||
342 | } |
||
343 | } |
||
344 | } |
||
8476 | bpr | 345 | |
4870 | bpr | 346 | ,_checkLetter: function(){ |
347 | // check that syntax hasn't changed |
||
348 | if( this.curr_syntax_str != editArea.settings['syntax'] ) |
||
349 | { |
||
350 | if( !parent.editAreaLoader.syntax[editArea.settings['syntax']]['autocompletion'] ) |
||
351 | this._parseSyntaxAutoCompletionDatas(); |
||
352 | this.curr_syntax= parent.editAreaLoader.syntax[editArea.settings['syntax']]['autocompletion']; |
||
353 | this.curr_syntax_str = editArea.settings['syntax']; |
||
354 | //console.log( this.curr_syntax ); |
||
355 | } |
||
8476 | bpr | 356 | |
4870 | bpr | 357 | if( editArea.is_editable ) |
358 | { |
||
359 | time=new Date; |
||
360 | t1= time.getTime(); |
||
361 | if(editArea.isIE) |
||
362 | editArea.getIESelection(); |
||
363 | this.selectIndex = -1; |
||
364 | start=editArea.textarea.selectionStart; |
||
365 | var str = editArea.textarea.value; |
||
366 | var results= []; |
||
8476 | bpr | 367 | |
368 | |||
4870 | bpr | 369 | for(var i in this.curr_syntax) |
370 | { |
||
371 | var last_chars = str.substring(Math.max(0, start-this.curr_syntax[i]["max_text_length"]), start); |
||
372 | var matchNextletter = str.substring(start, start+1).match( this.curr_syntax[i]["match_next_letter"]); |
||
373 | // if not writting in the middle of a word or if forcing display |
||
374 | if( matchNextletter || this.forceDisplay ) |
||
375 | { |
||
376 | // check if the last chars match a separator |
||
377 | var match_prefix_separator = last_chars.match(this.curr_syntax[i]["match_prefix_separator"]); |
||
8476 | bpr | 378 | |
4870 | bpr | 379 | // check if it match a possible word |
380 | var match_word= last_chars.match(this.curr_syntax[i]["match_word"]); |
||
8476 | bpr | 381 | |
4870 | bpr | 382 | //console.log( match_word ); |
383 | if( match_word ) |
||
384 | { |
||
385 | var begin_word= match_word[1]; |
||
386 | var match_curr_word= new RegExp("^"+ parent.editAreaLoader.get_escaped_regexp( begin_word ), this.curr_syntax[i]["modifiers"]); |
||
387 | //console.log( match_curr_word ); |
||
388 | for(var prefix in this.curr_syntax[i]["keywords"]) |
||
389 | { |
||
390 | // parent.console.log( this.curr_syntax[i]["keywords"][prefix] ); |
||
391 | for(var j=0; j<this.curr_syntax[i]["keywords"][prefix]['datas'].length; j++) |
||
392 | { |
||
393 | // parent.console.log( this.curr_syntax[i]["keywords"][prefix]['datas'][j]['is_typing'] ); |
||
8476 | bpr | 394 | // the key word match or force display |
4870 | bpr | 395 | if( this.curr_syntax[i]["keywords"][prefix]['datas'][j]['is_typing'].match(match_curr_word) ) |
396 | { |
||
397 | // parent.console.log('match'); |
||
398 | hasMatch = false; |
||
399 | var before = last_chars.substr( 0, last_chars.length - begin_word.length ); |
||
8476 | bpr | 400 | |
4870 | bpr | 401 | // no prefix to match => it's valid |
402 | if( !match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length == 0 ) |
||
403 | { |
||
404 | if( ! before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) ) |
||
405 | hasMatch = true; |
||
406 | } |
||
407 | // we still need to check the prefix if there is one |
||
408 | else if( this.curr_syntax[i]["keywords"][prefix]['prefix'].length > 0 ) |
||
409 | { |
||
410 | if( before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) ) |
||
411 | hasMatch = true; |
||
412 | } |
||
8476 | bpr | 413 | |
4870 | bpr | 414 | if( hasMatch ) |
415 | results[results.length]= [ this.curr_syntax[i]["keywords"][prefix], this.curr_syntax[i]["keywords"][prefix]['datas'][j] ]; |
||
8476 | bpr | 416 | } |
4870 | bpr | 417 | } |
418 | } |
||
419 | } |
||
420 | // it doesn't match any possible word but we want to display something |
||
421 | // we'll display to list of all available words |
||
422 | else if( this.forceDisplay || match_prefix_separator ) |
||
423 | { |
||
424 | for(var prefix in this.curr_syntax[i]["keywords"]) |
||
425 | { |
||
426 | for(var j=0; j<this.curr_syntax[i]["keywords"][prefix]['datas'].length; j++) |
||
427 | { |
||
428 | hasMatch = false; |
||
429 | // no prefix to match => it's valid |
||
430 | if( !match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length == 0 ) |
||
431 | { |
||
432 | hasMatch = true; |
||
433 | } |
||
434 | // we still need to check the prefix if there is one |
||
435 | else if( match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length > 0 ) |
||
436 | { |
||
437 | var before = last_chars; //.substr( 0, last_chars.length ); |
||
438 | if( before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) ) |
||
439 | hasMatch = true; |
||
8476 | bpr | 440 | } |
441 | |||
4870 | bpr | 442 | if( hasMatch ) |
8476 | bpr | 443 | results[results.length]= [ this.curr_syntax[i]["keywords"][prefix], this.curr_syntax[i]["keywords"][prefix]['datas'][j] ]; |
4870 | bpr | 444 | } |
445 | } |
||
446 | } |
||
447 | } |
||
448 | } |
||
8476 | bpr | 449 | |
4870 | bpr | 450 | // there is only one result, and we can select it automatically |
451 | if( results.length == 1 && this.autoSelectIfOneResult ) |
||
452 | { |
||
453 | // console.log( results ); |
||
454 | this._select( results[0][1]['replace_with'] ); |
||
455 | } |
||
456 | else if( results.length == 0 ) |
||
457 | { |
||
458 | this._hide(); |
||
459 | } |
||
460 | else |
||
461 | { |
||
462 | // build the suggestion box content |
||
463 | var lines=[]; |
||
464 | for(var i=0; i<results.length; i++) |
||
465 | { |
||
466 | var line= "<li><a href=\"#\" class=\"entry\" onmousedown=\"EditArea_autocompletion._select('"+ results[i][1]['replace_with'].replace(new RegExp('"', "g"), """) +"');return false;\">"+ results[i][1]['comment']; |
||
467 | if(results[i][0]['prefix_name'].length>0) |
||
468 | line+='<span class="prefix">'+ results[i][0]['prefix_name'] +'</span>'; |
||
469 | line+='</a></li>'; |
||
470 | lines[lines.length]=line; |
||
471 | } |
||
472 | // sort results |
||
473 | this.container.innerHTML = '<ul>'+ lines.sort().join('') +'</ul>'; |
||
8476 | bpr | 474 | |
4870 | bpr | 475 | var cursor = _$("cursor_pos"); |
476 | this.container.style.top = ( cursor.cursor_top + editArea.lineHeight ) +"px"; |
||
477 | this.container.style.left = ( cursor.cursor_left + 8 ) +"px"; |
||
478 | this._show(); |
||
479 | } |
||
8476 | bpr | 480 | |
4870 | bpr | 481 | this.autoSelectIfOneResult = false; |
482 | time=new Date; |
||
483 | t2= time.getTime(); |
||
8476 | bpr | 484 | |
4870 | bpr | 485 | //parent.console.log( begin_word +"\n"+ (t2-t1) +"\n"+ html ); |
486 | } |
||
487 | } |
||
488 | }; |
||
489 | |||
490 | // Load as a plugin |
||
491 | editArea.settings['plugins'][ editArea.settings['plugins'].length ] = 'autocompletion'; |
||
8476 | bpr | 492 | editArea.add_plugin('autocompletion', EditArea_autocompletion); |