activeadmin-rb 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +17 -12
  4. data/CHANGELOG.md +10 -1
  5. data/Gemfile +3 -11
  6. data/activeadmin-rb.gemspec +3 -2
  7. data/app/views/active_admin/devise/confirmations/new.html.erb +1 -1
  8. data/app/views/active_admin/devise/passwords/edit.html.erb +1 -1
  9. data/app/views/active_admin/devise/passwords/new.html.erb +1 -1
  10. data/app/views/active_admin/devise/registrations/new.html.erb +1 -1
  11. data/app/views/active_admin/devise/shared/_error_messages.html.erb +15 -0
  12. data/app/views/active_admin/devise/unlocks/new.html.erb +1 -1
  13. data/docs/documentation.md +1 -1
  14. data/features/index/filters.feature +3 -3
  15. data/features/index/pagination.feature +3 -3
  16. data/features/registering_assets.feature +4 -8
  17. data/features/support/env.rb +4 -0
  18. data/gemfiles/rails_42.gemfile +2 -1
  19. data/gemfiles/rails_50.gemfile +2 -1
  20. data/gemfiles/rails_51.gemfile +2 -1
  21. data/gemfiles/rails_52.gemfile +2 -1
  22. data/gemfiles/rails_60.gemfile +13 -0
  23. data/lib/active_admin.rb +1 -0
  24. data/lib/active_admin/application.rb +4 -3
  25. data/lib/active_admin/asset_registration.rb +0 -8
  26. data/lib/active_admin/version.rb +1 -1
  27. data/lib/bug_report_templates/active_admin_master.rb +3 -4
  28. data/spec/bug_report_templates_spec.rb +6 -4
  29. data/spec/support/active_admin_integration_spec_helper.rb +15 -7
  30. data/spec/support/rails_template.rb +8 -6
  31. data/spec/unit/asset_registration_spec.rb +0 -29
  32. data/spec/unit/auto_link_spec.rb +26 -16
  33. data/spec/unit/comments_spec.rb +22 -7
  34. data/spec/unit/filters/filter_form_builder_spec.rb +10 -10
  35. data/spec/unit/form_builder_spec.rb +1 -1
  36. data/spec/unit/pretty_format_spec.rb +73 -22
  37. data/spec/unit/resource_controller/data_access_spec.rb +3 -3
  38. data/spec/unit/routing_spec.rb +1 -1
  39. data/spec/unit/view_helpers/flash_helper_spec.rb +1 -1
  40. data/spec/unit/view_helpers/form_helper_spec.rb +2 -2
  41. data/spec/unit/views/components/attributes_table_spec.rb +1 -1
  42. metadata +20 -36
  43. data/vendor/assets/javascripts/jquery-ui/data.js +0 -41
  44. data/vendor/assets/javascripts/jquery-ui/disable-selection.js +0 -48
  45. data/vendor/assets/javascripts/jquery-ui/escape-selector.js +0 -23
  46. data/vendor/assets/javascripts/jquery-ui/focusable.js +0 -86
  47. data/vendor/assets/javascripts/jquery-ui/ie.js +0 -17
  48. data/vendor/assets/javascripts/jquery-ui/keycode.js +0 -47
  49. data/vendor/assets/javascripts/jquery-ui/plugin.js +0 -46
  50. data/vendor/assets/javascripts/jquery-ui/position.js +0 -500
  51. data/vendor/assets/javascripts/jquery-ui/safe-active-element.js +0 -42
  52. data/vendor/assets/javascripts/jquery-ui/safe-blur.js +0 -23
  53. data/vendor/assets/javascripts/jquery-ui/scroll-parent.js +0 -47
  54. data/vendor/assets/javascripts/jquery-ui/tabbable.js +0 -38
  55. data/vendor/assets/javascripts/jquery-ui/unique-id.js +0 -51
  56. data/vendor/assets/javascripts/jquery-ui/version.js +0 -17
  57. data/vendor/assets/javascripts/jquery-ui/widget.js +0 -735
  58. data/vendor/assets/javascripts/jquery-ui/widgets/button.js +0 -391
  59. data/vendor/assets/javascripts/jquery-ui/widgets/checkboxradio.js +0 -300
  60. data/vendor/assets/javascripts/jquery-ui/widgets/controlgroup.js +0 -300
  61. data/vendor/assets/javascripts/jquery-ui/widgets/datepicker.js +0 -2123
  62. data/vendor/assets/javascripts/jquery-ui/widgets/dialog.js +0 -954
  63. data/vendor/assets/javascripts/jquery-ui/widgets/draggable.js +0 -1259
  64. data/vendor/assets/javascripts/jquery-ui/widgets/mouse.js +0 -230
  65. data/vendor/assets/javascripts/jquery-ui/widgets/resizable.js +0 -1207
  66. data/vendor/assets/javascripts/jquery-ui/widgets/sortable.js +0 -1561
  67. data/vendor/assets/javascripts/jquery-ui/widgets/tabs.js +0 -931
