qwik2md 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. checksums.yaml +4 -4
  2. data/lib/qwik2md/version.rb +1 -1
  3. data/vendor/qwik/lib/qwik/act-christel.rb +1 -1
  4. data/vendor/qwik/lib/qwik/page-get.rb +4 -4
  5. data/vendor/qwik/lib/qwik/util-filename.rb +2 -5
  6. data/vendor/qwik/lib/qwik/util-string.rb +7 -7
  7. data/vendor/qwik/share/super/FrontPage.txt +17 -0
  8. data/vendor/qwik/share/super/QwikWebPlugin.txt +0 -0
  9. data/vendor/qwik/share/super/QwikWebStructure.txt +0 -0
  10. data/vendor/qwik/share/super/RecentList.txt +2 -0
  11. data/vendor/qwik/share/super/SandBox.txt +3 -0
  12. data/vendor/qwik/share/super/TextFormat.txt +186 -0
  13. data/vendor/qwik/share/super/TextFormatSimple.txt +23 -0
  14. data/vendor/qwik/share/super/TitleList.txt +2 -0
  15. data/vendor/qwik/share/super/_AdminMenu.txt +11 -0
  16. data/vendor/qwik/share/super/_BookSearch.txt +3 -0
  17. data/vendor/qwik/share/super/_EditorFooter.txt +9 -0
  18. data/vendor/qwik/share/super/_EditorHelp.txt +9 -0
  19. data/vendor/qwik/share/super/_InterWikiName.txt +17 -0
  20. data/vendor/qwik/share/super/_IsbnLink.txt +8 -0
  21. data/vendor/qwik/share/super/_MemberAdd.txt +4 -0
  22. data/vendor/qwik/share/super/_MemberList.txt +2 -0
  23. data/vendor/qwik/share/super/_MemberListCSV.txt +2 -0
  24. data/vendor/qwik/share/super/_PageAttribute.txt +7 -0
  25. data/vendor/qwik/share/super/_SideMenu.txt +15 -0
  26. data/vendor/qwik/share/super/_SiteConfig.txt +30 -0
  27. data/vendor/qwik/share/super/_SiteFooter.txt +3 -0
  28. data/vendor/qwik/share/super/_SiteLog.txt +0 -0
  29. data/vendor/qwik/share/super/_SiteLogView.txt +2 -0
  30. data/vendor/qwik/share/super/_SiteMember.txt +0 -0
  31. data/vendor/qwik/share/super/_SiteMenu.txt +2 -0
  32. data/vendor/qwik/share/super/_SiteSearch.txt +3 -0
  33. data/vendor/qwik/share/super/_SiteTheme.txt +9 -0
  34. data/vendor/qwik/share/super/_textformat.txt +2 -0
  35. data/vendor/qwik/share/template/Makefile +10 -0
  36. data/vendor/qwik/share/template/edit.html +22 -0
  37. data/vendor/qwik/share/template/edit.rb +40 -0
  38. data/vendor/qwik/share/template/editor.html +23 -0
  39. data/vendor/qwik/share/template/editor.rb +47 -0
  40. data/vendor/qwik/share/template/notice.html +21 -0
  41. data/vendor/qwik/share/template/notice.rb +43 -0
  42. data/vendor/qwik/share/template/plain.html +19 -0
  43. data/vendor/qwik/share/template/plain.rb +43 -0
  44. data/vendor/qwik/share/template/surface.html +22 -0
  45. data/vendor/qwik/share/template/surface.rb +50 -0
  46. data/vendor/qwik/share/template/system.html +30 -0
  47. data/vendor/qwik/share/template/system.rb +46 -0
  48. data/vendor/qwik/share/template/view.html +20 -0
  49. data/vendor/qwik/share/template/view.rb +40 -0
  50. data/vendor/qwik/share/theme/css/Makefile +10 -0
  51. data/vendor/qwik/share/theme/css/base.css +779 -0
  52. data/vendor/qwik/share/theme/css/delete.png +0 -0
  53. data/vendor/qwik/share/theme/css/menu.css +77 -0
  54. data/vendor/qwik/share/theme/css/wema.css +141 -0
  55. data/vendor/qwik/share/theme/i/a.gif +0 -0
  56. data/vendor/qwik/share/theme/i/binary.gif +0 -0
  57. data/vendor/qwik/share/theme/i/broken.gif +0 -0
  58. data/vendor/qwik/share/theme/i/compressed.gif +0 -0
  59. data/vendor/qwik/share/theme/i/external.png +0 -0
  60. data/vendor/qwik/share/theme/i/external_hover.png +0 -0
  61. data/vendor/qwik/share/theme/i/favicon.ico +0 -0
  62. data/vendor/qwik/share/theme/i/favicon.png +0 -0
  63. data/vendor/qwik/share/theme/i/generic.gif +0 -0
  64. data/vendor/qwik/share/theme/i/image2.gif +0 -0
  65. data/vendor/qwik/share/theme/i/login_bg.gif +0 -0
  66. data/vendor/qwik/share/theme/i/login_inputform_bg.gif +0 -0
  67. data/vendor/qwik/share/theme/i/login_inputform_bg_footer.gif +0 -0
  68. data/vendor/qwik/share/theme/i/login_inputform_bg_header.gif +0 -0
  69. data/vendor/qwik/share/theme/i/login_li.gif +0 -0
  70. data/vendor/qwik/share/theme/i/login_qwik_logo.gif +0 -0
  71. data/vendor/qwik/share/theme/i/movie.gif +0 -0
  72. data/vendor/qwik/share/theme/i/new.png +0 -0
  73. data/vendor/qwik/share/theme/i/pdf.gif +0 -0
  74. data/vendor/qwik/share/theme/i/ps.gif +0 -0
  75. data/vendor/qwik/share/theme/i/sound2.gif +0 -0
  76. data/vendor/qwik/share/theme/i/sphere2.gif +0 -0
  77. data/vendor/qwik/share/theme/i/tar.gif +0 -0
  78. data/vendor/qwik/share/theme/i/text.gif +0 -0
  79. data/vendor/qwik/share/theme/js/Makefile +23 -0
  80. data/vendor/qwik/share/theme/js/base.js +176 -0
  81. data/vendor/qwik/share/theme/js/builder.js +101 -0
  82. data/vendor/qwik/share/theme/js/controls.js +750 -0
  83. data/vendor/qwik/share/theme/js/debugwindow-test.html +60 -0
  84. data/vendor/qwik/share/theme/js/debugwindow.html +24 -0
  85. data/vendor/qwik/share/theme/js/debugwindow.js +476 -0
  86. data/vendor/qwik/share/theme/js/dragdrop.js +559 -0
  87. data/vendor/qwik/share/theme/js/effects.js +904 -0
  88. data/vendor/qwik/share/theme/js/event.js +98 -0
  89. data/vendor/qwik/share/theme/js/history.js +110 -0
  90. data/vendor/qwik/share/theme/js/menu.js +27 -0
  91. data/vendor/qwik/share/theme/js/monitor.js +96 -0
  92. data/vendor/qwik/share/theme/js/niftypp.js +272 -0
  93. data/vendor/qwik/share/theme/js/prototype.js +1758 -0
  94. data/vendor/qwik/share/theme/js/scriptaculous.js +48 -0
  95. data/vendor/qwik/share/theme/js/se_hilite_jp.js +234 -0
  96. data/vendor/qwik/share/theme/js/slider.js +275 -0
  97. data/vendor/qwik/share/theme/js/test-all.html +24 -0
  98. data/vendor/qwik/share/theme/js/test-debug.html +56 -0
  99. data/vendor/qwik/share/theme/js/test-wema.html +304 -0
  100. data/vendor/qwik/share/theme/js/test-xp.html +99 -0
  101. data/vendor/qwik/share/theme/js/unittest.js +363 -0
  102. data/vendor/qwik/share/theme/js/watch.js +109 -0
  103. data/vendor/qwik/share/theme/js/wema.js +580 -0
  104. data/vendor/qwik/share/theme/js/wysiwyg.js +143 -0
  105. data/vendor/qwik/share/theme/qwikborder/qwikborder.css +277 -0
  106. data/vendor/qwik/share/theme/qwikborder/qwikborder_ball.png +0 -0
  107. data/vendor/qwik/share/theme/qwikborder/qwikborder_h2.png +0 -0
  108. data/vendor/qwik/share/theme/qwikborder/qwikborder_li.png +0 -0
  109. data/vendor/qwik/share/theme/qwikcyan/qwikcyan.css +216 -0
  110. data/vendor/qwik/share/theme/qwikcyan/qwikcyan_li.png +0 -0
  111. data/vendor/qwik/share/theme/qwikeditor/command.gif +0 -0
  112. data/vendor/qwik/share/theme/qwikeditor/edit_form_bg.jpg +0 -0
  113. data/vendor/qwik/share/theme/qwikeditor/edit_qwik_logo.gif +0 -0
  114. data/vendor/qwik/share/theme/qwikeditor/edit_title_bg.jpg +0 -0
  115. data/vendor/qwik/share/theme/qwikeditor/login_bg.gif +0 -0
  116. data/vendor/qwik/share/theme/qwikeditor/login_qwik_logo.gif +0 -0
  117. data/vendor/qwik/share/theme/qwikeditor/qwikeditor.css +336 -0
  118. data/vendor/qwik/share/theme/qwikeditor/sidebar_bg.gif +0 -0
  119. data/vendor/qwik/share/theme/qwikgreen/qwikgreen.css +306 -0
  120. data/vendor/qwik/share/theme/qwiknotice/qwiknotice.css +246 -0
  121. data/vendor/qwik/share/theme/qwiknotice/qwiknotice_body_bg.gif +0 -0
  122. data/vendor/qwik/share/theme/qwiknotice/qwiknotice_inputform_bg.gif +0 -0
  123. data/vendor/qwik/share/theme/qwiknotice/qwiknotice_inputform_bg_footer.gif +0 -0
  124. data/vendor/qwik/share/theme/qwiknotice/qwiknotice_inputform_bg_header.gif +0 -0
  125. data/vendor/qwik/share/theme/qwiknotice/qwiknotice_li.gif +0 -0
  126. data/vendor/qwik/share/theme/qwiknotice/qwiknotice_qwik_logo.gif +0 -0
  127. data/vendor/qwik/share/theme/qwikplain/command.gif +0 -0
  128. data/vendor/qwik/share/theme/qwikplain/edit_form_bg.jpg +0 -0
  129. data/vendor/qwik/share/theme/qwikplain/edit_qwik_logo.gif +0 -0
  130. data/vendor/qwik/share/theme/qwikplain/edit_title_bg.jpg +0 -0
  131. data/vendor/qwik/share/theme/qwikplain/login_bg.gif +0 -0
  132. data/vendor/qwik/share/theme/qwikplain/login_qwik_logo.gif +0 -0
  133. data/vendor/qwik/share/theme/qwikplain/qwikplain.css +223 -0
  134. data/vendor/qwik/share/theme/qwikplain/sidebar_bg.gif +0 -0
  135. data/vendor/qwik/share/theme/qwikskelton/qwikskelton.css +224 -0
  136. data/vendor/qwik/share/theme/qwiksystem/qwiksystem.css +323 -0
  137. data/vendor/qwik/share/theme/qwiksystem/qwiksystem_bg.png +0 -0
  138. data/vendor/qwik/share/theme/qwiksystem/qwiksystem_header.png +0 -0
  139. data/vendor/qwik/share/theme/qwiksystem/qwiksystem_headerbar.png +0 -0
  140. data/vendor/qwik/share/theme/qwiksystem/qwiksystem_qwikweb.png +0 -0
  141. data/vendor/qwik/share/theme/qwikviridian/qwikviridian.css +413 -0
  142. data/vendor/qwik/share/theme/qwikviridian/qwikviridian_adminmenu_bg.gif +0 -0
  143. data/vendor/qwik/share/theme/qwikviridian/qwikviridian_bg.gif +0 -0
  144. data/vendor/qwik/share/theme/qwikviridian/qwikviridian_bg_shade.gif +0 -0
  145. data/vendor/qwik/share/theme/qwikviridian/qwikviridian_sidebar_a_bg.gif +0 -0
  146. data/vendor/qwik/share/theme/qwikviridian/qwikviridian_siderbar_li_a.gif +0 -0
  147. data/vendor/qwik/share/theme/s5/blue/bluebg.gif +0 -0
  148. data/vendor/qwik/share/theme/s5/blue/bluebottom.gif +0 -0
  149. data/vendor/qwik/share/theme/s5/blue/bluefooter.gif +0 -0
  150. data/vendor/qwik/share/theme/s5/blue/framing.css +25 -0
  151. data/vendor/qwik/share/theme/s5/blue/pretty.css +91 -0
  152. data/vendor/qwik/share/theme/s5/blue/s5-core.css +11 -0
  153. data/vendor/qwik/share/theme/s5/blue/slides.css +3 -0
  154. data/vendor/qwik/share/theme/s5/default/iepngfix.htc +42 -0
  155. data/vendor/qwik/share/theme/s5/default/opera.css +7 -0
  156. data/vendor/qwik/share/theme/s5/default/outline.css +15 -0
  157. data/vendor/qwik/share/theme/s5/default/print.css +24 -0
  158. data/vendor/qwik/share/theme/s5/default/slides.js +558 -0
  159. data/vendor/qwik/share/theme/s5/flower/blume.jpg +0 -0
  160. data/vendor/qwik/share/theme/s5/flower/blumerechts.jpg +0 -0
  161. data/vendor/qwik/share/theme/s5/flower/framing.css +25 -0
  162. data/vendor/qwik/share/theme/s5/flower/pretty.css +83 -0
  163. data/vendor/qwik/share/theme/s5/flower/s5-core.css +11 -0
  164. data/vendor/qwik/share/theme/s5/flower/slides.css +3 -0
  165. data/vendor/qwik/share/theme/s5/i18n/00_head.txt +8 -0
  166. data/vendor/qwik/share/theme/s5/i18n/bg-shade.png +0 -0
  167. data/vendor/qwik/share/theme/s5/i18n/bg-slide.jpg +0 -0
  168. data/vendor/qwik/share/theme/s5/i18n/framing.css +23 -0
  169. data/vendor/qwik/share/theme/s5/i18n/pretty.css +44 -0
  170. data/vendor/qwik/share/theme/s5/i18n/s5-core.css +9 -0
  171. data/vendor/qwik/share/theme/s5/i18n/slides.css +3 -0
  172. data/vendor/qwik/share/theme/s5/pixel/framing.css +25 -0
  173. data/vendor/qwik/share/theme/s5/pixel/pixelbg.gif +0 -0
  174. data/vendor/qwik/share/theme/s5/pixel/pixelheader.jpg +0 -0
  175. data/vendor/qwik/share/theme/s5/pixel/pixelslide0bg.gif +0 -0
  176. data/vendor/qwik/share/theme/s5/pixel/pretty.css +80 -0
  177. data/vendor/qwik/share/theme/s5/pixel/s5-core.css +11 -0
  178. data/vendor/qwik/share/theme/s5/pixel/slides.css +3 -0
  179. data/vendor/qwik/share/theme/s5/qwikblack/framing.css +23 -0
  180. data/vendor/qwik/share/theme/s5/qwikblack/pretty.css +245 -0
  181. data/vendor/qwik/share/theme/s5/qwikblack/s5-core.css +9 -0
  182. data/vendor/qwik/share/theme/s5/qwikblack/slides.css +3 -0
  183. data/vendor/qwik/share/theme/s5/qwikworld/bg-shade.png +0 -0
  184. data/vendor/qwik/share/theme/s5/qwikworld/bg-slide.jpg +0 -0
  185. data/vendor/qwik/share/theme/s5/qwikworld/framing.css +61 -0
  186. data/vendor/qwik/share/theme/s5/qwikworld/pretty.css +250 -0
  187. data/vendor/qwik/share/theme/s5/qwikworld/qwikcyan_li.png +0 -0
  188. data/vendor/qwik/share/theme/s5/qwikworld/s5-core.css +28 -0
  189. data/vendor/qwik/share/theme/s5/qwikworld/slides.css +3 -0
  190. data/vendor/qwik/share/theme/s5/shell/blank.gif +0 -0
  191. data/vendor/qwik/share/theme/s5/shell/bodybg.gif +0 -0
  192. data/vendor/qwik/share/theme/s5/shell/framing.css +23 -0
  193. data/vendor/qwik/share/theme/s5/shell/pretty.css +86 -0
  194. data/vendor/qwik/share/theme/s5/shell/s5-core.css +9 -0
  195. data/vendor/qwik/share/theme/s5/shell/slides.css +3 -0
  196. metadata +190 -1
