right-rails 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.textile +50 -0
  3. data/Rakefile +23 -0
  4. data/generators/right_rails/right_rails_generator.rb +41 -0
  5. data/generators/right_rails/templates/iframed.html.erb +10 -0
  6. data/generators/right_scaffold/right_scaffold_generator.rb +53 -0
  7. data/generators/right_scaffold/templates/controller.rb +99 -0
  8. data/generators/right_scaffold/templates/helper.rb +2 -0
  9. data/generators/right_scaffold/templates/layout.html.erb +18 -0
  10. data/generators/right_scaffold/templates/style.css +54 -0
  11. data/generators/right_scaffold/templates/view__form.html.erb +16 -0
  12. data/generators/right_scaffold/templates/view__item.html.erb +13 -0
  13. data/generators/right_scaffold/templates/view_edit.html.erb +6 -0
  14. data/generators/right_scaffold/templates/view_index.html.erb +9 -0
  15. data/generators/right_scaffold/templates/view_new.html.erb +5 -0
  16. data/generators/right_scaffold/templates/view_show.html.erb +10 -0
  17. data/init.rb +12 -0
  18. data/javascripts/right-autocompleter-src.js +303 -0
  19. data/javascripts/right-autocompleter.js +9 -0
  20. data/javascripts/right-behavior-src.js +240 -0
  21. data/javascripts/right-behavior.js +8 -0
  22. data/javascripts/right-calendar-src.js +855 -0
  23. data/javascripts/right-calendar.js +9 -0
  24. data/javascripts/right-dnd-src.js +555 -0
  25. data/javascripts/right-dnd.js +9 -0
  26. data/javascripts/right-effects-src.js +425 -0
  27. data/javascripts/right-effects.js +6 -0
  28. data/javascripts/right-events-src.js +369 -0
  29. data/javascripts/right-events.js +6 -0
  30. data/javascripts/right-json-src.js +176 -0
  31. data/javascripts/right-json.js +6 -0
  32. data/javascripts/right-lightbox-src.js +597 -0
  33. data/javascripts/right-lightbox.js +9 -0
  34. data/javascripts/right-rails-src.js +269 -0
  35. data/javascripts/right-rails.js +9 -0
  36. data/javascripts/right-rater-src.js +248 -0
  37. data/javascripts/right-rater.js +9 -0
  38. data/javascripts/right-selectable-src.js +507 -0
  39. data/javascripts/right-selectable.js +7 -0
  40. data/javascripts/right-slider-src.js +291 -0
  41. data/javascripts/right-slider.js +7 -0
  42. data/javascripts/right-sortable-src.js +221 -0
  43. data/javascripts/right-sortable.js +9 -0
  44. data/javascripts/right-src.js +4939 -0
  45. data/javascripts/right-tabs-src.js +776 -0
  46. data/javascripts/right-tabs.js +6 -0
  47. data/javascripts/right-tooltips-src.js +130 -0
  48. data/javascripts/right-tooltips.js +9 -0
  49. data/javascripts/right-ui-i18n-de.js +29 -0
  50. data/javascripts/right-ui-i18n-en-us.js +11 -0
  51. data/javascripts/right-ui-i18n-es.js +29 -0
  52. data/javascripts/right-ui-i18n-fr.js +29 -0
  53. data/javascripts/right-ui-i18n-jp.js +33 -0
  54. data/javascripts/right-ui-i18n-ru.js +29 -0
  55. data/javascripts/right-ui-i18n-uk.js +29 -0
  56. data/javascripts/right.js +10 -0
  57. data/lib/right-rails.rb +11 -0
  58. data/lib/right_rails/controller_extensions.rb +85 -0
  59. data/lib/right_rails/helpers/basic.rb +111 -0
  60. data/lib/right_rails/helpers/forms.rb +239 -0
  61. data/lib/right_rails/helpers/misc.rb +164 -0
  62. data/lib/right_rails/helpers/rails.rb +166 -0
  63. data/lib/right_rails/helpers.rb +5 -0
  64. data/lib/right_rails/java_script_generator.rb +313 -0
  65. data/lib/right_rails.rb +6 -0
  66. data/spec/lib/right_rails/controller_extensions_spec.rb +60 -0
  67. data/spec/lib/right_rails/helpers/basic_spec.rb +74 -0
  68. data/spec/lib/right_rails/helpers/forms_spec.rb +51 -0
  69. data/spec/lib/right_rails/helpers/misc_spec.rb +120 -0
  70. data/spec/lib/right_rails/helpers/rails_spec.rb +149 -0
  71. data/spec/lib/right_rails/java_script_generator_spec.rb +317 -0
  72. data/spec/spec.opts +5 -0
  73. data/spec/spec_helper.rb +15 -0
  74. metadata +128 -0
