puffer_pages 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/Gemfile +11 -7
  2. data/Gemfile.lock +130 -114
  3. data/Guardfile +20 -0
  4. data/README.md +3 -3
  5. data/VERSION +1 -1
  6. data/app/assets/javascripts/puffer/codemirror-base.js +1 -0
  7. data/app/assets/javascripts/puffer/codemirror-parser.js +1 -0
  8. data/app/assets/javascripts/puffer/codemirror.js +1 -0
  9. data/{spec/dummy/public/puffer/javascripts → app/assets/javascripts/puffer}/puffer_pages.js +11 -0
  10. data/{lib/generators/puffer_pages/install/templates/puffer/javascripts → app/assets/javascripts/puffer}/right-dialog.js +0 -0
  11. data/{lib/generators/puffer_pages/install/templates/puffer/javascripts → app/assets/javascripts/puffer}/right-tabs.js +0 -0
  12. data/app/assets/stylesheets/codemirror.css +135 -0
  13. data/app/assets/stylesheets/puffer_pages.css +12 -0
  14. data/{lib/generators/puffer_pages/install/templates/puffer → app/assets}/stylesheets/puffer_tree.css +0 -0
  15. data/{lib/generators/puffer_pages/install/templates/controllers → app/controllers/admin}/layouts_controller.rb +0 -0
  16. data/{lib/generators/puffer_pages/install/templates/controllers → app/controllers/admin}/pages_controller.rb +0 -0
  17. data/{lib/generators/puffer_pages/install/templates/controllers → app/controllers/admin}/snippets_controller.rb +0 -0
  18. data/app/controllers/pages_controller.rb +2 -2
  19. data/app/controllers/puffer_pages/layouts_controller.rb +2 -2
  20. data/app/controllers/puffer_pages/pages_controller.rb +1 -2
  21. data/app/controllers/puffer_pages/snippets_controller.rb +2 -2
  22. data/app/helpers/puffer_pages_helper.rb +1 -1
  23. data/app/models/layout.rb +1 -5
  24. data/app/models/page.rb +1 -105
  25. data/app/models/page_part.rb +1 -20
  26. data/app/models/puffer_pages/layout.rb +8 -0
  27. data/app/models/puffer_pages/page.rb +107 -0
  28. data/app/models/puffer_pages/page_part.rb +23 -0
  29. data/app/models/puffer_pages/snippet.rb +6 -0
  30. data/app/models/snippet.rb +1 -3
  31. data/app/views/{puffer_tree → puffer/tree_base}/_record.html.erb +0 -0
  32. data/app/views/{puffer_tree → puffer/tree_base}/toggle.js.erb +0 -0
  33. data/app/views/{puffer_tree → puffer/tree_base}/tree.html.erb +0 -0
  34. data/app/views/puffer_pages/{_page_part_builder.html.erb → pages/_page_part_builder.html.erb} +1 -1
  35. data/app/views/puffer_pages/{_page_parts.html.erb → pages/_page_parts.html.erb} +0 -0
  36. data/app/views/puffer_pages/{_tree_page.html.erb → pages/_tree_page.html.erb} +0 -0
  37. data/config/locales/en.yml +3 -1
  38. data/{lib/generators/puffer_pages/install/templates → db}/migrate/20090422092419_create_pages.rb +0 -0
  39. data/{lib/generators/puffer_pages/install/templates → db}/migrate/20090504132337_create_page_parts.rb +0 -0
  40. data/{lib/generators/puffer_pages/install/templates → db}/migrate/20090506102004_create_layouts.rb +0 -0
  41. data/{lib/generators/puffer_pages/install/templates → db}/migrate/20090510121824_create_snippets.rb +0 -0
  42. data/lib/puffer/inputs/page_parts.rb +0 -1
  43. data/lib/puffer/inputs/page_parts_body.rb +0 -1
  44. data/lib/puffer/tree_base.rb +1 -2
  45. data/lib/puffer_pages/engine.rb +0 -4
  46. data/lib/puffer_pages/liquid/file_system.rb +7 -3
  47. data/lib/puffer_pages/liquid/page_drop.rb +13 -6
  48. data/lib/puffer_pages.rb +0 -5
  49. data/puffer_pages.gemspec +63 -107
  50. data/spec/dummy/Rakefile +1 -1
  51. data/spec/dummy/app/assets/images/rails.png +0 -0
  52. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  53. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  54. data/spec/dummy/app/controllers/puffer/dashboard_controller.rb +1 -1
  55. data/spec/dummy/app/controllers/puffer/sessions_controller.rb +1 -1
  56. data/spec/dummy/app/views/layouts/application.html.erb +3 -3
  57. data/spec/dummy/config/application.rb +4 -8
  58. data/spec/dummy/config/application.rb.orig +43 -0
  59. data/spec/dummy/config/boot.rb +5 -7
  60. data/spec/dummy/config/boot.rb.orig +6 -0
  61. data/spec/dummy/config/environments/development.rb +4 -3
  62. data/spec/dummy/config/environments/pg_test.rb +5 -1
  63. data/spec/dummy/config/environments/production.rb +14 -12
  64. data/spec/dummy/config/environments/test.rb +5 -1
  65. data/spec/dummy/config/initializers/secret_token.rb +1 -1
  66. data/spec/dummy/config/initializers/session_store.rb +1 -1
  67. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  68. data/spec/dummy/config/locales/en.yml +1 -1
  69. data/spec/dummy/config/routes.rb +3 -1
  70. data/spec/dummy/config/routes.rb.orig +58 -0
  71. data/spec/dummy/db/seeds.rb +7 -0
  72. data/spec/dummy/public/robots.txt +5 -0
  73. data/spec/fabricators/pages_fabricator.rb +1 -0
  74. data/spec/lib/core_spec.rb +1 -1
  75. data/spec/lib/drops_spec.rb +13 -8
  76. data/spec/models/page_spec.rb +4 -3
  77. data/spec/spec_helper.rb +14 -1
  78. metadata +200 -288
  79. data/autotest/discover.rb +0 -2
  80. data/lib/generators/puffer_pages/install/USAGE +0 -6
  81. data/lib/generators/puffer_pages/install/install_generator.rb +0 -24
  82. data/lib/generators/puffer_pages/install/templates/puffer/javascripts/puffer_pages.js +0 -35
  83. data/lib/generators/puffer_pages/install/templates/puffer/stylesheets/puffer_pages.css +0 -4
  84. data/lib/generators/puffer_pages/install/templates/puffer_pages.rb +0 -16
  85. data/spec/dummy/app/controllers/admin/layouts_controller.rb +0 -3
  86. data/spec/dummy/app/controllers/admin/pages_controller.rb +0 -3
  87. data/spec/dummy/app/controllers/admin/snippets_controller.rb +0 -3
  88. data/spec/dummy/config/initializers/puffer.rb +0 -12
  89. data/spec/dummy/config/initializers/puffer_pages.rb +0 -16
  90. data/spec/dummy/public/javascripts/application.js +0 -2
  91. data/spec/dummy/public/javascripts/controls.js +0 -965
  92. data/spec/dummy/public/javascripts/dragdrop.js +0 -974
  93. data/spec/dummy/public/javascripts/effects.js +0 -1123
  94. data/spec/dummy/public/javascripts/prototype.js +0 -6001
  95. data/spec/dummy/public/javascripts/rails.js +0 -175
  96. data/spec/dummy/public/puffer/javascripts/puffer.js +0 -10
  97. data/spec/dummy/public/puffer/javascripts/rails.js +0 -57
  98. data/spec/dummy/public/puffer/javascripts/right-autocompleter.js +0 -621
  99. data/spec/dummy/public/puffer/javascripts/right-calendar.js +0 -1461
  100. data/spec/dummy/public/puffer/javascripts/right-dialog.js +0 -764
  101. data/spec/dummy/public/puffer/javascripts/right-tabs.js +0 -1144
  102. data/spec/dummy/public/puffer/javascripts/right.js +0 -5892
  103. data/spec/dummy/public/puffer/stylesheets/puffer.css +0 -469
  104. data/spec/dummy/public/puffer/stylesheets/puffer_pages.css +0 -4
  105. data/spec/dummy/public/puffer/stylesheets/puffer_tree.css +0 -64
  106. data/spec/dummy/public/puffer/stylesheets/reset.css +0 -60
  107. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
