right-rails 1.1.0 → 1.2.0

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 (47) hide show
  1. data/CHANGELOG +5 -0
  2. data/lib/right_rails/helpers/forms.rb +81 -47
  3. data/lib/right_rails/helpers.rb +9 -0
  4. data/public/javascripts/right/autocompleter-src.js +1 -1
  5. data/public/javascripts/right/autocompleter.js +1 -1
  6. data/public/javascripts/right/billboard-src.js +1 -1
  7. data/public/javascripts/right/billboard.js +1 -1
  8. data/public/javascripts/right/calendar-src.js +1 -1
  9. data/public/javascripts/right/calendar.js +1 -1
  10. data/public/javascripts/right/casting-src.js +183 -0
  11. data/public/javascripts/right/casting.js +7 -0
  12. data/public/javascripts/right/colorpicker-src.js +1 -1
  13. data/public/javascripts/right/colorpicker.js +1 -1
  14. data/public/javascripts/right/dialog-src.js +1 -1
  15. data/public/javascripts/right/dialog.js +1 -1
  16. data/public/javascripts/right/dnd-src.js +20 -20
  17. data/public/javascripts/right/dnd.js +2 -2
  18. data/public/javascripts/right/in-edit-src.js +1 -1
  19. data/public/javascripts/right/in-edit.js +1 -1
  20. data/public/javascripts/right/lightbox-src.js +24 -5
  21. data/public/javascripts/right/lightbox.js +2 -2
  22. data/public/javascripts/right/rails-src.js +1 -1
  23. data/public/javascripts/right/rails.js +1 -1
  24. data/public/javascripts/right/rater-src.js +1 -1
  25. data/public/javascripts/right/rater.js +1 -1
  26. data/public/javascripts/right/resizable-src.js +29 -3
  27. data/public/javascripts/right/resizable.js +2 -2
  28. data/public/javascripts/right/selectable-src.js +1 -1
  29. data/public/javascripts/right/selectable.js +1 -1
  30. data/public/javascripts/right/slider-src.js +5 -5
  31. data/public/javascripts/right/slider.js +2 -2
  32. data/public/javascripts/right/sortable-src.js +1 -1
  33. data/public/javascripts/right/sortable.js +1 -1
  34. data/public/javascripts/right/tabs-src.js +8 -6
  35. data/public/javascripts/right/tabs.js +2 -2
  36. data/public/javascripts/right/tags-src.js +745 -0
  37. data/public/javascripts/right/tags.js +7 -0
  38. data/public/javascripts/right/tooltips-src.js +1 -1
  39. data/public/javascripts/right/tooltips.js +1 -1
  40. data/public/javascripts/right/uploader-src.js +4 -3
  41. data/public/javascripts/right/uploader.js +2 -2
  42. data/public/javascripts/right-safe-src.js +2 -2
  43. data/public/javascripts/right-safe.js +2 -2
  44. data/public/javascripts/right-src.js +60 -47
  45. data/public/javascripts/right.js +2 -2
  46. data/spec/lib/right_rails/helpers/forms_spec.rb +67 -40
  47. metadata +10 -15
