right-rails 1.0.3 → 1.0.5

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 (36) hide show
  1. data/CHANGELOG +8 -2
  2. data/Rakefile +28 -28
  3. data/lib/right_rails/java_script_generator.rb +59 -51
  4. data/public/images/{colorpicker.png → rightjs-ui/colorpicker.png} +0 -0
  5. data/public/images/{resizable.png → rightjs-ui/resizable.png} +0 -0
  6. data/public/javascripts/right-olds-src.js +47 -46
  7. data/public/javascripts/right-safe-src.js +103 -102
  8. data/public/javascripts/right-safe.js +1 -1
  9. data/public/javascripts/right-src.js +611 -541
  10. data/public/javascripts/right.js +86 -85
  11. data/public/javascripts/right/autocompleter-src.js +81 -77
  12. data/public/javascripts/right/autocompleter.js +1 -1
  13. data/public/javascripts/right/calendar-src.js +209 -197
  14. data/public/javascripts/right/calendar.js +6 -6
  15. data/public/javascripts/right/colorpicker-src.js +127 -117
  16. data/public/javascripts/right/colorpicker.js +6 -6
  17. data/public/javascripts/right/dnd-src.js +63 -63
  18. data/public/javascripts/right/dnd.js +2 -2
  19. data/public/javascripts/right/in-edit-src.js +53 -48
  20. data/public/javascripts/right/in-edit.js +2 -2
  21. data/public/javascripts/right/lightbox-src.js +107 -99
  22. data/public/javascripts/right/lightbox.js +2 -2
  23. data/public/javascripts/right/rater-src.js +48 -46
  24. data/public/javascripts/right/rater.js +3 -3
  25. data/public/javascripts/right/resizable-src.js +53 -61
  26. data/public/javascripts/right/resizable.js +4 -4
  27. data/public/javascripts/right/selectable-src.js +97 -95
  28. data/public/javascripts/right/selectable.js +2 -2
  29. data/public/javascripts/right/slider-src.js +47 -45
  30. data/public/javascripts/right/slider.js +8 -8
  31. data/public/javascripts/right/sortable-src.js +54 -52
  32. data/public/javascripts/right/tabs-src.js +181 -171
  33. data/public/javascripts/right/tooltip-src.js +39 -37
  34. data/public/javascripts/right/uploader-src.js +21 -19
  35. data/spec/lib/right_rails/java_script_generator_spec.rb +61 -56
  36. metadata +9 -7
@@ -33,7 +33,7 @@ var R = RightJS,
33
33
 
34
34
 
35
35
 
36
-
36
+
37
37
 
38
38
 
39
39
 
@@ -43,13 +43,13 @@ var R = RightJS,
43
43
  * @param String tag-name or Object methods
44
44
  * @param Object methods
45
45
  * @return Widget wrapper
46
- */
46
+ */
47
47
  function Widget(tag_name, methods) {
48
48
  if (!methods) {
49
49
  methods = tag_name;
50
50
  tag_name = 'DIV';
51
51
  }
52
-
52
+
53
53
  /**
54
54
  * An Abstract Widget Unit
55
55
  *
@@ -66,17 +66,17 @@ function Widget(tag_name, methods) {
66
66
  initialize: function(key, options) {
67
67
  this.key = key;
68
68
  var args = [{'class': 'rui-' + key}];
69
-
69
+
70
70
  // those two have different constructors
71
71
  if (!(this instanceof RightJS.Input || this instanceof RightJS.Form)) {
72
72
  args.unshift(tag_name);
73
73
  }
74
74
  this.$super.apply(this, args);
75
-
75
+
76
76
  if (RightJS.isString(options)) {
77
77
  options = RightJS.$(options);
78
78
  }
79
-
79
+
80
80
  // if the options is another element then
81
81
  // try to dynamically rewrap it with our widget
82
82
  if (options instanceof RightJS.Element) {
@@ -109,16 +109,16 @@ function Widget(tag_name, methods) {
109
109
  return this;
110
110
  }
111
111
  });
112
-
112
+
113
113
  /**
114
114
  * Creating the actual widget class
115
115
  *
116
116
  */
117
117
  var Klass = new RightJS.Wrapper(AbstractWidget, methods);
118
-
118
+
119
119
  // creating the widget related shortcuts
120
120
  RightJS.Observer.createShortcuts(Klass.prototype, Klass.EVENTS || []);
121
-
121
+
122
122
  return Klass;
123
123
  }
124
124
 