@@ -0,0 +1,750 @@
1
+ // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
+ // (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
3
+ // (c) 2005 Jon Tirsen (http://www.tirsen.com)
4
+ // Contributors:
5
+ // Richard Livsey
6
+ // Rahul Bhargava
7
+ // Rob Wills
8
+ //
9
+ // See scriptaculous.js for full license.
10
+
11
+ // Autocompleter.Base handles all the autocompletion functionality
12
+ // that's independent of the data source for autocompletion. This
13
+ // includes drawing the autocompletion menu, observing keyboard
14
+ // and mouse events, and similar.
15
+ //
16
+ // Specific autocompleters need to provide, at the very least,
17
+ // a getUpdatedChoices function that will be invoked every time
18
+ // the text inside the monitored textbox changes. This method
19
+ // should get the text for which to provide autocompletion by
20
+ // invoking this.getToken(), NOT by directly accessing
21
+ // this.element.value. This is to allow incremental tokenized
22
+ // autocompletion. Specific auto-completion logic (AJAX, etc)
23
+ // belongs in getUpdatedChoices.
24
+ //
25
+ // Tokenized incremental autocompletion is enabled automatically
26
+ // when an autocompleter is instantiated with the 'tokens' option
27
+ // in the options parameter, e.g.:
28
+ // new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
29
+ // will incrementally autocomplete with a comma as the token.
30
+ // Additionally, ',' in the above example can be replaced with
31
+ // a token array, e.g. { tokens: [',', '\n'] } which
32
+ // enables autocompletion on multiple tokens. This is most
33
+ // useful when one of the tokens is \n (a newline), as it
34
+ // allows smart autocompletion after linebreaks.
35
+
36
+ var Autocompleter = {}
37
+ Autocompleter.Base = function() {};
38
+ Autocompleter.Base.prototype = {
39
+ baseInitialize: function(element, update, options) {
40
+ this.element = $(element);
41
+ this.update = $(update);
42
+ this.hasFocus = false;
43
+ this.changed = false;
44
+ this.active = false;
45
+ this.index = 0;
46
+ this.entryCount = 0;
47
+
48
+ if (this.setOptions)
49
+ this.setOptions(options);
50
+ else
51
+ this.options = options || {};
52
+
53
+ this.options.paramName = this.options.paramName || this.element.name;
54
+ this.options.tokens = this.options.tokens || [];
55
+ this.options.frequency = this.options.frequency || 0.4;
56
+ this.options.minChars = this.options.minChars || 1;
57
+ this.options.onShow = this.options.onShow ||
58
+ function(element, update){
59
+ if(!update.style.position || update.style.position=='absolute') {
60
+ update.style.position = 'absolute';
61
+ Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight});
62
+ }
63
+ Effect.Appear(update,{duration:0.15});
64
+ };
65
+ this.options.onHide = this.options.onHide ||
66
+ function(element, update){ new Effect.Fade(update,{duration:0.15}) };
67
+
68
+ if (typeof(this.options.tokens) == 'string')
69
+ this.options.tokens = new Array(this.options.tokens);
70
+
71
+ this.observer = null;
72
+
73
+ this.element.setAttribute('autocomplete','off');
74
+
75
+ Element.hide(this.update);
76
+
77
+ Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
78
+ Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
79
+ },
80
+
81
+ show: function() {
82
+ if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
83
+ if(!this.iefix &&
84
+ (navigator.appVersion.indexOf('MSIE')>0) &&
85
+ (navigator.userAgent.indexOf('Opera')<0) &&
86
+ (Element.getStyle(this.update, 'position')=='absolute')) {
87
+ new Insertion.After(this.update,
88
+ '<iframe id="' + this.update.id + '_iefix" '+
89
+ 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
90
+ 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
91
+ this.iefix = $(this.update.id+'_iefix');
92
+ }
93
+ if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
94
+ },
95
+
96
+ fixIEOverlapping: function() {
97
+ Position.clone(this.update, this.iefix);
98
+ this.iefix.style.zIndex = 1;
99
+ this.update.style.zIndex = 2;
100
+ Element.show(this.iefix);
101
+ },
102
+
103
+ hide: function() {
104
+ this.stopIndicator();
105
+ if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
106
+ if(this.iefix) Element.hide(this.iefix);
107
+ },
108
+
109
+ startIndicator: function() {
110
+ if(this.options.indicator) Element.show(this.options.indicator);
111
+ },
112
+
113
+ stopIndicator: function() {
114
+ if(this.options.indicator) Element.hide(this.options.indicator);
115
+ },
116
+
117
+ onKeyPress: function(event) {
118
+ if(this.active)
119
+ switch(event.keyCode) {
120
+ case Event.KEY_TAB:
121
+ case Event.KEY_RETURN:
122
+ this.selectEntry();
123
+ Event.stop(event);
124
+ case Event.KEY_ESC:
125
+ this.hide();
126
+ this.active = false;
127
+ Event.stop(event);
128
+ return;
129
+ case Event.KEY_LEFT:
130
+ case Event.KEY_RIGHT:
131
+ return;
132
+ case Event.KEY_UP:
133
+ this.markPrevious();
134
+ this.render();
135
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
136
+ return;
137
+ case Event.KEY_DOWN:
138
+ this.markNext();
139
+ this.render();
140
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
141
+ return;
142
+ }
143
+ else
144
+ if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN)
145
+ return;
146
+
147
+ this.changed = true;
148
+ this.hasFocus = true;
149
+
150
+ if(this.observer) clearTimeout(this.observer);
151
+ this.observer =
152
+ setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
153
+ },
154
+
155
+ onHover: function(event) {
156
+ var element = Event.findElement(event, 'LI');
157
+ if(this.index != element.autocompleteIndex)
158
+ {
159
+ this.index = element.autocompleteIndex;
160
+ this.render();
161
+ }
162
+ Event.stop(event);
163
+ },
164
+
165
+ onClick: function(event) {
166
+ var element = Event.findElement(event, 'LI');
167
+ this.index = element.autocompleteIndex;
168
+ this.selectEntry();
169
+ this.hide();
170
+ },
171
+
172
+ onBlur: function(event) {
173
+ // needed to make click events working
174
+ setTimeout(this.hide.bind(this), 250);
175
+ this.hasFocus = false;
176
+ this.active = false;
177
+ },
178
+
179
+ render: function() {
180
+ if(this.entryCount > 0) {
181
+ for (var i = 0; i < this.entryCount; i++)
182
+ this.index==i ?
183
+ Element.addClassName(this.getEntry(i),"selected") :
184
+ Element.removeClassName(this.getEntry(i),"selected");
185
+
186
+ if(this.hasFocus) {
187
+ this.show();
188
+ this.active = true;
189
+ }
190
+ } else {
191
+ this.active = false;
192
+ this.hide();
193
+ }
194
+ },
195
+
196
+ markPrevious: function() {
197
+ if(this.index > 0) this.index--
198
+ else this.index = this.entryCount-1;
199
+ },
200
+
201
+ markNext: function() {
202
+ if(this.index < this.entryCount-1) this.index++
203
+ else this.index = 0;
204
+ },
205
+
206
+ getEntry: function(index) {
207
+ return this.update.firstChild.childNodes[index];
208
+ },
209
+
210
+ getCurrentEntry: function() {
211
+ return this.getEntry(this.index);
212
+ },
213
+
214
+ selectEntry: function() {
215
+ this.active = false;
216
+ this.updateElement(this.getCurrentEntry());
217
+ },
218
+
219
+ updateElement: function(selectedElement) {
220
+ if (this.options.updateElement) {
221
+ this.options.updateElement(selectedElement);
222
+ return;
223
+ }
224
+
225
+ var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
226
+ var lastTokenPos = this.findLastToken();
227
+ if (lastTokenPos != -1) {
228
+ var newValue = this.element.value.substr(0, lastTokenPos + 1);
229
+ var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
230
+ if (whitespace)
231
+ newValue += whitespace[0];
232
+ this.element.value = newValue + value;
233
+ } else {
234
+ this.element.value = value;
235
+ }
236
+ this.element.focus();
237
+
238
+ if (this.options.afterUpdateElement)
239
+ this.options.afterUpdateElement(this.element, selectedElement);
240
+ },
241
+
242
+ updateChoices: function(choices) {
243
+ if(!this.changed && this.hasFocus) {
244
+ this.update.innerHTML = choices;
245
+ Element.cleanWhitespace(this.update);
246
+ Element.cleanWhitespace(this.update.firstChild);
247
+
248
+ if(this.update.firstChild && this.update.firstChild.childNodes) {
249
+ this.entryCount =
250
+ this.update.firstChild.childNodes.length;
251
+ for (var i = 0; i < this.entryCount; i++) {
252
+ var entry = this.getEntry(i);
253
+ entry.autocompleteIndex = i;
254
+ this.addObservers(entry);
255
+ }
256
+ } else {
257
+ this.entryCount = 0;
258
+ }
259
+
260
+ this.stopIndicator();
261
+
262
+ this.index = 0;
263
+ this.render();
264
+ }
265
+ },
266
+
267
+ addObservers: function(element) {
268
+ Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
269
+ Event.observe(element, "click", this.onClick.bindAsEventListener(this));
270
+ },
271
+
272
+ onObserverEvent: function() {
273
+ this.changed = false;
274
+ if(this.getToken().length>=this.options.minChars) {
275
+ this.startIndicator();
276
+ this.getUpdatedChoices();
277
+ } else {
278
+ this.active = false;
279
+ this.hide();
280
+ }
281
+ },
282
+
283
+ getToken: function() {
284
+ var tokenPos = this.findLastToken();
285
+ if (tokenPos != -1)
286
+ var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
287
+ else
288
+ var ret = this.element.value;
289
+
290
+ return /\n/.test(ret) ? '' : ret;
291
+ },
292
+
293
+ findLastToken: function() {
294
+ var lastTokenPos = -1;
295
+
296
+ for (var i=0; i<this.options.tokens.length; i++) {
297
+ var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
298
+ if (thisTokenPos > lastTokenPos)
299
+ lastTokenPos = thisTokenPos;
300
+ }
301
+ return lastTokenPos;
302
+ }
303
+ }
304
+
305
+ Ajax.Autocompleter = Class.create();
306
+ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
307
+ initialize: function(element, update, url, options) {
308
+ this.baseInitialize(element, update, options);
309
+ this.options.asynchronous = true;
310
+ this.options.onComplete = this.onComplete.bind(this);
311
+ this.options.defaultParams = this.options.parameters || null;
312
+ this.url = url;
313
+ },
314
+
315
+ getUpdatedChoices: function() {
316
+ entry = encodeURIComponent(this.options.paramName) + '=' +
317
+ encodeURIComponent(this.getToken());
318
+
319
+ this.options.parameters = this.options.callback ?
320
+ this.options.callback(this.element, entry) : entry;
321
+
322
+ if(this.options.defaultParams)
323
+ this.options.parameters += '&' + this.options.defaultParams;
324
+
325
+ new Ajax.Request(this.url, this.options);
326
+ },
327
+
328
+ onComplete: function(request) {
329
+ this.updateChoices(request.responseText);
330
+ }
331
+
332
+ });
333
+
334
+ // The local array autocompleter. Used when you'd prefer to
335
+ // inject an array of autocompletion options into the page, rather
336
+ // than sending out Ajax queries, which can be quite slow sometimes.
337
+ //
338
+ // The constructor takes four parameters. The first two are, as usual,
339
+ // the id of the monitored textbox, and id of the autocompletion menu.
340
+ // The third is the array you want to autocomplete from, and the fourth
341
+ // is the options block.
342
+ //
343
+ // Extra local autocompletion options:
344
+ // - choices - How many autocompletion choices to offer
345
+ //
346
+ // - partialSearch - If false, the autocompleter will match entered
347
+ // text only at the beginning of strings in the
348
+ // autocomplete array. Defaults to true, which will
349
+ // match text at the beginning of any *word* in the
350
+ // strings in the autocomplete array. If you want to
351
+ // search anywhere in the string, additionally set
352
+ // the option fullSearch to true (default: off).
353
+ //
354
+ // - fullSsearch - Search anywhere in autocomplete array strings.
355
+ //
356
+ // - partialChars - How many characters to enter before triggering
357
+ // a partial match (unlike minChars, which defines
358
+ // how many characters are required to do any match
359
+ // at all). Defaults to 2.
360
+ //
361
+ // - ignoreCase - Whether to ignore case when autocompleting.
362
+ // Defaults to true.
363
+ //
364
+ // It's possible to pass in a custom function as the 'selector'
365
+ // option, if you prefer to write your own autocompletion logic.
366
+ // In that case, the other options above will not apply unless
367
+ // you support them.
368
+
369
+ Autocompleter.Local = Class.create();
370
+ Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
371
+ initialize: function(element, update, array, options) {
372
+ this.baseInitialize(element, update, options);
373
+ this.options.array = array;
374
+ },
375
+
376
+ getUpdatedChoices: function() {
377
+ this.updateChoices(this.options.selector(this));
378
+ },
379
+
380
+ setOptions: function(options) {
381
+ this.options = Object.extend({
382
+ choices: 10,
383
+ partialSearch: true,
384
+ partialChars: 2,
385
+ ignoreCase: true,
386
+ fullSearch: false,
387
+ selector: function(instance) {
388
+ var ret = []; // Beginning matches
389
+ var partial = []; // Inside matches
390
+ var entry = instance.getToken();
391
+ var count = 0;
392
+
393
+ for (var i = 0; i < instance.options.array.length &&
394
+ ret.length < instance.options.choices ; i++) {
395
+
396
+ var elem = instance.options.array[i];
397
+ var foundPos = instance.options.ignoreCase ?
398
+ elem.toLowerCase().indexOf(entry.toLowerCase()) :
399
+ elem.indexOf(entry);
400
+
401
+ while (foundPos != -1) {
402
+ if (foundPos == 0 && elem.length != entry.length) {
403
+ ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
404
+ elem.substr(entry.length) + "</li>");
405
+ break;
406
+ } else if (entry.length >= instance.options.partialChars &&
407
+ instance.options.partialSearch && foundPos != -1) {
408
+ if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
409
+ partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
410
+ elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
411
+ foundPos + entry.length) + "</li>");
412
+ break;
413
+ }
414
+ }
415
+
416
+ foundPos = instance.options.ignoreCase ?
417
+ elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
418
+ elem.indexOf(entry, foundPos + 1);
419
+
420
+ }
421
+ }
422
+ if (partial.length)
423
+ ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
424
+ return "<ul>" + ret.join('') + "</ul>";
425
+ }
426
+ }, options || {});
427
+ }
428
+ });
429
+
430
+ // AJAX in-place editor
431
+ //
432
+ // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
433
+
434
+ // Use this if you notice weird scrolling problems on some browsers,
435
+ // the DOM might be a bit confused when this gets called so do this
436
+ // waits 1 ms (with setTimeout) until it does the activation
437
+ Field.scrollFreeActivate = function(field) {
438
+ setTimeout(function() {
439
+ Field.activate(field);
440
+ }, 1);
441
+ }
442
+
443
+ Ajax.InPlaceEditor = Class.create();
444
+ Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
445
+ Ajax.InPlaceEditor.prototype = {
446
+ initialize: function(element, url, options) {
447
+ this.url = url;
448
+ this.element = $(element);
449
+
450
+ this.options = Object.extend({
451
+ okText: "ok",
452
+ cancelText: "cancel",
453
+ savingText: "Saving...",
454
+ clickToEditText: "Click to edit",
455
+ okText: "ok",
456
+ rows: 1,
457
+ onComplete: function(transport, element) {
458
+ new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
459
+ },
460
+ onFailure: function(transport) {
461
+ alert("Error communicating with the server: " + transport.responseText.stripTags());
462
+ },
463
+ callback: function(form) {
464
+ return Form.serialize(form);
465
+ },
466
+ handleLineBreaks: true,
467
+ loadingText: 'Loading...',
468
+ savingClassName: 'inplaceeditor-saving',
469
+ loadingClassName: 'inplaceeditor-loading',
470
+ formClassName: 'inplaceeditor-form',
471
+ highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
472
+ highlightendcolor: "#FFFFFF",
473
+ externalControl: null,
474
+ ajaxOptions: {}
475
+ }, options || {});
476
+
477
+ if(!this.options.formId && this.element.id) {
478
+ this.options.formId = this.element.id + "-inplaceeditor";
479
+ if ($(this.options.formId)) {
480
+ // there's already a form with that name, don't specify an id
481
+ this.options.formId = null;
482
+ }
483
+ }
484
+
485
+ if (this.options.externalControl) {
486
+ this.options.externalControl = $(this.options.externalControl);
487
+ }
488
+
489
+ this.originalBackground = Element.getStyle(this.element, 'background-color');
490
+ if (!this.originalBackground) {
491
+ this.originalBackground = "transparent";
492
+ }
493
+
494
+ this.element.title = this.options.clickToEditText;
495
+
496
+ this.onclickListener = this.enterEditMode.bindAsEventListener(this);
497
+ this.mouseoverListener = this.enterHover.bindAsEventListener(this);
498
+ this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
499
+ Event.observe(this.element, 'click', this.onclickListener);
500
+ Event.observe(this.element, 'mouseover', this.mouseoverListener);
501
+ Event.observe(this.element, 'mouseout', this.mouseoutListener);
502
+ if (this.options.externalControl) {
503
+ Event.observe(this.options.externalControl, 'click', this.onclickListener);
504
+ Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
505
+ Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
506
+ }
507
+ },
508
+ enterEditMode: function(evt) {
509
+ if (this.saving) return;
510
+ if (this.editing) return;
511
+ this.editing = true;
512
+ this.onEnterEditMode();
513
+ if (this.options.externalControl) {
514
+ Element.hide(this.options.externalControl);
515
+ }
516
+ Element.hide(this.element);
517
+ this.createForm();
518
+ this.element.parentNode.insertBefore(this.form, this.element);
519
+ Field.scrollFreeActivate(this.editField);
520
+ // stop the event to avoid a page refresh in Safari
521
+ if (evt) {
522
+ Event.stop(evt);
523
+ }
524
+ return false;
525
+ },
526
+ createForm: function() {
527
+ this.form = document.createElement("form");
528
+ this.form.id = this.options.formId;
529
+ Element.addClassName(this.form, this.options.formClassName)
530
+ this.form.onsubmit = this.onSubmit.bind(this);
531
+
532
+ this.createEditField();
533
+
534
+ if (this.options.textarea) {
535
+ var br = document.createElement("br");
536
+ this.form.appendChild(br);
537
+ }
538
+
539
+ okButton = document.createElement("input");
540
+ okButton.type = "submit";
541
+ okButton.value = this.options.okText;
542
+ this.form.appendChild(okButton);
543
+
544
+ cancelLink = document.createElement("a");
545
+ cancelLink.href = "#";
546
+ cancelLink.appendChild(document.createTextNode(this.options.cancelText));
547
+ cancelLink.onclick = this.onclickCancel.bind(this);
548
+ this.form.appendChild(cancelLink);
549
+ },
550
+ hasHTMLLineBreaks: function(string) {
551
+ if (!this.options.handleLineBreaks) return false;
552
+ return string.match(/<br/i) || string.match(/<p>/i);
553
+ },
554
+ convertHTMLLineBreaks: function(string) {
555
+ return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
556
+ },
557
+ createEditField: function() {
558
+ var text;
559
+ if(this.options.loadTextURL) {
560
+ text = this.options.loadingText;
561
+ } else {
562
+ text = this.getText();
563
+ }
564
+
565
+ if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
566
+ this.options.textarea = false;
567
+ var textField = document.createElement("input");
568
+ textField.type = "text";
569
+ textField.name = "value";
570
+ textField.value = text;
571
+ textField.style.backgroundColor = this.options.highlightcolor;
572
+ var size = this.options.size || this.options.cols || 0;
573
+ if (size != 0) textField.size = size;
574
+ this.editField = textField;
575
+ } else {
576
+ this.options.textarea = true;
577
+ var textArea = document.createElement("textarea");
578
+ textArea.name = "value";
579
+ textArea.value = this.convertHTMLLineBreaks(text);
580
+ textArea.rows = this.options.rows;
581
+ textArea.cols = this.options.cols || 40;
582
+ this.editField = textArea;
583
+ }
584
+
585
+ if(this.options.loadTextURL) {
586
+ this.loadExternalText();
587
+ }
588
+ this.form.appendChild(this.editField);
589
+ },
590
+ getText: function() {
591
+ return this.element.innerHTML;
592
+ },
593
+ loadExternalText: function() {
594
+ Element.addClassName(this.form, this.options.loadingClassName);
595
+ this.editField.disabled = true;
596
+ new Ajax.Request(
597
+ this.options.loadTextURL,
598
+ Object.extend({
599
+ asynchronous: true,
600
+ onComplete: this.onLoadedExternalText.bind(this)
601
+ }, this.options.ajaxOptions)
602
+ );
603
+ },
604
+ onLoadedExternalText: function(transport) {
605
+ Element.removeClassName(this.form, this.options.loadingClassName);
606
+ this.editField.disabled = false;
607
+ this.editField.value = transport.responseText.stripTags();
608
+ },
609
+ onclickCancel: function() {
610
+ this.onComplete();
611
+ this.leaveEditMode();
612
+ return false;
613
+ },
614
+ onFailure: function(transport) {
615
+ this.options.onFailure(transport);
616
+ if (this.oldInnerHTML) {
617
+ this.element.innerHTML = this.oldInnerHTML;
618
+ this.oldInnerHTML = null;
619
+ }
620
+ return false;
621
+ },
622
+ onSubmit: function() {
623
+ // onLoading resets these so we need to save them away for the Ajax call
624
+ var form = this.form;
625
+ var value = this.editField.value;
626
+
627
+ // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
628
+ // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
629
+ // to be displayed indefinitely
630
+ this.onLoading();
631
+
632
+ new Ajax.Updater(
633
+ {
634
+ success: this.element,
635
+ // don't update on failure (this could be an option)
636
+ failure: null
637
+ },
638
+ this.url,
639
+ Object.extend({
640
+ parameters: this.options.callback(form, value),
641
+ onComplete: this.onComplete.bind(this),
642
+ onFailure: this.onFailure.bind(this)
643
+ }, this.options.ajaxOptions)
644
+ );
645
+ // stop the event to avoid a page refresh in Safari
646
+ if (arguments.length > 1) {
647
+ Event.stop(arguments[0]);
648
+ }
649
+ return false;
650
+ },
651
+ onLoading: function() {
652
+ this.saving = true;
653
+ this.removeForm();
654
+ this.leaveHover();
655
+ this.showSaving();
656
+ },
657
+ showSaving: function() {
658
+ this.oldInnerHTML = this.element.innerHTML;
659
+ this.element.innerHTML = this.options.savingText;
660
+ Element.addClassName(this.element, this.options.savingClassName);
661
+ this.element.style.backgroundColor = this.originalBackground;
662
+ Element.show(this.element);
663
+ },
664
+ removeForm: function() {
665
+ if(this.form) {
666
+ if (this.form.parentNode) Element.remove(this.form);
667
+ this.form = null;
668
+ }
669
+ },
670
+ enterHover: function() {
671
+ if (this.saving) return;
672
+ this.element.style.backgroundColor = this.options.highlightcolor;
673
+ if (this.effect) {
674
+ this.effect.cancel();
675
+ }
676
+ Element.addClassName(this.element, this.options.hoverClassName)
677
+ },
678
+ leaveHover: function() {
679
+ if (this.options.backgroundColor) {
680
+ this.element.style.backgroundColor = this.oldBackground;
681
+ }
682
+ Element.removeClassName(this.element, this.options.hoverClassName)
683
+ if (this.saving) return;
684
+ this.effect = new Effect.Highlight(this.element, {
685
+ startcolor: this.options.highlightcolor,
686
+ endcolor: this.options.highlightendcolor,
687
+ restorecolor: this.originalBackground
688
+ });
689
+ },
690
+ leaveEditMode: function() {
691
+ Element.removeClassName(this.element, this.options.savingClassName);
692
+ this.removeForm();
693
+ this.leaveHover();
694
+ this.element.style.backgroundColor = this.originalBackground;
695
+ Element.show(this.element);
696
+ if (this.options.externalControl) {
697
+ Element.show(this.options.externalControl);
698
+ }
699
+ this.editing = false;
700
+ this.saving = false;
701
+ this.oldInnerHTML = null;
702
+ this.onLeaveEditMode();
703
+ },
704
+ onComplete: function(transport) {
705
+ this.leaveEditMode();
706
+ this.options.onComplete.bind(this)(transport, this.element);
707
+ },
708
+ onEnterEditMode: function() {},
709
+ onLeaveEditMode: function() {},
710
+ dispose: function() {
711
+ if (this.oldInnerHTML) {
712
+ this.element.innerHTML = this.oldInnerHTML;
713
+ }
714
+ this.leaveEditMode();
715
+ Event.stopObserving(this.element, 'click', this.onclickListener);
716
+ Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
717
+ Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
718
+ if (this.options.externalControl) {
719
+ Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
720
+ Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
721
+ Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
722
+ }
723
+ }
724
+ };
725
+
726
+ // Delayed observer, like Form.Element.Observer,
727
+ // but waits for delay after last key input
728
+ // Ideal for live-search fields
729
+
730
+ Form.Element.DelayedObserver = Class.create();
731
+ Form.Element.DelayedObserver.prototype = {
732
+ initialize: function(element, delay, callback) {
733
+ this.delay = delay || 0.5;
734
+ this.element = $(element);
735
+ this.callback = callback;
736
+ this.timer = null;
737
+ this.lastValue = $F(this.element);
738
+ Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
739
+ },
740
+ delayedListener: function(event) {
741
+ if(this.lastValue == $F(this.element)) return;
742
+ if(this.timer) clearTimeout(this.timer);
743
+ this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
744
+ this.lastValue = $F(this.element);
745
+ },
746
+ onTimerEvent: function() {
747
+ this.timer = null;
748
+ this.callback(this.element, $F(this.element));
749
+ }
750
+ };