@@ -0,0 +1,745 @@
1
+ /**
2
+ * RightJS-UI Tags v2.2.1
3
+ * http://rightjs.org/ui/tags
4
+ *
5
+ * Copyright (C) 2011 Nikolay Nemshilov
6
+ */
7
+ var Tags = RightJS.Tags = (function(RightJS) {
8
+ /**
9
+ * This module defines the basic widgets constructor
10
+ * it creates an abstract proxy with the common functionality
11
+ * which then we reuse and override in the actual widgets
12
+ *
13
+ * Copyright (C) 2010-2011 Nikolay Nemshilov
14
+ */
15
+
16
+ /**
17
+ * The widget units constructor
18
+ *
19
+ * @param String tag-name or Object methods
20
+ * @param Object methods
21
+ * @return Widget wrapper
22
+ */
23
+ function Widget(tag_name, methods) {
24
+ if (!methods) {
25
+ methods = tag_name;
26
+ tag_name = 'DIV';
27
+ }
28
+
29
+ /**
30
+ * An Abstract Widget Unit
31
+ *
32
+ * Copyright (C) 2010 Nikolay Nemshilov
33
+ */
34
+ var AbstractWidget = new RightJS.Class(RightJS.Element.Wrappers[tag_name] || RightJS.Element, {
35
+ /**
36
+ * The common constructor
37
+ *
38
+ * @param Object options
39
+ * @param String optional tag name
40
+ * @return void
41
+ */
42
+ initialize: function(key, options) {
43
+ this.key = key;
44
+ var args = [{'class': 'rui-' + key}];
45
+
46
+ // those two have different constructors
47
+ if (!(this instanceof RightJS.Input || this instanceof RightJS.Form)) {
48
+ args.unshift(tag_name);
49
+ }
50
+ this.$super.apply(this, args);
51
+
52
+ if (RightJS.isString(options)) {
53
+ options = RightJS.$(options);
54
+ }
55
+
56
+ // if the options is another element then
57
+ // try to dynamically rewrap it with our widget
58
+ if (options instanceof RightJS.Element) {
59
+ this._ = options._;
60
+ if ('$listeners' in options) {
61
+ options.$listeners = options.$listeners;
62
+ }
63
+ options = {};
64
+ }
65
+ this.setOptions(options, this);
66
+
67
+ return (RightJS.Wrapper.Cache[RightJS.$uid(this._)] = this);
68
+ },
69
+
70
+ // protected
71
+
72
+ /**
73
+ * Catches the options
74
+ *
75
+ * @param Object user-options
76
+ * @param Element element with contextual options
77
+ * @return void
78
+ */
79
+ setOptions: function(options, element) {
80
+ if (element) {
81
+ options = RightJS.Object.merge(options, new Function("return "+(
82
+ element.get('data-'+ this.key) || '{}'
83
+ ))());
84
+ }
85
+
86
+ if (options) {
87
+ RightJS.Options.setOptions.call(this, RightJS.Object.merge(this.options, options));
88
+ }
89
+
90
+ return this;
91
+ }
92
+ });
93
+
94
+ /**
95
+ * Creating the actual widget class
96
+ *
97
+ */
98
+ var Klass = new RightJS.Class(AbstractWidget, methods);
99
+
100
+ // creating the widget related shortcuts
101
+ RightJS.Observer.createShortcuts(Klass.prototype, Klass.EVENTS || RightJS([]));
102
+
103
+ return Klass;
104
+ }
105
+
106
+
107
+ /**
108
+ * The tags widget initialization script
109
+ *
110
+ * Copyright (C) 2011 Nikolay Nemshilov
111
+ */
112
+ var R = RightJS,
113
+ $ = RightJS.$,
114
+ $w = RightJS.$w,
115
+ Class = RightJS.Class,
116
+ Input = RightJS.Input,
117
+ Element = RightJS.Element;
118
+
119
+
120
+
121
+
122
+
123
+ /**
124
+ * The main unit for the Tags widget
125
+ *
126
+ * Copyright (C) 2011 Nikolay Nemshilov
127
+ */
128
+ var Tags = new Widget('INPUT', {
129
+ extend: {
130
+ version: '2.2.1',
131
+
132
+ EVENTS: $w('add remove'),
133
+
134
+ Options: {
135
+ tags: [], // the tags list
136
+ vertical: false, // use a vertical tags list
137
+
138
+ allowNew: true, // allow new tags to be created
139
+ nocase: true, // caseinsensitive
140
+ autocomplete: true, // autocomplete the user's input
141
+
142
+ separator: ',', // the tokens separator
143
+
144
+ cssRule: 'input[data-tags]' // the autoinitialization css-rule
145
+ },
146
+
147
+ /**
148
+ * Rescans and initializes the input elements in the area
149
+ *
150
+ * @param {Wrapper} optional scope
151
+ * @return void
152
+ */
153
+ rescan: function(scope) {
154
+ $(scope || document).find(Tags.Options.cssRule).each(function(input) {
155
+ if (!(input instanceof Tags)) {
156
+ input = new Tags(input);
157
+ }
158
+ });
159
+ }
160
+ },
161
+
162
+ /**
163
+ * Basic constructor
164
+ *
165
+ * @param {Input} element
166
+ * @param {Object} options
167
+ * @return void
168
+ */
169
+ initialize: function(element, options) {
170
+ // trying to extract a plain list of tags
171
+ var tags = R(R(''+ $(element).get('data-tags')).trim());
172
+
173
+ if (tags.startsWith('[') && tags.endsWith(']')) {
174
+ if (!options) { options = {}; }
175
+ options.tags = new Function('return '+tags)();
176
+ }
177
+
178
+ this
179
+ .$super('tags', element)
180
+ .setOptions(options);
181
+
182
+ if (RightJS.Browser.OLD) {
183
+ this.setStyle({color: this.getStyle('backgroundColor')});
184
+ }
185
+
186
+ this.container = new Element('div', {'class': 'rui-tags'}).insertTo(this, 'after');
187
+
188
+ this.list = new Tags.List(this);
189
+ this.input = new Tags.Input(this);
190
+ this.completer = new Tags.Completer(this);
191
+
192
+ this.onFocus(function() { this.input.focus(); });
193
+
194
+ // reinitializing with default values
195
+ this.setValue(this._.value);
196
+ },
197
+
198
+ /**
199
+ * Overloading the method so that it updated the visible list as well
200
+ *
201
+ * @param {String|Array} string tokens
202
+ * @return {Tags} this
203
+ */
204
+ setValue: function(tags) {
205
+ if (isString(tags)) {
206
+ tags = R(tags.split(this.options.separator))
207
+ .map('trim').reject('blank');
208
+ }
209
+
210
+ // merging the tags into the known list
211
+ this.options.tags = R(this.options.tags).merge(tags);
212
+
213
+ // repopulating the list
214
+ this.list.setTags(tags);
215
+
216
+ // setting the internal value
217
+ return this.$super(tags.join(this.options.separator + ' '));
218
+ }
219
+ });
220
+
221
+
222
+ /**
223
+ * The tags list element custom wrapper
224
+ *
225
+ * Copyright (C) 2011 Nikolay Nemshilov
226
+ */
227
+ Tags.List = new Class(Element, {
228
+
229
+ /**
230
+ * Constructor, creates the list and places where it supposed to be
231
+ *
232
+ * @param {Tags} tags instance
233
+ * @return void
234
+ */
235
+ initialize: function(main) {
236
+ this.main = main;
237
+
238
+ this.$super('ul', {'class': 'list'});
239
+ this.insertTo(main.container);
240
+
241
+ if (this.main.options.vertical) {
242
+ this.addClass('vertical');
243
+ }
244
+
245
+ function double_styles(name) {
246
+ return main.getStyle(name).replace(
247
+ /[\d\.]+/, function(m) { return parseFloat(m) * 2; }
248
+ );
249
+ }
250
+
251
+ this.setStyle({
252
+ fontSize: main.getStyle('fontSize'),
253
+ fontFamily: main.getStyle('fontFamily'),
254
+ fontWeight: main.getStyle('fontWeight'),
255
+ letterSpacing: main.getStyle('letterSpacing'),
256
+ paddingTop: double_styles('borderTopWidth'),
257
+ paddingLeft: double_styles('borderLeftWidth'),
258
+ paddingRight: double_styles('borderRightWidth'),
259
+ paddingBottom: main.getStyle('borderBottomWidth')
260
+ });
261
+
262
+ // frakking Opera '0em' sizes bug fallback
263
+ if (main.getStyle('fontSize') === '0em') {
264
+ this.setStyle({fontSize: '1em'});
265
+ }
266
+
267
+ this.setWidth(main.size().x);
268
+ this.reposition(true);
269
+
270
+ this.onClick(this._click);
271
+ },
272
+
273
+ /**
274
+ * Sets a list of tags
275
+ *
276
+ * @param {Array} tags
277
+ * @return {Tags.List} this
278
+ */
279
+ setTags: function(tags) {
280
+ tags.uniq().each(this.clean().addTag, this);
281
+
282
+ return this;
283
+ },
284
+
285
+ /**
286
+ * Returns a list of tags on the list
287
+ *
288
+ * @return {Array} of tokens
289
+ */
290
+ getTags: function() {
291
+ return this.find('div.text').map('text');
292
+ },
293
+
294
+ /**
295
+ * adds the tag to the list
296
+ *
297
+ * @param {String} tag
298
+ * @return {Tags.List} this
299
+ */
300
+ addTag: function(tag) {
301
+ if (this._allowed(tag)) {
302
+ this
303
+ .append(
304
+ '<li>'+
305
+ '<div class="text">'+ R(tag).trim() +'</div>'+
306
+ '<div class="close">&times;</div>' +
307
+ '</li>'
308
+ ).reposition();
309
+
310
+ this.main.fire('add', {tag: tag});
311
+ }
312
+
313
+ this.main._.value = this.getTags().join(
314
+ this.main.options.separator + ' '
315
+ );
316
+
317
+ return this;
318
+ },
319
+
320
+ /**
321
+ * Removes the last item from the list
322
+ *
323
+ * @return {Tags.List} this
324
+ */
325
+ removeLast: function() {
326
+ var item = this.find('li').last();
327
+
328
+ if (item) {
329
+ this._remove(item);
330
+ }
331
+
332
+ return this;
333
+ },
334
+
335
+ /**
336
+ * Adjusts the original input field size and
337
+ * places the list right above it,
338
+ * in case if the list will start folding
339
+ *
340
+ * @return {Tags.List} this
341
+ */
342
+ reposition: function(force) {
343
+ var size = this.size().y, main = this.main.size().y, style;
344
+
345
+ if (size !== main || force === true) {
346
+ this.main.setHeight(size);
347
+
348
+ style = this._.style;
349
+
350
+ style.top = '0px';
351
+ style.left = '0px';
352
+
353
+ size = this.position();
354
+ main = this.main.position();
355
+
356
+ style.top = main.y - size.y + 'px';
357
+ style.left = main.x - size.x + 'px';
358
+ }
359
+
360
+ return this;
361
+ },
362
+
363
+ // private
364
+
365
+ // catches the clicks on the list
366
+ _click: function(event) {
367
+ if (event.target.hasClass('close')) {
368
+ this._remove(event.target.parent());
369
+ } else {
370
+ this.main.input.focus();
371
+ }
372
+ },
373
+
374
+ // checks if the tag is allowed to be added to the list
375
+ _allowed: function(tag) {
376
+ var tags = this.getTags(),
377
+ options = this.main.options,
378
+ casesensitive = !options.nocase;
379
+
380
+ return !(casesensitive ? tags.include(tag) :
381
+ tags.map('toLowerCase').include(tag.toLowerCase())
382
+ ) && (
383
+ options.allowNew || (
384
+ casesensitive ? tags.include(tag) :
385
+ options.tags.map('toLowerCase').include(tag.toLowerCase())
386
+ )
387
+ );
388
+ },
389
+
390
+ // removes an item out of the list
391
+ _remove: function(item) {
392
+ var tag = item.first('div.text').text();
393
+
394
+ this.main.setValue(
395
+ this.getTags().without(tag)
396
+ );
397
+
398
+ this.main.fire('remove', {tag: tag});
399
+ }
400
+
401
+ });
402
+
403
+ /**
404
+ * The 'fake' input field element
405
+ *
406
+ * Copyright (C) 2011 Nikolay Nemshilov
407
+ */
408
+ Tags.Input = new Class(Input, {
409
+
410
+ /**
411
+ * Constructor
412
+ *
413
+ * @param {Tabs} the main object
414
+ * @return void
415
+ */
416
+ initialize: function(main) {
417
+ this.main = main;
418
+ this.list = main.list;
419
+
420
+ this.$super({type: 'text', size: 1});
421
+ this.onKeydown(this._keydown);
422
+ this.onKeyup(this._keyup);
423
+ this.onBlur(this._blur);
424
+ this.insertTo(main.list);
425
+
426
+ // used to dynamically measure the size of the field
427
+ this.meter = new Element('div', {
428
+ 'class': 'meter',
429
+ 'style': {
430
+ whiteSpace: 'nowrap',
431
+ position: 'absolute',
432
+ left: '-99999em'
433
+ }
434
+ }).insertTo(this, 'after');
435
+ },
436
+
437
+ /**
438
+ * Inserting itself into the tags list on the 'focus' call
439
+ *
440
+ * @return {Tags.Input} this
441
+ */
442
+ focus: function() {
443
+ this.main.list.append(this, this.meter).reposition();
444
+ return this.$super();
445
+ },
446
+
447
+ /**
448
+ * Resets the input field state
449
+ *
450
+ * @return {Tags.Input} this
451
+ */
452
+ reset: function() {
453
+ this.remove();
454
+ this.meter.remove();
455
+ this.list.reposition();
456
+ this._.value = '';
457
+
458
+ return this;
459
+ },
460
+
461
+ // private
462
+
463
+ _keydown: function(event) {
464
+ if (event.keyCode === 8 && this._.value === '') {
465
+ this.list.removeLast(); // deleting the last tag with backspace
466
+ this.focus();
467
+ } else if (event.keyCode === 13) {
468
+ event.preventDefault(); // preventing the for to go off on Enter
469
+ }
470
+ },
471
+
472
+ _keyup: function(event) {
473
+ if (!R([9, 27, 37, 38, 39, 40, 13]).include(event.keyCode)) {
474
+ if (this._.value.indexOf(this.main.options.separator) !== -1) {
475
+ this._add();
476
+ this.focus();
477
+ } else {
478
+ this._resize();
479
+ this.main.completer.suggest(this._.value);
480
+ }
481
+ }
482
+ },
483
+
484
+ _blur: function(event) {
485
+ if (this.main.completer.hidden() && this._.value !== '') {
486
+ this._add();
487
+ this.reset();
488
+ }
489
+ },
490
+
491
+ // resizes the field to fit the text
492
+ _resize: function() {
493
+ this.meter.html(this._.value + 'xx');
494
+ this._.style.width = this.meter.size().x + 'px';
495
+ this.list.reposition();
496
+ },
497
+
498
+ // makes a tag out of the current value
499
+ _add: function() {
500
+ var value = this._.value.replace(this.main.options.separator, '');
501
+ this._.value = '';
502
+
503
+ if (!(/^\s*$/).test(value)) {
504
+ this.list.addTag(value);
505
+ }
506
+
507
+ if (this.main.completer.visible()) {
508
+ this.main.completer.hide();
509
+ }
510
+ }
511
+
512
+ });
513
+
514
+ /**
515
+ * The tags completer popup menu
516
+ *
517
+ * Copyright (C) 2011 Nikolay Nemshilov
518
+ */
519
+ Tags.Completer = new Class(Element, {
520
+
521
+ extend: {
522
+ current: null // currently visible list reference
523
+ },
524
+
525
+ /**
526
+ * Constructor
527
+ *
528
+ * @param {Tags} main object
529
+ * @return void
530
+ */
531
+ initialize: function(main) {
532
+ this.main = main;
533
+ this.list = main.list;
534
+ this.input = main.input;
535
+
536
+ this.$super('ul', {'class': 'completer'});
537
+ this.addClass('rui-dd-menu');
538
+ this.insertTo(main.container);
539
+
540
+ this.onClick(this._click);
541
+ },
542
+
543
+ /**
544
+ * Starts the suggesting process
545
+ *
546
+ */
547
+ suggest: function(value) {
548
+ if (!(/^\s*$/).test(value) && this.main.options.autocomplete) {
549
+ var tags = this._filter(this.main.options.tags, value);
550
+
551
+ if (tags.length !== 0) {
552
+ this.html(tags.map(function(tag) {
553
+ return '<li>'+ tag.replace(value, '<b>'+ value + '</b>') +'</li>';
554
+ }).join(''));
555
+
556
+ this.picked = false;
557
+
558
+ return this.show();
559
+ }
560
+ }
561
+
562
+ return this.hide();
563
+ },
564
+
565
+ /**
566
+ * Overloading the method so it appeared right below the input field
567
+ *
568
+ * @return {Tags.Completer} this
569
+ */
570
+ show: function() {
571
+ var input = this.input.dimensions(),
572
+ style = this._.style,
573
+ pos;
574
+
575
+ style.display = 'block';
576
+
577
+ style.top = '0px';
578
+ style.left = '0px';
579
+
580
+ pos = this.position();
581
+
582
+ style.left = input.left - pos.x + 'px';
583
+ style.top = input.top - pos.y + input.height + 'px';
584
+
585
+ return (Tags.Completer.current = this);
586
+ },
587
+
588
+ /**
589
+ * Hides the list of suggestions
590
+ *
591
+ * @return {Tags.Completer} this
592
+ */
593
+ hide: function() {
594
+ this._.innerHTML = '';
595
+ this._.style.display = 'none';
596
+
597
+ Tags.Completer.current = null;
598
+
599
+ return this;
600
+ },
601
+
602
+
603
+ /**
604
+ * Highlights the next item on the list
605
+ *
606
+ * @return {Tags.Completer} this
607
+ */
608
+ next: function() {
609
+ var item = this.first('.current');
610
+
611
+ if (item) { item = item.next(); }
612
+ if (!item) { item = this.first(); }
613
+ if (item) { item.radioClass('current'); }
614
+
615
+ return this;
616
+ },
617
+
618
+ /**
619
+ * Highlights the previous item on the list
620
+ *
621
+ * @return {Tags.Completer} this
622
+ */
623
+ prev: function() {
624
+ var item = this.first('.current');
625
+
626
+ if (item) { item = item.prev(); }
627
+ if (!item) { item = this.children().last(); }
628
+ if (item) { item.radioClass('current'); }
629
+
630
+ return this;
631
+ },
632
+
633
+ /**
634
+ * Copies the picked item data into the input field
635
+ * and hides the list
636
+ *
637
+ * @return {Tags.Completer} this
638
+ */
639
+ done: function() {
640
+ var item = this.first('.current');
641
+
642
+ if (item) {
643
+ this.list.addTag(item.text());
644
+ this.input.reset().focus();
645
+ }
646
+
647
+ return this.hide();
648
+ },
649
+
650
+ // private
651
+
652
+ // handles mouse clicks on the list
653
+ _click: function(event) {
654
+ var item = event.find('li');
655
+
656
+ if (item) {
657
+ item.radioClass('current');
658
+ }
659
+
660
+ this.done();
661
+ },
662
+
663
+ // finds an appropriate list of tags for the suggestion
664
+ _filter: function(tags, value) {
665
+ var used = this.list.getTags(),
666
+ nocase = this.main.options.nocase;
667
+
668
+ if (nocase) {
669
+ used = used.map('toLowerCase');
670
+ value = value.toLowerCase();
671
+ }
672
+
673
+ return tags.filter(function(tag) {
674
+ var low_tag = nocase ? tag.toLowerCase() : tag;
675
+
676
+ return low_tag.indexOf(value) !== -1 && !used.include(low_tag);
677
+ });
678
+ }
679
+ });
680
+
681
+ /**
682
+ * Document - on-load hook
683
+ *
684
+ * Copyright (C) 2011 Nikolay Nemshilov
685
+ */
686
+ $(document).on({
687
+ /**
688
+ * Triggers autoinitialization when the document is loaded
689
+ *
690
+ * @return void
691
+ */
692
+ ready: function() {
693
+ Tags.rescan();
694
+ },
695
+
696
+ /**
697
+ * Handles the suggestions list navigation
698
+ *
699
+ * @param {Event} event
700
+ * @return void
701
+ */
702
+ keydown: function(event) {
703
+ var list = Tags.Completer.current,
704
+ keys = {
705
+ 13: 'done', // Enter
706
+ 27: 'hide', // Escape
707
+ 38: 'prev', // Up
708
+ 40: 'next' // Down
709
+ };
710
+
711
+ if (list !== null && event.keyCode in keys) {
712
+ event.stop();
713
+ list[keys[event.keyCode]]();
714
+ }
715
+ },
716
+
717
+ /**
718
+ * Hides the completer menu by an outer click
719
+ *
720
+ * @param {Event} click
721
+ * @return void
722
+ */
723
+ click: function(event) {
724
+ if (Tags.Completer.current) {
725
+ Tags.Completer.current.hide();
726
+ }
727
+ }
728
+
729
+ });
730
+
731
+ var embed_style = document.createElement('style'),
732
+ embed_rules = document.createTextNode("*.rui-dd-menu, *.rui-dd-menu li{margin:0;padding:0;border:none;background:none;list-style:none;font-weight:normal;float:none} *.rui-dd-menu{display:none;position:absolute;z-index:9999;background:white;border:1px solid #BBB;border-radius:.2em;-moz-border-radius:.2em;-webkit-border-radius:.2em;box-shadow:#DDD .2em .2em .4em;-moz-box-shadow:#DDD .2em .2em .4em;-webkit-box-shadow:#DDD .2em .2em .4em} *.rui-dd-menu li{padding:.2em .4em;border-top:none;border-bottom:none;cursor:pointer} *.rui-dd-menu li.current{background:#DDD} *.rui-dd-menu li:hover{background:#EEE}dl.rui-dd-menu dt{padding:.3em .5em;cursor:default;font-weight:bold;font-style:italic;color:#444;background:#EEE}dl.rui-dd-menu dd li{padding-left:1.5em}div.rui-tags,div.rui-tags ul.list,div.rui-tags ul.list *{position:static;top:auto;left:auto;right:auto;bottom:auto;float:none;margin:0;padding:0;border:none;background:none;display:block}input[data-tags],input.rui-tags{color:transparent;color:rgba(0,0,0,0)}div.rui-tags{position:absolute;display:inline}div.rui-tags ul.list{position:absolute;overflow:hidden;min-height:1.3em}div.rui-tags ul.list li{display:inline-block; *display:inline; *zoom:1;position:relative;cursor:default;margin-right:.1em;margin-bottom:.1em;padding:0 .5em;padding-right:1.1em;background:#ddd;border-radius:.2em;-moz-border-radius:.2em;-webkit-border-radius:.2em;vertical-align:top}div.rui-tags ul.list li div.text{position:inline}div.rui-tags ul.list li div.close{margin-left:.25em;cursor:pointer;font-family:Arial;font-weight:normal;opacity:0.5;position:absolute;right:.25em;top:0.04em}div.rui-tags ul.list li div.close:hover{opacity:1}div.rui-tags ul.vertical li{display:block}div.rui-tags ul.list input{width:auto;height:auto;display:inline-block; *display:inline; *zoom:1;width:1em;outline:none;vertical-align:top;font-family:inherit;font-size:inherit;font-weight:inherit;letter-spacing:inherit}");
733
+
734
+ embed_style.type = 'text/css';
735
+ document.getElementsByTagName('head')[0].appendChild(embed_style);
736
+
737
+ if(embed_style.styleSheet) {
738
+ embed_style.styleSheet.cssText = embed_rules.nodeValue;
739
+ } else {
740
+ embed_style.appendChild(embed_rules);
741
+ }
742
+
743
+
744
+ return Tags;
745
+ })(RightJS);