rasputin-jui 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,973 @@
1
+
2
+ (function(exports) {
3
+ /*
4
+ * jQuery UI Autocomplete SC Extension
5
+ */
6
+
7
+ $.widget('ui.sc_autocomplete', $.ui.autocomplete, {
8
+ _renderItem: function(ul, item) {
9
+ var view = this.options.itemViewClass.create({content:item, widget: this});
10
+ view.appendTo(ul);
11
+ return view.$();
12
+ }
13
+ });
14
+
15
+ })({});
16
+
17
+
18
+ (function(exports) {
19
+ if ('undefined' === typeof JUI) {
20
+
21
+ /**
22
+ @namespace
23
+ @name JUI
24
+ @version 1.0.alpha
25
+ */
26
+ JUI = {};
27
+
28
+ // aliases needed to keep minifiers from removing the global context
29
+ if ('undefined' !== typeof window) {
30
+ window.JUI = JUI;
31
+ }
32
+
33
+ }
34
+
35
+ /**
36
+ @static
37
+ @type String
38
+ @default '1.0.alpha'
39
+ @constant
40
+ */
41
+ JUI.VERSION = '1.0.beta.1.pre';
42
+
43
+ })({});
44
+
45
+
46
+ (function(exports) {
47
+
48
+ var get = SC.get, set = SC.set, none = SC.none;
49
+
50
+ /**
51
+ @mixin
52
+ @since SproutCore JUI 1.0
53
+ @extends JUI.Widget
54
+ */
55
+ JUI.Widget = SC.Mixin.create({
56
+
57
+ uiWidget: function() {
58
+ return jQuery.ui[this.get('uiType')];
59
+ }.property().cacheable(),
60
+
61
+ didInsertElement: function() {
62
+ this._super();
63
+ var options = this._gatherOptions();
64
+ this._gatherEvents(options);
65
+
66
+ var ui = get(this, 'uiWidget')(options, get(this, 'element'));
67
+ set(this, 'ui', ui);
68
+ },
69
+
70
+ willDestroyElement: function() {
71
+ var ui = get(this, 'ui');
72
+ if (ui) {
73
+ var observers = this._observers;
74
+ for (var prop in observers) {
75
+ if (observers.hasOwnProperty(prop)) {
76
+ this.removeObserver(prop, observers[prop]);
77
+ }
78
+ }
79
+ ui._destroy();
80
+ }
81
+ },
82
+
83
+ didCreateWidget: SC.K,
84
+
85
+ concatenatedProperties: ['uiEvents', 'uiOptions', 'uiMethods'],
86
+
87
+ uiEvents: ['create'],
88
+ uiOptions: ['disabled'],
89
+ uiMethods: [],
90
+
91
+ _gatherEvents: function(options) {
92
+ var uiEvents = get(this, 'uiEvents');
93
+
94
+ uiEvents.forEach(function(eventType) {
95
+ var eventHandler = eventType === 'create' ? this.didCreateWidget : this[eventType];
96
+ if (eventHandler) {
97
+ options[eventType] = $.proxy(function(event, ui) {
98
+ eventHandler.call(this, event, ui);
99
+ }, this);
100
+ }
101
+ }, this);
102
+ },
103
+
104
+ _gatherOptions: function() {
105
+ var uiOptions = get(this, 'uiOptions'),
106
+ options = {},
107
+ defaultOptions = get(this, 'uiWidget').prototype.options;
108
+
109
+ uiOptions.forEach(function(key) {
110
+ var value = get(this, key),
111
+ uiKey = key.replace(/^_/, '');
112
+ if (!none(value)) {
113
+ options[uiKey] = value;
114
+ } else {
115
+ set(this, key, defaultOptions[uiKey]);
116
+ }
117
+
118
+ var observer = function() {
119
+ var value = get(this, key);
120
+ ui = get(this, 'ui');
121
+ if (ui.options[uiKey] != value) {
122
+ ui._setOption(uiKey, value);
123
+ }
124
+ };
125
+
126
+ this.addObserver(key, observer);
127
+ //this._observers = this._observers || {};
128
+ //this._observers[key] = observer;
129
+ }, this);
130
+
131
+ return options;
132
+ }
133
+ });
134
+
135
+ })({});
136
+
137
+
138
+ (function(exports) {
139
+
140
+ var get = SC.get;
141
+
142
+ /**
143
+ @mixin
144
+ @since SproutCore JUI 1.0
145
+ @extends JUI.TargetSupport
146
+ */
147
+ JUI.TargetSupport = SC.Mixin.create({
148
+
149
+ // @private
150
+ targetObject: function() {
151
+ var target = get(this, 'target');
152
+
153
+ if (SC.typeOf(target) === 'string') {
154
+ return SC.getPath(this, target);
155
+ } else {
156
+ return target;
157
+ }
158
+ }.property('target').cacheable(),
159
+
160
+ // @private
161
+ executeAction: function() {
162
+ var args = SC.$.makeArray(arguments),
163
+ action = args.shift(),
164
+ target = get(this, 'targetObject');
165
+ if (target && action) {
166
+ if (SC.typeOf(action) === 'string') {
167
+ action = target[action];
168
+ }
169
+ action.apply(target, args);
170
+ }
171
+ }
172
+
173
+ });
174
+
175
+ })({});
176
+
177
+
178
+ (function(exports) {
179
+
180
+
181
+
182
+ var get = SC.get;
183
+
184
+ /**
185
+ @class
186
+ @since SproutCore JUI 1.0
187
+ @extends JUI.AutocompleteItem
188
+ */
189
+ JUI.AutocompleteItem = SC.View.extend({
190
+ tagName: 'li',
191
+ defaultTemplate: SC.Handlebars.compile('<a>{{content.label}}</a>'),
192
+ didInsertElement: function() {
193
+ this._super();
194
+ this.$().data('item.autocomplete', {
195
+ value: this.getPath('content.value'),
196
+ label: this.getPath('content.label')
197
+ });
198
+ this.get('widget').menu.refresh();
199
+ }
200
+ });
201
+
202
+ /**
203
+ @class
204
+ @since SproutCore JUI 1.0
205
+ @extends JUI.AutocompleteTextField
206
+ */
207
+ JUI.AutocompleteTextField = SC.TextField.extend(JUI.Widget, JUI.TargetSupport, {
208
+ uiType: 'sc_autocomplete',
209
+ uiOptions: ['_source', 'delay', 'autoFocus', 'position', 'minLength', 'itemViewClass'],
210
+ uiEvents: ['select', 'focus', 'open', 'close'],
211
+
212
+ itemViewClass: JUI.AutocompleteItem,
213
+ requestContent: SC.K,
214
+ content: [],
215
+
216
+ _source: function() {
217
+ var source = this.get('source');
218
+ if (source) {
219
+ this.set('content', source);
220
+ return source;
221
+ } else {
222
+ return $.proxy(this, '_requestContent');
223
+ }
224
+ }.property('source').cacheable(),
225
+
226
+ _requestContent: function (data, callback) {
227
+ this._lastCallback = callback;
228
+ this.requestContent(data);
229
+ },
230
+
231
+ _contentDidChange: function() {
232
+ if (this._lastCallback) {
233
+ this._lastCallback(this.get('content'));
234
+ this._lastCallback = null;
235
+ }
236
+ }.observes('content'),
237
+
238
+ select: function(event, ui) {
239
+ if (ui.item) {
240
+ this.executeAction(get(this, 'action'), ui.item.value);
241
+ event.preventDefault();
242
+ }
243
+ }
244
+ });
245
+
246
+ })({});
247
+
248
+
249
+ (function(exports) {
250
+
251
+ var get = SC.get;
252
+
253
+ /**
254
+ @class
255
+ @since SproutCore JUI 1.0
256
+ @extends JUI.Button
257
+ */
258
+ JUI.Button = SC.Button.extend(JUI.Widget, {
259
+ uiType: 'button',
260
+ uiOptions: ['label'],
261
+
262
+ isActiveBinding: SC.Binding.oneWay('.disabled'),
263
+
264
+ _icons: function() {
265
+ var icons = {};
266
+ icons.primary = get(this, 'icon');
267
+ if (icons.primary) {
268
+ icons.primary = 'ui-icon-'.fmt(icons.primary);
269
+ }
270
+ return icons;
271
+ }.property('icon').cacheable()
272
+ });
273
+
274
+ })({});
275
+
276
+
277
+ (function(exports) {
278
+
279
+ var set = SC.set;
280
+
281
+ /**
282
+ @class
283
+ @since SproutCore JUI 1.0
284
+ @extends JUI.Slider
285
+ */
286
+ JUI.Slider = SC.View.extend(JUI.Widget, {
287
+ uiType: 'slider',
288
+ uiOptions: ['value', 'min', 'max', 'step', 'orientation', 'range'],
289
+ uiEvents: ['slide', 'start', 'stop'],
290
+
291
+ slide: function(event, ui) {
292
+ set(this, 'value', ui.value);
293
+ }
294
+ });
295
+
296
+ })({});
297
+
298
+
299
+ (function(exports) {
300
+
301
+ var set = SC.set;
302
+
303
+ /**
304
+ @class
305
+ @since SproutCore JUI 1.0
306
+ @extends JUI.Spinner
307
+ */
308
+ JUI.Spinner = SC.TextField.extend(JUI.Widget, {
309
+ uiType: 'spinner',
310
+ uiOptions: ['value', 'min', 'max', 'step'],
311
+ uiEvents: ['spin', 'start', 'stop'],
312
+ uiMethods: ['pageDown', 'pageUp', 'stepDown', 'stepUp'],
313
+
314
+ spin: function(event, ui) {
315
+ set(this, 'value', ui.value);
316
+ }
317
+ });
318
+
319
+ })({});
320
+
321
+
322
+ (function(exports) {
323
+
324
+ var get = SC.get, set = SC.set, none = SC.none;
325
+
326
+ /**
327
+ @class
328
+ @since SproutCore JUI 1.0
329
+ @extends JUI.ProgressBar
330
+ */
331
+ JUI.ProgressBar = SC.View.extend(JUI.Widget, {
332
+ uiType: 'progressbar',
333
+ uiOptions: ['_value', 'max'],
334
+ uiEvents: ['change', 'complete'],
335
+
336
+ _value: function(key, value) {
337
+ if (!none(value)) {
338
+ set(this, 'value', parseInt(value));
339
+ }
340
+ return parseInt(get(this, 'value'));
341
+ }.property('value').cacheable()
342
+ });
343
+
344
+ })({});
345
+
346
+
347
+ (function(exports) {
348
+
349
+ var get = SC.get;
350
+
351
+ /**
352
+ @class
353
+ @since SproutCore JUI 1.0
354
+ @extends JUI.Menu
355
+ */
356
+ JUI.Menu = SC.CollectionView.extend(JUI.Widget, {
357
+ uiType: 'menu',
358
+ uiEvents: ['select'],
359
+
360
+ tagName: 'ul',
361
+
362
+ arrayDidChange: function(content, start, removed, added) {
363
+ this._super(content, start, removed, added);
364
+
365
+ var ui = get(this, 'ui');
366
+ if (ui) { ui.refresh(); }
367
+ }
368
+ });
369
+
370
+ })({});
371
+
372
+
373
+ (function(exports) {
374
+ /*
375
+ * jQuery UI Dialog Auto Reposition Extension
376
+ *
377
+ * Copyright 2010, Scott González (http://scottgonzalez.com)
378
+ * Dual licensed under the MIT or GPL Version 2 licenses.
379
+ *
380
+ * http://github.com/scottgonzalez/jquery-ui-extensions
381
+ */
382
+
383
+ $.ui.dialog.prototype.options.autoReposition = true;
384
+ jQuery(window).resize(function() {
385
+ $('.ui-dialog-content:visible').each(function() {
386
+ var dialog = $(this).data('dialog');
387
+ if (dialog.options.autoReposition) {
388
+ dialog.option('position', dialog.options.position);
389
+ }
390
+ });
391
+ });
392
+
393
+ })({});
394
+
395
+
396
+ (function(exports) {
397
+
398
+
399
+
400
+ var get = SC.get, set = SC.set;
401
+
402
+ JUI.DialogButton = SC.Object.extend(JUI.TargetSupport, {
403
+ label: 'OK',
404
+ action: 'close',
405
+ executeAction: function() {
406
+ this._super(get(this, 'action'));
407
+ }
408
+ });
409
+
410
+ /**
411
+ @class
412
+ @since SproutCore JUI 1.0
413
+ @extends JUI.Dialog
414
+ */
415
+ JUI.Dialog = SC.View.extend(JUI.Widget, JUI.TargetSupport, {
416
+ uiType: 'dialog',
417
+ uiEvents: ['beforeClose'],
418
+ uiOptions: ['title', '_buttons', 'position', 'closeOnEscape',
419
+ 'modal', 'draggable', 'resizable', 'autoReposition',
420
+ 'width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight'],
421
+
422
+ isOpen: false,
423
+ message: '',
424
+ buttons: [],
425
+
426
+ defaultTemplate: SC.Handlebars.compile('<p>{{message}}</p>'),
427
+
428
+ open: function() {
429
+ if (get(this, 'state') !== 'inDOM') {
430
+ this._insertElementLater(SC.K);
431
+ } else {
432
+ get(this, 'ui').open();
433
+ }
434
+ },
435
+
436
+ close: function() {
437
+ get(this, 'ui').close();
438
+ },
439
+
440
+ didInsertElement: function() {
441
+ this._super();
442
+ get(this, 'ui')._bind({
443
+ dialogopen: $.proxy(this._open, this),
444
+ dialogclose: $.proxy(this._close, this)
445
+ });
446
+ },
447
+
448
+ _buttons: function() {
449
+ return get(this, 'buttons').map(this._buildButton, this);
450
+ }.property('buttons').cacheable(),
451
+
452
+ _buildButton: function(buttonPath) {
453
+ var button = this.getPath(buttonPath);
454
+ if (!button.isInstance) {
455
+ button = button.create({
456
+ target: get(this, 'targetObject') || this
457
+ });
458
+ set(this, buttonPath, button);
459
+ }
460
+ var props = {text: get(button, 'label')};
461
+ props.click = $.proxy(button, 'executeAction')
462
+ return props;
463
+ },
464
+
465
+ _open: function() {
466
+ set(this, 'isOpen', true);
467
+ this.didOpenDialog();
468
+ },
469
+
470
+ _close: function() {
471
+ set(this, 'isOpen', false);
472
+ this.didCloseDialog();
473
+ },
474
+
475
+ didOpenDialog: SC.K,
476
+ didCloseDialog: SC.K
477
+ });
478
+
479
+ JUI.Dialog.close = function() {
480
+ $('.ui-dialog-content:visible').dialog('close');
481
+ };
482
+
483
+ JUI.ModalDialog = JUI.Dialog.extend({
484
+ buttons: ['ok'],
485
+ ok: JUI.DialogButton,
486
+ resizable: false,
487
+ draggable: false,
488
+ modal: true
489
+ });
490
+
491
+ JUI.AlertDialog = JUI.ModalDialog.create({
492
+ open: function(message, title, type) {
493
+ set(this, 'title', title);
494
+ set(this, 'message', message);
495
+ set(this, 'icon', type);
496
+ this._super();
497
+ },
498
+ info: function(message, title) {
499
+ this.open(message, title, 'info');
500
+ },
501
+ error: function(message, title) {
502
+ this.open(message, title, 'error');
503
+ }
504
+ });
505
+
506
+ JUI.ConfirmDialog = JUI.ModalDialog.create({
507
+ buttons: ['yes', 'no'],
508
+ yes: JUI.DialogButton.extend({
509
+ label: 'YES',
510
+ action: 'didConfirm'
511
+ }),
512
+ no: JUI.DialogButton.extend({label: 'NO'}),
513
+ didConfirm: function() {
514
+ get(this, 'answer').resolve();
515
+ this.close();
516
+ },
517
+ didCloseDialog: function() {
518
+ var answer = get(this, 'answer');
519
+ if (answer && !answer.isResolved()) {
520
+ answer.reject();
521
+ }
522
+ set(this, 'answer', null);
523
+ },
524
+ open: function(message, title) {
525
+ var answer = SC.$.Deferred();
526
+ set(this, 'answer', answer);
527
+ set(this, 'title', title);
528
+ set(this, 'message', message);
529
+ this._super();
530
+ return answer.promise();
531
+ }
532
+ });
533
+
534
+ })({});
535
+
536
+
537
+ (function(exports) {
538
+
539
+ var get = SC.get, set = SC.set, none = SC.none;
540
+
541
+ /**
542
+ @class
543
+ @since SproutCore JUI 1.0
544
+ @extends JUI.Datepicker
545
+ */
546
+ JUI.Datepicker = SC.TextField.extend(JUI.Widget, {
547
+ uiType: 'datepicker',
548
+ uiOptions: ['dateFormat', 'maxDate', 'minDate', 'defaultDate'],
549
+ uiEvents: ['onSelect'],
550
+
551
+ date: function(key, value) {
552
+ var ui = get(this, 'ui');
553
+ if (!none(value)) {
554
+ ui.setDate(value);
555
+ }
556
+ return ui.getDate();
557
+ }.property('value').cacheable(),
558
+
559
+ open: function() {
560
+ get(this, 'ui').show();
561
+ },
562
+
563
+ close: function() {
564
+ get(this, 'ui').hide();
565
+ },
566
+
567
+ // @private
568
+ uiWidget: function() {
569
+ var datepicker = function(options, elem) {
570
+ return SC.$(elem).datepicker(options).datepicker('widget');
571
+ };
572
+ datepicker.prototype.options = SC.$.datepicker._defaults;
573
+ return datepicker;
574
+ }.property().cacheable(),
575
+
576
+ // @private
577
+ onSelect: function(dateText, ui) {
578
+ this.select();
579
+ },
580
+
581
+ select: SC.K
582
+ });
583
+
584
+ JUI.Datepicker.formatDate = SC.$.datepicker.formatDate;
585
+ JUI.Datepicker.parseDate = SC.$.datepicker.parseDate;
586
+
587
+ })({});
588
+
589
+
590
+ (function(exports) {
591
+
592
+ var get = SC.get, set = SC.set;
593
+
594
+ /**
595
+ @mixin
596
+ @since SproutCore JUI 1.0
597
+ @extends JUI.Tooltip
598
+ */
599
+ JUI.Tooltip = SC.Mixin.create({
600
+ tooltip: '',
601
+ hasTooltip: false,
602
+
603
+ // @private
604
+ toggleTooltip: function() {
605
+ var flag = get(this, 'hasTooltip'),
606
+ ui = get(this, 'tooltipWidget');
607
+ if (flag && !ui) {
608
+ ui = this.$().tooltip({
609
+ content: get(this, 'tooltipTemplate')
610
+ }).tooltip('widget');
611
+ set(this, 'tooltipWidget', ui);
612
+ } else if (ui) {
613
+ ui._destroy();
614
+ }
615
+ }.observes('hasTooltip'),
616
+
617
+ // @private
618
+ tooltipTemplate: function() {
619
+ return SC.Handlebars.compile(get(this, 'tooltip'));
620
+ }.property('tooltip').cacheable()
621
+
622
+ });
623
+
624
+ })({});
625
+
626
+
627
+ (function(exports) {
628
+
629
+ var get = SC.get, set = SC.set;
630
+
631
+ /**
632
+ @class
633
+ @since SproutCore JUI 1.0
634
+ @extends JUI.SortableCollectionView
635
+ */
636
+ JUI.SortableCollectionView = SC.CollectionView.extend(JUI.Widget, {
637
+ uiType: 'sortable',
638
+ uiEvents: ['start', 'stop'],
639
+
640
+ draggedStartPos: null,
641
+
642
+ start: function(event, ui) {
643
+ set(this, 'dragging', true);
644
+ set(this, 'draggedStartPos', ui.item.index());
645
+ },
646
+
647
+ stop: function(event, ui) {
648
+ var oldIdx = get(this, 'draggedStartPos');
649
+ var newIdx = ui.item.index();
650
+ if (oldIdx != newIdx) {
651
+ var content = get(this, 'content');
652
+ content.beginPropertyChanges();
653
+ var el = content.objectAt(oldIdx);
654
+ content.removeAt(oldIdx);
655
+ content.insertAt(newIdx, el);
656
+ content.endPropertyChanges();
657
+ }
658
+ set(this, 'dragging', false);
659
+ },
660
+
661
+ // @private
662
+ // Overriding these to prevent CollectionView from reapplying content array modifications
663
+ arrayWillChange: function(content, start, removedCount, addedCount) {
664
+ if (get(this, 'dragging')) {
665
+ //this._super(content, 0, 0, 0);
666
+ } else {
667
+ this._super(content, start, removedCount, addedCount);
668
+ }
669
+ },
670
+
671
+ // @private
672
+ arrayDidChange: function(content, start, removedCount, addedCount) {
673
+ if (get(this, 'dragging')) {
674
+ //this._super(content, 0, 0, 0);
675
+ } else {
676
+ this._super(content, start, removedCount, addedCount);
677
+ }
678
+ }
679
+ });
680
+
681
+ })({});
682
+
683
+
684
+ (function(exports) {
685
+
686
+ /**
687
+ @class
688
+ @since SproutCore JUI 1.0
689
+ @extends JUI.ResizableView
690
+ */
691
+ JUI.ResizableView = SC.View.extend(JUI.Widget, {
692
+ uiType: 'resizable',
693
+ uiEvents: ['start', 'stop', 'resize'],
694
+ uiOptions: ['aspectRatio', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'containment', 'autoHide']
695
+ });
696
+
697
+ })({});
698
+
699
+
700
+ (function(exports) {
701
+ /*!
702
+ * jQuery UI Throbber
703
+ *
704
+ * Copyright (c) 2011 Paul Chavard
705
+ * Licensed under the MIT license
706
+ *
707
+ * Author: Paul Chavard [paul at chavard dot net]
708
+ * Version: 0.5.0
709
+ *
710
+ * Credits: Felix Gnass [fgnass at neteye dot de]
711
+ *
712
+ */
713
+
714
+ (function($, undefined) {
715
+
716
+ $.widget('ui.throbber', {
717
+ options: {
718
+ segments: 12,
719
+ space: 3,
720
+ length: 7,
721
+ width: 4,
722
+ speed: 1.2,
723
+ align: 'center',
724
+ valign: 'center',
725
+ padding: 4,
726
+ autoStart: false,
727
+ outside: true
728
+ },
729
+
730
+ _create: function() {
731
+ this.options = $.extend({color: this.element.css('color')}, this.options);
732
+ this._prepare();
733
+ if (this.options.autoStart) {
734
+ this._activate();
735
+ }
736
+ },
737
+
738
+ _setOption: function(key, value) {
739
+ this.options[key] = value;
740
+
741
+ if (key === 'disabled') {
742
+ if (this.throbber) {
743
+ clearInterval(this.interval);
744
+ this.throbber.remove();
745
+ }
746
+ if (value === false) {
747
+ this._activate();
748
+ }
749
+ }
750
+
751
+ return this;
752
+ },
753
+
754
+ _activate: function() {
755
+ var options = this.options;
756
+ this.throbber = this._render().css('position', 'absolute').prependTo(options.outside ? 'body' : this.element);
757
+ var h = this.element.outerHeight() - this.throbber.height();
758
+ var w = this.element.outerWidth() - this.throbber.width();
759
+ var margin = {
760
+ top: options.valign == 'top' ? options.padding : options.valign == 'bottom' ? h - options.padding : Math.floor(h / 2),
761
+ left: options.align == 'left' ? options.padding : options.align == 'right' ? w - options.padding : Math.floor(w / 2)
762
+ };
763
+ var offset = this.element.offset();
764
+ if (options.outside) {
765
+ this.throbber.css({top: offset.top + 'px', left: offset.left + 'px'});
766
+ } else {
767
+ margin.top -= this.throbber.offset().top - offset.top;
768
+ margin.left -= this.throbber.offset().left - offset.left;
769
+ }
770
+ this.throbber.css({marginTop: margin.top + 'px', marginLeft: margin.left + 'px'});
771
+ this._animate(options.segments, Math.round(10 / options.speed) / 10);
772
+ },
773
+
774
+ _prepare: function() {
775
+ if ($.ui.throbber.renderMethod) {
776
+ this.renderMethod = $.ui.throbber.renderMethod;
777
+ this.animateMethod = $.ui.throbber.animateMethod;
778
+ return;
779
+ }
780
+ if (document.createElementNS && document.createElementNS( "http://www.w3.org/2000/svg", "svg").createSVGRect) {
781
+ $.ui.throbber.renderMethod = 'SVG';
782
+ if (document.createElement('div').style.WebkitAnimationName !== undefined) {
783
+ $.ui.throbber.animateMethod = 'CSS';
784
+ } else {
785
+ $.ui.throbber.animateMethod = 'SVG';
786
+ }
787
+ } else if (this._prepareVML()) {
788
+ $.ui.throbber.renderMethod = $.ui.throbber.animateMethod = 'VML';
789
+ } else {
790
+ $.ui.throbber.renderMethod = $.ui.throbber.animateMethod = 'DOM';
791
+ }
792
+ this.renderMethod = $.ui.throbber.renderMethod;
793
+ this.animateMethod = $.ui.throbber.animateMethod;
794
+ },
795
+
796
+ _prepareVML: function() {
797
+ var s = $('<shape>').css('behavior', 'url(#default#VML)');
798
+ var ok = false;
799
+ $('body').append(s);
800
+ if (s.get(0).adj) {
801
+ // VML support detected. Insert CSS rules for group, shape and stroke.
802
+ var sheet = document.createStyleSheet();
803
+ $.each(['group', 'shape', 'stroke'], function() {
804
+ sheet.addRule(this, "behavior:url(#default#VML);");
805
+ });
806
+ ok = true;
807
+ }
808
+ $(s).remove();
809
+ return ok;
810
+ },
811
+
812
+ _getOpacity: function(i) {
813
+ var steps = this.options.steps || this.options.segments-1;
814
+ var end = this.options.opacity !== undefined ? this.options.opacity : 1/steps;
815
+ return 1 - Math.min(i, steps) * (1 - end) / steps;
816
+ },
817
+
818
+ _render: function() {
819
+ return this['_render'+this.renderMethod]();
820
+ },
821
+
822
+ _renderDOM: function() {
823
+ return $('<div>').addClass('ui-throbber');
824
+ },
825
+
826
+ _renderSVG: function() {
827
+ var o = this.options;
828
+ var innerRadius = o.width*2 + o.space;
829
+ var r = (innerRadius + o.length + Math.ceil(o.width / 2) + 1);
830
+
831
+ var el = svg().width(r*2).height(r*2);
832
+
833
+ var g = svg('g', {
834
+ 'stroke-width': o.width,
835
+ 'stroke-linecap': 'round',
836
+ stroke: o.color
837
+ }).appendTo(svg('g', {transform: 'translate('+ r +','+ r +')'}).appendTo(el));
838
+
839
+ for (var i = 0; i < o.segments; i++) {
840
+ g.append(svg('line', {
841
+ x1: 0,
842
+ y1: innerRadius,
843
+ x2: 0,
844
+ y2: innerRadius + o.length,
845
+ transform: 'rotate(' + (360 / o.segments * i) + ', 0, 0)',
846
+ opacity: this._getOpacity(i)
847
+ }));
848
+ }
849
+ return $('<div>').append(el).width(2*r).height(2*r);
850
+ },
851
+
852
+ _renderVML: function() {
853
+ var o = this.options;
854
+ var innerRadius = o.width*2 + o.space;
855
+ var r = (innerRadius + o.length + Math.ceil(o.width / 2) + 1);
856
+ var s = r*2;
857
+ var c = -Math.ceil(s/2);
858
+
859
+ var el = $('<group>', {coordsize: s + ' ' + s, coordorigin: c + ' ' + c}).css({top: c, left: c, width: s, height: s});
860
+ for (var i = 0; i < o.segments; i++) {
861
+ el.append($('<shape>', {path: 'm ' + innerRadius + ',0 l ' + (innerRadius + o.length) + ',0'}).css({
862
+ width: s,
863
+ height: s,
864
+ rotation: (360 / o.segments * i) + 'deg'
865
+ }).append($('<stroke>', {color: o.color, weight: o.width + 'px', endcap: 'round', opacity: this._getOpacity(i)})));
866
+ }
867
+ return $('<group>', {coordsize: s + ' ' + s}).css({width: s, height: s, overflow: 'hidden'}).append(el);
868
+ },
869
+
870
+ _animate: function(steps, duration) {
871
+ this['_animate'+this.animateMethod](steps, duration);
872
+ },
873
+
874
+ _animateCSS: function(steps, duration) {
875
+ if (!animations[steps]) {
876
+ var name = 'spin' + steps;
877
+ var rule = '@-webkit-keyframes '+ name +' {';
878
+ for (var i=0; i < steps; i++) {
879
+ var p1 = Math.round(100000 / steps * i) / 1000;
880
+ var p2 = Math.round(100000 / steps * (i+1) - 1) / 1000;
881
+ var value = '% { -webkit-transform:rotate(' + Math.round(360 / steps * i) + 'deg); }\n';
882
+ rule += p1 + value + p2 + value;
883
+ }
884
+ rule += '100% { -webkit-transform:rotate(100deg); }\n}';
885
+ document.styleSheets[0].insertRule(rule);
886
+ animations[steps] = name;
887
+ }
888
+ this.throbber.css('-webkit-animation', animations[steps] + ' ' + duration +'s linear infinite');
889
+ },
890
+
891
+ _animateSVG: function(steps, duration) {
892
+ var rotation = 0;
893
+ var g = this.throbber.find('g g').get(0);
894
+ this.interval = setInterval(function() {
895
+ g.setAttributeNS(null, 'transform', 'rotate(' + (++rotation % steps * (360 / steps)) + ')');
896
+ }, duration * 1000 / steps);
897
+ },
898
+
899
+ _animateVML: function(steps, duration) {
900
+ var rotation = 0;
901
+ var g = this.throbber.get(0);
902
+ this.interval = setInterval(function() {
903
+ g.style.rotation = ++rotation % steps * (360 / steps);
904
+ }, duration * 1000 / steps);
905
+ },
906
+
907
+ _animateDOM: function(steps, duration) {}
908
+
909
+ });
910
+
911
+ /**
912
+ * Utility function to create elements in the SVG namespace.
913
+ */
914
+ function svg(tag, attr) {
915
+ var el = document.createElementNS("http://www.w3.org/2000/svg", tag || 'svg');
916
+ if (attr) {
917
+ $.each(attr, function(k, v) {
918
+ el.setAttributeNS(null, k, v);
919
+ });
920
+ }
921
+ return $(el);
922
+ }
923
+
924
+ var animations = {};
925
+
926
+ })(jQuery);
927
+
928
+ })({});
929
+
930
+
931
+ (function(exports) {
932
+
933
+
934
+ /*
935
+ * JUI.Throbber
936
+ */
937
+
938
+ JUI.Throbber = SC.View.extend(JUI.Widget, {
939
+ uiType: 'throbber',
940
+ uiOptions: ['segments', 'space', 'length', 'width',
941
+ 'speed', 'align', 'valign', 'padding', 'autoStart', 'outside']
942
+ });
943
+
944
+ })({});
945
+
946
+
947
+ (function(exports) {
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+
960
+ })({});
961
+
962
+
963
+ (function(exports) {
964
+ // ==========================================================================
965
+ // Project: SproutCore JUI
966
+ // Copyright: ©2011 Paul Chavard
967
+ // License: Licensed under MIT license (see license.js)
968
+ // ==========================================================================
969
+
970
+ //require('jquery-ui');
971
+
972
+
973
+ })({});