@@ -0,0 +1,303 @@
1
+ /**
2
+ * The autocompletion feature implemented with RightJS
3
+ *
4
+ * Home page: http://rightjs.org/ui/autocompleter
5
+ *
6
+ * @copyright (C) 2009 Nikolay V. Nemshilov aka St.
7
+ */
8
+ if (!RightJS) { throw "Gimme RightJS. Please." };
9
+
10
+ /**
11
+ * The RightJS UI Autocompleter unit base class
12
+ *
13
+ * Copyright (C) Nikolay V. Nemshilov aka St.
14
+ */
15
+ var Autocompleter = new Class(Observer, {
16
+ extend: {
17
+ EVENTS: $w('show hide update load select done'),
18
+
19
+ Options: {
20
+ url: document.location.href,
21
+ param: 'search',
22
+ method: 'get',
23
+
24
+ minLength: 1, // the minimal length when it starts work
25
+ threshold: 200, // the typing pause threshold
26
+
27
+ cache: true, // the use the results cache
28
+ local: null, // an optional local search results list
29
+
30
+ fxName: 'slide',
31
+ fxDuration: 'short',
32
+
33
+ spinner: 'native',
34
+
35
+ relName: 'autocompleter'
36
+ },
37
+
38
+ // scans the document for autocompletion fields
39
+ rescan: function() {
40
+ var key = Autocompleter.Options.relName;
41
+ var reg = new RegExp('^'+key+'+\\[(.*?)\\]$');
42
+
43
+ $$('input[rel^="'+key+'"]').each(function(input) {
44
+ if (!input.autocompleter) {
45
+ var data = input.get('data-'+key+'-options');
46
+ var options = Object.merge(eval('('+data+')'));
47
+ var match = input.get('rel').match(reg);
48
+
49
+ if (match) {
50
+ var url = match[1];
51
+
52
+ // if looks like a list of local options
53
+ if (url.match(/^['"].*?['"]$/)) {
54
+ options.local = eval('['+url+']');
55
+ } else if (!url.blank()) {
56
+ options.url = url;
57
+ }
58
+ }
59
+
60
+ new Autocompleter(input, options);
61
+ }
62
+ });
63
+ }
64
+ },
65
+
66
+ /**
67
+ * basic constructor
68
+ *
69
+ * @param mixed the input element reference, a string id or the element instance
70
+ * @param Object options
71
+ */
72
+ initialize: function(input, options) {
73
+ this.$super(options);
74
+
75
+ // storing the callbacks so we could detach them later
76
+ this._watch = this.watch.bind(this);
77
+ this._hide = this.hide.bind(this);
78
+
79
+ this.input = $(input).onKeyup(this._watch).onBlur(this._hide);
80
+ this.container = $E('div', {'class': 'autocompleter'}).insertTo(this.input, 'after');
81
+
82
+ this.input.autocompleter = this;
83
+ },
84
+
85
+ // kills the autocompleter
86
+ destroy: function() {
87
+ this.input.stopObserving('keyup', this._watch).stopObserving('blur', this._hide);
88
+ delete(this.input.autocompleter);
89
+ return this;
90
+ },
91
+
92
+ // catching up with some additonal options
93
+ setOptions: function(options) {
94
+ this.$super(options);
95
+
96
+ // building the correct url template with a placeholder
97
+ if (!this.options.url.includes('%{search}')) {
98
+ this.options.url += (this.options.url.includes('?') ? '&' : '?') + this.options.param + '=%{search}';
99
+ }
100
+ },
101
+
102
+ // handles the list appearance
103
+ show: function() {
104
+ if (this.container.hidden()) {
105
+ var dims = this.input.dimensions();
106
+
107
+ this.container.setStyle({
108
+ top: (dims.top + dims.height) + 'px',
109
+ left: dims.left + 'px',
110
+ width: dims.width + 'px'
111
+ }).show(this.options.fxName, {
112
+ duration: this.options.fxDuration,
113
+ onFinish: this.fire.bind(this, 'show')
114
+ });
115
+ }
116
+
117
+ return Autocompleter.current = this;
118
+ },
119
+
120
+ // handles the list hidding
121
+ hide: function() {
122
+ if (this.container.visible()) {
123
+ this.container.hide();
124
+ this.fire.bind(this, 'hide');
125
+ }
126
+
127
+ Autocompleter.current = null;
128
+
129
+ return this;
130
+ },
131
+
132
+ // selects the next item on the list
133
+ prev: function() {
134
+ return this.select('prev', this.container.select('li').last());
135
+ },
136
+
137
+ // selects the next item on the list
138
+ next: function() {
139
+ return this.select('next', this.container.first('li'));
140
+ },
141
+
142
+ // marks it done
143
+ done: function(current) {
144
+ var current = current || this.container.first('li.current');
145
+ if (current) {
146
+ this.input.value = current.innerHTML.stripTags();
147
+ }
148
+
149
+ return this.fire('done').hide();
150
+ },
151
+
152
+ // protected
153
+
154
+ // works with the 'prev' and 'next' methods
155
+ select: function(what, fallback) {
156
+ var current = this.container.first('li.current');
157
+ if (current) {
158
+ current = current[what]('li') || current;
159
+ }
160
+
161
+ return this.fire('select', (current || fallback).radioClass('current'));
162
+ },
163
+
164
+ // receives the keyboard events out of the input element
165
+ watch: function(event) {
166
+ // skip the overlaping key codes that are already watched in the hooker.js
167
+ if ([27,37,38,39,40,13].include(event.keyCode)) return;
168
+
169
+ if (this.input.value.length >= this.options.minLength) {
170
+ if (this.timeout) {
171
+ this.timeout.cancel();
172
+ }
173
+ this.timeout = this.trigger.bind(this).delay(this.options.threshold);
174
+ } else {
175
+ return this.hide();
176
+ }
177
+ },
178
+
179
+ // triggers the actual action
180
+ trigger: function() {
181
+ this.timeout = null;
182
+
183
+ this.cache = this.cache || {};
184
+ var search = this.input.value;
185
+
186
+ if (search.length < this.options.minLength) return this.hide();
187
+
188
+ if (this.cache[search]) {
189
+ this.suggest(this.cache[search], search);
190
+ } else if (this.options.local) {
191
+ this.suggest(this.findLocal(search), search);
192
+ } else {
193
+ this.request = Xhr.load(this.options.url.replace('%{search}', encodeURIComponent(search)), {
194
+ method: this.options.method,
195
+ spinner: this.getSpinner(),
196
+ onComplete: function(response) {
197
+ this.fire('load').suggest(response.responseText, search);
198
+ }.bind(this)
199
+ });
200
+ }
201
+ },
202
+
203
+ // updates the suggestions list
204
+ suggest: function(result, search) {
205
+ this.container.update(result).select('li').each(function(li) {
206
+ // we reassiging the events each time so the were no doublecalls
207
+ li.onmouseover = function() { li.radioClass('current'); };
208
+ li.onmousedown = function() { this.done(li); }.bind(this);
209
+ }, this);
210
+
211
+ // saving the result in cache
212
+ if (this.options.cache) {
213
+ this.cache[search] = result;
214
+ }
215
+
216
+ return this.fire('update').show();
217
+ },
218
+
219
+ // performs the locals search
220
+ findLocal: function(search) {
221
+ var regexp = new RegExp("("+RegExp.escape(search)+")", 'ig');
222
+ return $E('ul').insert(
223
+ this.options.local.map(function(option) {
224
+ if (regexp.test(option)) {
225
+ return $E('li', {html:
226
+ option.replace(regexp, '<strong>$1</strong>')
227
+ });
228
+ }
229
+ }).compact()
230
+ );
231
+ },
232
+
233
+ // builds a native textual spinner if necessary
234
+ getSpinner: function() {
235
+ this._spinner = this._spinner || this.options.spinner;
236
+
237
+ // building the native spinner
238
+ if (this._spinner == 'native') {
239
+ this._spinner = $E('div', {
240
+ 'class': 'autocompleter-spinner'
241
+ }).insertTo(this.input, 'after');
242
+
243
+ var dots = '123'.split('').map(function(i) {
244
+ return $E('div', {'class': 'dot-'+i, html: '&raquo;'});
245
+ });
246
+
247
+ (function() {
248
+ var dot = dots.shift();
249
+ dots.push(dot);
250
+ this._spinner.update(dot);
251
+ }.bind(this)).periodical(400);
252
+ }
253
+
254
+ // repositioning the native spinner
255
+ if (this.options.spinner == 'native') {
256
+ var dims = this.input.dimensions();
257
+
258
+ this._spinner.setStyle('visiblity: hidden').show();
259
+
260
+ this._spinner.setStyle({
261
+ visibility: 'visible',
262
+ top: (dims.top + 1) + 'px',
263
+ height: (dims.height - 2) + 'px',
264
+ lineHeight: (dims.height - 2) + 'px',
265
+ left: (dims.left + dims.width - this._spinner.offsetWidth - 1) + 'px'
266
+ }).hide();
267
+ }
268
+
269
+ return this._spinner;
270
+ }
271
+ });
272
+
273
+ /**
274
+ * The document events hooking
275
+ *
276
+ * Copyright (C) Nikolay V. Nemshilov aka St.
277
+ */
278
+ document.on({
279
+ ready: Autocompleter.rescan,
280
+
281
+ // the autocompletion list navigation
282
+ keydown: function(event) {
283
+ if (Autocompleter.current) {
284
+ var name;
285
+
286
+ switch (event.keyCode) {
287
+ case 27: name = 'hide'; break;
288
+ case 37: name = 'prev'; break;
289
+ case 39: name = 'next'; break;
290
+ case 38: name = 'prev'; break;
291
+ case 40: name = 'next'; break;
292
+ case 13: name = 'done'; break;
293
+ }
294
+
295
+ if (name) {
296
+ Autocompleter.current[name]();
297
+ event.stop();
298
+ }
299
+ }
300
+ }
301
+ });
302
+
303
+ document.write("<style type=\"text/css\">div.autocompleter{display:none;position:absolute;z-index:100000000;border:none;margin:0;padding:0;background:white;-moz-box-shadow:#BBB .2em .2em .4em;-webkit-box-shadow:#BBB .2em .2em .4em;overflow:hidden}div.autocompleter ul{list-style:none;margin:0;padding:0;border:none;background:none;*border-bottom:1px solid #CCC}div.autocompleter ul li{list-style:none;font-weight:normal;margin:0;padding:.2em .4em;border:1px solid #CCC;border-top:none;border-bottom:none;background:none;cursor:pointer}div.autocompleter ul li:first-child{border-top:1px solid #CCC}div.autocompleter ul li:last-child{border-bottom:1px solid #CCC;*border-bottom:none}div.autocompleter ul li.current{background:#DDD}div.autocompleter-spinner{position:absolute;z-index:100000000;text-align:center;font-size:140%;font-family:Georgia;background:#DDD;color:#666;display:none;width:1em;margin:0;padding:0}div.autocompleter-spinner div.dot-1{margin-left:-4px}div.autocompleter-spinner div.dot-2{}div.autocompleter-spinner div.dot-3{margin-left:4px}</style>");
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The autocompletion feature implemented with RightJS
3
+ *
4
+ * Home page: http://rightjs.org/ui/autocompleter
5
+ *
6
+ * @copyright (C) 2009 Nikolay V. Nemshilov aka St.
7
+ */
8
+ if (!RightJS) { throw "Gimme RightJS. Please." };
9
+ eval((function(s,d){for(var i=d.length-1;i>-1;i--)if(d[i])s=s.replace(new RegExp(i,'g'),d[i]);return s})("26 17=96 Class(Observer,{extend:{EVENTS:$w('49 32 52 101 33 57'),90:{58:56.location.href,114:'54',70:'113',45:1,75:200,34:true,62:102,107:'slide',69:'short',22:'73',94:'11'},104:15(){26 k=17.90.94;26 r=96 72('^'+k+'+\\\\[(.*?)\\\\]$');$$('25[126^=\"'+k+'\"]').117(15(i){if(!i.11){26 d=i.113('data-'+k+'-16');26 o=Object.merge(118('('+d+')'));26 m=i.113('126').110(r);if(m){26 u=m[1];if(u.110(/^['\"].*?['\"]$/))o.62=118('['+u+']');81 if(!u.blank())o.58=u}96 17(i,o)}})}},initialize:15(i,o){5.105(o);5.74=5.115.36(5);5._32=5.32.36(5);5.25=$(i).onKeyup(5.74).onBlur(5._32);5.19=$E('28',{'85':'11'}).88(5.25,'111');5.25.11=5},destroy:15(){5.25.50('keyup',5.74).50('blur',5._32);delete(5.25.11);18 5},set90:15(o){5.105(o);if(!5.16.58.86('%{54}'))5.16.58+=(5.16.58.86('?')?'&':'?')+5.16.114+'=%{54}'},49:15(){if(5.19.71()){26 d=5.25.65();5.19.55({59:(d.59+d.53)+'px',48:d.48+'px',64:d.64+'px'}).49(5.16.107,{duration:5.16.69,onFinish:5.46.36(5,'49')})}18 17.24=5},32:15(){if(5.19.97()){5.19.32();5.46.36(5,'32')}17.24=102;18 5},80:15(){18 5.33('80',5.19.33('li').122())},79:15(){18 5.33('79',5.19.63('li'))},57:15(c){26 c=c||5.19.63('li.24');if(c)5.25.83=c.innerHTML.stripTags();18 5.46('57').32()},33:15(w,f){26 c=5.19.63('li.24');if(c)c=c[w]('li')||c;18 5.46('33',(c||f).67('24'))},115:15(e){if([27,37,38,39,40,13].include(e.99))18;if(5.25.83.103>=5.16.45){if(5.44)5.44.cancel();5.44=5.93.36(5).delay(5.16.75)}81 18 5.32()},93:15(){5.44=102;5.34=5.34||{};26 s=5.25.83;if(s.103<5.16.45)18 5.32();if(5.34[s])5.42(5.34[s],s);81 if(5.16.62)5.42(5.77(s),s);81 5.request=Xhr.101(5.16.58.98('%{54}',encodeURIComponent(s)),{70:5.16.70,22:5.68(),onComplete:15(r){5.46('101').42(r.responseText,s)}.36(5)})},42:15(r,s){5.19.52(r).33('li').117(15(l){l.onmouseover=15(){l.67('24')};l.onmousedown=15(){5.57(l)}.36(5)},5);if(5.16.34)5.34[s]=r;18 5.46('52').49()},77:15(s){26 r=96 72(\"(\"+72.escape(s)+\")\",'ig');18 $E('ul').insert(5.16.62.124(15(o){if(r.test(o))18 $E('li',{120:o.98(r,'<106>$1</106>')})}).compact())},68:15(){5.21=5.21||5.16.22;if(5.21=='73'){5.21=$E('28',{'85':'11-22'}).88(5.25,'111');26 c='123'.split('').124(15(a){18 $E('28',{'85':'89-'+a,120:'&raquo;'})});(15(){26 d=c.shift();c.push(d);5.21.52(d)}.36(5)).periodical(400)}if(5.16.22=='73'){26 b=5.25.65();5.21.55('visiblity: 71').49();5.21.55({visibility:'97',59:(b.59+1)+'px',53:(b.53-2)+'px',lineHeight:(b.53-2)+'px',48:(b.48+b.64-5.21.offsetWidth-1)+'px'}).32()}18 5.21}});56.on({ready:17.104,keydown:15(e){if(17.24){26 n;switch(e.99){47 27:n='32';41;47 37:n='80';41;47 39:n='79';41;47 38:n='80';41;47 40:n='79';41;47 13:n='57';41}if(n){17.24[n]();e.s59()}}}});56.write(\"<61 type=\\\"119/css\\\">28.11{91:30;82:87;z-116:76;29:30;35:0;43:0;31:white;-moz-125-108:#128 .78 .78 .109;-webkit-125-108:#128 .78 .78 .109;overflow:71}28.11 ul{121-61:30;35:0;43:0;29:30;31:30;*29-51:92 60 #95}28.11 ul li{121-61:30;100-weight:normal;35:0;43:.78 .109;29:92 60 #95;29-59:30;29-51:30;31:30;cursor:pointer}28.11 ul li:63-112{29-59:92 60 #95}28.11 ul li:122-112{29-51:92 60 #95;*29-51:30}28.11 ul li.24{31:#127}28.11-22{82:87;z-116:76;119-align:center;100-size:140%;100-family:Georgia;31:#127;color:#666;91:30;64:1em;35:0;43:0}28.11-22 28.89-1{35-48:-129}28.11-22 28.89-2{}28.11-22 28.89-3{35-48:129}</61>\");",",,,,,this,,,,,,autocompleter,,,,function,options,Autocompleter,return,container,,_spinner,spinner,,current,input,var,,div,border,none,background,hide,select,cache,margin,bind,,,,,break,suggest,padding,timeout,minLength,fire,case,left,show,stopObserving,bottom,update,height,search,setStyle,document,done,url,top,solid,style,local,first,width,dimensions,,radioClass,getSpinner,fxDuration,method,hidden,RegExp,native,_watch,threshold,100000000,findLocal,2em,next,prev,else,position,value,_hide,class,includes,absolute,insertTo,dot,Options,display,1px,trigger,relName,CCC,new,visible,replace,keyCode,font,load,null,length,rescan,$super,strong,fxName,shadow,4em,match,after,child,get,param,watch,index,each,eval,text,html,list,last,,map,box,rel,DDD,BBB,4px".split(",")));
@@ -0,0 +1,240 @@
1
+ /**
2
+ * The behavior definitions library for RightJS
3
+ *
4
+ * See http://rightjs.org/goods/behave for more details
5
+ *
6
+ * Copyright (C) 2009 Nikolay V. Nemshilov aka St.
7
+ */
8
+
9
+ /**
10
+ * The behavior definition unit
11
+ *
12
+ * Once created will have two methods #start and #stop
13
+ * Once started will be added to all the matching elemnts
14
+ * on the page, and will watch any updates on the page
15
+ * and refresh the behaves automatically
16
+ *
17
+ * Copyright (C) 2009 Nikolay V. Nemshilov aka St.
18
+ */
19
+ var Behavior = new Class({
20
+ extend: {
21
+ /**
22
+ * Class level behavior creator
23
+ *
24
+ * @param String css-selector
25
+ * @param String event name or a hash of events
26
+ * @param Function callback or a method name or a list of callbacks/names
27
+ * @param mixed optional argument
28
+ * ....
29
+ * @return Behavior instance
30
+ */
31
+ add: function() {
32
+ var args = $A(arguments);
33
+ var behavior = new Behavior(args.shift());
34
+
35
+ return behavior.on.apply(behavior, args).start();
36
+ },
37
+
38
+ /**
39
+ * makes a certain behavior stop
40
+ *
41
+ * @param String css-selector
42
+ * @return Behavior stopped behavior or null if there weren't any
43
+ */
44
+ stop: function(rule) {
45
+ var behavior = Behavior.active[rule];
46
+ if (behavior) behavior.stop();
47
+
48
+ return behavior;
49
+ },
50
+
51
+ /**
52
+ * applies all the active behaviors to the page
53
+ *
54
+ * @return void
55
+ */
56
+ refresh: function() {
57
+ for (var key in Behavior.active) {
58
+ Behavior.active[key].refresh();
59
+ }
60
+ },
61
+
62
+ // a hash of active behaviors
63
+ active: {}
64
+ },
65
+
66
+
67
+ rule: null, // the css rule
68
+ args: null, // the received arguments
69
+ regs: null, // the list of UID of elements that are already processed
70
+
71
+ /**
72
+ * The basic constructor
73
+ *
74
+ * @param String css-rule
75
+ * @param String event name or a hash of event definitions
76
+ * @return void
77
+ */
78
+ initialize: function() {
79
+ var args = $A(arguments);
80
+ this.rule = args.shift();
81
+ this.on.apply(this, args);
82
+
83
+ this.regs = [];
84
+ },
85
+
86
+ /**
87
+ * makes the behavior active
88
+ *
89
+ * @return Behavior self
90
+ */
91
+ start: function() {
92
+ return Behavior.active[this.rule] = this.refresh();
93
+ },
94
+
95
+ /**
96
+ * Deactivates the behavior
97
+ *
98
+ * @return Behavior self
99
+ */
100
+ stop: function() {
101
+ var args = this.args;
102
+
103
+ // converting a non-hash args into a hash
104
+ if (!isHash(args[0])) {
105
+ var hash = {};
106
+ hash[args.shift()] = args;
107
+ args = hash;
108
+ } else {
109
+ args = args[0];
110
+ }
111
+
112
+ // unregistering the listeners
113
+ $$(this.rule).each(function(element) {
114
+ var uid = $uid(element);
115
+ if (this.regs[uid]) {
116
+ for (var key in args) {
117
+
118
+ // if the definition had some nauty arrays and call-by name definitions
119
+ if (isArray(args[key])) {
120
+ args[key].each(function(option) {
121
+ if (isArray(option)) {
122
+ element.stopObserving.apply(element, [key].concat(options[0]));
123
+ }
124
+ });
125
+ if (!isArray(args[key][0])) {
126
+ element.stopObserving.apply(element, [key].concat(args[key][0]));
127
+ }
128
+ } else {
129
+ element.stopObserving.apply(element, [key].concat(args[key]));
130
+ }
131
+ }
132
+ }
133
+ }, this);
134
+
135
+ this.regs = [];
136
+
137
+ delete(Behavior.active[this.rule]);
138
+
139
+ return this;
140
+ },
141
+
142
+ /**
143
+ * Checks if the given behavior is active
144
+ *
145
+ * @return boolean check result
146
+ */
147
+ active: function() {
148
+ return Behavior.active[this.rule] === this;
149
+ },
150
+
151
+ // private
152
+
153
+ /**
154
+ * Defines the behavior options
155
+ *
156
+ * Takes all the same type of options as the {Observer#on} method
157
+ *
158
+ * @param String event name or anevents definition hash
159
+ * @param Function callback or method name to call
160
+ * @return Behavior self
161
+ */
162
+ on: function() {
163
+ this.args = $A(arguments);
164
+ return this;
165
+ },
166
+
167
+ /**
168
+ * refreshes the behavior applying on the page elements
169
+ *
170
+ * @return Behavior self
171
+ */
172
+ refresh: function() {
173
+ $$(this.rule).each(function(element) {
174
+ var uid = $uid(element);
175
+ if (!this.regs[uid]) {
176
+ element.on.apply(element, this.args);
177
+ this.regs[uid] = 1;
178
+ }
179
+ }, this);
180
+
181
+ return this;
182
+ }
183
+ });
184
+
185
+ document.onReady(Behavior.refresh);
186
+ /**
187
+ * The Element unit wrapups for automaticall behaves processing on the page updates
188
+ *
189
+ * Copyright (C) 2009 Nikolay V. Nemshilov aka St.
190
+ */
191
+ Element.addMethods((function(old_methods) {
192
+ var old_insert = old_methods.insert;
193
+ var old_update = old_methods.update;
194
+
195
+ return {
196
+ insert: function() {
197
+ old_insert.apply(this, arguments);
198
+ Behavior.refresh();
199
+
200
+ return this;
201
+ },
202
+
203
+ update: function(content) {
204
+ old_update.apply(this, arguments);
205
+ if (isString(content)) Behavior.refresh();
206
+
207
+ return this;
208
+ }
209
+ };
210
+
211
+ })(Element.Methods));
212
+ /**
213
+ * The bahave library string level shortcuts, mean to create behaviors like that
214
+ *
215
+ * USAGE:
216
+ * "div#sidebar ul li".behave('click', function() {...});
217
+ *
218
+ * "div#sidebar ul li".stopBehave('click', function() {...});
219
+ *
220
+ * Copyright (C) 2009 Nikolay V Nemshilov aka St.
221
+ */
222
+ $ext(String.prototype, {
223
+ /**
224
+ * Starts behavior
225
+ *
226
+ * Takes all the same params as the {Behavior#on} method
227
+ */
228
+ behave: function() {
229
+ return Behavior.add.apply(Behavior, [''+this].concat($A(arguments)));
230
+ },
231
+
232
+ /**
233
+ * Stops a behavior
234
+ *
235
+ * Takes all the same params as the {Behavior#stop} method
236
+ */
237
+ stopBehave: function() {
238
+ return Behavior.stop.apply(Behavior, [''+this].concat($A(arguments)));
239
+ }
240
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The behavior definitions library for RightJS
3
+ *
4
+ * See http://rightjs.org/goods/behave for more details
5
+ *
6
+ * Copyright (C) 2009 Nikolay V. Nemshilov aka St.
7
+ */
8
+ eval((function(s,d){for(var i=d.length-1;i>-1;i--)if(d[i])s=s.replace(new RegExp(i,'g'),d[i]);return s})("10 4=27 Class({extend:{28:2(){10 a=$A(6);10 b=27 4(a.18());5 b.on.7(b,a).24()},16:2(r){10 b=4.9[r];if(b)b.16();5 b},8:2(){29(10 k in 4.9)4.9[k].8()},9:{}},12:21,17:21,14:21,initialize:2(){10 a=$A(6);3.12=a.18();3.on.7(3,a);3.14=[]},24:2(){5 4.9[3.12]=3.8()},16:2(){10 a=3.17;if(!isHash(a[0])){10 h={};h[a.18()]=a;a=h}26 a=a[0];$$(3.12).20(2(e){10 u=25(e);if(3.14[u])29(10 k in a){if(15(a[k])){a[k].20(2(o){if(15(o))e.11.7(e,[k].13(options[0]))});if(!15(a[k][0]))e.11.7(e,[k].13(a[k][0]))}26 e.11.7(e,[k].13(a[k]))}},3);3.14=[];delete(4.9[3.12]);5 3},9:2(){5 4.9[3.12]===3},on:2(){3.17=$A(6);5 3},8:2(){$$(3.12).20(2(e){10 u=25(e);if(!3.14[u]){e.on.7(e,3.17);3.14[u]=1}},3);5 3}});document.onReady(4.8);19.2830((2(a){10 o=a.23;10 b=a.22;5{23:2(){o.7(3,6);4.8();5 3},22:2(c){b.7(3,6);if(is31(c))4.8();5 3}}})(19.30));$ext(31.prototype,{behave:2(){5 4.28.7(4,[''+3].13($A(6)))},16Behave:2(){5 4.16.7(4,[''+3].13($A(6)))}});",",,function,this,Behavior,return,arguments,apply,refresh,active,var,stopObserving,rule,concat,regs,isArray,stop,args,shift,Element,each,null,update,insert,start,$uid,else,new,add,for,Methods,String".split(",")));