@@ -1,931 +0,0 @@
1
- //= require jquery-ui/escape-selector
2
- //= require jquery-ui/keycode
3
- //= require jquery-ui/safe-active-element
4
- //= require jquery-ui/unique-id
5
- //= require jquery-ui/version
6
- //= require jquery-ui/widget
7
-
8
- /*!
9
- * jQuery UI Tabs 1.12.1
10
- * http://jqueryui.com
11
- *
12
- * Copyright jQuery Foundation and other contributors
13
- * Released under the MIT license.
14
- * http://jquery.org/license
15
- */
16
-
17
- //>>label: Tabs
18
- //>>group: Widgets
19
- //>>description: Transforms a set of container elements into a tab structure.
20
- //>>docs: http://api.jqueryui.com/tabs/
21
- //>>demos: http://jqueryui.com/tabs/
22
- //>>css.structure: ../../themes/base/core.css
23
- //>>css.structure: ../../themes/base/tabs.css
24
- //>>css.theme: ../../themes/base/theme.css
25
-
26
- ( function( factory ) {
27
- if ( typeof define === "function" && define.amd ) {
28
-
29
- // AMD. Register as an anonymous module.
30
- define( [
31
- "jquery",
32
- "../escape-selector",
33
- "../keycode",
34
- "../safe-active-element",
35
- "../unique-id",
36
- "../version",
37
- "../widget"
38
- ], factory );
39
- } else {
40
-
41
- // Browser globals
42
- factory( jQuery );
43
- }
44
- }( function( $ ) {
45
-
46
- $.widget( "ui.tabs", {
47
- version: "1.12.1",
48
- delay: 300,
49
- options: {
50
- active: null,
51
- classes: {
52
- "ui-tabs": "ui-corner-all",
53
- "ui-tabs-nav": "ui-corner-all",
54
- "ui-tabs-panel": "ui-corner-bottom",
55
- "ui-tabs-tab": "ui-corner-top"
56
- },
57
- collapsible: false,
58
- event: "click",
59
- heightStyle: "content",
60
- hide: null,
61
- show: null,
62
-
63
- // Callbacks
64
- activate: null,
65
- beforeActivate: null,
66
- beforeLoad: null,
67
- load: null
68
- },
69
-
70
- _isLocal: ( function() {
71
- var rhash = /#.*$/;
72
-
73
- return function( anchor ) {
74
- var anchorUrl, locationUrl;
75
-
76
- anchorUrl = anchor.href.replace( rhash, "" );
77
- locationUrl = location.href.replace( rhash, "" );
78
-
79
- // Decoding may throw an error if the URL isn't UTF-8 (#9518)
80
- try {
81
- anchorUrl = decodeURIComponent( anchorUrl );
82
- } catch ( error ) {}
83
- try {
84
- locationUrl = decodeURIComponent( locationUrl );
85
- } catch ( error ) {}
86
-
87
- return anchor.hash.length > 1 && anchorUrl === locationUrl;
88
- };
89
- } )(),
90
-
91
- _create: function() {
92
- var that = this,
93
- options = this.options;
94
-
95
- this.running = false;
96
-
97
- this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
98
- this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
99
-
100
- this._processTabs();
101
- options.active = this._initialActive();
102
-
103
- // Take disabling tabs via class attribute from HTML
104
- // into account and update option properly.
105
- if ( $.isArray( options.disabled ) ) {
106
- options.disabled = $.unique( options.disabled.concat(
107
- $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
108
- return that.tabs.index( li );
109
- } )
110
- ) ).sort();
111
- }
112
-
113
- // Check for length avoids error when initializing empty list
114
- if ( this.options.active !== false && this.anchors.length ) {
115
- this.active = this._findActive( options.active );
116
- } else {
117
- this.active = $();
118
- }
119
-
120
- this._refresh();
121
-
122
- if ( this.active.length ) {
123
- this.load( options.active );
124
- }
125
- },
126
-
127
- _initialActive: function() {
128
- var active = this.options.active,
129
- collapsible = this.options.collapsible,
130
- locationHash = location.hash.substring( 1 );
131
-
132
- if ( active === null ) {
133
-
134
- // check the fragment identifier in the URL
135
- if ( locationHash ) {
136
- this.tabs.each( function( i, tab ) {
137
- if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
138
- active = i;
139
- return false;
140
- }
141
- } );
142
- }
143
-
144
- // Check for a tab marked active via a class
145
- if ( active === null ) {
146
- active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
147
- }
148
-
149
- // No active tab, set to false
150
- if ( active === null || active === -1 ) {
151
- active = this.tabs.length ? 0 : false;
152
- }
153
- }
154
-
155
- // Handle numbers: negative, out of range
156
- if ( active !== false ) {
157
- active = this.tabs.index( this.tabs.eq( active ) );
158
- if ( active === -1 ) {
159
- active = collapsible ? false : 0;
160
- }
161
- }
162
-
163
- // Don't allow collapsible: false and active: false
164
- if ( !collapsible && active === false && this.anchors.length ) {
165
- active = 0;
166
- }
167
-
168
- return active;
169
- },
170
-
171
- _getCreateEventData: function() {
172
- return {
173
- tab: this.active,
174
- panel: !this.active.length ? $() : this._getPanelForTab( this.active )
175
- };
176
- },
177
-
178
- _tabKeydown: function( event ) {
179
- var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
180
- selectedIndex = this.tabs.index( focusedTab ),
181
- goingForward = true;
182
-
183
- if ( this._handlePageNav( event ) ) {
184
- return;
185
- }
186
-
187
- switch ( event.keyCode ) {
188
- case $.ui.keyCode.RIGHT:
189
- case $.ui.keyCode.DOWN:
190
- selectedIndex++;
191
- break;
192
- case $.ui.keyCode.UP:
193
- case $.ui.keyCode.LEFT:
194
- goingForward = false;
195
- selectedIndex--;
196
- break;
197
- case $.ui.keyCode.END:
198
- selectedIndex = this.anchors.length - 1;
199
- break;
200
- case $.ui.keyCode.HOME:
201
- selectedIndex = 0;
202
- break;
203
- case $.ui.keyCode.SPACE:
204
-
205
- // Activate only, no collapsing
206
- event.preventDefault();
207
- clearTimeout( this.activating );
208
- this._activate( selectedIndex );
209
- return;
210
- case $.ui.keyCode.ENTER:
211
-
212
- // Toggle (cancel delayed activation, allow collapsing)
213
- event.preventDefault();
214
- clearTimeout( this.activating );
215
-
216
- // Determine if we should collapse or activate
217
- this._activate( selectedIndex === this.options.active ? false : selectedIndex );
218
- return;
219
- default:
220
- return;
221
- }
222
-
223
- // Focus the appropriate tab, based on which key was pressed
224
- event.preventDefault();
225
- clearTimeout( this.activating );
226
- selectedIndex = this._focusNextTab( selectedIndex, goingForward );
227
-
228
- // Navigating with control/command key will prevent automatic activation
229
- if ( !event.ctrlKey && !event.metaKey ) {
230
-
231
- // Update aria-selected immediately so that AT think the tab is already selected.
232
- // Otherwise AT may confuse the user by stating that they need to activate the tab,
233
- // but the tab will already be activated by the time the announcement finishes.
234
- focusedTab.attr( "aria-selected", "false" );
235
- this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
236
-
237
- this.activating = this._delay( function() {
238
- this.option( "active", selectedIndex );
239
- }, this.delay );
240
- }
241
- },
242
-
243
- _panelKeydown: function( event ) {
244
- if ( this._handlePageNav( event ) ) {
245
- return;
246
- }
247
-
248
- // Ctrl+up moves focus to the current tab
249
- if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
250
- event.preventDefault();
251
- this.active.trigger( "focus" );
252
- }
253
- },
254
-
255
- // Alt+page up/down moves focus to the previous/next tab (and activates)
256
- _handlePageNav: function( event ) {
257
- if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
258
- this._activate( this._focusNextTab( this.options.active - 1, false ) );
259
- return true;
260
- }
261
- if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
262
- this._activate( this._focusNextTab( this.options.active + 1, true ) );
263
- return true;
264
- }
265
- },
266
-
267
- _findNextTab: function( index, goingForward ) {
268
- var lastTabIndex = this.tabs.length - 1;
269
-
270
- function constrain() {
271
- if ( index > lastTabIndex ) {
272
- index = 0;
273
- }
274
- if ( index < 0 ) {
275
- index = lastTabIndex;
276
- }
277
- return index;
278
- }
279
-
280
- while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
281
- index = goingForward ? index + 1 : index - 1;
282
- }
283
-
284
- return index;
285
- },
286
-
287
- _focusNextTab: function( index, goingForward ) {
288
- index = this._findNextTab( index, goingForward );
289
- this.tabs.eq( index ).trigger( "focus" );
290
- return index;
291
- },
292
-
293
- _setOption: function( key, value ) {
294
- if ( key === "active" ) {
295
-
296
- // _activate() will handle invalid values and update this.options
297
- this._activate( value );
298
- return;
299
- }
300
-
301
- this._super( key, value );
302
-
303
- if ( key === "collapsible" ) {
304
- this._toggleClass( "ui-tabs-collapsible", null, value );
305
-
306
- // Setting collapsible: false while collapsed; open first panel
307
- if ( !value && this.options.active === false ) {
308
- this._activate( 0 );
309
- }
310
- }
311
-
312
- if ( key === "event" ) {
313
- this._setupEvents( value );
314
- }
315
-
316
- if ( key === "heightStyle" ) {
317
- this._setupHeightStyle( value );
318
- }
319
- },
320
-
321
- _sanitizeSelector: function( hash ) {
322
- return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
323
- },
324
-
325
- refresh: function() {
326
- var options = this.options,
327
- lis = this.tablist.children( ":has(a[href])" );
328
-
329
- // Get disabled tabs from class attribute from HTML
330
- // this will get converted to a boolean if needed in _refresh()
331
- options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
332
- return lis.index( tab );
333
- } );
334
-
335
- this._processTabs();
336
-
337
- // Was collapsed or no tabs
338
- if ( options.active === false || !this.anchors.length ) {
339
- options.active = false;
340
- this.active = $();
341
-
342
- // was active, but active tab is gone
343
- } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
344
-
345
- // all remaining tabs are disabled
346
- if ( this.tabs.length === options.disabled.length ) {
347
- options.active = false;
348
- this.active = $();
349
-
350
- // activate previous tab
351
- } else {
352
- this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
353
- }
354
-
355
- // was active, active tab still exists
356
- } else {
357
-
358
- // make sure active index is correct
359
- options.active = this.tabs.index( this.active );
360
- }
361
-
362
- this._refresh();
363
- },
364
-
365
- _refresh: function() {
366
- this._setOptionDisabled( this.options.disabled );
367
- this._setupEvents( this.options.event );
368
- this._setupHeightStyle( this.options.heightStyle );
369
-
370
- this.tabs.not( this.active ).attr( {
371
- "aria-selected": "false",
372
- "aria-expanded": "false",
373
- tabIndex: -1
374
- } );
375
- this.panels.not( this._getPanelForTab( this.active ) )
376
- .hide()
377
- .attr( {
378
- "aria-hidden": "true"
379
- } );
380
-
381
- // Make sure one tab is in the tab order
382
- if ( !this.active.length ) {
383
- this.tabs.eq( 0 ).attr( "tabIndex", 0 );
384
- } else {
385
- this.active
386
- .attr( {
387
- "aria-selected": "true",
388
- "aria-expanded": "true",
389
- tabIndex: 0
390
- } );
391
- this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
392
- this._getPanelForTab( this.active )
393
- .show()
394
- .attr( {
395
- "aria-hidden": "false"
396
- } );
397
- }
398
- },
399
-
400
- _processTabs: function() {
401
- var that = this,
402
- prevTabs = this.tabs,
403
- prevAnchors = this.anchors,
404
- prevPanels = this.panels;
405
-
406
- this.tablist = this._getList().attr( "role", "tablist" );
407
- this._addClass( this.tablist, "ui-tabs-nav",
408
- "ui-helper-reset ui-helper-clearfix ui-widget-header" );
409
-
410
- // Prevent users from focusing disabled tabs via click
411
- this.tablist
412
- .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
413
- if ( $( this ).is( ".ui-state-disabled" ) ) {
414
- event.preventDefault();
415
- }
416
- } )
417
-
418
- // Support: IE <9
419
- // Preventing the default action in mousedown doesn't prevent IE
420
- // from focusing the element, so if the anchor gets focused, blur.
421
- // We don't have to worry about focusing the previously focused
422
- // element since clicking on a non-focusable element should focus
423
- // the body anyway.
424
- .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
425
- if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
426
- this.blur();
427
- }
428
- } );
429
-
430
- this.tabs = this.tablist.find( "> li:has(a[href])" )
431
- .attr( {
432
- role: "tab",
433
- tabIndex: -1
434
- } );
435
- this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
436
-
437
- this.anchors = this.tabs.map( function() {
438
- return $( "a", this )[ 0 ];
439
- } )
440
- .attr( {
441
- role: "presentation",
442
- tabIndex: -1
443
- } );
444
- this._addClass( this.anchors, "ui-tabs-anchor" );
445
-
446
- this.panels = $();
447
-
448
- this.anchors.each( function( i, anchor ) {
449
- var selector, panel, panelId,
450
- anchorId = $( anchor ).uniqueId().attr( "id" ),
451
- tab = $( anchor ).closest( "li" ),
452
- originalAriaControls = tab.attr( "aria-controls" );
453
-
454
- // Inline tab
455
- if ( that._isLocal( anchor ) ) {
456
- selector = anchor.hash;
457
- panelId = selector.substring( 1 );
458
- panel = that.element.find( that._sanitizeSelector( selector ) );
459
-
460
- // remote tab
461
- } else {
462
-
463
- // If the tab doesn't already have aria-controls,
464
- // generate an id by using a throw-away element
465
- panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
466
- selector = "#" + panelId;
467
- panel = that.element.find( selector );
468
- if ( !panel.length ) {
469
- panel = that._createPanel( panelId );
470
- panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
471
- }
472
- panel.attr( "aria-live", "polite" );
473
- }
474
-
475
- if ( panel.length ) {
476
- that.panels = that.panels.add( panel );
477
- }
478
- if ( originalAriaControls ) {
479
- tab.data( "ui-tabs-aria-controls", originalAriaControls );
480
- }
481
- tab.attr( {
482
- "aria-controls": panelId,
483
- "aria-labelledby": anchorId
484
- } );
485
- panel.attr( "aria-labelledby", anchorId );
486
- } );
487
-
488
- this.panels.attr( "role", "tabpanel" );
489
- this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
490
-
491
- // Avoid memory leaks (#10056)
492
- if ( prevTabs ) {
493
- this._off( prevTabs.not( this.tabs ) );
494
- this._off( prevAnchors.not( this.anchors ) );
495
- this._off( prevPanels.not( this.panels ) );
496
- }
497
- },
498
-
499
- // Allow overriding how to find the list for rare usage scenarios (#7715)
500
- _getList: function() {
501
- return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
502
- },
503
-
504
- _createPanel: function( id ) {
505
- return $( "<div>" )
506
- .attr( "id", id )
507
- .data( "ui-tabs-destroy", true );
508
- },
509
-
510
- _setOptionDisabled: function( disabled ) {
511
- var currentItem, li, i;
512
-
513
- if ( $.isArray( disabled ) ) {
514
- if ( !disabled.length ) {
515
- disabled = false;
516
- } else if ( disabled.length === this.anchors.length ) {
517
- disabled = true;
518
- }
519
- }
520
-
521
- // Disable tabs
522
- for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
523
- currentItem = $( li );
524
- if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
525
- currentItem.attr( "aria-disabled", "true" );
526
- this._addClass( currentItem, null, "ui-state-disabled" );
527
- } else {
528
- currentItem.removeAttr( "aria-disabled" );
529
- this._removeClass( currentItem, null, "ui-state-disabled" );
530
- }
531
- }
532
-
533
- this.options.disabled = disabled;
534
-
535
- this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
536
- disabled === true );
537
- },
538
-
539
- _setupEvents: function( event ) {
540
- var events = {};
541
- if ( event ) {
542
- $.each( event.split( " " ), function( index, eventName ) {
543
- events[ eventName ] = "_eventHandler";
544
- } );
545
- }
546
-
547
- this._off( this.anchors.add( this.tabs ).add( this.panels ) );
548
-
549
- // Always prevent the default action, even when disabled
550
- this._on( true, this.anchors, {
551
- click: function( event ) {
552
- event.preventDefault();
553
- }
554
- } );
555
- this._on( this.anchors, events );
556
- this._on( this.tabs, { keydown: "_tabKeydown" } );
557
- this._on( this.panels, { keydown: "_panelKeydown" } );
558
-
559
- this._focusable( this.tabs );
560
- this._hoverable( this.tabs );
561
- },
562
-
563
- _setupHeightStyle: function( heightStyle ) {
564
- var maxHeight,
565
- parent = this.element.parent();
566
-
567
- if ( heightStyle === "fill" ) {
568
- maxHeight = parent.height();
569
- maxHeight -= this.element.outerHeight() - this.element.height();
570
-
571
- this.element.siblings( ":visible" ).each( function() {
572
- var elem = $( this ),
573
- position = elem.css( "position" );
574
-
575
- if ( position === "absolute" || position === "fixed" ) {
576
- return;
577
- }
578
- maxHeight -= elem.outerHeight( true );
579
- } );
580
-
581
- this.element.children().not( this.panels ).each( function() {
582
- maxHeight -= $( this ).outerHeight( true );
583
- } );
584
-
585
- this.panels.each( function() {
586
- $( this ).height( Math.max( 0, maxHeight -
587
- $( this ).innerHeight() + $( this ).height() ) );
588
- } )
589
- .css( "overflow", "auto" );
590
- } else if ( heightStyle === "auto" ) {
591
- maxHeight = 0;
592
- this.panels.each( function() {
593
- maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
594
- } ).height( maxHeight );
595
- }
596
- },
597
-
598
- _eventHandler: function( event ) {
599
- var options = this.options,
600
- active = this.active,
601
- anchor = $( event.currentTarget ),
602
- tab = anchor.closest( "li" ),
603
- clickedIsActive = tab[ 0 ] === active[ 0 ],
604
- collapsing = clickedIsActive && options.collapsible,
605
- toShow = collapsing ? $() : this._getPanelForTab( tab ),
606
- toHide = !active.length ? $() : this._getPanelForTab( active ),
607
- eventData = {
608
- oldTab: active,
609
- oldPanel: toHide,
610
- newTab: collapsing ? $() : tab,
611
- newPanel: toShow
612
- };
613
-
614
- event.preventDefault();
615
-
616
- if ( tab.hasClass( "ui-state-disabled" ) ||
617
-
618
- // tab is already loading
619
- tab.hasClass( "ui-tabs-loading" ) ||
620
-
621
- // can't switch durning an animation
622
- this.running ||
623
-
624
- // click on active header, but not collapsible
625
- ( clickedIsActive && !options.collapsible ) ||
626
-
627
- // allow canceling activation
628
- ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
629
- return;
630
- }
631
-
632
- options.active = collapsing ? false : this.tabs.index( tab );
633
-
634
- this.active = clickedIsActive ? $() : tab;
635
- if ( this.xhr ) {
636
- this.xhr.abort();
637
- }
638
-
639
- if ( !toHide.length && !toShow.length ) {
640
- $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
641
- }
642
-
643
- if ( toShow.length ) {
644
- this.load( this.tabs.index( tab ), event );
645
- }
646
- this._toggle( event, eventData );
647
- },
648
-
649
- // Handles show/hide for selecting tabs
650
- _toggle: function( event, eventData ) {
651
- var that = this,
652
- toShow = eventData.newPanel,
653
- toHide = eventData.oldPanel;
654
-
655
- this.running = true;
656
-
657
- function complete() {
658
- that.running = false;
659
- that._trigger( "activate", event, eventData );
660
- }
661
-
662
- function show() {
663
- that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
664
-
665
- if ( toShow.length && that.options.show ) {
666
- that._show( toShow, that.options.show, complete );
667
- } else {
668
- toShow.show();
669
- complete();
670
- }
671
- }
672
-
673
- // Start out by hiding, then showing, then completing
674
- if ( toHide.length && this.options.hide ) {
675
- this._hide( toHide, this.options.hide, function() {
676
- that._removeClass( eventData.oldTab.closest( "li" ),
677
- "ui-tabs-active", "ui-state-active" );
678
- show();
679
- } );
680
- } else {
681
- this._removeClass( eventData.oldTab.closest( "li" ),
682
- "ui-tabs-active", "ui-state-active" );
683
- toHide.hide();
684
- show();
685
- }
686
-
687
- toHide.attr( "aria-hidden", "true" );
688
- eventData.oldTab.attr( {
689
- "aria-selected": "false",
690
- "aria-expanded": "false"
691
- } );
692
-
693
- // If we're switching tabs, remove the old tab from the tab order.
694
- // If we're opening from collapsed state, remove the previous tab from the tab order.
695
- // If we're collapsing, then keep the collapsing tab in the tab order.
696
- if ( toShow.length && toHide.length ) {
697
- eventData.oldTab.attr( "tabIndex", -1 );
698
- } else if ( toShow.length ) {
699
- this.tabs.filter( function() {
700
- return $( this ).attr( "tabIndex" ) === 0;
701
- } )
702
- .attr( "tabIndex", -1 );
703
- }
704
-
705
- toShow.attr( "aria-hidden", "false" );
706
- eventData.newTab.attr( {
707
- "aria-selected": "true",
708
- "aria-expanded": "true",
709
- tabIndex: 0
710
- } );
711
- },
712
-
713
- _activate: function( index ) {
714
- var anchor,
715
- active = this._findActive( index );
716
-
717
- // Trying to activate the already active panel
718
- if ( active[ 0 ] === this.active[ 0 ] ) {
719
- return;
720
- }
721
-
722
- // Trying to collapse, simulate a click on the current active header
723
- if ( !active.length ) {
724
- active = this.active;
725
- }
726
-
727
- anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
728
- this._eventHandler( {
729
- target: anchor,
730
- currentTarget: anchor,
731
- preventDefault: $.noop
732
- } );
733
- },
734
-
735
- _findActive: function( index ) {
736
- return index === false ? $() : this.tabs.eq( index );
737
- },
738
-
739
- _getIndex: function( index ) {
740
-
741
- // meta-function to give users option to provide a href string instead of a numerical index.
742
- if ( typeof index === "string" ) {
743
- index = this.anchors.index( this.anchors.filter( "[href$='" +
744
- $.ui.escapeSelector( index ) + "']" ) );
745
- }
746
-
747
- return index;
748
- },
749
-
750
- _destroy: function() {
751
- if ( this.xhr ) {
752
- this.xhr.abort();
753
- }
754
-
755
- this.tablist
756
- .removeAttr( "role" )
757
- .off( this.eventNamespace );
758
-
759
- this.anchors
760
- .removeAttr( "role tabIndex" )
761
- .removeUniqueId();
762
-
763
- this.tabs.add( this.panels ).each( function() {
764
- if ( $.data( this, "ui-tabs-destroy" ) ) {
765
- $( this ).remove();
766
- } else {
767
- $( this ).removeAttr( "role tabIndex " +
768
- "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
769
- }
770
- } );
771
-
772
- this.tabs.each( function() {
773
- var li = $( this ),
774
- prev = li.data( "ui-tabs-aria-controls" );
775
- if ( prev ) {
776
- li
777
- .attr( "aria-controls", prev )
778
- .removeData( "ui-tabs-aria-controls" );
779
- } else {
780
- li.removeAttr( "aria-controls" );
781
- }
782
- } );
783
-
784
- this.panels.show();
785
-
786
- if ( this.options.heightStyle !== "content" ) {
787
- this.panels.css( "height", "" );
788
- }
789
- },
790
-
791
- enable: function( index ) {
792
- var disabled = this.options.disabled;
793
- if ( disabled === false ) {
794
- return;
795
- }
796
-
797
- if ( index === undefined ) {
798
- disabled = false;
799
- } else {
800
- index = this._getIndex( index );
801
- if ( $.isArray( disabled ) ) {
802
- disabled = $.map( disabled, function( num ) {
803
- return num !== index ? num : null;
804
- } );
805
- } else {
806
- disabled = $.map( this.tabs, function( li, num ) {
807
- return num !== index ? num : null;
808
- } );
809
- }
810
- }
811
- this._setOptionDisabled( disabled );
812
- },
813
-
814
- disable: function( index ) {
815
- var disabled = this.options.disabled;
816
- if ( disabled === true ) {
817
- return;
818
- }
819
-
820
- if ( index === undefined ) {
821
- disabled = true;
822
- } else {
823
- index = this._getIndex( index );
824
- if ( $.inArray( index, disabled ) !== -1 ) {
825
- return;
826
- }
827
- if ( $.isArray( disabled ) ) {
828
- disabled = $.merge( [ index ], disabled ).sort();
829
- } else {
830
- disabled = [ index ];
831
- }
832
- }
833
- this._setOptionDisabled( disabled );
834
- },
835
-
836
- load: function( index, event ) {
837
- index = this._getIndex( index );
838
- var that = this,
839
- tab = this.tabs.eq( index ),
840
- anchor = tab.find( ".ui-tabs-anchor" ),
841
- panel = this._getPanelForTab( tab ),
842
- eventData = {
843
- tab: tab,
844
- panel: panel
845
- },
846
- complete = function( jqXHR, status ) {
847
- if ( status === "abort" ) {
848
- that.panels.stop( false, true );
849
- }
850
-
851
- that._removeClass( tab, "ui-tabs-loading" );
852
- panel.removeAttr( "aria-busy" );
853
-
854
- if ( jqXHR === that.xhr ) {
855
- delete that.xhr;
856
- }
857
- };
858
-
859
- // Not remote
860
- if ( this._isLocal( anchor[ 0 ] ) ) {
861
- return;
862
- }
863
-
864
- this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
865
-
866
- // Support: jQuery <1.8
867
- // jQuery <1.8 returns false if the request is canceled in beforeSend,
868
- // but as of 1.8, $.ajax() always returns a jqXHR object.
869
- if ( this.xhr && this.xhr.statusText !== "canceled" ) {
870
- this._addClass( tab, "ui-tabs-loading" );
871
- panel.attr( "aria-busy", "true" );
872
-
873
- this.xhr
874
- .done( function( response, status, jqXHR ) {
875
-
876
- // support: jQuery <1.8
877
- // http://bugs.jquery.com/ticket/11778
878
- setTimeout( function() {
879
- panel.html( response );
880
- that._trigger( "load", event, eventData );
881
-
882
- complete( jqXHR, status );
883
- }, 1 );
884
- } )
885
- .fail( function( jqXHR, status ) {
886
-
887
- // support: jQuery <1.8
888
- // http://bugs.jquery.com/ticket/11778
889
- setTimeout( function() {
890
- complete( jqXHR, status );
891
- }, 1 );
892
- } );
893
- }
894
- },
895
-
896
- _ajaxSettings: function( anchor, event, eventData ) {
897
- var that = this;
898
- return {
899
-
900
- // Support: IE <11 only
901
- // Strip any hash that exists to prevent errors with the Ajax request
902
- url: anchor.attr( "href" ).replace( /#.*$/, "" ),
903
- beforeSend: function( jqXHR, settings ) {
904
- return that._trigger( "beforeLoad", event,
905
- $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
906
- }
907
- };
908
- },
909
-
910
- _getPanelForTab: function( tab ) {
911
- var id = $( tab ).attr( "aria-controls" );
912
- return this.element.find( this._sanitizeSelector( "#" + id ) );
913
- }
914
- } );
915
-
916
- // DEPRECATED
917
- // TODO: Switch return back to widget declaration at top of file when this is removed
918
- if ( $.uiBackCompat !== false ) {
919
-
920
- // Backcompat for ui-tab class (now ui-tabs-tab)
921
- $.widget( "ui.tabs", $.ui.tabs, {
922
- _processTabs: function() {
923
- this._superApply( arguments );
924
- this._addClass( this.tabs, "ui-tab" );
925
- }
926
- } );
927
- }
928
-
929
- return $.ui.tabs;
930
-
931
- } ) );