editarea-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);