@@ -136,18 +136,18 @@ var Spinner = new RightJS.Wrapper(RightJS.Element, {
136
136
  * @return void
137
137
  */
138
138
  initialize: function(size) {
139
- this.$super('div', {'class': 'rui-spinner'});
139
+ this.$super('div', {'class': 'rui-spinner'});
140
140
  this.dots = [];
141
-
141
+
142
142
  for (var i=0; i < (size || 4); i++) {
143
143
  this.dots.push(new RightJS.Element('div'));
144
144
  }
145
-
145
+
146
146
  this.dots[0].addClass('glowing');
147
147
  this.insert(this.dots);
148
148
  RightJS(this.shift).bind(this).periodical(300);
149
149
  },
150
-
150
+
151
151
  /**
152
152
  * Shifts the spinner elements
153
153
  *
@@ -162,6 +162,7 @@ var Spinner = new RightJS.Wrapper(RightJS.Element, {
162
162
  }
163
163
  });
164
164
 
165
+
165
166
  /**
166
167
  * The basic tabs handling engine
167
168
  *
@@ -170,34 +171,34 @@ var Spinner = new RightJS.Wrapper(RightJS.Element, {
170
171
  var Tabs = new Widget('UL', {
171
172
  extend: {
172
173
  version: '2.0.0',
173
-
174
+
174
175
  EVENTS: $w('select hide load disable enable add remove move'),
175
-
176
+
176
177
  Options: {
177
178
  idPrefix: '', // the tab-body elements id prefix
178
179
  tabsElement: null, // the tabs list element reference, in case it's situated somewhere else
179
-
180
+
180
181
  resizeFx: 'both', // 'slide', 'fade', 'both' or null for no fx
181
182
  resizeDuration: 400, // the tab panels resize fx duration
182
-
183
+
183
184
  scrollTabs: false, // use the tabs list scrolling
184
185
  scrollDuration: 400, // the tabs scrolling fx duration
185
-
186
+
186
187
  selected: null, // the index of the currently opened tab, by default will check url, cookies or set 0
187
188
  disabled: null, // list of disabled tab indexes
188
-
189
+
189
190
  closable: false, // set true if you want a close icon on your tabs
190
-
191
+
191
192
  loop: false, // put a delay in ms to make it autostart the slideshow loop
192
193
  loopPause: true, // make the loop get paused when user hovers the tabs with mouse
193
-
194
+
194
195
  url: false, // a common remote tabs url template, should have the %{id} placeholder
195
196
  cache: false, // marker if the remote tabs should be cached
196
-
197
+
197
198
  Xhr: null, // the xhr addtional options
198
199
  Cookie: null // set the cookie options if you'd like to keep the last selected tab index in cookies
199
200
  },
200
-
201
+
201
202
  // scans and automatically intializes the tabs
202
203
  rescan: function(scope) {
203
204
  $(scope || document).find('.rui-tabs,*[data-tabs]').each(function(element) {
@@ -205,7 +206,7 @@ var Tabs = new Widget('UL', {
205
206
  });
206
207
  }
207
208
  },
208
-
209
+
209
210
  /**
210
211
  * The basic constructor
211
212
  *
@@ -217,26 +218,26 @@ var Tabs = new Widget('UL', {
217
218
  .$super('tabs', element)
218
219
  .setOptions(options)
219
220
  .addClass('rui-tabs');
220
-
221
+
221
222
  this.isHarmonica = this._.tagName === 'DL';
222
223
  this.isCarousel = this.hasClass('rui-tabs-carousel');
223
224
  this.isSimple = !this.isHarmonica && !this.isCarousel;
224
-
225
+
225
226
  this
226
227
  .findTabs()
227
228
  .initScrolls()
228
229
  .findCurrent()
229
230
  .setStyle('visibility:visible');
230
-
231
+
231
232
  if (this.options.disabled) {
232
233
  this.disable(this.options.disabled);
233
234
  }
234
-
235
+
235
236
  if (this.options.loop) {
236
237
  this.startLoop();
237
238
  }
238
239
  },
239
-
240
+
240
241
  /**
241
242
  * Shows the given tab
242
243
  *
@@ -246,7 +247,7 @@ var Tabs = new Widget('UL', {
246
247
  select: function(tab) {
247
248
  return this.callTab(tab, 'select');
248
249
  },
249
-
250
+
250
251
  /**
251
252
  * Disables the given tab
252
253
  *
@@ -256,7 +257,7 @@ var Tabs = new Widget('UL', {
256
257
  disable: function(tab) {
257
258
  return this.callTab(tab, 'disable');
258
259
  },
259
-
260
+
260
261
  /**
261
262
  * Enables the given tab
262
263
  *
@@ -266,7 +267,7 @@ var Tabs = new Widget('UL', {
266
267
  enable: function(tab) {
267
268
  return this.callTab(tab, 'enable');
268
269
  },
269
-
270
+
270
271
  /**
271
272
  * Returns the reference to the currently opened tab
272
273
  *
@@ -275,7 +276,7 @@ var Tabs = new Widget('UL', {
275
276
  current: function() {
276
277
  return this.tabs.first('current');
277
278
  },
278
-
279
+
279
280
  /**
280
281
  * Returns the list of enabled tabs
281
282
  *
@@ -284,9 +285,9 @@ var Tabs = new Widget('UL', {
284
285
  enabled: function() {
285
286
  return this.tabs.filter('enabled');
286
287
  },
287
-
288
+
288
289
  // protected
289
-
290
+
290
291
  // calls the tab (or tabs) method
291
292
  callTab: function(tabs, method) {
292
293
  R(isArray(tabs) ? tabs : [tabs]).each(function(tab) {
@@ -295,31 +296,32 @@ var Tabs = new Widget('UL', {
295
296
  tab[method]();
296
297
  }
297
298
  }, this);
298
-
299
+
299
300
  return this;
300
301
  },
301
-
302
+
302
303
  // finds and interconnects the tabs
303
304
  findTabs: function() {
304
305
  this.tabsList = this.isHarmonica ? this :
305
306
  $(this.options.tabsElement) || this.first('.rui-tabs-list') ||
306
307
  (this.first('UL') || $E('UL').insertTo(this)).addClass('rui-tabs-list');
307
-
308
+
308
309
  this.tabs = R([]);
309
-
310
+
310
311
  this.tabsList.children(this.isHarmonica ? 'dt' : null).map(function(node) {
311
312
  this.tabs.push(new Tab(node, this));
312
313
  }, this);
313
-
314
+
314
315
  // removing the whitespaces so the didn't screw with the margins
315
316
  for (var i=0, list = this.tabsList.get('childNodes'); i < list.length; i++) {
316
317
  if (list[i].nodeType == 3) { this.tabsList._.removeChild(list[i]); }
317
318
  }
318
-
319
+
319
320
  return this;
320
321
  }
321
322
  });
322
323
 
324
+
323
325
  /**
324
326
  * A single tab handling object
325
327
  *
@@ -329,7 +331,7 @@ var Tab = Tabs.Tab = new Wrapper(Element, {
329
331
  extend: {
330
332
  autoId: 0
331
333
  },
332
-
334
+
333
335
  /**
334
336
  * Constructor
335
337
  *
@@ -340,81 +342,81 @@ var Tab = Tabs.Tab = new Wrapper(Element, {
340
342
  initialize: function(element, main) {
341
343
  this.$super(element._);
342
344
  this.addClass('rui-tabs-tab');
343
-
345
+
344
346
  this.main = main;
345
347
  this.link = this.first('a');
346
348
  this.id = this.link.get('href').split('#')[1] || Tab.autoId++;
347
349
  this.panel = new Panel(this.findPanel(), this);
348
-
350
+
349
351
  if (this.current()) {
350
352
  this.select();
351
353
  }
352
-
354
+
353
355
  // adding the 'close' icon onto the tab if needed
354
356
  if (main.options.closable) {
355
357
  this.link.insert($E('div', {
356
358
  'class': 'rui-tabs-tab-close-icon', 'html': '&times;'
357
359
  }).onClick(R(this.remove).bind(this)));
358
360
  }
359
-
361
+
360
362
  this.onClick(this._clicked);
361
363
  },
362
-
364
+
363
365
  select: function() {
364
366
  if (this.enabled()) {
365
367
  var prev_tab = this.main.current();
366
368
  if (prev_tab) {
367
369
  prev_tab.removeClass('rui-tabs-current').fire('hide');
368
370
  }
369
-
371
+
370
372
  this.addClass('rui-tabs-current');
371
373
  this.main.scrollToTab(this);
372
374
  this.panel.show();
373
375
  }
374
-
376
+
375
377
  return this.fire('select');
376
378
  },
377
-
379
+
378
380
  disable: function() {
379
381
  return this.addClass('rui-tabs-disabled').fire('disable');
380
382
  },
381
-
383
+
382
384
  enable: function() {
383
385
  return this.removeClass('rui-tabs-disabled').fire('enable');
384
386
  },
385
-
387
+
386
388
  disabled: function() {
387
389
  return !this.enabled();
388
390
  },
389
-
391
+
390
392
  enabled: function() {
391
393
  return !this.hasClass('rui-tabs-disabled');
392
394
  },
393
-
395
+
394
396
  current: function() {
395
397
  return this.hasClass('rui-tabs-current');
396
398
  },
397
-
399
+
398
400
  remove: function(event) {
399
401
  if (event) { event.stop(); }
400
-
402
+
401
403
  // switching to the next available sibling
402
404
  if (this.current()) {
403
405
  var enabled = this.main.enabled();
404
406
  var sibling = enabled[enabled.indexOf(this) + 1] || enabled[enabled.indexOf(this)-1];
405
-
407
+
406
408
  if (sibling) {
407
409
  sibling.select();
408
410
  }
409
411
  }
410
-
412
+
411
413
  // removing the tab out of the list
412
414
  this.main.tabs.splice(this.main.tabs.indexOf(this), 1);
413
415
  this.panel.remove();
414
-
416
+
415
417
  return this.$super().fire('remove');
416
418
  },
417
-
419
+
418
420
  // protected
419
421
 
420
422
  // handles the clicks on the tabs
@@ -426,21 +428,21 @@ var Tab = Tabs.Tab = new Wrapper(Element, {
426
428
  // searches for a panel for the tab
427
429
  findPanel: function() {
428
430
  var main = this.main, panel_id = main.options.idPrefix + this.id, panel;
429
-
431
+
430
432
  if (main.isHarmonica) {
431
433
  var next = this.next();
432
434
  panel = (next && next._.tagName === 'DD') ? next : $E('DD').insertTo(this, 'after');
433
435
  } else {
434
436
  panel = $(panel_id) || $E(main._.tagName === 'UL' ? 'LI' : 'DIV').insertTo(main);
435
437
  }
436
-
438
+
437
439
  return panel.set('id', panel_id);
438
440
  },
439
-
441
+
440
442
  // returns the tab width, used for the scrolling calculations
441
443
  width: function() {
442
444
  var next = this.next();
443
-
445
+
444
446
  if (next) {
445
447
  return next.position().x - this.position().x;
446
448
  } else {
@@ -450,13 +452,14 @@ var Tab = Tabs.Tab = new Wrapper(Element, {
450
452
 
451
453
  });
452
454
 
455
+
453
456
  /**
454
457
  * The tab panels behavior logic
455
458
  *
456
459
  * Copyright (C) 2009-2010 Nikolay Nemshilov
457
460
  */
458
461
  var Panel = Tabs.Panel = new Wrapper(Element, {
459
-
462
+
460
463
  /**
461
464
  * Basic constructor
462
465
  *
@@ -467,11 +470,11 @@ var Panel = Tabs.Panel = new Wrapper(Element, {
467
470
  initialize: function(element, tab) {
468
471
  this.$super(element._);
469
472
  this.addClass('rui-tabs-panel');
470
-
473
+
471
474
  this.tab = tab;
472
475
  this.id = this.get('id');
473
476
  },
474
-
477
+
475
478
  // shows the panel
476
479
  show: function() {
477
480
  return this.resizing(function() {
@@ -480,7 +483,7 @@ var Panel = Tabs.Panel = new Wrapper(Element, {
480
483
  }, this);
481
484
  });
482
485
  },
483
-
486
+
484
487
  // updates the panel content
485
488
  update: function(content) {
486
489
  // don't use resize if it's some other hidden tab was loaded asynch
@@ -491,69 +494,69 @@ var Panel = Tabs.Panel = new Wrapper(Element, {
491
494
  } else {
492
495
  this.$super(content||'');
493
496
  }
494
-
497
+
495
498
  return this;
496
499
  },
497
-
500
+
498
501
  // locks the panel with a spinner locker
499
502
  lock: function() {
500
503
  this.insert(this.locker(), 'top');
501
504
  },
502
-
505
+
503
506
  // protected
504
-
507
+
505
508
  resizing: function(callback) {
506
509
  var controller = this.tab.main;
507
-
510
+
508
511
  if (controller.__working) { return this.resizing.bind(this, callback).delay(100); }
509
-
512
+
510
513
  var options = controller.options;
511
514
  var prev_panel = controller.first('.rui-tabs-panel.rui-tabs-current');
512
515
  var this_panel = this;
513
516
  var swapping = prev_panel !== this_panel;
514
517
  var loading = this.first('div.rui-tabs-panel-locker');
515
-
518
+
516
519
  // sometimes it looses the parent on remote tabs
517
520
  if (this_panel.parent().hasClass('rui-tabs-resizer')) {
518
521
  this_panel.insertTo(prev_panel.parent());
519
522
  }
520
-
523
+
521
524
  if (options.resizeFx && RightJS.Fx && prev_panel && (swapping || loading)) {
522
525
  controller.__working = true;
523
526
  var unlock = function() { controller.__working = false; };
524
-
527
+
525
528
  // calculating the visual effects durations
526
529
  var fx_name = (options.resizeFx === 'both' && loading) ? 'slide' : options.resizeFx;
527
530
  var duration = options.resizeDuration; duration = Fx.Durations[duration] || duration;
528
531
  var resize_duration = fx_name === 'fade' ? 0 : fx_name === 'slide' ? duration : duration / 2;
529
532
  var fade_duration = duration - resize_duration;
530
-
533
+
531
534
  if (fx_name !== 'slide') {
532
535
  this_panel.setStyle({opacity: 0});
533
536
  }
534
-
537
+
535
538
  // saving the previous sizes
536
539
  var prev_panel_height = (controller.isHarmonica && swapping) ? 0 : prev_panel.size().y;
537
-
540
+
538
541
  // applying the changes
539
542
  callback.call(this);
540
-
543
+
541
544
  // getting the new size
542
545
  var new_panel_height = this_panel.size().y;
543
546
  var fx_wrapper = null;
544
547
  var hide_wrapper = null;
545
548
  var prev_back = null;
546
-
549
+
547
550
  if (fx_name !== 'fade' && prev_panel_height !== new_panel_height) {
548
551
  // preserving the whole element size so it didn't jump when we are tossing the tabs around
549
552
  controller._.style.height = controller.size().y + 'px';
550
-
553
+
551
554
  // wrapping the element with an overflowed element to visualize the resize
552
555
  fx_wrapper = $E('div', {
553
556
  'class': 'rui-tabs-resizer',
554
557
  'style': 'height: '+ prev_panel_height + 'px'
555
558
  });
556
-
559
+
557
560
  // in case of harmonica nicely hidding the previous panel
558
561
  if (controller.isHarmonica && swapping) {
559
562
  prev_panel.addClass('rui-tabs-current');
@@ -563,69 +566,70 @@ var Panel = Tabs.Panel = new Wrapper(Element, {
563
566
  hide_wrapper.replace(prev_panel.removeClass('rui-tabs-current'));
564
567
  };
565
568
  prev_panel.wrap(hide_wrapper);
566
-
569
+
567
570
  fx_wrapper._.style.height = '0px';
568
571
  }
569
-
572
+
570
573
  this_panel.wrap(fx_wrapper);
571
-
574
+
572
575
  // getting back the auto-size so we could resize it
573
576
  controller._.style.height = 'auto';
574
-
577
+
575
578
  } else {
576
579
  // removing the resize duration out of the equasion
577
580
  rezise_duration = 0;
578
581
  duration = fade_duration;
579
582
  }
580
-
583
+
581
584
  var counter = 0;
582
585
  var set_back = function() {
583
586
  if (fx_wrapper) {
584
587
  if (fx_name == 'both' && !counter) {
585
588
  return counter ++;
586
589
  }
587
-
590
+
588
591
  fx_wrapper.replace(this_panel);
589
592
  }
590
-
593
+
591
594
  unlock();
592
595
  };
593
-
596
+
594
597
  if (hide_wrapper) {
595
- hide_wrapper.morph({height: '0px'},
598
+ hide_wrapper.morph({height: '0px'},
596
599
  {duration: resize_duration, onFinish: prev_back});
597
600
  }
598
-
601
+
599
602
  if (fx_wrapper) {
600
603
  fx_wrapper.morph({height: new_panel_height + 'px'},
601
604
  {duration: resize_duration, onFinish: set_back});
602
605
  }
603
-
606
+
604
607
  if (fx_name !== 'slide') {
605
608
  this_panel.morph.bind(this_panel, {opacity: 1},
606
609
  {duration: fade_duration, onFinish: set_back}
607
610
  ).delay(resize_duration);
608
611
  }
609
-
612
+
610
613
  if (!fx_wrapper && fx_name === 'slide') {
611
614
  set_back();
612
615
  }
613
-
616
+
614
617
  } else {
615
618
  callback.call(this);
616
619
  }
617
-
620
+
618
621
  return this;
619
622
  },
620
-
623
+
621
624
  // builds the locker element
622
625
  locker: function() {
623
- return this._locker || (this._locker =
626
+ return this._locker || (this._locker =
624
627
  $E('div', {'class': 'rui-tabs-panel-locker'}).insert(new Spinner(5))
625
628
  );
626
629
  }
627
630
  });
628
631
 
632
+
629
633
  /**
630
634
  * Contains the tabs scrolling functionality
631
635
  *
@@ -698,7 +702,7 @@ Tabs.include({
698
702
  )) {
699
703
  this.prevButton = $E('div', {'class': 'rui-tabs-scroller-prev', 'html': '&laquo;'});
700
704
  this.nextButton = $E('div', {'class': 'rui-tabs-scroller-next', 'html': '&raquo;'});
701
-
705
+
702
706
  // using a dummy element to insert the scroller in place of the tabs list
703
707
  $E('div').insertTo(this.tabsList, 'before')
704
708
  .replace(
@@ -709,7 +713,7 @@ Tabs.include({
709
713
  ])
710
714
  ).remove();
711
715
  }
712
-
716
+
713
717
  this.prevButton.onClick(R(this.scrollLeft).bind(this));
714
718
  this.nextButton.onClick(R(this.scrollRight).bind(this));
715
719
  },
@@ -723,7 +727,7 @@ Tabs.include({
723
727
  if (tab) { tab.select(); }
724
728
  }
725
729
  },
726
-
730
+
727
731
  // scrolls the tabs line to make the tab visible
728
732
  scrollToTab: function(tab) {
729
733
  if (this.scroller) {
@@ -733,63 +737,63 @@ Tabs.include({
733
737
  tabs_width += this.tabs[i].width();
734
738
  if (this.tabs[i] === tab) { break; }
735
739
  }
736
-
740
+
737
741
  // calculating the scroll (the carousel tabs should be centralized)
738
742
  var available_width = this.scroller.size().x;
739
743
  var scroll = (this.isCarousel ? (available_width/2 + tab.width()/2) : available_width) - tabs_width;
740
-
744
+
741
745
  // check if the tab doesn't need to be scrolled
742
746
  if (!this.isCarousel) {
743
747
  var current_scroll = parseInt(this.tabsList.getStyle('left') || 0, 10);
744
-
748
+
745
749
  if (scroll >= current_scroll && scroll < (current_scroll + available_width - tab.width())) {
746
750
  scroll = current_scroll;
747
751
  } else if (current_scroll > -tabs_width && current_scroll <= (tab.width() - tabs_width)) {
748
752
  scroll = tab.width() - tabs_width;
749
753
  }
750
754
  }
751
-
755
+
752
756
  this.scrollTo(scroll);
753
757
  }
754
758
  },
755
-
759
+
756
760
  // just scrolls the scrollable area onto the given number of scrollable area widths
757
761
  justScroll: function(size) {
758
762
  if (!this.scroller) { return this; }
759
763
  var current_scroll = parseInt(this.tabsList.getStyle('left') || 0, 10);
760
764
  var available_width = this.scroller.size().x;
761
-
765
+
762
766
  this.scrollTo(current_scroll + available_width * size);
763
767
  },
764
-
768
+
765
769
  // scrolls the tabs list to the position
766
770
  scrollTo: function(scroll) {
767
771
  // checking the constraints
768
772
  var available_width = this.scroller.size().x;
769
773
  var overall_width = this.tabs.map('width').sum();
770
-
774
+
771
775
  if (scroll < (available_width - overall_width)) {
772
776
  scroll = available_width - overall_width;
773
777
  }
774
778
  if (scroll > 0) { scroll = 0; }
775
-
779
+
776
780
  // applying the scroll
777
781
  this.tabsList.morph({left: scroll+'px'}, {duration: this.options.scrollDuration});
778
-
782
+
779
783
  this.checkScrollButtons(overall_width, available_width, scroll);
780
784
  },
781
-
785
+
782
786
  // checks the scroll buttons
783
787
  checkScrollButtons: function(overall_width, available_width, scroll) {
784
788
  var has_prev = false, has_next = false;
785
-
789
+
786
790
  if (this.isCarousel) {
787
791
  var enabled = this.enabled();
788
792
  var current = enabled.first('current');
789
-
793
+
790
794
  if (current) {
791
795
  var index = enabled.indexOf(current);
792
-
796
+
793
797
  has_prev = index > 0;
794
798
  has_next = index < enabled.length - 1;
795
799
  }
@@ -797,13 +801,14 @@ Tabs.include({
797
801
  has_prev = scroll !== 0;
798
802
  has_next = scroll > (available_width - overall_width);
799
803
  }
800
-
804
+
801
805
  this.prevButton[has_prev ? 'removeClass' : 'addClass']('rui-tabs-scroller-disabled');
802
806
  this.nextButton[has_next ? 'removeClass' : 'addClass']('rui-tabs-scroller-disabled');
803
807
  }
804
-
808
+
805
809
  });
806
810
 
811
+
807
812
  /**
808
813
  * This module handles the current tab state saving/restoring processes
809
814
  *
@@ -823,9 +828,9 @@ function save_tab_in_cookies(options, tabs, event) {
823
828
  }
824
829
 
825
830
  Tabs.include({
826
-
831
+
827
832
  // protected
828
-
833
+
829
834
  // searches and activates the current tab
830
835
  findCurrent: function() {
831
836
  var current;
@@ -835,23 +840,23 @@ Tabs.include({
835
840
  var enabled = this.enabled();
836
841
  current = enabled[this.urlIndex()] || enabled[this.cookieIndex()] || enabled.first('current') || enabled[0];
837
842
  }
838
-
843
+
839
844
  if (current) {
840
845
  current.select();
841
846
  }
842
-
847
+
843
848
  // initializing the cookies storage if set
844
849
  if (this.options.Cookie) {
845
850
  this.onSelect(R(save_tab_in_cookies).curry(this.options.Cookie, this.tabs));
846
851
  }
847
-
852
+
848
853
  return this;
849
854
  },
850
-
855
+
851
856
  // tries to find the current tab index in the url hash
852
857
  urlIndex: function() {
853
858
  var index = -1, id = document.location.href.split('#')[1];
854
-
859
+
855
860
  if (id) {
856
861
  for (var i=0; i < this.tabs.length; i++) {
857
862
  if (this.tabs[i].id == id) {
@@ -860,14 +865,14 @@ Tabs.include({
860
865
  }
861
866
  }
862
867
  }
863
-
868
+
864
869
  return index;
865
870
  },
866
-
871
+
867
872
  // tries to find the current tab index in the cookies storage
868
873
  cookieIndex: function() {
869
874
  var index = -1;
870
-
875
+
871
876
  if (this.options.Cookie) {
872
877
  var indexes = get_cookie_indexes();
873
878
  for (var i=0; i < this.tabs.length; i++) {
@@ -877,14 +882,15 @@ Tabs.include({
877
882
  }
878
883
  }
879
884
  }
880
-
885
+
881
886
  return index;
882
887
  }
883
-
888
+
884
889
  });
885
890
 
891
+
886
892
  /**
887
- * This module handles the tabs cration and removing processes
893
+ * This module handles the tabs cration and removing processes
888
894
  *
889
895
  * Copyright (C) 2009-2010 Nikolay Nemshilov
890
896
  */
@@ -908,26 +914,26 @@ Tabs.include({
908
914
  */
909
915
  add: function(title, content, options) {
910
916
  options = options || {};
911
-
917
+
912
918
  // creating the new tab element
913
919
  var element = $E(this.isHarmonica ? 'dt' : 'li').insert(
914
920
  $E('a', {html: title, href: options.url || '#'+(options.id||'')}
915
921
  )).insertTo(this.tabsList);
916
-
922
+
917
923
  // creating the actual tab instance
918
924
  var tab = new Tab(element, this);
919
925
  tab.panel.update(content||'');
920
926
  this.tabs.push(tab);
921
927
  tab.fire('add');
922
-
928
+
923
929
  // moving the tab in place if asked
924
930
  if ('position' in options) {
925
931
  this.move(tab, options.position);
926
932
  }
927
-
933
+
928
934
  return this;
929
935
  },
930
-
936
+
931
937
  /**
932
938
  * Moves the given tab to the given position
933
939
  *
@@ -939,26 +945,26 @@ Tabs.include({
939
945
  */
940
946
  move: function(tab, position) {
941
947
  tab = this.tabs[tab] || tab;
942
-
948
+
943
949
  if (this.tabs[position] && this.tabs[position] !== tab) {
944
950
  // moving the tab element
945
951
  this.tabs[position].insert(tab, (position === this.tabs.length-1) ? 'after' : 'before');
946
-
952
+
947
953
  // inserting the panel after the tab if it's a harmonica
948
954
  if (this.isHarmonica) {
949
955
  tab.insert(tab.panel, 'after');
950
956
  }
951
-
957
+
952
958
  // moving the tab in the registry
953
959
  this.tabs.splice(this.tabs.indexOf(tab), 1);
954
960
  this.tabs.splice(position, 0, tab);
955
-
961
+
956
962
  tab.fire('move', {index: position});
957
963
  }
958
-
964
+
959
965
  return this;
960
966
  },
961
-
967
+
962
968
  /**
963
969
  * Removes the given tab
964
970
  *
@@ -968,9 +974,10 @@ Tabs.include({
968
974
  remove: function(tab) {
969
975
  return this.callTab(tab, 'remove');
970
976
  }
971
-
977
+
972
978
  });
973
979
 
980
+
974
981
  /**
975
982
  * This module contains the remote tabs loading logic
976
983
  *
@@ -979,32 +986,32 @@ Tabs.include({
979
986
  var old_select = Tab.prototype.select;
980
987
 
981
988
  Tab.include({
982
-
989
+
983
990
  // wrapping the original mehtod, to catch the remote requests
984
991
  select: function() {
985
992
  if (this.dogPiling(arguments)) { return this; }
986
-
993
+
987
994
  var result = old_select.apply(this, arguments);
988
995
  var url = R(this.link.get('href'));
989
996
  var options = this.main.options;
990
-
997
+
991
998
  // building the url
992
999
  if (url.includes('#')) {
993
1000
  url = options.url ? options.url.replace('%{id}', url.split('#')[1]) : null;
994
1001
  }
995
-
1002
+
996
1003
  // if there is an actual url and no ongoing request or a cache, starting the request
997
1004
  if (url && !this.request && !(options.cache || this.cache)) {
998
1005
  this.panel.lock();
999
-
1006
+
1000
1007
  try { // basically that's for the development tests, so the IE browsers didn't get screwed on the test page
1001
-
1008
+
1002
1009
  this.request = new RightJS.Xhr(url, Object.merge({method: 'get'}, options.Xhr))
1003
1010
  .onComplete(R(function(response) {
1004
1011
  if (this.main.__working) {
1005
1012
  return arguments.callee.bind(this, response).delay(100);
1006
1013
  }
1007
-
1014
+
1008
1015
  this.panel.update(response.text);
1009
1016
 
1010
1017
  this.request = null; // removing the request marker so it could be rerun
@@ -1015,13 +1022,13 @@ Tab.include({
1015
1022
  this.fire('load');
1016
1023
  }).bind(this)
1017
1024
  ).send();
1018
-
1025
+
1019
1026
  } catch(e) { if (!Browser.OLD) { throw(e); } }
1020
1027
  }
1021
-
1028
+
1022
1029
  return result;
1023
1030
  },
1024
-
1031
+
1025
1032
  // protected
1026
1033
 
1027
1034
  dogPiling: function(args) {
@@ -1029,26 +1036,27 @@ Tab.include({
1029
1036
  if (this.main.__timeout) {
1030
1037
  this.main.__timeout.cancel();
1031
1038
  }
1032
-
1039
+
1033
1040
  this.main.__timeout = R(function(args) {
1034
1041
  this.select.apply(this, args);
1035
1042
  }).bind(this, args).delay(100);
1036
-
1043
+
1037
1044
  return true;
1038
1045
  }
1039
-
1046
+
1040
1047
  return (this.main.__timeout = null);
1041
1048
  }
1042
-
1049
+
1043
1050
  });
1044
1051
 
1052
+
1045
1053
  /**
1046
1054
  * This module handles the slide-show loop feature for the Tabs
1047
1055
  *
1048
1056
  * Copyright (C) 2009-2010 Nikolay Nemshilov
1049
1057
  */
1050
1058
  Tabs.include({
1051
-
1059
+
1052
1060
  /**
1053
1061
  * Starts the slideshow loop
1054
1062
  *
@@ -1057,32 +1065,32 @@ Tabs.include({
1057
1065
  */
1058
1066
  startLoop: function(delay) {
1059
1067
  if (!delay && !this.options.loop) { return this; }
1060
-
1068
+
1061
1069
  // attaching the loop pause feature
1062
1070
  if (this.options.loopPause) {
1063
1071
  this._stopLoop = this._stopLoop || R(this.stopLoop).bind(this, true);
1064
1072
  this._startLoop = this._startLoop || R(this.startLoop).bind(this, delay);
1065
-
1073
+
1066
1074
  this.forgetHovers().on({
1067
1075
  mouseover: this._stopLoop,
1068
1076
  mouseout: this._startLoop
1069
1077
  });
1070
1078
  }
1071
-
1079
+
1072
1080
  if (this.timer) { this.timer.stop(); }
1073
-
1081
+
1074
1082
  this.timer = R(function() {
1075
1083
  var enabled = this.enabled();
1076
1084
  var current = this.current();
1077
1085
  var next = enabled[enabled.indexOf(current)+1];
1078
-
1086
+
1079
1087
  this.select(next || enabled.first());
1080
-
1088
+
1081
1089
  }).bind(this).periodical(this.options.loop || delay);
1082
-
1090
+
1083
1091
  return this;
1084
1092
  },
1085
-
1093
+
1086
1094
  /**
1087
1095
  * Stops the slideshow loop
1088
1096
  *
@@ -1097,17 +1105,18 @@ Tabs.include({
1097
1105
  this.forgetHovers();
1098
1106
  }
1099
1107
  },
1100
-
1108
+
1101
1109
  // private
1102
1110
  forgetHovers: function() {
1103
1111
  return this
1104
1112
  .stopObserving('mouseover', this._stopLoop)
1105
1113
  .stopObserving('mouseout', this._startLoop);
1106
1114
  }
1107
-
1108
-
1115
+
1116
+
1109
1117
  });
1110
1118
 
1119
+
1111
1120
  /**
1112
1121
  * The document level hooks for the tabs-egnine
1113
1122
  *
@@ -1117,7 +1126,8 @@ $(document).onReady(function() {
1117
1126
  Tabs.rescan();
1118
1127
  });
1119
1128
 
1129
+
1120
1130
  document.write("<style type=\"text/css\">div.rui-spinner,div.rui-spinner div{margin:0;padding:0;border:none;background:none;list-style:none;font-weight:normal;float:none;display:inline-block; *display:inline; *zoom:1;border-radius:.12em;-moz-border-radius:.12em;-webkit-border-radius:.12em}div.rui-spinner{text-align:center;white-space:nowrap;background:#EEE;border:1px solid #DDD;height:1.2em;padding:0 .2em}div.rui-spinner div{width:.4em;height:70%;background:#BBB;margin-left:1px}div.rui-spinner div:first-child{margin-left:0}div.rui-spinner div.glowing{background:#777}.rui-tabs,.rui-tabs-list,.rui-tabs-tab,.rui-tabs-panel,.rui-tabs-scroll-left,.rui-tabs-scroll-right,.rui-tabs-scroll-body,.rui-tabs-panel-locker,.rui-tabs-resizer{margin:0;padding:0;background:none;border:none;list-style:none;display:block;width:auto;height:auto}.rui-tabs{display:block;visibility:hidden;border-bottom:1px solid #CCC}.rui-tabs-resizer{overflow:hidden}.rui-tabs-list{display:block;position:relative;padding:0 .5em;border-bottom:1px solid #CCC;white-space:nowrap}.rui-tabs-list .rui-tabs-tab,.rui-tabs-tab *,.rui-tabs-tab *:hover{display:inline-block; *display:inline; *zoom:1;cursor:pointer;text-decoration:none;vertical-align:center}.rui-tabs-list .rui-tabs-tab{vertical-align:bottom;margin-right:.1em}.rui-tabs-tab a{outline:none;position:relative;border:1px solid #CCC;background:#DDD;color:#444;padding:.3em 1em;border-radius:.3em;-moz-border-radius:.3em;-webkit-border-radius:.3em;border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-bottomright:0;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0}.rui-tabs-tab a:hover{border-color:#CCC;background:#EEE}.rui-tabs-list .rui-tabs-current a,.rui-tabs-list .rui-tabs-current a:hover{font-weight:bold;color:#000;background:#FFF;border-bottom:1px solid #FFF;border-top-width:2px;padding-top:.34em;padding-bottom:.34em;top:1px}.rui-tabs-tab a img{border:none;opacity:.6;filter:alpha(opacity=60)}.rui-tabs-tab a:hover img,.rui-tabs-list .rui-tabs-current a img{opacity:1;filter:alpha(opacity=100)}.rui-tabs-disabled a,.rui-tabs-disabled a:hover{background:#EEE;border-color:#DDD;color:#AAA;cursor:default}.rui-tabs-disabled a img,.rui-tabs-disabled a:hover img{opacity:.5;filter:alpha(opacity=50)}.rui-tabs-tab-close-icon{display:inline-block; *display:inline; *zoom:1;margin-right:-0.5em;margin-left:0.5em;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}.rui-tabs-tab-close-icon:hover{opacity:1;filter:alpha(opacity=100);color:#B00;text-shadow:#888 .15em .15em .2em}.rui-tabs-panel{display:none;position:relative;min-height:4em;padding:.5em 0}.rui-tabs-current{display:block}.rui-tabs-scroller{position:relative;padding:0 1.4em}.rui-tabs-scroller-prev,.rui-tabs-scroller-next{width:1.1em;text-align:center;background:#EEE;color:#666;cursor:pointer;border:1px solid #CCC;border-radius:.2em;-moz-border-radius:.2em;-webkit-border-radius:.2em;position:absolute;bottom:0px;left:0px;padding:0.3em 0;user-select:none;-moz-user-select:none;-webkit-user-select:none}.rui-tabs-scroller-prev:hover,.rui-tabs-scroller-next:hover{color:#000;background:#DDD;border-color:#AAA}.rui-tabs-scroller-prev:active,.rui-tabs-scroller-next:active{background:#eee;border-color:#ccc}.rui-tabs-scroller-next{left:auto;right:0px}.rui-tabs-scroller-disabled,.rui-tabs-scroller-disabled:hover{cursor:default;background:#DDD;border-color:#DDD;color:#AAA}.rui-tabs-scroller-body{overflow:hidden;width:100%;position:relative}.rui-tabs-scroller .rui-tabs-list{padding-left:0;padding-right:0;width:9999em;z-index:10}.rui-tabs-panel-locker{position:absolute;top:0px;left:0px;opacity:0.5;filter:alpha(opacity=50);background:#CCC;width:100%;height:100%;text-align:center}.rui-tabs-panel-locker .rui-spinner{position:absolute;left:44%;top:44%;background:none;border:none;height:2em}.rui-tabs-panel-locker .rui-spinner div{background:#666;width:.65em;margin-left:.15em}.rui-tabs-panel-locker .rui-spinner div.glowing{background:#000}.rui-tabs-carousel .rui-tabs-list{border:none}.rui-tabs-carousel .rui-tabs-tab a,.rui-tabs-carousel .rui-tabs-scroller .rui-tabs-scroller-prev,.rui-tabs-carousel .rui-tabs-scroller .rui-tabs-scroller-next{height:6em;line-height:6em;padding:0;border-bottom:1px solid #ccc;border-radius:.25em;-moz-border-radius:.25em;-webkit-border-radius:.25em}.rui-tabs-carousel .rui-tabs-tab{margin-right:3px}.rui-tabs-carousel .rui-tabs-tab a img{border:1px solid #CCC;vertical-align:middle;margin:.4em;padding:0;border-radius:0;-moz-border-radius:0;-webkit-border-radius:0}.rui-tabs-carousel .rui-tabs-list .rui-tabs-current a{border-width:1px;border-color:#AAA;padding:0;top:auto}.rui-tabs-carousel .rui-tabs-list .rui-tabs-current a img{border-color:#bbb}.rui-tabs-carousel .rui-tabs-panel{text-align:center}dl.rui-tabs{border:none}dt.rui-tabs-tab,dt.rui-tabs-tab a,dt.rui-tabs-tab a:hover{display:block;float:none}dt.rui-tabs-tab a,dt.rui-tabs-tab a:hover{padding:.2em 1em;border:1px solid #ccc;border-radius:.25em;-moz-border-radius:.3em;-webkit-border-radius:.3em}dl.rui-tabs dt.rui-tabs-current a{background:#EEE;border-bottom-left-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-bottomright:0;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0}dl.rui-tabs dd.rui-tabs-current+dt.rui-tabs-tab a{border-top-left-radius:0;border-top-right-radius:0;-moz-border-radius-topleft:0;-moz-border-radius-topright:0;-webkit-border-top-left-radius:0;-webkit-border-top-right-radius:0}</style>");
1121
1131
 
1122
1132
  return Tabs;
1123
- })(document, parseInt, RightJS);
1133
+ })(document, parseInt, RightJS);