editarea-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/LICENSE.txt +22 -0
  2. data/README.md +31 -0
  3. data/lib/editarea-rails.rb +8 -0
  4. data/lib/editarea-rails/version.rb +5 -0
  5. data/vendor/assets/images/autocompletion.gif +0 -0
  6. data/vendor/assets/images/close.gif +0 -0
  7. data/vendor/assets/images/fullscreen.gif +0 -0
  8. data/vendor/assets/images/go_to_line.gif +0 -0
  9. data/vendor/assets/images/help.gif +0 -0
  10. data/vendor/assets/images/highlight.gif +0 -0
  11. data/vendor/assets/images/load.gif +0 -0
  12. data/vendor/assets/images/move.gif +0 -0
  13. data/vendor/assets/images/newdocument.gif +0 -0
  14. data/vendor/assets/images/opacity.png +0 -0
  15. data/vendor/assets/images/plugins/charmap/charmap.gif +0 -0
  16. data/vendor/assets/images/plugins/test/css/test.css +3 -0
  17. data/vendor/assets/images/plugins/test/images/Thumbs.db +0 -0
  18. data/vendor/assets/images/plugins/test/images/test.gif +0 -0
  19. data/vendor/assets/images/plugins/test/langs/bg.js +10 -0
  20. data/vendor/assets/images/plugins/test/langs/cs.js +4 -0
  21. data/vendor/assets/images/plugins/test/langs/de.js +4 -0
  22. data/vendor/assets/images/plugins/test/langs/dk.js +4 -0
  23. data/vendor/assets/images/plugins/test/langs/en.js +4 -0
  24. data/vendor/assets/images/plugins/test/langs/eo.js +4 -0
  25. data/vendor/assets/images/plugins/test/langs/es.js +4 -0
  26. data/vendor/assets/images/plugins/test/langs/fr.js +4 -0
  27. data/vendor/assets/images/plugins/test/langs/hr.js +4 -0
  28. data/vendor/assets/images/plugins/test/langs/it.js +4 -0
  29. data/vendor/assets/images/plugins/test/langs/ja.js +4 -0
  30. data/vendor/assets/images/plugins/test/langs/mk.js +4 -0
  31. data/vendor/assets/images/plugins/test/langs/nl.js +4 -0
  32. data/vendor/assets/images/plugins/test/langs/pl.js +4 -0
  33. data/vendor/assets/images/plugins/test/langs/pt.js +4 -0
  34. data/vendor/assets/images/plugins/test/langs/ru.js +4 -0
  35. data/vendor/assets/images/plugins/test/langs/sk.js +4 -0
  36. data/vendor/assets/images/plugins/test/langs/zh.js +4 -0
  37. data/vendor/assets/images/plugins/test/test.js +110 -0
  38. data/vendor/assets/images/plugins/test/test2.js +1 -0
  39. data/vendor/assets/images/processing.gif +0 -0
  40. data/vendor/assets/images/redo.gif +0 -0
  41. data/vendor/assets/images/reset_highlight.gif +0 -0
  42. data/vendor/assets/images/save.gif +0 -0
  43. data/vendor/assets/images/search.gif +0 -0
  44. data/vendor/assets/images/smooth_selection.gif +0 -0
  45. data/vendor/assets/images/spacer.gif +0 -0
  46. data/vendor/assets/images/statusbar_resize.gif +0 -0
  47. data/vendor/assets/images/undo.gif +0 -0
  48. data/vendor/assets/images/word_wrap.gif +0 -0
  49. data/vendor/assets/javascripts/autocompletion.js +491 -0
  50. data/vendor/assets/javascripts/edit_area.js +527 -0
  51. data/vendor/assets/javascripts/edit_area_full.js +38 -0
  52. data/vendor/assets/javascripts/edit_area_functions.js +1202 -0
  53. data/vendor/assets/javascripts/edit_area_loader.js +1081 -0
  54. data/vendor/assets/javascripts/elements_functions.js +336 -0
  55. data/vendor/assets/javascripts/highlight.js +407 -0
  56. data/vendor/assets/javascripts/keyboard.js +145 -0
  57. data/vendor/assets/javascripts/langs/bg.js +54 -0
  58. data/vendor/assets/javascripts/langs/cs.js +48 -0
  59. data/vendor/assets/javascripts/langs/de.js +48 -0
  60. data/vendor/assets/javascripts/langs/dk.js +48 -0
  61. data/vendor/assets/javascripts/langs/en.js +48 -0
  62. data/vendor/assets/javascripts/langs/eo.js +48 -0
  63. data/vendor/assets/javascripts/langs/es.js +48 -0
  64. data/vendor/assets/javascripts/langs/fi.js +48 -0
  65. data/vendor/assets/javascripts/langs/fr.js +48 -0
  66. data/vendor/assets/javascripts/langs/hr.js +48 -0
  67. data/vendor/assets/javascripts/langs/it.js +48 -0
  68. data/vendor/assets/javascripts/langs/ja.js +48 -0
  69. data/vendor/assets/javascripts/langs/mk.js +48 -0
  70. data/vendor/assets/javascripts/langs/nl.js +48 -0
  71. data/vendor/assets/javascripts/langs/pl.js +48 -0
  72. data/vendor/assets/javascripts/langs/pt.js +48 -0
  73. data/vendor/assets/javascripts/langs/ru.js +48 -0
  74. data/vendor/assets/javascripts/langs/sk.js +48 -0
  75. data/vendor/assets/javascripts/langs/zh.js +48 -0
  76. data/vendor/assets/javascripts/manage_area.js +623 -0
  77. data/vendor/assets/javascripts/plugins/charmap/charmap.js +90 -0
  78. data/vendor/assets/javascripts/plugins/charmap/jscripts/map.js +373 -0
  79. data/vendor/assets/javascripts/plugins/charmap/langs/bg.js +12 -0
  80. data/vendor/assets/javascripts/plugins/charmap/langs/cs.js +6 -0
  81. data/vendor/assets/javascripts/plugins/charmap/langs/de.js +6 -0
  82. data/vendor/assets/javascripts/plugins/charmap/langs/dk.js +6 -0
  83. data/vendor/assets/javascripts/plugins/charmap/langs/en.js +6 -0
  84. data/vendor/assets/javascripts/plugins/charmap/langs/eo.js +6 -0
  85. data/vendor/assets/javascripts/plugins/charmap/langs/es.js +6 -0
  86. data/vendor/assets/javascripts/plugins/charmap/langs/fr.js +6 -0
  87. data/vendor/assets/javascripts/plugins/charmap/langs/hr.js +6 -0
  88. data/vendor/assets/javascripts/plugins/charmap/langs/it.js +6 -0
  89. data/vendor/assets/javascripts/plugins/charmap/langs/ja.js +6 -0
  90. data/vendor/assets/javascripts/plugins/charmap/langs/mk.js +6 -0
  91. data/vendor/assets/javascripts/plugins/charmap/langs/nl.js +6 -0
  92. data/vendor/assets/javascripts/plugins/charmap/langs/pl.js +6 -0
  93. data/vendor/assets/javascripts/plugins/charmap/langs/pt.js +6 -0
  94. data/vendor/assets/javascripts/plugins/charmap/langs/ru.js +6 -0
  95. data/vendor/assets/javascripts/plugins/charmap/langs/sk.js +6 -0
  96. data/vendor/assets/javascripts/plugins/charmap/langs/zh.js +6 -0
  97. data/vendor/assets/javascripts/plugins/charmap/popup.html +24 -0
  98. data/vendor/assets/javascripts/plugins/test/langs/bg.js +10 -0
  99. data/vendor/assets/javascripts/plugins/test/langs/cs.js +4 -0
  100. data/vendor/assets/javascripts/plugins/test/langs/de.js +4 -0
  101. data/vendor/assets/javascripts/plugins/test/langs/dk.js +4 -0
  102. data/vendor/assets/javascripts/plugins/test/langs/en.js +4 -0
  103. data/vendor/assets/javascripts/plugins/test/langs/eo.js +4 -0
  104. data/vendor/assets/javascripts/plugins/test/langs/es.js +4 -0
  105. data/vendor/assets/javascripts/plugins/test/langs/fr.js +4 -0
  106. data/vendor/assets/javascripts/plugins/test/langs/hr.js +4 -0
  107. data/vendor/assets/javascripts/plugins/test/langs/it.js +4 -0
  108. data/vendor/assets/javascripts/plugins/test/langs/ja.js +4 -0
  109. data/vendor/assets/javascripts/plugins/test/langs/mk.js +4 -0
  110. data/vendor/assets/javascripts/plugins/test/langs/nl.js +4 -0
  111. data/vendor/assets/javascripts/plugins/test/langs/pl.js +4 -0
  112. data/vendor/assets/javascripts/plugins/test/langs/pt.js +4 -0
  113. data/vendor/assets/javascripts/plugins/test/langs/ru.js +4 -0
  114. data/vendor/assets/javascripts/plugins/test/langs/sk.js +4 -0
  115. data/vendor/assets/javascripts/plugins/test/langs/zh.js +4 -0
  116. data/vendor/assets/javascripts/plugins/test/test.js +110 -0
  117. data/vendor/assets/javascripts/plugins/test/test2.js +1 -0
  118. data/vendor/assets/javascripts/reg_syntax.js +166 -0
  119. data/vendor/assets/javascripts/reg_syntax/basic.js +70 -0
  120. data/vendor/assets/javascripts/reg_syntax/brainfuck.js +45 -0
  121. data/vendor/assets/javascripts/reg_syntax/c.js +63 -0
  122. data/vendor/assets/javascripts/reg_syntax/coldfusion.js +120 -0
  123. data/vendor/assets/javascripts/reg_syntax/cpp.js +66 -0
  124. data/vendor/assets/javascripts/reg_syntax/css.js +85 -0
  125. data/vendor/assets/javascripts/reg_syntax/html.js +51 -0
  126. data/vendor/assets/javascripts/reg_syntax/java.js +57 -0
  127. data/vendor/assets/javascripts/reg_syntax/js.js +94 -0
  128. data/vendor/assets/javascripts/reg_syntax/pas.js +83 -0
  129. data/vendor/assets/javascripts/reg_syntax/perl.js +88 -0
  130. data/vendor/assets/javascripts/reg_syntax/php.js +157 -0
  131. data/vendor/assets/javascripts/reg_syntax/python.js +145 -0
  132. data/vendor/assets/javascripts/reg_syntax/robotstxt.js +25 -0
  133. data/vendor/assets/javascripts/reg_syntax/ruby.js +68 -0
  134. data/vendor/assets/javascripts/reg_syntax/sql.js +56 -0
  135. data/vendor/assets/javascripts/reg_syntax/tsql.js +88 -0
  136. data/vendor/assets/javascripts/reg_syntax/vb.js +53 -0
  137. data/vendor/assets/javascripts/reg_syntax/xml.js +57 -0
  138. data/vendor/assets/javascripts/regexp.js +139 -0
  139. data/vendor/assets/javascripts/resize_area.js +73 -0
  140. data/vendor/assets/javascripts/search_replace.js +174 -0
  141. data/vendor/assets/stylesheets/edit_area.css +530 -0
  142. data/vendor/assets/stylesheets/plugins/charmap/css/charmap.css +64 -0
  143. data/vendor/assets/stylesheets/plugins/test/css/test.css +3 -0
  144. metadata +210 -0
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jun
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Editarea::Rails
2
+
3
+ Gem for editarea
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'editarea-rails'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install editarea-rails
19
+
20
+ ## Usage
21
+
22
+ //= require edit_area_full
23
+
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
@@ -0,0 +1,8 @@
1
+ require "editarea-rails/version"
2
+
3
+ module Editarea
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Editarea
2
+ module Rails
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,3 @@
1
+ select#test_select{
2
+ background-color: #FF0000;
3
+ }
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Bulgarian translation
3
+ * Author: Valentin Hristov
4
+ * Company: SOFTKIT Bulgarian
5
+ * Site: http://www.softkit-bg.com
6
+ */
7
+ editArea.add_lang("bg",{
8
+ test_select: "избери таг",
9
+ test_but: "тествай копието"
10
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("cs",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("de",{
2
+ test_select: "Tag ausw&auml;hlen",
3
+ test_but: "Test Button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("dk",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("en",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("eo",{
2
+ test_select:"elekto de marko",
3
+ test_but: "provo-butono"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("es",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("fr",{
2
+ test_select:"choix balise",
3
+ test_but: "bouton de test"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("hr",{
2
+ test_select: "Odaberi tag",
3
+ test_but: "Probna tipka"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("it",{
2
+ test_select: "seleziona tag",
3
+ test_but: "pulsante di test"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("ja",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("mk",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("nl",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("pl",{
2
+ test_select: "wybierz tag",
3
+ test_but: "test"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("pt",{
2
+ test_select: "select tag",
3
+ test_but: "test button"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("ru",{
2
+ test_select: "выбрать тэг",
3
+ test_but: "тестировать кнопку"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("sk",{
2
+ test_select: "vyber tag",
3
+ test_but: "testovacie tlačidlo"
4
+ });
@@ -0,0 +1,4 @@
1
+ editArea.add_lang("zh",{
2
+ test_select: "选择标签",
3
+ test_but: "测试按钮"
4
+ });
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Plugin designed for test prupose. It add a button (that manage an alert) and a select (that allow to insert tags) in the toolbar.
3
+ * This plugin also disable the "f" key in the editarea, and load a CSS and a JS file
4
+ */
5
+ var EditArea_test= {
6
+ /**
7
+ * Get called once this file is loaded (editArea still not initialized)
8
+ *
9
+ * @return nothing
10
+ */
11
+ init: function(){
12
+ // alert("test init: "+ this._someInternalFunction(2, 3));
13
+ editArea.load_css(this.baseURL+"css/test.css");
14
+ editArea.load_script(this.baseURL+"test2.js");
15
+ }
16
+ /**
17
+ * Returns the HTML code for a specific control string or false if this plugin doesn't have that control.
18
+ * A control can be a button, select list or any other HTML item to present in the EditArea user interface.
19
+ * Language variables such as {$lang_somekey} will also be replaced with contents from
20
+ * the language packs.
21
+ *
22
+ * @param {string} ctrl_name: the name of the control to add
23
+ * @return HTML code for a specific control or false.
24
+ * @type string or boolean
25
+ */
26
+ ,get_control_html: function(ctrl_name){
27
+ switch(ctrl_name){
28
+ case "test_but":
29
+ // Control id, button img, command
30
+ return parent.editAreaLoader.get_button_html('test_but', 'test.gif', 'test_cmd', false, this.baseURL);
31
+ case "test_select":
32
+ html= "<select id='test_select' onchange='javascript:editArea.execCommand(\"test_select_change\")' fileSpecific='no'>"
33
+ +" <option value='-1'>{$test_select}</option>"
34
+ +" <option value='h1'>h1</option>"
35
+ +" <option value='h2'>h2</option>"
36
+ +" <option value='h3'>h3</option>"
37
+ +" <option value='h4'>h4</option>"
38
+ +" <option value='h5'>h5</option>"
39
+ +" <option value='h6'>h6</option>"
40
+ +" </select>";
41
+ return html;
42
+ }
43
+ return false;
44
+ }
45
+ /**
46
+ * Get called once EditArea is fully loaded and initialised
47
+ *
48
+ * @return nothing
49
+ */
50
+ ,onload: function(){
51
+ alert("test load");
52
+ }
53
+
54
+ /**
55
+ * Is called each time the user touch a keyboard key.
56
+ *
57
+ * @param (event) e: the keydown event
58
+ * @return true - pass to next handler in chain, false - stop chain execution
59
+ * @type boolean
60
+ */
61
+ ,onkeydown: function(e){
62
+ var str= String.fromCharCode(e.keyCode);
63
+ // desactivate the "f" character
64
+ if(str.toLowerCase()=="f"){
65
+ return true;
66
+ }
67
+ return false;
68
+ }
69
+
70
+ /**
71
+ * Executes a specific command, this function handles plugin commands.
72
+ *
73
+ * @param {string} cmd: the name of the command being executed
74
+ * @param {unknown} param: the parameter of the command
75
+ * @return true - pass to next handler in chain, false - stop chain execution
76
+ * @type boolean
77
+ */
78
+ ,execCommand: function(cmd, param){
79
+ // Handle commands
80
+ switch(cmd){
81
+ case "test_select_change":
82
+ var val= document.getElementById("test_select").value;
83
+ if(val!=-1)
84
+ parent.editAreaLoader.insertTags(editArea.id, "<"+val+">", "</"+val+">");
85
+ document.getElementById("test_select").options[0].selected=true;
86
+ return false;
87
+ case "test_cmd":
88
+ alert("user clicked on test_cmd");
89
+ return false;
90
+ }
91
+ // Pass to next handler in chain
92
+ return true;
93
+ }
94
+
95
+ /**
96
+ * This is just an internal plugin method, prefix all internal methods with a _ character.
97
+ * The prefix is needed so they doesn't collide with future EditArea callback functions.
98
+ *
99
+ * @param {string} a Some arg1.
100
+ * @param {string} b Some arg2.
101
+ * @return Some return.
102
+ * @type unknown
103
+ */
104
+ ,_someInternalFunction : function(a, b) {
105
+ return a+b;
106
+ }
107
+ };
108
+
109
+ // Adds the plugin class to the list of available EditArea plugins
110
+ editArea.add_plugin("test", EditArea_test);
@@ -0,0 +1 @@
1
+ alert("test2.js is loaded from test plugin");
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,491 @@
1
+ /**
2
+ * Autocompletion class
3
+ *
4
+ * An auto completion box appear while you're writing. It's possible to force it to appear with Ctrl+Space short cut
5
+ *
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
9
+ *
10
+ * - init param: autocompletion_start
11
+ * - Button name: "autocompletion"
12
+ */
13
+
14
+ var EditArea_autocompletion= {
15
+
16
+ /**
17
+ * Get called once this file is loaded (editArea still not initialized)
18
+ *
19
+ * @return nothing
20
+ */
21
+ init: function(){
22
+ // alert("test init: "+ this._someInternalFunction(2, 3));
23
+
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 = '';
37
+
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.
45
+ *
46
+ * @param {string} ctrl_name: the name of the control to add
47
+ * @return HTML code for a specific control or false.
48
+ * @type string or boolean
49
+ */
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
61
+ *
62
+ * @return nothing
63
+ */
64
+ ,onload: function(){
65
+ if(this.enabled)
66
+ {
67
+ var icon= document.getElementById("autocompletion");
68
+ if(icon)
69
+ editArea.switchClassSticky(icon, 'editAreaButtonSelected', true);
70
+ }
71
+
72
+ this.container = document.createElement('div');
73
+ this.container.id = "auto_completion_area";
74
+ editArea.container.insertBefore( this.container, editArea.container.firstChild );
75
+
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();} );
79
+
80
+ }
81
+
82
+ /**
83
+ * Is called each time the user touch a keyboard key.
84
+ *
85
+ * @param (event) e: the keydown event
86
+ * @return true - pass to next handler in chain, false - stop chain execution
87
+ * @type boolean
88
+ */
89
+ ,onkeydown: function(e){
90
+ if(!this.enabled)
91
+ return true;
92
+
93
+ if (EA_keys[e.keyCode])
94
+ letter=EA_keys[e.keyCode];
95
+ else
96
+ letter=String.fromCharCode(e.keyCode);
97
+ // shown
98
+ if( this._isShown() )
99
+ {
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
+ {
137
+
138
+ }
139
+
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
+ }
149
+
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;
154
+ }
155
+ /**
156
+ * Executes a specific command, this function handles plugin commands.
157
+ *
158
+ * @param {string} cmd: the name of the command being executed
159
+ * @param {unknown} param: the parameter of the command
160
+ * @return true - pass to next handler in chain, false - stop chain execution
161
+ * @type boolean
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');
221
+
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
+ }
228
+
229
+ this.selectIndex++;
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');
237
+
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
+ }
244
+
245
+ this.selectIndex--;
246
+
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, '' );
254
+ editArea.getIESelection();
255
+
256
+ // retrive the number of matching characters
257
+ var start_index = Math.max( 0, editArea.textarea.selectionEnd - content.length );
258
+
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);
270
+
271
+ parent.editAreaLoader.setSelectedText(editArea.id, content );
272
+ range= parent.editAreaLoader.getSelectionRange(editArea.id);
273
+
274
+ if( cursor_forced_position != -1 )
275
+ new_pos = range["end"] - ( content.length-cursor_forced_position );
276
+ else
277
+ new_pos = range["end"];
278
+ parent.editAreaLoader.setSelectionRange(editArea.id, new_pos, new_pos);
279
+ this._hide();
280
+ }
281
+
282
+
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] ) : '',
325
+ comment: datas["KEYWORDS"][prefix][j][2] ? datas["KEYWORDS"][prefix][j][2] : ''
326
+ };
327
+
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'];
331
+
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
+ }
336
+
337
+ }
338
+ tmp["max_text_length"]= datas["MAX_TEXT_LENGTH"];
339
+ parent.editAreaLoader.syntax[lang]['autocompletion'][i] = tmp;
340
+ }
341
+ }
342
+ }
343
+ }
344
+ }
345
+
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
+ }
356
+
357
+ if( editArea.is_editable )
358
+ {
359
+ time=new Date;
360
+ t1= time.getTime();
361
+ editArea.getIESelection();
362
+ this.selectIndex = -1;
363
+ start=editArea.textarea.selectionStart;
364
+ var str = editArea.textarea.value;
365
+ var results= [];
366
+
367
+
368
+ for(var i in this.curr_syntax)
369
+ {
370
+ var last_chars = str.substring(Math.max(0, start-this.curr_syntax[i]["max_text_length"]), start);
371
+ var matchNextletter = str.substring(start, start+1).match( this.curr_syntax[i]["match_next_letter"]);
372
+ // if not writting in the middle of a word or if forcing display
373
+ if( matchNextletter || this.forceDisplay )
374
+ {
375
+ // check if the last chars match a separator
376
+ var match_prefix_separator = last_chars.match(this.curr_syntax[i]["match_prefix_separator"]);
377
+
378
+ // check if it match a possible word
379
+ var match_word= last_chars.match(this.curr_syntax[i]["match_word"]);
380
+
381
+ //console.log( match_word );
382
+ if( match_word )
383
+ {
384
+ var begin_word= match_word[1];
385
+ var match_curr_word= new RegExp("^"+ parent.editAreaLoader.get_escaped_regexp( begin_word ), this.curr_syntax[i]["modifiers"]);
386
+ //console.log( match_curr_word );
387
+ for(var prefix in this.curr_syntax[i]["keywords"])
388
+ {
389
+ // parent.console.log( this.curr_syntax[i]["keywords"][prefix] );
390
+ for(var j=0; j<this.curr_syntax[i]["keywords"][prefix]['datas'].length; j++)
391
+ {
392
+ // parent.console.log( this.curr_syntax[i]["keywords"][prefix]['datas'][j]['is_typing'] );
393
+ // the key word match or force display
394
+ if( this.curr_syntax[i]["keywords"][prefix]['datas'][j]['is_typing'].match(match_curr_word) )
395
+ {
396
+ // parent.console.log('match');
397
+ hasMatch = false;
398
+ var before = last_chars.substr( 0, last_chars.length - begin_word.length );
399
+
400
+ // no prefix to match => it's valid
401
+ if( !match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length == 0 )
402
+ {
403
+ if( ! before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) )
404
+ hasMatch = true;
405
+ }
406
+ // we still need to check the prefix if there is one
407
+ else if( this.curr_syntax[i]["keywords"][prefix]['prefix'].length > 0 )
408
+ {
409
+ if( before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) )
410
+ hasMatch = true;
411
+ }
412
+
413
+ if( hasMatch )
414
+ results[results.length]= [ this.curr_syntax[i]["keywords"][prefix], this.curr_syntax[i]["keywords"][prefix]['datas'][j] ];
415
+ }
416
+ }
417
+ }
418
+ }
419
+ // it doesn't match any possible word but we want to display something
420
+ // we'll display to list of all available words
421
+ else if( this.forceDisplay || match_prefix_separator )
422
+ {
423
+ for(var prefix in this.curr_syntax[i]["keywords"])
424
+ {
425
+ for(var j=0; j<this.curr_syntax[i]["keywords"][prefix]['datas'].length; j++)
426
+ {
427
+ hasMatch = false;
428
+ // no prefix to match => it's valid
429
+ if( !match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length == 0 )
430
+ {
431
+ hasMatch = true;
432
+ }
433
+ // we still need to check the prefix if there is one
434
+ else if( match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length > 0 )
435
+ {
436
+ var before = last_chars; //.substr( 0, last_chars.length );
437
+ if( before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) )
438
+ hasMatch = true;
439
+ }
440
+
441
+ if( hasMatch )
442
+ results[results.length]= [ this.curr_syntax[i]["keywords"][prefix], this.curr_syntax[i]["keywords"][prefix]['datas'][j] ];
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
448
+
449
+ // there is only one result, and we can select it automatically
450
+ if( results.length == 1 && this.autoSelectIfOneResult )
451
+ {
452
+ // console.log( results );
453
+ this._select( results[0][1]['replace_with'] );
454
+ }
455
+ else if( results.length == 0 )
456
+ {
457
+ this._hide();
458
+ }
459
+ else
460
+ {
461
+ // build the suggestion box content
462
+ var lines=[];
463
+ for(var i=0; i<results.length; i++)
464
+ {
465
+ var line= "<li><a href=\"#\" class=\"entry\" onmousedown=\"EditArea_autocompletion._select('"+ results[i][1]['replace_with'].replace(new RegExp('"', "g"), "&quot;") +"');return false;\">"+ results[i][1]['comment'];
466
+ if(results[i][0]['prefix_name'].length>0)
467
+ line+='<span class="prefix">'+ results[i][0]['prefix_name'] +'</span>';
468
+ line+='</a></li>';
469
+ lines[lines.length]=line;
470
+ }
471
+ // sort results
472
+ this.container.innerHTML = '<ul>'+ lines.sort().join('') +'</ul>';
473
+
474
+ var cursor = _$("cursor_pos");
475
+ this.container.style.top = ( cursor.cursor_top + editArea.lineHeight ) +"px";
476
+ this.container.style.left = ( cursor.cursor_left + 8 ) +"px";
477
+ this._show();
478
+ }
479
+
480
+ this.autoSelectIfOneResult = false;
481
+ time=new Date;
482
+ t2= time.getTime();
483
+
484
+ //parent.console.log( begin_word +"\n"+ (t2-t1) +"\n"+ html );
485
+ }
486
+ }
487
+ };
488
+
489
+ // Load as a plugin
490
+ editArea.settings['plugins'][ editArea.settings['plugins'].length ] = 'autocompletion';
491
+ editArea.add_plugin('autocompletion', EditArea_autocompletion);