@@ -1,1144 +0,0 @@
1
- /**
2
- * Tabs widget for RightJS (http://rightjs.org/ui/tabs)
3
- *
4
- * Copyright (C) 2009-2010 Nikolay Nemshilov
5
- */
6
- var Tabs = RightJS.Tabs = (function(document, parseInt, RightJS) {
7
- /**
8
- * This module defines the basic widgets constructor
9
- * it creates an abstract proxy with the common functionality
10
- * which then we reuse and override in the actual widgets
11
- *
12
- * Copyright (C) 2010-2011 Nikolay Nemshilov
13
- */
14
-
15
- /**
16
- * The tabs init-script
17
- *
18
- * Copyright (C) 2010-2011 Nikolay Nemshilov
19
- */
20
- var R = RightJS,
21
- $ = RightJS.$,
22
- $$ = RightJS.$$,
23
- $w = RightJS.$w,
24
- $E = RightJS.$E,
25
- Fx = RightJS.Fx,
26
- Object = RightJS.Object,
27
- Browser = RightJS.Browser,
28
- isArray = RightJS.isArray,
29
- isNumber = RightJS.isNumber,
30
- Class = RightJS.Class,
31
- Element = RightJS.Element,
32
- Cookie = RightJS.Cookie;
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
- /**
41
- * The widget units constructor
42
- *
43
- * @param String tag-name or Object methods
44
- * @param Object methods
45
- * @return Widget wrapper
46
- */
47
- function Widget(tag_name, methods) {
48
- if (!methods) {
49
- methods = tag_name;
50
- tag_name = 'DIV';
51
- }
52
-
53
- /**
54
- * An Abstract Widget Unit
55
- *
56
- * Copyright (C) 2010 Nikolay Nemshilov
57
- */
58
- var AbstractWidget = new RightJS.Class(RightJS.Element.Wrappers[tag_name] || RightJS.Element, {
59
- /**
60
- * The common constructor
61
- *
62
- * @param Object options
63
- * @param String optional tag name
64
- * @return void
65
- */
66
- initialize: function(key, options) {
67
- this.key = key;
68
- var args = [{'class': 'rui-' + key}];
69
-
70
- // those two have different constructors
71
- if (!(this instanceof RightJS.Input || this instanceof RightJS.Form)) {
72
- args.unshift(tag_name);
73
- }
74
- this.$super.apply(this, args);
75
-
76
- if (RightJS.isString(options)) {
77
- options = RightJS.$(options);
78
- }
79
-
80
- // if the options is another element then
81
- // try to dynamically rewrap it with our widget
82
- if (options instanceof RightJS.Element) {
83
- this._ = options._;
84
- if ('$listeners' in options) {
85
- options.$listeners = options.$listeners;
86
- }
87
- options = {};
88
- }
89
- this.setOptions(options, this);
90
-
91
- return (RightJS.Wrapper.Cache[RightJS.$uid(this._)] = this);
92
- },
93
-
94
- // protected
95
-
96
- /**
97
- * Catches the options
98
- *
99
- * @param Object user-options
100
- * @param Element element with contextual options
101
- * @return void
102
- */
103
- setOptions: function(options, element) {
104
- element = element || this;
105
- RightJS.Options.setOptions.call(this,
106
- RightJS.Object.merge(options, eval("("+(
107
- element.get('data-'+ this.key) || '{}'
108
- )+")"))
109
- );
110
- return this;
111
- }
112
- });
113
-
114
- /**
115
- * Creating the actual widget class
116
- *
117
- */
118
- var Klass = new RightJS.Class(AbstractWidget, methods);
119
-
120
- // creating the widget related shortcuts
121
- RightJS.Observer.createShortcuts(Klass.prototype, Klass.EVENTS || []);
122
-
123
- return Klass;
124
- }
125
-
126
-
127
- /**
128
- * A shared module to create textual spinners
129
- *
130
- * Copyright (C) 2010-2011 Nikolay Nemshilov
131
- */
132
- var Spinner = new RightJS.Class(RightJS.Element, {
133
- /**
134
- * Constructor
135
- *
136
- * @param Number optional spinner size (4 by default)
137
- * @return void
138
- */
139
- initialize: function(size) {
140
- this.$super('div', {'class': 'rui-spinner'});
141
- this.dots = [];
142
-
143
- for (var i=0; i < (size || 4); i++) {
144
- this.dots.push(new RightJS.Element('div'));
145
- }
146
-
147
- this.dots[0].addClass('glowing');
148
- this.insert(this.dots);
149
- RightJS(this.shift).bind(this).periodical(300);
150
- },
151
-
152
- /**
153
- * Shifts the spinner elements
154
- *
155
- * @return void
156
- */
157
- shift: function() {
158
- if (this.visible()) {
159
- var dot = this.dots.pop();
160
- this.dots.unshift(dot);
161
- this.insert(dot, 'top');
162
- }
163
- }
164
- });
165
-
166
-
167
- /**
168
- * The basic tabs handling engine
169
- *
170
- * Copyright (C) 2009-2011 Nikolay Nemshilov
171
- */
172
- var Tabs = new Widget('UL', {
173
- extend: {
174
- version: '2.2.0',
175
-
176
- EVENTS: $w('select hide load disable enable add remove move'),
177
-
178
- Options: {
179
- idPrefix: '', // the tab-body elements id prefix
180
- tabsElement: null, // the tabs list element reference, in case it's situated somewhere else
181
-
182
- resizeFx: 'both', // 'slide', 'fade', 'both' or null for no fx
183
- resizeDuration: 400, // the tab panels resize fx duration
184
-
185
- scrollTabs: false, // use the tabs list scrolling
186
- scrollDuration: 400, // the tabs scrolling fx duration
187
-
188
- selected: null, // the index of the currently opened tab, by default will check url, cookies or set 0
189
- disabled: null, // list of disabled tab indexes
190
-
191
- closable: false, // set true if you want a close icon on your tabs
192
-
193
- loop: false, // put a delay in ms to make it autostart the slideshow loop
194
- loopPause: true, // make the loop get paused when user hovers the tabs with mouse
195
-
196
- url: false, // a common remote tabs url template, should have the %{id} placeholder
197
- cache: false, // marker if the remote tabs should be cached
198
-
199
- Xhr: null, // the xhr addtional options
200
- Cookie: null // set the cookie options if you'd like to keep the last selected tab index in cookies
201
- },
202
-
203
- // scans and automatically intializes the tabs
204
- rescan: function(scope) {
205
- $(scope || document).find('.rui-tabs,*[data-tabs]').each(function(element) {
206
- element = element instanceof Tabs ? element : new Tabs(element);
207
- });
208
- }
209
- },
210
-
211
- /**
212
- * The basic constructor
213
- *
214
- * @param element or id
215
- * @param Object options
216
- */
217
- initialize: function(element, options) {
218
- this
219
- .$super('tabs', element)
220
- .addClass('rui-tabs');
221
-
222
- this.isHarmonica = this._.tagName === 'DL';
223
- this.isCarousel = this.hasClass('rui-tabs-carousel');
224
- this.isSimple = !this.isHarmonica && !this.isCarousel;
225
-
226
- this
227
- .findTabs()
228
- .initScrolls()
229
- .findCurrent()
230
- .setStyle('visibility:visible');
231
-
232
- if (this.options.disabled) {
233
- this.disable(this.options.disabled);
234
- }
235
-
236
- if (this.options.loop) {
237
- this.startLoop();
238
- }
239
- },
240
-
241
- /**
242
- * Shows the given tab
243
- *
244
- * @param integer tab index or a Tabs.Tab instance
245
- * @return Tabs this
246
- */
247
- select: function(tab) {
248
- return this.callTab(tab, 'select');
249
- },
250
-
251
- /**
252
- * Disables the given tab
253
- *
254
- * @param integer tab index or a Tabs.Tab instance or a list of them
255
- * @return Tabs this
256
- */
257
- disable: function(tab) {
258
- return this.callTab(tab, 'disable');
259
- },
260
-
261
- /**
262
- * Enables the given tab
263
- *
264
- * @param integer tab index or a Tabs.Tab instance or a list of them
265
- * @return Tabs this
266
- */
267
- enable: function(tab) {
268
- return this.callTab(tab, 'enable');
269
- },
270
-
271
- /**
272
- * Returns the reference to the currently opened tab
273
- *
274
- * @return Tab tab or undefined
275
- */
276
- current: function() {
277
- return this.tabs.first('current');
278
- },
279
-
280
- /**
281
- * Returns the list of enabled tabs
282
- *
283
- * @return Array of enabled tabs
284
- */
285
- enabled: function() {
286
- return this.tabs.filter('enabled');
287
- },
288
-
289
- // protected
290
-
291
- // calls the tab (or tabs) method
292
- callTab: function(tabs, method) {
293
- R(isArray(tabs) ? tabs : [tabs]).each(function(tab) {
294
- if (isNumber(tab)) { tab = this.tabs[tab]; }
295
- if (tab && tab instanceof Tab) {
296
- tab[method]();
297
- }
298
- }, this);
299
-
300
- return this;
301
- },
302
-
303
- // finds and interconnects the tabs
304
- findTabs: function() {
305
- this.tabsList = this.isHarmonica ? this :
306
- $(this.options.tabsElement) || this.first('.rui-tabs-list') ||
307
- (this.first('UL') || $E('UL').insertTo(this)).addClass('rui-tabs-list');
308
-
309
- this.tabs = R([]);
310
-
311
- this.tabsList.children(this.isHarmonica ? 'dt' : null).map(function(node) {
312
- this.tabs.push(new Tab(node, this));
313
- }, this);
314
-
315
- // removing the whitespaces so the didn't screw with the margins
316
- for (var i=0, list = this.tabsList.get('childNodes'); i < list.length; i++) {
317
- if (list[i].nodeType == 3) { this.tabsList._.removeChild(list[i]); }
318
- }
319
-
320
- return this;
321
- }
322
- });
323
-
324
-
325
- /**
326
- * A single tab handling object
327
- *
328
- * Copyright (C) 2009-2011 Nikolay Nemshilov
329
- */
330
- var Tab = Tabs.Tab = new Class(Element, {
331
- extend: {
332
- autoId: 0
333
- },
334
-
335
- /**
336
- * Constructor
337
- *
338
- * @param Element the tab's element
339
- * @param Tabs the main element
340
- * @return void
341
- */
342
- initialize: function(element, main) {
343
- this.$super(element._);
344
- this.addClass('rui-tabs-tab');
345
-
346
- this.main = main;
347
- this.link = this.first('a');
348
- this.id = this.link.get('href').split('#')[1] || Tab.autoId++;
349
- this.panel = new Panel(this.findPanel(), this);
350
-
351
- if (this.current()) {
352
- this.select();
353
- }
354
-
355
- // adding the 'close' icon onto the tab if needed
356
- if (main.options.closable) {
357
- this.link.insert($E('div', {
358
- 'class': 'rui-tabs-tab-close-icon', 'html': '&times;'
359
- }).onClick(R(this.remove).bind(this)));
360
- }
361
-
362
- this.onClick(this._clicked);
363
- },
364
-
365
- select: function() {
366
- if (this.enabled()) {
367
- var prev_tab = this.main.current();
368
- if (prev_tab) {
369
- prev_tab.removeClass('rui-tabs-current').fire('hide');
370
- }
371
-
372
- this.addClass('rui-tabs-current');
373
- this.main.scrollToTab(this);
374
- this.panel.show();
375
- }
376
-
377
- return this.fire('select');
378
- },
379
-
380
- disable: function() {
381
- return this.addClass('rui-tabs-disabled').fire('disable');
382
- },
383
-
384
- enable: function() {
385
- return this.removeClass('rui-tabs-disabled').fire('enable');
386
- },
387
-
388
- disabled: function() {
389
- return !this.enabled();
390
- },
391
-
392
- enabled: function() {
393
- return !this.hasClass('rui-tabs-disabled');
394
- },
395
-
396
- current: function() {
397
- return this.hasClass('rui-tabs-current');
398
- },
399
-
400
- remove: function(event) {
401
- if (event) { event.stop(); }
402
-
403
- // switching to the next available sibling
404
- if (this.current()) {
405
- var enabled = this.main.enabled();
406
- var sibling = enabled[enabled.indexOf(this) + 1] || enabled[enabled.indexOf(this)-1];
407
-
408
- if (sibling) {
409
- sibling.select();
410
- }
411
- }
412
-
413
- // removing the tab out of the list
414
- this.main.tabs.splice(this.main.tabs.indexOf(this), 1);
415
- this.panel.remove();
416
-
417
- return this.fire('remove').$super();
418
- },
419
-
420
- // protected
421
-
422
- // handles the clicks on the tabs
423
- _clicked: function(event) {
424
- event.stop();
425
- return this.select();
426
- },
427
-
428
- // searches for a panel for the tab
429
- findPanel: function() {
430
- var main = this.main, panel_id = main.options.idPrefix + this.id, panel;
431
-
432
- if (main.isHarmonica) {
433
- var next = this.next();
434
- panel = (next && next._.tagName === 'DD') ? next : $E('DD').insertTo(this, 'after');
435
- } else {
436
- panel = $(panel_id) || $E(main._.tagName === 'UL' ? 'LI' : 'DIV').insertTo(main);
437
- }
438
-
439
- return panel.set('id', panel_id);
440
- },
441
-
442
- // returns the tab width, used for the scrolling calculations
443
- width: function() {
444
- var next = this.next();
445
-
446
- if (next) {
447
- return next.position().x - this.position().x;
448
- } else {
449
- return this.size().x + 1;
450
- }
451
- }
452
-
453
- });
454
-
455
-
456
- /**
457
- * The tab panels behavior logic
458
- *
459
- * Copyright (C) 2009-2011 Nikolay Nemshilov
460
- */
461
- var Panel = Tabs.Panel = new Class(Element, {
462
-
463
- /**
464
- * Basic constructor
465
- *
466
- * @param Element panel-element
467
- * @param Tab the tab object
468
- * @return void
469
- */
470
- initialize: function(element, tab) {
471
- this.$super(element._);
472
- this.addClass('rui-tabs-panel');
473
-
474
- this.tab = tab;
475
- this.id = this.get('id');
476
- },
477
-
478
- // shows the panel
479
- show: function() {
480
- return this.resizing(function() {
481
- this.tab.main.find('.rui-tabs-panel').each(function(panel) {
482
- panel[panel === this ? 'addClass' : 'removeClass']('rui-tabs-current');
483
- }, this);
484
- });
485
- },
486
-
487
- // updates the panel content
488
- update: function(content) {
489
- // don't use resize if it's some other hidden tab was loaded asynch
490
- if (this.tab.current()) {
491
- this.resizing(function() {
492
- Element.prototype.update.call(this, content||'');
493
- });
494
- } else {
495
- this.$super(content||'');
496
- }
497
-
498
- return this;
499
- },
500
-
501
- // locks the panel with a spinner locker
502
- lock: function() {
503
- this.insert(this.locker(), 'top');
504
- },
505
-
506
- // protected
507
-
508
- resizing: function(callback) {
509
- var controller = this.tab.main;
510
-
511
- if (controller.__working) { return this.resizing.bind(this, callback).delay(100); }
512
-
513
- var options = controller.options;
514
- var prev_panel = controller.first('.rui-tabs-panel.rui-tabs-current');
515
- var this_panel = this;
516
- var swapping = prev_panel !== this_panel;
517
- var loading = this.first('div.rui-tabs-panel-locker');
518
-
519
- // sometimes it looses the parent on remote tabs
520
- if (this_panel.parent().hasClass('rui-tabs-resizer')) {
521
- this_panel.insertTo(prev_panel.parent());
522
- }
523
-
524
- if (options.resizeFx && RightJS.Fx && prev_panel && (swapping || loading)) {
525
- controller.__working = true;
526
- var unlock = function() { controller.__working = false; };
527
-
528
- // calculating the visual effects durations
529
- var fx_name = (options.resizeFx === 'both' && loading) ? 'slide' : options.resizeFx;
530
- var duration = options.resizeDuration; duration = Fx.Durations[duration] || duration;
531
- var resize_duration = fx_name === 'fade' ? 0 : fx_name === 'slide' ? duration : duration / 2;
532
- var fade_duration = duration - resize_duration;
533
-
534
- if (fx_name !== 'slide') {
535
- this_panel.setStyle({opacity: 0});
536
- }
537
-
538
- // saving the previous sizes
539
- var prev_panel_height = (controller.isHarmonica && swapping) ? 0 : prev_panel.size().y;
540
-
541
- // applying the changes
542
- callback.call(this);
543
-
544
- // getting the new size
545
- var new_panel_height = this_panel.size().y;
546
- var fx_wrapper = null;
547
- var hide_wrapper = null;
548
- var prev_back = null;
549
-
550
- if (fx_name !== 'fade' && prev_panel_height !== new_panel_height) {
551
- // preserving the whole element size so it didn't jump when we are tossing the tabs around
552
- controller._.style.height = controller.size().y + 'px';
553
-
554
- // wrapping the element with an overflowed element to visualize the resize
555
- fx_wrapper = $E('div', {
556
- 'class': 'rui-tabs-resizer',
557
- 'style': 'height: '+ prev_panel_height + 'px'
558
- });
559
-
560
- // in case of harmonica nicely hidding the previous panel
561
- if (controller.isHarmonica && swapping) {
562
- prev_panel.addClass('rui-tabs-current');
563
- hide_wrapper = $E('div', {'class': 'rui-tabs-resizer'});
564
- hide_wrapper._.style.height = prev_panel.size().y + 'px';
565
- prev_back = function() {
566
- hide_wrapper.replace(prev_panel.removeClass('rui-tabs-current'));
567
- };
568
- prev_panel.wrap(hide_wrapper);
569
-
570
- fx_wrapper._.style.height = '0px';
571
- }
572
-
573
- this_panel.wrap(fx_wrapper);
574
-
575
- // getting back the auto-size so we could resize it
576
- controller._.style.height = 'auto';
577
-
578
- } else {
579
- // removing the resize duration out of the equasion
580
- rezise_duration = 0;
581
- duration = fade_duration;
582
- }
583
-
584
- var counter = 0;
585
- var set_back = function() {
586
- if (fx_wrapper) {
587
- if (fx_name == 'both' && !counter) {
588
- return counter ++;
589
- }
590
-
591
- fx_wrapper.replace(this_panel);
592
- }
593
-
594
- unlock();
595
- };
596
-
597
- if (hide_wrapper) {
598
- hide_wrapper.morph({height: '0px'},
599
- {duration: resize_duration, onFinish: prev_back});
600
- }
601
-
602
- if (fx_wrapper) {
603
- fx_wrapper.morph({height: new_panel_height + 'px'},
604
- {duration: resize_duration, onFinish: set_back});
605
- }
606
-
607
- if (fx_name !== 'slide') {
608
- this_panel.morph.bind(this_panel, {opacity: 1},
609
- {duration: fade_duration, onFinish: set_back}
610
- ).delay(resize_duration);
611
- }
612
-
613
- if (!fx_wrapper && fx_name === 'slide') {
614
- set_back();
615
- }
616
-
617
- } else {
618
- callback.call(this);
619
- }
620
-
621
- return this;
622
- },
623
-
624
- // builds the locker element
625
- locker: function() {
626
- return this._locker || (this._locker =
627
- $E('div', {'class': 'rui-tabs-panel-locker'}).insert(new Spinner(5))
628
- );
629
- }
630
- });
631
-
632
-
633
- /**
634
- * Contains the tabs scrolling functionality
635
- *
636
- * NOTE: different types of tabs have different scrolling behavior
637
- * simple tabs just scroll the tabs line without actually picking
638
- * any tab. But the carousel tabs scrolls to the next/previous
639
- * tabs on the list.
640
- *
641
- * Copyright (C) 2009-2010 Nikolay Nemshilov
642
- */
643
- Tabs.include({
644
- /**
645
- * Shows the next tab
646
- *
647
- * @return Tabs this
648
- */
649
- next: function() {
650
- return this.pickTab(+1);
651
- },
652
-
653
- /**
654
- * Shows the preveious tab
655
- *
656
- * @return Tabs this
657
- */
658
- prev: function() {
659
- return this.pickTab(-1);
660
- },
661
-
662
- /**
663
- * Scrolls the tabs to the left
664
- *
665
- * @return Tabs this
666
- */
667
- scrollLeft: function() {
668
- if (!this.prevButton.hasClass('rui-tabs-scroller-disabled')) {
669
- this[this.isCarousel ? 'prev' : 'justScroll'](+0.6);
670
- }
671
- return this;
672
- },
673
-
674
- /**
675
- * Scrolls the tabs to the right
676
- *
677
- * @return Tabs this
678
- */
679
- scrollRight: function() {
680
- if (!this.nextButton.hasClass('rui-tabs-scroller-disabled')) {
681
- this[this.isCarousel ? 'next' : 'justScroll'](-0.6);
682
- }
683
- return this;
684
- },
685
-
686
- // protected
687
-
688
- // overloading the init script to add the scrollbar support
689
- initScrolls: function() {
690
- if ((this.scrollable = (this.options.scrollTabs || this.isCarousel))) {
691
- this.buildScroller();
692
- }
693
-
694
- return this;
695
- },
696
-
697
- // builds the tabs scroller block
698
- buildScroller: function() {
699
- if (!(
700
- (this.prevButton = this.first('.rui-tabs-scroller-prev')) &&
701
- (this.nextButton = this.first('.rui-tabs-scroller-next'))
702
- )) {
703
- this.prevButton = $E('div', {'class': 'rui-tabs-scroller-prev', 'html': '&laquo;'});
704
- this.nextButton = $E('div', {'class': 'rui-tabs-scroller-next', 'html': '&raquo;'});
705
-
706
- // using a dummy element to insert the scroller in place of the tabs list
707
- $E('div').insertTo(this.tabsList, 'before')
708
- .replace(
709
- $E('div', {'class': 'rui-tabs-scroller'}).insert([
710
- this.prevButton, this.nextButton, this.scroller = $E('div', {
711
- 'class': 'rui-tabs-scroller-body'
712
- }).insert(this.tabsList)
713
- ])
714
- ).remove();
715
- }
716
-
717
- this.prevButton.onClick(R(this.scrollLeft).bind(this));
718
- this.nextButton.onClick(R(this.scrollRight).bind(this));
719
- },
720
-
721
- // picks the next/prev non-disabled available tab
722
- pickTab: function(pos) {
723
- var current = this.current();
724
- if (current && current.enabled()) {
725
- var enabled_tabs = this.enabled();
726
- var tab = enabled_tabs[enabled_tabs.indexOf(current) + pos];
727
- if (tab) { tab.select(); }
728
- }
729
- },
730
-
731
- // scrolls the tabs line to make the tab visible
732
- scrollToTab: function(tab) {
733
- if (this.scroller) {
734
- // calculating the previous tabs widths
735
- var tabs_width = 0;
736
- for (var i=0; i < this.tabs.length; i++) {
737
- tabs_width += this.tabs[i].width();
738
- if (this.tabs[i] === tab) { break; }
739
- }
740
-
741
- // calculating the scroll (the carousel tabs should be centralized)
742
- var available_width = this.scroller.size().x;
743
- var scroll = (this.isCarousel ? (available_width/2 + tab.width()/2) : available_width) - tabs_width;
744
-
745
- // check if the tab doesn't need to be scrolled
746
- if (!this.isCarousel) {
747
- var current_scroll = parseInt(this.tabsList.getStyle('left') || 0, 10);
748
-
749
- if (scroll >= current_scroll && scroll < (current_scroll + available_width - tab.width())) {
750
- scroll = current_scroll;
751
- } else if (current_scroll > -tabs_width && current_scroll <= (tab.width() - tabs_width)) {
752
- scroll = tab.width() - tabs_width;
753
- }
754
- }
755
-
756
- this.scrollTo(scroll);
757
- }
758
- },
759
-
760
- // just scrolls the scrollable area onto the given number of scrollable area widths
761
- justScroll: function(size) {
762
- if (!this.scroller) { return this; }
763
- var current_scroll = parseInt(this.tabsList.getStyle('left') || 0, 10);
764
- var available_width = this.scroller.size().x;
765
-
766
- this.scrollTo(current_scroll + available_width * size);
767
- },
768
-
769
- // scrolls the tabs list to the position
770
- scrollTo: function(scroll) {
771
- // checking the constraints
772
- var available_width = this.scroller.size().x;
773
- var overall_width = this.tabs.map('width').sum();
774
-
775
- if (scroll < (available_width - overall_width)) {
776
- scroll = available_width - overall_width;
777
- }
778
- if (scroll > 0) { scroll = 0; }
779
-
780
- // applying the scroll
781
- this.tabsList.morph({left: scroll+'px'}, {duration: this.options.scrollDuration});
782
-
783
- this.checkScrollButtons(overall_width, available_width, scroll);
784
- },
785
-
786
- // checks the scroll buttons
787
- checkScrollButtons: function(overall_width, available_width, scroll) {
788
- var has_prev = false, has_next = false;
789
-
790
- if (this.isCarousel) {
791
- var enabled = this.enabled();
792
- var current = enabled.first('current');
793
-
794
- if (current) {
795
- var index = enabled.indexOf(current);
796
-
797
- has_prev = index > 0;
798
- has_next = index < enabled.length - 1;
799
- }
800
- } else {
801
- has_prev = scroll !== 0;
802
- has_next = scroll > (available_width - overall_width);
803
- }
804
-
805
- this.prevButton[has_prev ? 'removeClass' : 'addClass']('rui-tabs-scroller-disabled');
806
- this.nextButton[has_next ? 'removeClass' : 'addClass']('rui-tabs-scroller-disabled');
807
- }
808
-
809
- });
810
-
811
-
812
- /**
813
- * This module handles the current tab state saving/restoring processes
814
- *
815
- * Copyright (C) 2009-2010 Nikolay Nemshilov
816
- */
817
- function get_cookie_indexes() {
818
- return R(RightJS.Cookie ? (Cookie.get('right-tabs-indexes') || '').split(',') : []);
819
- }
820
-
821
- function save_tab_in_cookies(options, tabs, event) {
822
- if (RightJS.Cookie) {
823
- var indexes = get_cookie_indexes();
824
- indexes = indexes.without.apply(indexes, tabs.map('id'));
825
- indexes.push(event.target.id);
826
- Cookie.set('right-tabs-indexes', indexes.uniq().join(','), options);
827
- }
828
- }
829
-
830
- Tabs.include({
831
-
832
- // protected
833
-
834
- // searches and activates the current tab
835
- findCurrent: function() {
836
- var enabled = this.enabled(), current = (
837
- this.tabs[this.options.selected] ||
838
- this.tabs[this.urlIndex()] ||
839
- this.tabs[this.cookieIndex()] ||
840
- enabled.first('current') ||
841
- enabled[0]
842
- );
843
-
844
- if (current) {
845
- current.select();
846
- }
847
-
848
- // initializing the cookies storage if set
849
- if (this.options.Cookie) {
850
- this.onSelect(R(save_tab_in_cookies).curry(this.options.Cookie, this.tabs));
851
- }
852
-
853
- return this;
854
- },
855
-
856
- // tries to find the current tab index in the url hash
857
- urlIndex: function() {
858
- var index = -1, id = document.location.href.split('#')[1];
859
-
860
- if (id) {
861
- for (var i=0; i < this.tabs.length; i++) {
862
- if (this.tabs[i].id == id) {
863
- index = i;
864
- break;
865
- }
866
- }
867
- }
868
-
869
- return index;
870
- },
871
-
872
- // tries to find the current tab index in the cookies storage
873
- cookieIndex: function() {
874
- var index = -1;
875
-
876
- if (this.options.Cookie) {
877
- var indexes = get_cookie_indexes();
878
- for (var i=0; i < this.tabs.length; i++) {
879
- if (indexes.include(this.tabs[i].id)) {
880
- index = i;
881
- break;
882
- }
883
- }
884
- }
885
-
886
- return index;
887
- }
888
-
889
- });
890
-
891
-
892
- /**
893
- * This module handles the tabs cration and removing processes
894
- *
895
- * Copyright (C) 2009-2010 Nikolay Nemshilov
896
- */
897
- Tabs.include({
898
- /**
899
- * Creates a new tab
900
- *
901
- * USAGE:
902
- * With the #add method you have to specify the tab title
903
- * optional content (possibly empty or null) and some options
904
- * The options might have the following keys
905
- *
906
- * * id - the tab/panel id (will use the idPrefix option for the panels)
907
- * * url - a remote tab content address
908
- * * position - an integer position of the tab in the stack
909
- *
910
- * @param String title
911
- * @param mixed content
912
- * @param Object options
913
- * @return Tabs this
914
- */
915
- add: function(title, content, options) {
916
- options = options || {};
917
-
918
- // creating the new tab element
919
- var element = $E(this.isHarmonica ? 'dt' : 'li').insert(
920
- $E('a', {html: title, href: options.url || '#'+(options.id||'')}
921
- )).insertTo(this.tabsList);
922
-
923
- // creating the actual tab instance
924
- var tab = new Tab(element, this);
925
- tab.panel.update(content||'');
926
- this.tabs.push(tab);
927
- tab.fire('add');
928
-
929
- // moving the tab in place if asked
930
- if ('position' in options) {
931
- this.move(tab, options.position);
932
- }
933
-
934
- return this;
935
- },
936
-
937
- /**
938
- * Moves the given tab to the given position
939
- *
940
- * NOTE if the position is not within the tabs range then it will do nothing
941
- *
942
- * @param mixed tab index or a tab instance
943
- * @param Integer position
944
- * @return Tabs this
945
- */
946
- move: function(tab, position) {
947
- tab = this.tabs[tab] || tab;
948
-
949
- if (this.tabs[position] && this.tabs[position] !== tab) {
950
- // moving the tab element
951
- this.tabs[position].insert(tab, (position === this.tabs.length-1) ? 'after' : 'before');
952
-
953
- // inserting the panel after the tab if it's a harmonica
954
- if (this.isHarmonica) {
955
- tab.insert(tab.panel, 'after');
956
- }
957
-
958
- // moving the tab in the registry
959
- this.tabs.splice(this.tabs.indexOf(tab), 1);
960
- this.tabs.splice(position, 0, tab);
961
-
962
- tab.fire('move', {index: position});
963
- }
964
-
965
- return this;
966
- },
967
-
968
- /**
969
- * Removes the given tab
970
- *
971
- * @param integer tab index or a Tabs.Tab instance or a list of them
972
- * @return Tabs this
973
- */
974
- remove: function(tab) {
975
- return this.callTab(tab, 'remove');
976
- }
977
-
978
- });
979
-
980
-
981
- /**
982
- * This module contains the remote tabs loading logic
983
- *
984
- * Copyright (C) 2009-2010 Nikolay Nemshilov
985
- */
986
- var old_select = Tab.prototype.select;
987
-
988
- Tab.include({
989
-
990
- // wrapping the original mehtod, to catch the remote requests
991
- select: function() {
992
- if (this.dogPiling(arguments)) { return this; }
993
-
994
- var result = old_select.apply(this, arguments);
995
- var url = R(this.link.get('href'));
996
- var options = this.main.options;
997
-
998
- // building the url
999
- if (url.includes('#')) {
1000
- url = options.url ? options.url.replace('%{id}', url.split('#')[1]) : null;
1001
- }
1002
-
1003
- // if there is an actual url and no ongoing request or a cache, starting the request
1004
- if (url && !this.request && !(options.cache || this.cache)) {
1005
- this.panel.lock();
1006
-
1007
- try { // basically that's for the development tests, so the IE browsers didn't get screwed on the test page
1008
-
1009
- this.request = new RightJS.Xhr(url, Object.merge({method: 'get'}, options.Xhr))
1010
- .onComplete(R(function(response) {
1011
- if (this.main.__working) {
1012
- return arguments.callee.bind(this, response).delay(100);
1013
- }
1014
-
1015
- this.panel.update(response.text);
1016
-
1017
- this.request = null; // removing the request marker so it could be rerun
1018
- if (options.cache) {
1019
- this.cache = true;
1020
- }
1021
-
1022
- this.fire('load');
1023
- }).bind(this)
1024
- ).send();
1025
-
1026
- } catch(e) { if (!Browser.OLD) { throw(e); } }
1027
- }
1028
-
1029
- return result;
1030
- },
1031
-
1032
- // protected
1033
-
1034
- dogPiling: function(args) {
1035
- if (this.main.__working) {
1036
- if (this.main.__timeout) {
1037
- this.main.__timeout.cancel();
1038
- }
1039
-
1040
- this.main.__timeout = R(function(args) {
1041
- this.select.apply(this, args);
1042
- }).bind(this, args).delay(100);
1043
-
1044
- return true;
1045
- }
1046
-
1047
- return (this.main.__timeout = null);
1048
- }
1049
-
1050
- });
1051
-
1052
-
1053
- /**
1054
- * This module handles the slide-show loop feature for the Tabs
1055
- *
1056
- * Copyright (C) 2009-2010 Nikolay Nemshilov
1057
- */
1058
- Tabs.include({
1059
-
1060
- /**
1061
- * Starts the slideshow loop
1062
- *
1063
- * @param Number optional delay in ms
1064
- * @return Tabs this
1065
- */
1066
- startLoop: function(delay) {
1067
- if (!delay && !this.options.loop) { return this; }
1068
-
1069
- // attaching the loop pause feature
1070
- if (this.options.loopPause) {
1071
- this._stopLoop = this._stopLoop || R(this.stopLoop).bind(this, true);
1072
- this._startLoop = this._startLoop || R(this.startLoop).bind(this, delay);
1073
-
1074
- this.forgetHovers().on({
1075
- mouseover: this._stopLoop,
1076
- mouseout: this._startLoop
1077
- });
1078
- }
1079
-
1080
- if (this.timer) { this.timer.stop(); }
1081
-
1082
- this.timer = R(function() {
1083
- var enabled = this.enabled();
1084
- var current = this.current();
1085
- var next = enabled[enabled.indexOf(current)+1];
1086
-
1087
- this.select(next || enabled.first());
1088
-
1089
- }).bind(this).periodical(this.options.loop || delay);
1090
-
1091
- return this;
1092
- },
1093
-
1094
- /**
1095
- * Stops the slideshow loop
1096
- *
1097
- * @return Tabs this
1098
- */
1099
- stopLoop: function(event, pause) {
1100
- if (this.timer) {
1101
- this.timer.stop();
1102
- this.timer = null;
1103
- }
1104
- if (!pause && this._startLoop) {
1105
- this.forgetHovers();
1106
- }
1107
- },
1108
-
1109
- // private
1110
- forgetHovers: function() {
1111
- return this
1112
- .stopObserving('mouseover', this._stopLoop)
1113
- .stopObserving('mouseout', this._startLoop);
1114
- }
1115
-
1116
-
1117
- });
1118
-
1119
-
1120
- /**
1121
- * The document level hooks for the tabs-egnine
1122
- *
1123
- * Copyright (C) 2009-2010 Nikolay Nemshilov
1124
- */
1125
- $(document).onReady(function() {
1126
- Tabs.rescan();
1127
- });
1128
- (function() {
1129
- var style = document.createElement('style'),
1130
- rules = document.createTextNode("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}");
1131
-
1132
- style.type = 'text/css';
1133
-
1134
- if(style.styleSheet) {
1135
- style.styleSheet.cssText = rules.nodeValue;
1136
- } else {
1137
- style.appendChild(rules);
1138
- }
1139
-
1140
- document.getElementsByTagName('head')[0].appendChild(style);
1141
- })();
1142
-
1143
- return Tabs;
1144
- })(document, parseInt, RightJS);