|
1 /*! jQuery UI - v1.13.2 - 2022-07-14 |
|
2 * http://jqueryui.com |
|
3 * Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js |
|
4 * Copyright jQuery Foundation and other contributors; Licensed MIT */ |
|
5 |
|
6 ( function( factory ) { |
|
7 "use strict"; |
|
8 |
|
9 if ( typeof define === "function" && define.amd ) { |
|
10 |
|
11 // AMD. Register as an anonymous module. |
|
12 define( [ "jquery" ], factory ); |
|
13 } else { |
|
14 |
|
15 // Browser globals |
|
16 factory( jQuery ); |
|
17 } |
|
18 } )( function( $ ) { |
|
19 "use strict"; |
|
20 |
|
21 $.ui = $.ui || {}; |
|
22 |
|
23 var version = $.ui.version = "1.13.2"; |
|
24 |
|
25 |
1 /*! |
26 /*! |
2 * jQuery UI 1.8.16 |
27 * jQuery UI Widget 1.13.2 |
|
28 * http://jqueryui.com |
3 * |
29 * |
4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) |
30 * Copyright jQuery Foundation and other contributors |
5 * Dual licensed under the MIT or GPL Version 2 licenses. |
31 * Released under the MIT license. |
|
32 * http://jquery.org/license |
|
33 */ |
|
34 |
|
35 //>>label: Widget |
|
36 //>>group: Core |
|
37 //>>description: Provides a factory for creating stateful widgets with a common API. |
|
38 //>>docs: http://api.jqueryui.com/jQuery.widget/ |
|
39 //>>demos: http://jqueryui.com/widget/ |
|
40 |
|
41 |
|
42 var widgetUuid = 0; |
|
43 var widgetHasOwnProperty = Array.prototype.hasOwnProperty; |
|
44 var widgetSlice = Array.prototype.slice; |
|
45 |
|
46 $.cleanData = ( function( orig ) { |
|
47 return function( elems ) { |
|
48 var events, elem, i; |
|
49 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { |
|
50 |
|
51 // Only trigger remove when necessary to save time |
|
52 events = $._data( elem, "events" ); |
|
53 if ( events && events.remove ) { |
|
54 $( elem ).triggerHandler( "remove" ); |
|
55 } |
|
56 } |
|
57 orig( elems ); |
|
58 }; |
|
59 } )( $.cleanData ); |
|
60 |
|
61 $.widget = function( name, base, prototype ) { |
|
62 var existingConstructor, constructor, basePrototype; |
|
63 |
|
64 // ProxiedPrototype allows the provided prototype to remain unmodified |
|
65 // so that it can be used as a mixin for multiple widgets (#8876) |
|
66 var proxiedPrototype = {}; |
|
67 |
|
68 var namespace = name.split( "." )[ 0 ]; |
|
69 name = name.split( "." )[ 1 ]; |
|
70 var fullName = namespace + "-" + name; |
|
71 |
|
72 if ( !prototype ) { |
|
73 prototype = base; |
|
74 base = $.Widget; |
|
75 } |
|
76 |
|
77 if ( Array.isArray( prototype ) ) { |
|
78 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); |
|
79 } |
|
80 |
|
81 // Create selector for plugin |
|
82 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { |
|
83 return !!$.data( elem, fullName ); |
|
84 }; |
|
85 |
|
86 $[ namespace ] = $[ namespace ] || {}; |
|
87 existingConstructor = $[ namespace ][ name ]; |
|
88 constructor = $[ namespace ][ name ] = function( options, element ) { |
|
89 |
|
90 // Allow instantiation without "new" keyword |
|
91 if ( !this || !this._createWidget ) { |
|
92 return new constructor( options, element ); |
|
93 } |
|
94 |
|
95 // Allow instantiation without initializing for simple inheritance |
|
96 // must use "new" keyword (the code above always passes args) |
|
97 if ( arguments.length ) { |
|
98 this._createWidget( options, element ); |
|
99 } |
|
100 }; |
|
101 |
|
102 // Extend with the existing constructor to carry over any static properties |
|
103 $.extend( constructor, existingConstructor, { |
|
104 version: prototype.version, |
|
105 |
|
106 // Copy the object used to create the prototype in case we need to |
|
107 // redefine the widget later |
|
108 _proto: $.extend( {}, prototype ), |
|
109 |
|
110 // Track widgets that inherit from this widget in case this widget is |
|
111 // redefined after a widget inherits from it |
|
112 _childConstructors: [] |
|
113 } ); |
|
114 |
|
115 basePrototype = new base(); |
|
116 |
|
117 // We need to make the options hash a property directly on the new instance |
|
118 // otherwise we'll modify the options hash on the prototype that we're |
|
119 // inheriting from |
|
120 basePrototype.options = $.widget.extend( {}, basePrototype.options ); |
|
121 $.each( prototype, function( prop, value ) { |
|
122 if ( typeof value !== "function" ) { |
|
123 proxiedPrototype[ prop ] = value; |
|
124 return; |
|
125 } |
|
126 proxiedPrototype[ prop ] = ( function() { |
|
127 function _super() { |
|
128 return base.prototype[ prop ].apply( this, arguments ); |
|
129 } |
|
130 |
|
131 function _superApply( args ) { |
|
132 return base.prototype[ prop ].apply( this, args ); |
|
133 } |
|
134 |
|
135 return function() { |
|
136 var __super = this._super; |
|
137 var __superApply = this._superApply; |
|
138 var returnValue; |
|
139 |
|
140 this._super = _super; |
|
141 this._superApply = _superApply; |
|
142 |
|
143 returnValue = value.apply( this, arguments ); |
|
144 |
|
145 this._super = __super; |
|
146 this._superApply = __superApply; |
|
147 |
|
148 return returnValue; |
|
149 }; |
|
150 } )(); |
|
151 } ); |
|
152 constructor.prototype = $.widget.extend( basePrototype, { |
|
153 |
|
154 // TODO: remove support for widgetEventPrefix |
|
155 // always use the name + a colon as the prefix, e.g., draggable:start |
|
156 // don't prefix for widgets that aren't DOM-based |
|
157 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name |
|
158 }, proxiedPrototype, { |
|
159 constructor: constructor, |
|
160 namespace: namespace, |
|
161 widgetName: name, |
|
162 widgetFullName: fullName |
|
163 } ); |
|
164 |
|
165 // If this widget is being redefined then we need to find all widgets that |
|
166 // are inheriting from it and redefine all of them so that they inherit from |
|
167 // the new version of this widget. We're essentially trying to replace one |
|
168 // level in the prototype chain. |
|
169 if ( existingConstructor ) { |
|
170 $.each( existingConstructor._childConstructors, function( i, child ) { |
|
171 var childPrototype = child.prototype; |
|
172 |
|
173 // Redefine the child widget using the same prototype that was |
|
174 // originally used, but inherit from the new version of the base |
|
175 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, |
|
176 child._proto ); |
|
177 } ); |
|
178 |
|
179 // Remove the list of existing child constructors from the old constructor |
|
180 // so the old child constructors can be garbage collected |
|
181 delete existingConstructor._childConstructors; |
|
182 } else { |
|
183 base._childConstructors.push( constructor ); |
|
184 } |
|
185 |
|
186 $.widget.bridge( name, constructor ); |
|
187 |
|
188 return constructor; |
|
189 }; |
|
190 |
|
191 $.widget.extend = function( target ) { |
|
192 var input = widgetSlice.call( arguments, 1 ); |
|
193 var inputIndex = 0; |
|
194 var inputLength = input.length; |
|
195 var key; |
|
196 var value; |
|
197 |
|
198 for ( ; inputIndex < inputLength; inputIndex++ ) { |
|
199 for ( key in input[ inputIndex ] ) { |
|
200 value = input[ inputIndex ][ key ]; |
|
201 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { |
|
202 |
|
203 // Clone objects |
|
204 if ( $.isPlainObject( value ) ) { |
|
205 target[ key ] = $.isPlainObject( target[ key ] ) ? |
|
206 $.widget.extend( {}, target[ key ], value ) : |
|
207 |
|
208 // Don't extend strings, arrays, etc. with objects |
|
209 $.widget.extend( {}, value ); |
|
210 |
|
211 // Copy everything else by reference |
|
212 } else { |
|
213 target[ key ] = value; |
|
214 } |
|
215 } |
|
216 } |
|
217 } |
|
218 return target; |
|
219 }; |
|
220 |
|
221 $.widget.bridge = function( name, object ) { |
|
222 var fullName = object.prototype.widgetFullName || name; |
|
223 $.fn[ name ] = function( options ) { |
|
224 var isMethodCall = typeof options === "string"; |
|
225 var args = widgetSlice.call( arguments, 1 ); |
|
226 var returnValue = this; |
|
227 |
|
228 if ( isMethodCall ) { |
|
229 |
|
230 // If this is an empty collection, we need to have the instance method |
|
231 // return undefined instead of the jQuery instance |
|
232 if ( !this.length && options === "instance" ) { |
|
233 returnValue = undefined; |
|
234 } else { |
|
235 this.each( function() { |
|
236 var methodValue; |
|
237 var instance = $.data( this, fullName ); |
|
238 |
|
239 if ( options === "instance" ) { |
|
240 returnValue = instance; |
|
241 return false; |
|
242 } |
|
243 |
|
244 if ( !instance ) { |
|
245 return $.error( "cannot call methods on " + name + |
|
246 " prior to initialization; " + |
|
247 "attempted to call method '" + options + "'" ); |
|
248 } |
|
249 |
|
250 if ( typeof instance[ options ] !== "function" || |
|
251 options.charAt( 0 ) === "_" ) { |
|
252 return $.error( "no such method '" + options + "' for " + name + |
|
253 " widget instance" ); |
|
254 } |
|
255 |
|
256 methodValue = instance[ options ].apply( instance, args ); |
|
257 |
|
258 if ( methodValue !== instance && methodValue !== undefined ) { |
|
259 returnValue = methodValue && methodValue.jquery ? |
|
260 returnValue.pushStack( methodValue.get() ) : |
|
261 methodValue; |
|
262 return false; |
|
263 } |
|
264 } ); |
|
265 } |
|
266 } else { |
|
267 |
|
268 // Allow multiple hashes to be passed on init |
|
269 if ( args.length ) { |
|
270 options = $.widget.extend.apply( null, [ options ].concat( args ) ); |
|
271 } |
|
272 |
|
273 this.each( function() { |
|
274 var instance = $.data( this, fullName ); |
|
275 if ( instance ) { |
|
276 instance.option( options || {} ); |
|
277 if ( instance._init ) { |
|
278 instance._init(); |
|
279 } |
|
280 } else { |
|
281 $.data( this, fullName, new object( options, this ) ); |
|
282 } |
|
283 } ); |
|
284 } |
|
285 |
|
286 return returnValue; |
|
287 }; |
|
288 }; |
|
289 |
|
290 $.Widget = function( /* options, element */ ) {}; |
|
291 $.Widget._childConstructors = []; |
|
292 |
|
293 $.Widget.prototype = { |
|
294 widgetName: "widget", |
|
295 widgetEventPrefix: "", |
|
296 defaultElement: "<div>", |
|
297 |
|
298 options: { |
|
299 classes: {}, |
|
300 disabled: false, |
|
301 |
|
302 // Callbacks |
|
303 create: null |
|
304 }, |
|
305 |
|
306 _createWidget: function( options, element ) { |
|
307 element = $( element || this.defaultElement || this )[ 0 ]; |
|
308 this.element = $( element ); |
|
309 this.uuid = widgetUuid++; |
|
310 this.eventNamespace = "." + this.widgetName + this.uuid; |
|
311 |
|
312 this.bindings = $(); |
|
313 this.hoverable = $(); |
|
314 this.focusable = $(); |
|
315 this.classesElementLookup = {}; |
|
316 |
|
317 if ( element !== this ) { |
|
318 $.data( element, this.widgetFullName, this ); |
|
319 this._on( true, this.element, { |
|
320 remove: function( event ) { |
|
321 if ( event.target === element ) { |
|
322 this.destroy(); |
|
323 } |
|
324 } |
|
325 } ); |
|
326 this.document = $( element.style ? |
|
327 |
|
328 // Element within the document |
|
329 element.ownerDocument : |
|
330 |
|
331 // Element is window or document |
|
332 element.document || element ); |
|
333 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); |
|
334 } |
|
335 |
|
336 this.options = $.widget.extend( {}, |
|
337 this.options, |
|
338 this._getCreateOptions(), |
|
339 options ); |
|
340 |
|
341 this._create(); |
|
342 |
|
343 if ( this.options.disabled ) { |
|
344 this._setOptionDisabled( this.options.disabled ); |
|
345 } |
|
346 |
|
347 this._trigger( "create", null, this._getCreateEventData() ); |
|
348 this._init(); |
|
349 }, |
|
350 |
|
351 _getCreateOptions: function() { |
|
352 return {}; |
|
353 }, |
|
354 |
|
355 _getCreateEventData: $.noop, |
|
356 |
|
357 _create: $.noop, |
|
358 |
|
359 _init: $.noop, |
|
360 |
|
361 destroy: function() { |
|
362 var that = this; |
|
363 |
|
364 this._destroy(); |
|
365 $.each( this.classesElementLookup, function( key, value ) { |
|
366 that._removeClass( value, key ); |
|
367 } ); |
|
368 |
|
369 // We can probably remove the unbind calls in 2.0 |
|
370 // all event bindings should go through this._on() |
|
371 this.element |
|
372 .off( this.eventNamespace ) |
|
373 .removeData( this.widgetFullName ); |
|
374 this.widget() |
|
375 .off( this.eventNamespace ) |
|
376 .removeAttr( "aria-disabled" ); |
|
377 |
|
378 // Clean up events and states |
|
379 this.bindings.off( this.eventNamespace ); |
|
380 }, |
|
381 |
|
382 _destroy: $.noop, |
|
383 |
|
384 widget: function() { |
|
385 return this.element; |
|
386 }, |
|
387 |
|
388 option: function( key, value ) { |
|
389 var options = key; |
|
390 var parts; |
|
391 var curOption; |
|
392 var i; |
|
393 |
|
394 if ( arguments.length === 0 ) { |
|
395 |
|
396 // Don't return a reference to the internal hash |
|
397 return $.widget.extend( {}, this.options ); |
|
398 } |
|
399 |
|
400 if ( typeof key === "string" ) { |
|
401 |
|
402 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } |
|
403 options = {}; |
|
404 parts = key.split( "." ); |
|
405 key = parts.shift(); |
|
406 if ( parts.length ) { |
|
407 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); |
|
408 for ( i = 0; i < parts.length - 1; i++ ) { |
|
409 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; |
|
410 curOption = curOption[ parts[ i ] ]; |
|
411 } |
|
412 key = parts.pop(); |
|
413 if ( arguments.length === 1 ) { |
|
414 return curOption[ key ] === undefined ? null : curOption[ key ]; |
|
415 } |
|
416 curOption[ key ] = value; |
|
417 } else { |
|
418 if ( arguments.length === 1 ) { |
|
419 return this.options[ key ] === undefined ? null : this.options[ key ]; |
|
420 } |
|
421 options[ key ] = value; |
|
422 } |
|
423 } |
|
424 |
|
425 this._setOptions( options ); |
|
426 |
|
427 return this; |
|
428 }, |
|
429 |
|
430 _setOptions: function( options ) { |
|
431 var key; |
|
432 |
|
433 for ( key in options ) { |
|
434 this._setOption( key, options[ key ] ); |
|
435 } |
|
436 |
|
437 return this; |
|
438 }, |
|
439 |
|
440 _setOption: function( key, value ) { |
|
441 if ( key === "classes" ) { |
|
442 this._setOptionClasses( value ); |
|
443 } |
|
444 |
|
445 this.options[ key ] = value; |
|
446 |
|
447 if ( key === "disabled" ) { |
|
448 this._setOptionDisabled( value ); |
|
449 } |
|
450 |
|
451 return this; |
|
452 }, |
|
453 |
|
454 _setOptionClasses: function( value ) { |
|
455 var classKey, elements, currentElements; |
|
456 |
|
457 for ( classKey in value ) { |
|
458 currentElements = this.classesElementLookup[ classKey ]; |
|
459 if ( value[ classKey ] === this.options.classes[ classKey ] || |
|
460 !currentElements || |
|
461 !currentElements.length ) { |
|
462 continue; |
|
463 } |
|
464 |
|
465 // We are doing this to create a new jQuery object because the _removeClass() call |
|
466 // on the next line is going to destroy the reference to the current elements being |
|
467 // tracked. We need to save a copy of this collection so that we can add the new classes |
|
468 // below. |
|
469 elements = $( currentElements.get() ); |
|
470 this._removeClass( currentElements, classKey ); |
|
471 |
|
472 // We don't use _addClass() here, because that uses this.options.classes |
|
473 // for generating the string of classes. We want to use the value passed in from |
|
474 // _setOption(), this is the new value of the classes option which was passed to |
|
475 // _setOption(). We pass this value directly to _classes(). |
|
476 elements.addClass( this._classes( { |
|
477 element: elements, |
|
478 keys: classKey, |
|
479 classes: value, |
|
480 add: true |
|
481 } ) ); |
|
482 } |
|
483 }, |
|
484 |
|
485 _setOptionDisabled: function( value ) { |
|
486 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); |
|
487 |
|
488 // If the widget is becoming disabled, then nothing is interactive |
|
489 if ( value ) { |
|
490 this._removeClass( this.hoverable, null, "ui-state-hover" ); |
|
491 this._removeClass( this.focusable, null, "ui-state-focus" ); |
|
492 } |
|
493 }, |
|
494 |
|
495 enable: function() { |
|
496 return this._setOptions( { disabled: false } ); |
|
497 }, |
|
498 |
|
499 disable: function() { |
|
500 return this._setOptions( { disabled: true } ); |
|
501 }, |
|
502 |
|
503 _classes: function( options ) { |
|
504 var full = []; |
|
505 var that = this; |
|
506 |
|
507 options = $.extend( { |
|
508 element: this.element, |
|
509 classes: this.options.classes || {} |
|
510 }, options ); |
|
511 |
|
512 function bindRemoveEvent() { |
|
513 var nodesToBind = []; |
|
514 |
|
515 options.element.each( function( _, element ) { |
|
516 var isTracked = $.map( that.classesElementLookup, function( elements ) { |
|
517 return elements; |
|
518 } ) |
|
519 .some( function( elements ) { |
|
520 return elements.is( element ); |
|
521 } ); |
|
522 |
|
523 if ( !isTracked ) { |
|
524 nodesToBind.push( element ); |
|
525 } |
|
526 } ); |
|
527 |
|
528 that._on( $( nodesToBind ), { |
|
529 remove: "_untrackClassesElement" |
|
530 } ); |
|
531 } |
|
532 |
|
533 function processClassString( classes, checkOption ) { |
|
534 var current, i; |
|
535 for ( i = 0; i < classes.length; i++ ) { |
|
536 current = that.classesElementLookup[ classes[ i ] ] || $(); |
|
537 if ( options.add ) { |
|
538 bindRemoveEvent(); |
|
539 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); |
|
540 } else { |
|
541 current = $( current.not( options.element ).get() ); |
|
542 } |
|
543 that.classesElementLookup[ classes[ i ] ] = current; |
|
544 full.push( classes[ i ] ); |
|
545 if ( checkOption && options.classes[ classes[ i ] ] ) { |
|
546 full.push( options.classes[ classes[ i ] ] ); |
|
547 } |
|
548 } |
|
549 } |
|
550 |
|
551 if ( options.keys ) { |
|
552 processClassString( options.keys.match( /\S+/g ) || [], true ); |
|
553 } |
|
554 if ( options.extra ) { |
|
555 processClassString( options.extra.match( /\S+/g ) || [] ); |
|
556 } |
|
557 |
|
558 return full.join( " " ); |
|
559 }, |
|
560 |
|
561 _untrackClassesElement: function( event ) { |
|
562 var that = this; |
|
563 $.each( that.classesElementLookup, function( key, value ) { |
|
564 if ( $.inArray( event.target, value ) !== -1 ) { |
|
565 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); |
|
566 } |
|
567 } ); |
|
568 |
|
569 this._off( $( event.target ) ); |
|
570 }, |
|
571 |
|
572 _removeClass: function( element, keys, extra ) { |
|
573 return this._toggleClass( element, keys, extra, false ); |
|
574 }, |
|
575 |
|
576 _addClass: function( element, keys, extra ) { |
|
577 return this._toggleClass( element, keys, extra, true ); |
|
578 }, |
|
579 |
|
580 _toggleClass: function( element, keys, extra, add ) { |
|
581 add = ( typeof add === "boolean" ) ? add : extra; |
|
582 var shift = ( typeof element === "string" || element === null ), |
|
583 options = { |
|
584 extra: shift ? keys : extra, |
|
585 keys: shift ? element : keys, |
|
586 element: shift ? this.element : element, |
|
587 add: add |
|
588 }; |
|
589 options.element.toggleClass( this._classes( options ), add ); |
|
590 return this; |
|
591 }, |
|
592 |
|
593 _on: function( suppressDisabledCheck, element, handlers ) { |
|
594 var delegateElement; |
|
595 var instance = this; |
|
596 |
|
597 // No suppressDisabledCheck flag, shuffle arguments |
|
598 if ( typeof suppressDisabledCheck !== "boolean" ) { |
|
599 handlers = element; |
|
600 element = suppressDisabledCheck; |
|
601 suppressDisabledCheck = false; |
|
602 } |
|
603 |
|
604 // No element argument, shuffle and use this.element |
|
605 if ( !handlers ) { |
|
606 handlers = element; |
|
607 element = this.element; |
|
608 delegateElement = this.widget(); |
|
609 } else { |
|
610 element = delegateElement = $( element ); |
|
611 this.bindings = this.bindings.add( element ); |
|
612 } |
|
613 |
|
614 $.each( handlers, function( event, handler ) { |
|
615 function handlerProxy() { |
|
616 |
|
617 // Allow widgets to customize the disabled handling |
|
618 // - disabled as an array instead of boolean |
|
619 // - disabled class as method for disabling individual parts |
|
620 if ( !suppressDisabledCheck && |
|
621 ( instance.options.disabled === true || |
|
622 $( this ).hasClass( "ui-state-disabled" ) ) ) { |
|
623 return; |
|
624 } |
|
625 return ( typeof handler === "string" ? instance[ handler ] : handler ) |
|
626 .apply( instance, arguments ); |
|
627 } |
|
628 |
|
629 // Copy the guid so direct unbinding works |
|
630 if ( typeof handler !== "string" ) { |
|
631 handlerProxy.guid = handler.guid = |
|
632 handler.guid || handlerProxy.guid || $.guid++; |
|
633 } |
|
634 |
|
635 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); |
|
636 var eventName = match[ 1 ] + instance.eventNamespace; |
|
637 var selector = match[ 2 ]; |
|
638 |
|
639 if ( selector ) { |
|
640 delegateElement.on( eventName, selector, handlerProxy ); |
|
641 } else { |
|
642 element.on( eventName, handlerProxy ); |
|
643 } |
|
644 } ); |
|
645 }, |
|
646 |
|
647 _off: function( element, eventName ) { |
|
648 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + |
|
649 this.eventNamespace; |
|
650 element.off( eventName ); |
|
651 |
|
652 // Clear the stack to avoid memory leaks (#10056) |
|
653 this.bindings = $( this.bindings.not( element ).get() ); |
|
654 this.focusable = $( this.focusable.not( element ).get() ); |
|
655 this.hoverable = $( this.hoverable.not( element ).get() ); |
|
656 }, |
|
657 |
|
658 _delay: function( handler, delay ) { |
|
659 function handlerProxy() { |
|
660 return ( typeof handler === "string" ? instance[ handler ] : handler ) |
|
661 .apply( instance, arguments ); |
|
662 } |
|
663 var instance = this; |
|
664 return setTimeout( handlerProxy, delay || 0 ); |
|
665 }, |
|
666 |
|
667 _hoverable: function( element ) { |
|
668 this.hoverable = this.hoverable.add( element ); |
|
669 this._on( element, { |
|
670 mouseenter: function( event ) { |
|
671 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); |
|
672 }, |
|
673 mouseleave: function( event ) { |
|
674 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); |
|
675 } |
|
676 } ); |
|
677 }, |
|
678 |
|
679 _focusable: function( element ) { |
|
680 this.focusable = this.focusable.add( element ); |
|
681 this._on( element, { |
|
682 focusin: function( event ) { |
|
683 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); |
|
684 }, |
|
685 focusout: function( event ) { |
|
686 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); |
|
687 } |
|
688 } ); |
|
689 }, |
|
690 |
|
691 _trigger: function( type, event, data ) { |
|
692 var prop, orig; |
|
693 var callback = this.options[ type ]; |
|
694 |
|
695 data = data || {}; |
|
696 event = $.Event( event ); |
|
697 event.type = ( type === this.widgetEventPrefix ? |
|
698 type : |
|
699 this.widgetEventPrefix + type ).toLowerCase(); |
|
700 |
|
701 // The original event may come from any element |
|
702 // so we need to reset the target on the new event |
|
703 event.target = this.element[ 0 ]; |
|
704 |
|
705 // Copy original event properties over to the new event |
|
706 orig = event.originalEvent; |
|
707 if ( orig ) { |
|
708 for ( prop in orig ) { |
|
709 if ( !( prop in event ) ) { |
|
710 event[ prop ] = orig[ prop ]; |
|
711 } |
|
712 } |
|
713 } |
|
714 |
|
715 this.element.trigger( event, data ); |
|
716 return !( typeof callback === "function" && |
|
717 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || |
|
718 event.isDefaultPrevented() ); |
|
719 } |
|
720 }; |
|
721 |
|
722 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { |
|
723 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { |
|
724 if ( typeof options === "string" ) { |
|
725 options = { effect: options }; |
|
726 } |
|
727 |
|
728 var hasOptions; |
|
729 var effectName = !options ? |
|
730 method : |
|
731 options === true || typeof options === "number" ? |
|
732 defaultEffect : |
|
733 options.effect || defaultEffect; |
|
734 |
|
735 options = options || {}; |
|
736 if ( typeof options === "number" ) { |
|
737 options = { duration: options }; |
|
738 } else if ( options === true ) { |
|
739 options = {}; |
|
740 } |
|
741 |
|
742 hasOptions = !$.isEmptyObject( options ); |
|
743 options.complete = callback; |
|
744 |
|
745 if ( options.delay ) { |
|
746 element.delay( options.delay ); |
|
747 } |
|
748 |
|
749 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { |
|
750 element[ method ]( options ); |
|
751 } else if ( effectName !== method && element[ effectName ] ) { |
|
752 element[ effectName ]( options.duration, options.easing, callback ); |
|
753 } else { |
|
754 element.queue( function( next ) { |
|
755 $( this )[ method ](); |
|
756 if ( callback ) { |
|
757 callback.call( element[ 0 ] ); |
|
758 } |
|
759 next(); |
|
760 } ); |
|
761 } |
|
762 }; |
|
763 } ); |
|
764 |
|
765 var widget = $.widget; |
|
766 |
|
767 |
|
768 /*! |
|
769 * jQuery UI Position 1.13.2 |
|
770 * http://jqueryui.com |
|
771 * |
|
772 * Copyright jQuery Foundation and other contributors |
|
773 * Released under the MIT license. |
6 * http://jquery.org/license |
774 * http://jquery.org/license |
7 * |
775 * |
8 * http://docs.jquery.com/UI |
776 * http://api.jqueryui.com/position/ |
9 */ |
777 */ |
10 (function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.16", |
778 |
11 keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d= |
779 //>>label: Position |
12 this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this, |
780 //>>group: Core |
13 "overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart": |
781 //>>description: Positions elements relative to other elements. |
14 "mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight, |
782 //>>docs: http://api.jqueryui.com/position/ |
15 outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a, |
783 //>>demos: http://jqueryui.com/position/ |
16 "tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&& |
784 |
17 a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&& |
785 |
18 c.ui.isOverAxis(b,e,i)}})}})(jQuery); |
786 ( function() { |
19 ;/*! |
787 var cachedScrollbarWidth, |
20 * jQuery UI Widget 1.8.16 |
788 max = Math.max, |
|
789 abs = Math.abs, |
|
790 rhorizontal = /left|center|right/, |
|
791 rvertical = /top|center|bottom/, |
|
792 roffset = /[\+\-]\d+(\.[\d]+)?%?/, |
|
793 rposition = /^\w+/, |
|
794 rpercent = /%$/, |
|
795 _position = $.fn.position; |
|
796 |
|
797 function getOffsets( offsets, width, height ) { |
|
798 return [ |
|
799 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), |
|
800 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) |
|
801 ]; |
|
802 } |
|
803 |
|
804 function parseCss( element, property ) { |
|
805 return parseInt( $.css( element, property ), 10 ) || 0; |
|
806 } |
|
807 |
|
808 function isWindow( obj ) { |
|
809 return obj != null && obj === obj.window; |
|
810 } |
|
811 |
|
812 function getDimensions( elem ) { |
|
813 var raw = elem[ 0 ]; |
|
814 if ( raw.nodeType === 9 ) { |
|
815 return { |
|
816 width: elem.width(), |
|
817 height: elem.height(), |
|
818 offset: { top: 0, left: 0 } |
|
819 }; |
|
820 } |
|
821 if ( isWindow( raw ) ) { |
|
822 return { |
|
823 width: elem.width(), |
|
824 height: elem.height(), |
|
825 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } |
|
826 }; |
|
827 } |
|
828 if ( raw.preventDefault ) { |
|
829 return { |
|
830 width: 0, |
|
831 height: 0, |
|
832 offset: { top: raw.pageY, left: raw.pageX } |
|
833 }; |
|
834 } |
|
835 return { |
|
836 width: elem.outerWidth(), |
|
837 height: elem.outerHeight(), |
|
838 offset: elem.offset() |
|
839 }; |
|
840 } |
|
841 |
|
842 $.position = { |
|
843 scrollbarWidth: function() { |
|
844 if ( cachedScrollbarWidth !== undefined ) { |
|
845 return cachedScrollbarWidth; |
|
846 } |
|
847 var w1, w2, |
|
848 div = $( "<div style=" + |
|
849 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + |
|
850 "<div style='height:300px;width:auto;'></div></div>" ), |
|
851 innerDiv = div.children()[ 0 ]; |
|
852 |
|
853 $( "body" ).append( div ); |
|
854 w1 = innerDiv.offsetWidth; |
|
855 div.css( "overflow", "scroll" ); |
|
856 |
|
857 w2 = innerDiv.offsetWidth; |
|
858 |
|
859 if ( w1 === w2 ) { |
|
860 w2 = div[ 0 ].clientWidth; |
|
861 } |
|
862 |
|
863 div.remove(); |
|
864 |
|
865 return ( cachedScrollbarWidth = w1 - w2 ); |
|
866 }, |
|
867 getScrollInfo: function( within ) { |
|
868 var overflowX = within.isWindow || within.isDocument ? "" : |
|
869 within.element.css( "overflow-x" ), |
|
870 overflowY = within.isWindow || within.isDocument ? "" : |
|
871 within.element.css( "overflow-y" ), |
|
872 hasOverflowX = overflowX === "scroll" || |
|
873 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), |
|
874 hasOverflowY = overflowY === "scroll" || |
|
875 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); |
|
876 return { |
|
877 width: hasOverflowY ? $.position.scrollbarWidth() : 0, |
|
878 height: hasOverflowX ? $.position.scrollbarWidth() : 0 |
|
879 }; |
|
880 }, |
|
881 getWithinInfo: function( element ) { |
|
882 var withinElement = $( element || window ), |
|
883 isElemWindow = isWindow( withinElement[ 0 ] ), |
|
884 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, |
|
885 hasOffset = !isElemWindow && !isDocument; |
|
886 return { |
|
887 element: withinElement, |
|
888 isWindow: isElemWindow, |
|
889 isDocument: isDocument, |
|
890 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, |
|
891 scrollLeft: withinElement.scrollLeft(), |
|
892 scrollTop: withinElement.scrollTop(), |
|
893 width: withinElement.outerWidth(), |
|
894 height: withinElement.outerHeight() |
|
895 }; |
|
896 } |
|
897 }; |
|
898 |
|
899 $.fn.position = function( options ) { |
|
900 if ( !options || !options.of ) { |
|
901 return _position.apply( this, arguments ); |
|
902 } |
|
903 |
|
904 // Make a copy, we don't want to modify arguments |
|
905 options = $.extend( {}, options ); |
|
906 |
|
907 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, |
|
908 |
|
909 // Make sure string options are treated as CSS selectors |
|
910 target = typeof options.of === "string" ? |
|
911 $( document ).find( options.of ) : |
|
912 $( options.of ), |
|
913 |
|
914 within = $.position.getWithinInfo( options.within ), |
|
915 scrollInfo = $.position.getScrollInfo( within ), |
|
916 collision = ( options.collision || "flip" ).split( " " ), |
|
917 offsets = {}; |
|
918 |
|
919 dimensions = getDimensions( target ); |
|
920 if ( target[ 0 ].preventDefault ) { |
|
921 |
|
922 // Force left top to allow flipping |
|
923 options.at = "left top"; |
|
924 } |
|
925 targetWidth = dimensions.width; |
|
926 targetHeight = dimensions.height; |
|
927 targetOffset = dimensions.offset; |
|
928 |
|
929 // Clone to reuse original targetOffset later |
|
930 basePosition = $.extend( {}, targetOffset ); |
|
931 |
|
932 // Force my and at to have valid horizontal and vertical positions |
|
933 // if a value is missing or invalid, it will be converted to center |
|
934 $.each( [ "my", "at" ], function() { |
|
935 var pos = ( options[ this ] || "" ).split( " " ), |
|
936 horizontalOffset, |
|
937 verticalOffset; |
|
938 |
|
939 if ( pos.length === 1 ) { |
|
940 pos = rhorizontal.test( pos[ 0 ] ) ? |
|
941 pos.concat( [ "center" ] ) : |
|
942 rvertical.test( pos[ 0 ] ) ? |
|
943 [ "center" ].concat( pos ) : |
|
944 [ "center", "center" ]; |
|
945 } |
|
946 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; |
|
947 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; |
|
948 |
|
949 // Calculate offsets |
|
950 horizontalOffset = roffset.exec( pos[ 0 ] ); |
|
951 verticalOffset = roffset.exec( pos[ 1 ] ); |
|
952 offsets[ this ] = [ |
|
953 horizontalOffset ? horizontalOffset[ 0 ] : 0, |
|
954 verticalOffset ? verticalOffset[ 0 ] : 0 |
|
955 ]; |
|
956 |
|
957 // Reduce to just the positions without the offsets |
|
958 options[ this ] = [ |
|
959 rposition.exec( pos[ 0 ] )[ 0 ], |
|
960 rposition.exec( pos[ 1 ] )[ 0 ] |
|
961 ]; |
|
962 } ); |
|
963 |
|
964 // Normalize collision option |
|
965 if ( collision.length === 1 ) { |
|
966 collision[ 1 ] = collision[ 0 ]; |
|
967 } |
|
968 |
|
969 if ( options.at[ 0 ] === "right" ) { |
|
970 basePosition.left += targetWidth; |
|
971 } else if ( options.at[ 0 ] === "center" ) { |
|
972 basePosition.left += targetWidth / 2; |
|
973 } |
|
974 |
|
975 if ( options.at[ 1 ] === "bottom" ) { |
|
976 basePosition.top += targetHeight; |
|
977 } else if ( options.at[ 1 ] === "center" ) { |
|
978 basePosition.top += targetHeight / 2; |
|
979 } |
|
980 |
|
981 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); |
|
982 basePosition.left += atOffset[ 0 ]; |
|
983 basePosition.top += atOffset[ 1 ]; |
|
984 |
|
985 return this.each( function() { |
|
986 var collisionPosition, using, |
|
987 elem = $( this ), |
|
988 elemWidth = elem.outerWidth(), |
|
989 elemHeight = elem.outerHeight(), |
|
990 marginLeft = parseCss( this, "marginLeft" ), |
|
991 marginTop = parseCss( this, "marginTop" ), |
|
992 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + |
|
993 scrollInfo.width, |
|
994 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + |
|
995 scrollInfo.height, |
|
996 position = $.extend( {}, basePosition ), |
|
997 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); |
|
998 |
|
999 if ( options.my[ 0 ] === "right" ) { |
|
1000 position.left -= elemWidth; |
|
1001 } else if ( options.my[ 0 ] === "center" ) { |
|
1002 position.left -= elemWidth / 2; |
|
1003 } |
|
1004 |
|
1005 if ( options.my[ 1 ] === "bottom" ) { |
|
1006 position.top -= elemHeight; |
|
1007 } else if ( options.my[ 1 ] === "center" ) { |
|
1008 position.top -= elemHeight / 2; |
|
1009 } |
|
1010 |
|
1011 position.left += myOffset[ 0 ]; |
|
1012 position.top += myOffset[ 1 ]; |
|
1013 |
|
1014 collisionPosition = { |
|
1015 marginLeft: marginLeft, |
|
1016 marginTop: marginTop |
|
1017 }; |
|
1018 |
|
1019 $.each( [ "left", "top" ], function( i, dir ) { |
|
1020 if ( $.ui.position[ collision[ i ] ] ) { |
|
1021 $.ui.position[ collision[ i ] ][ dir ]( position, { |
|
1022 targetWidth: targetWidth, |
|
1023 targetHeight: targetHeight, |
|
1024 elemWidth: elemWidth, |
|
1025 elemHeight: elemHeight, |
|
1026 collisionPosition: collisionPosition, |
|
1027 collisionWidth: collisionWidth, |
|
1028 collisionHeight: collisionHeight, |
|
1029 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], |
|
1030 my: options.my, |
|
1031 at: options.at, |
|
1032 within: within, |
|
1033 elem: elem |
|
1034 } ); |
|
1035 } |
|
1036 } ); |
|
1037 |
|
1038 if ( options.using ) { |
|
1039 |
|
1040 // Adds feedback as second argument to using callback, if present |
|
1041 using = function( props ) { |
|
1042 var left = targetOffset.left - position.left, |
|
1043 right = left + targetWidth - elemWidth, |
|
1044 top = targetOffset.top - position.top, |
|
1045 bottom = top + targetHeight - elemHeight, |
|
1046 feedback = { |
|
1047 target: { |
|
1048 element: target, |
|
1049 left: targetOffset.left, |
|
1050 top: targetOffset.top, |
|
1051 width: targetWidth, |
|
1052 height: targetHeight |
|
1053 }, |
|
1054 element: { |
|
1055 element: elem, |
|
1056 left: position.left, |
|
1057 top: position.top, |
|
1058 width: elemWidth, |
|
1059 height: elemHeight |
|
1060 }, |
|
1061 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", |
|
1062 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" |
|
1063 }; |
|
1064 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { |
|
1065 feedback.horizontal = "center"; |
|
1066 } |
|
1067 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { |
|
1068 feedback.vertical = "middle"; |
|
1069 } |
|
1070 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { |
|
1071 feedback.important = "horizontal"; |
|
1072 } else { |
|
1073 feedback.important = "vertical"; |
|
1074 } |
|
1075 options.using.call( this, props, feedback ); |
|
1076 }; |
|
1077 } |
|
1078 |
|
1079 elem.offset( $.extend( position, { using: using } ) ); |
|
1080 } ); |
|
1081 }; |
|
1082 |
|
1083 $.ui.position = { |
|
1084 fit: { |
|
1085 left: function( position, data ) { |
|
1086 var within = data.within, |
|
1087 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, |
|
1088 outerWidth = within.width, |
|
1089 collisionPosLeft = position.left - data.collisionPosition.marginLeft, |
|
1090 overLeft = withinOffset - collisionPosLeft, |
|
1091 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, |
|
1092 newOverRight; |
|
1093 |
|
1094 // Element is wider than within |
|
1095 if ( data.collisionWidth > outerWidth ) { |
|
1096 |
|
1097 // Element is initially over the left side of within |
|
1098 if ( overLeft > 0 && overRight <= 0 ) { |
|
1099 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - |
|
1100 withinOffset; |
|
1101 position.left += overLeft - newOverRight; |
|
1102 |
|
1103 // Element is initially over right side of within |
|
1104 } else if ( overRight > 0 && overLeft <= 0 ) { |
|
1105 position.left = withinOffset; |
|
1106 |
|
1107 // Element is initially over both left and right sides of within |
|
1108 } else { |
|
1109 if ( overLeft > overRight ) { |
|
1110 position.left = withinOffset + outerWidth - data.collisionWidth; |
|
1111 } else { |
|
1112 position.left = withinOffset; |
|
1113 } |
|
1114 } |
|
1115 |
|
1116 // Too far left -> align with left edge |
|
1117 } else if ( overLeft > 0 ) { |
|
1118 position.left += overLeft; |
|
1119 |
|
1120 // Too far right -> align with right edge |
|
1121 } else if ( overRight > 0 ) { |
|
1122 position.left -= overRight; |
|
1123 |
|
1124 // Adjust based on position and margin |
|
1125 } else { |
|
1126 position.left = max( position.left - collisionPosLeft, position.left ); |
|
1127 } |
|
1128 }, |
|
1129 top: function( position, data ) { |
|
1130 var within = data.within, |
|
1131 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, |
|
1132 outerHeight = data.within.height, |
|
1133 collisionPosTop = position.top - data.collisionPosition.marginTop, |
|
1134 overTop = withinOffset - collisionPosTop, |
|
1135 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, |
|
1136 newOverBottom; |
|
1137 |
|
1138 // Element is taller than within |
|
1139 if ( data.collisionHeight > outerHeight ) { |
|
1140 |
|
1141 // Element is initially over the top of within |
|
1142 if ( overTop > 0 && overBottom <= 0 ) { |
|
1143 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - |
|
1144 withinOffset; |
|
1145 position.top += overTop - newOverBottom; |
|
1146 |
|
1147 // Element is initially over bottom of within |
|
1148 } else if ( overBottom > 0 && overTop <= 0 ) { |
|
1149 position.top = withinOffset; |
|
1150 |
|
1151 // Element is initially over both top and bottom of within |
|
1152 } else { |
|
1153 if ( overTop > overBottom ) { |
|
1154 position.top = withinOffset + outerHeight - data.collisionHeight; |
|
1155 } else { |
|
1156 position.top = withinOffset; |
|
1157 } |
|
1158 } |
|
1159 |
|
1160 // Too far up -> align with top |
|
1161 } else if ( overTop > 0 ) { |
|
1162 position.top += overTop; |
|
1163 |
|
1164 // Too far down -> align with bottom edge |
|
1165 } else if ( overBottom > 0 ) { |
|
1166 position.top -= overBottom; |
|
1167 |
|
1168 // Adjust based on position and margin |
|
1169 } else { |
|
1170 position.top = max( position.top - collisionPosTop, position.top ); |
|
1171 } |
|
1172 } |
|
1173 }, |
|
1174 flip: { |
|
1175 left: function( position, data ) { |
|
1176 var within = data.within, |
|
1177 withinOffset = within.offset.left + within.scrollLeft, |
|
1178 outerWidth = within.width, |
|
1179 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, |
|
1180 collisionPosLeft = position.left - data.collisionPosition.marginLeft, |
|
1181 overLeft = collisionPosLeft - offsetLeft, |
|
1182 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, |
|
1183 myOffset = data.my[ 0 ] === "left" ? |
|
1184 -data.elemWidth : |
|
1185 data.my[ 0 ] === "right" ? |
|
1186 data.elemWidth : |
|
1187 0, |
|
1188 atOffset = data.at[ 0 ] === "left" ? |
|
1189 data.targetWidth : |
|
1190 data.at[ 0 ] === "right" ? |
|
1191 -data.targetWidth : |
|
1192 0, |
|
1193 offset = -2 * data.offset[ 0 ], |
|
1194 newOverRight, |
|
1195 newOverLeft; |
|
1196 |
|
1197 if ( overLeft < 0 ) { |
|
1198 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - |
|
1199 outerWidth - withinOffset; |
|
1200 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { |
|
1201 position.left += myOffset + atOffset + offset; |
|
1202 } |
|
1203 } else if ( overRight > 0 ) { |
|
1204 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + |
|
1205 atOffset + offset - offsetLeft; |
|
1206 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { |
|
1207 position.left += myOffset + atOffset + offset; |
|
1208 } |
|
1209 } |
|
1210 }, |
|
1211 top: function( position, data ) { |
|
1212 var within = data.within, |
|
1213 withinOffset = within.offset.top + within.scrollTop, |
|
1214 outerHeight = within.height, |
|
1215 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, |
|
1216 collisionPosTop = position.top - data.collisionPosition.marginTop, |
|
1217 overTop = collisionPosTop - offsetTop, |
|
1218 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, |
|
1219 top = data.my[ 1 ] === "top", |
|
1220 myOffset = top ? |
|
1221 -data.elemHeight : |
|
1222 data.my[ 1 ] === "bottom" ? |
|
1223 data.elemHeight : |
|
1224 0, |
|
1225 atOffset = data.at[ 1 ] === "top" ? |
|
1226 data.targetHeight : |
|
1227 data.at[ 1 ] === "bottom" ? |
|
1228 -data.targetHeight : |
|
1229 0, |
|
1230 offset = -2 * data.offset[ 1 ], |
|
1231 newOverTop, |
|
1232 newOverBottom; |
|
1233 if ( overTop < 0 ) { |
|
1234 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - |
|
1235 outerHeight - withinOffset; |
|
1236 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { |
|
1237 position.top += myOffset + atOffset + offset; |
|
1238 } |
|
1239 } else if ( overBottom > 0 ) { |
|
1240 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + |
|
1241 offset - offsetTop; |
|
1242 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { |
|
1243 position.top += myOffset + atOffset + offset; |
|
1244 } |
|
1245 } |
|
1246 } |
|
1247 }, |
|
1248 flipfit: { |
|
1249 left: function() { |
|
1250 $.ui.position.flip.left.apply( this, arguments ); |
|
1251 $.ui.position.fit.left.apply( this, arguments ); |
|
1252 }, |
|
1253 top: function() { |
|
1254 $.ui.position.flip.top.apply( this, arguments ); |
|
1255 $.ui.position.fit.top.apply( this, arguments ); |
|
1256 } |
|
1257 } |
|
1258 }; |
|
1259 |
|
1260 } )(); |
|
1261 |
|
1262 var position = $.ui.position; |
|
1263 |
|
1264 |
|
1265 /*! |
|
1266 * jQuery UI :data 1.13.2 |
|
1267 * http://jqueryui.com |
21 * |
1268 * |
22 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) |
1269 * Copyright jQuery Foundation and other contributors |
23 * Dual licensed under the MIT or GPL Version 2 licenses. |
1270 * Released under the MIT license. |
|
1271 * http://jquery.org/license |
|
1272 */ |
|
1273 |
|
1274 //>>label: :data Selector |
|
1275 //>>group: Core |
|
1276 //>>description: Selects elements which have data stored under the specified key. |
|
1277 //>>docs: http://api.jqueryui.com/data-selector/ |
|
1278 |
|
1279 |
|
1280 var data = $.extend( $.expr.pseudos, { |
|
1281 data: $.expr.createPseudo ? |
|
1282 $.expr.createPseudo( function( dataName ) { |
|
1283 return function( elem ) { |
|
1284 return !!$.data( elem, dataName ); |
|
1285 }; |
|
1286 } ) : |
|
1287 |
|
1288 // Support: jQuery <1.8 |
|
1289 function( elem, i, match ) { |
|
1290 return !!$.data( elem, match[ 3 ] ); |
|
1291 } |
|
1292 } ); |
|
1293 |
|
1294 /*! |
|
1295 * jQuery UI Disable Selection 1.13.2 |
|
1296 * http://jqueryui.com |
|
1297 * |
|
1298 * Copyright jQuery Foundation and other contributors |
|
1299 * Released under the MIT license. |
|
1300 * http://jquery.org/license |
|
1301 */ |
|
1302 |
|
1303 //>>label: disableSelection |
|
1304 //>>group: Core |
|
1305 //>>description: Disable selection of text content within the set of matched elements. |
|
1306 //>>docs: http://api.jqueryui.com/disableSelection/ |
|
1307 |
|
1308 // This file is deprecated |
|
1309 |
|
1310 var disableSelection = $.fn.extend( { |
|
1311 disableSelection: ( function() { |
|
1312 var eventType = "onselectstart" in document.createElement( "div" ) ? |
|
1313 "selectstart" : |
|
1314 "mousedown"; |
|
1315 |
|
1316 return function() { |
|
1317 return this.on( eventType + ".ui-disableSelection", function( event ) { |
|
1318 event.preventDefault(); |
|
1319 } ); |
|
1320 }; |
|
1321 } )(), |
|
1322 |
|
1323 enableSelection: function() { |
|
1324 return this.off( ".ui-disableSelection" ); |
|
1325 } |
|
1326 } ); |
|
1327 |
|
1328 |
|
1329 |
|
1330 // Create a local jQuery because jQuery Color relies on it and the |
|
1331 // global may not exist with AMD and a custom build (#10199). |
|
1332 // This module is a noop if used as a regular AMD module. |
|
1333 // eslint-disable-next-line no-unused-vars |
|
1334 var jQuery = $; |
|
1335 |
|
1336 |
|
1337 /*! |
|
1338 * jQuery Color Animations v2.2.0 |
|
1339 * https://github.com/jquery/jquery-color |
|
1340 * |
|
1341 * Copyright OpenJS Foundation and other contributors |
|
1342 * Released under the MIT license. |
24 * http://jquery.org/license |
1343 * http://jquery.org/license |
25 * |
1344 * |
26 * http://docs.jquery.com/UI/Widget |
1345 * Date: Sun May 10 09:02:36 2020 +0200 |
27 */ |
1346 */ |
28 (function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)try{b(d).triggerHandler("remove")}catch(e){}k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(d){}});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]= |
1347 |
29 function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)): |
1348 |
30 d;if(e&&d.charAt(0)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options= |
1349 |
31 b.extend(true,{},this.options,this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+ |
1350 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + |
32 "-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled", |
1351 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", |
33 c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery); |
1352 |
34 ;/*! |
1353 class2type = {}, |
35 * jQuery UI Mouse 1.8.16 |
1354 toString = class2type.toString, |
|
1355 |
|
1356 // plusequals test for += 100 -= 100 |
|
1357 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, |
|
1358 |
|
1359 // a set of RE's that can match strings and generate color tuples. |
|
1360 stringParsers = [ { |
|
1361 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, |
|
1362 parse: function( execResult ) { |
|
1363 return [ |
|
1364 execResult[ 1 ], |
|
1365 execResult[ 2 ], |
|
1366 execResult[ 3 ], |
|
1367 execResult[ 4 ] |
|
1368 ]; |
|
1369 } |
|
1370 }, { |
|
1371 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, |
|
1372 parse: function( execResult ) { |
|
1373 return [ |
|
1374 execResult[ 1 ] * 2.55, |
|
1375 execResult[ 2 ] * 2.55, |
|
1376 execResult[ 3 ] * 2.55, |
|
1377 execResult[ 4 ] |
|
1378 ]; |
|
1379 } |
|
1380 }, { |
|
1381 |
|
1382 // this regex ignores A-F because it's compared against an already lowercased string |
|
1383 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, |
|
1384 parse: function( execResult ) { |
|
1385 return [ |
|
1386 parseInt( execResult[ 1 ], 16 ), |
|
1387 parseInt( execResult[ 2 ], 16 ), |
|
1388 parseInt( execResult[ 3 ], 16 ), |
|
1389 execResult[ 4 ] ? |
|
1390 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : |
|
1391 1 |
|
1392 ]; |
|
1393 } |
|
1394 }, { |
|
1395 |
|
1396 // this regex ignores A-F because it's compared against an already lowercased string |
|
1397 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, |
|
1398 parse: function( execResult ) { |
|
1399 return [ |
|
1400 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), |
|
1401 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), |
|
1402 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), |
|
1403 execResult[ 4 ] ? |
|
1404 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) |
|
1405 .toFixed( 2 ) : |
|
1406 1 |
|
1407 ]; |
|
1408 } |
|
1409 }, { |
|
1410 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, |
|
1411 space: "hsla", |
|
1412 parse: function( execResult ) { |
|
1413 return [ |
|
1414 execResult[ 1 ], |
|
1415 execResult[ 2 ] / 100, |
|
1416 execResult[ 3 ] / 100, |
|
1417 execResult[ 4 ] |
|
1418 ]; |
|
1419 } |
|
1420 } ], |
|
1421 |
|
1422 // jQuery.Color( ) |
|
1423 color = jQuery.Color = function( color, green, blue, alpha ) { |
|
1424 return new jQuery.Color.fn.parse( color, green, blue, alpha ); |
|
1425 }, |
|
1426 spaces = { |
|
1427 rgba: { |
|
1428 props: { |
|
1429 red: { |
|
1430 idx: 0, |
|
1431 type: "byte" |
|
1432 }, |
|
1433 green: { |
|
1434 idx: 1, |
|
1435 type: "byte" |
|
1436 }, |
|
1437 blue: { |
|
1438 idx: 2, |
|
1439 type: "byte" |
|
1440 } |
|
1441 } |
|
1442 }, |
|
1443 |
|
1444 hsla: { |
|
1445 props: { |
|
1446 hue: { |
|
1447 idx: 0, |
|
1448 type: "degrees" |
|
1449 }, |
|
1450 saturation: { |
|
1451 idx: 1, |
|
1452 type: "percent" |
|
1453 }, |
|
1454 lightness: { |
|
1455 idx: 2, |
|
1456 type: "percent" |
|
1457 } |
|
1458 } |
|
1459 } |
|
1460 }, |
|
1461 propTypes = { |
|
1462 "byte": { |
|
1463 floor: true, |
|
1464 max: 255 |
|
1465 }, |
|
1466 "percent": { |
|
1467 max: 1 |
|
1468 }, |
|
1469 "degrees": { |
|
1470 mod: 360, |
|
1471 floor: true |
|
1472 } |
|
1473 }, |
|
1474 support = color.support = {}, |
|
1475 |
|
1476 // element for support tests |
|
1477 supportElem = jQuery( "<p>" )[ 0 ], |
|
1478 |
|
1479 // colors = jQuery.Color.names |
|
1480 colors, |
|
1481 |
|
1482 // local aliases of functions called often |
|
1483 each = jQuery.each; |
|
1484 |
|
1485 // determine rgba support immediately |
|
1486 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; |
|
1487 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; |
|
1488 |
|
1489 // define cache name and alpha properties |
|
1490 // for rgba and hsla spaces |
|
1491 each( spaces, function( spaceName, space ) { |
|
1492 space.cache = "_" + spaceName; |
|
1493 space.props.alpha = { |
|
1494 idx: 3, |
|
1495 type: "percent", |
|
1496 def: 1 |
|
1497 }; |
|
1498 } ); |
|
1499 |
|
1500 // Populate the class2type map |
|
1501 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), |
|
1502 function( _i, name ) { |
|
1503 class2type[ "[object " + name + "]" ] = name.toLowerCase(); |
|
1504 } ); |
|
1505 |
|
1506 function getType( obj ) { |
|
1507 if ( obj == null ) { |
|
1508 return obj + ""; |
|
1509 } |
|
1510 |
|
1511 return typeof obj === "object" ? |
|
1512 class2type[ toString.call( obj ) ] || "object" : |
|
1513 typeof obj; |
|
1514 } |
|
1515 |
|
1516 function clamp( value, prop, allowEmpty ) { |
|
1517 var type = propTypes[ prop.type ] || {}; |
|
1518 |
|
1519 if ( value == null ) { |
|
1520 return ( allowEmpty || !prop.def ) ? null : prop.def; |
|
1521 } |
|
1522 |
|
1523 // ~~ is an short way of doing floor for positive numbers |
|
1524 value = type.floor ? ~~value : parseFloat( value ); |
|
1525 |
|
1526 // IE will pass in empty strings as value for alpha, |
|
1527 // which will hit this case |
|
1528 if ( isNaN( value ) ) { |
|
1529 return prop.def; |
|
1530 } |
|
1531 |
|
1532 if ( type.mod ) { |
|
1533 |
|
1534 // we add mod before modding to make sure that negatives values |
|
1535 // get converted properly: -10 -> 350 |
|
1536 return ( value + type.mod ) % type.mod; |
|
1537 } |
|
1538 |
|
1539 // for now all property types without mod have min and max |
|
1540 return Math.min( type.max, Math.max( 0, value ) ); |
|
1541 } |
|
1542 |
|
1543 function stringParse( string ) { |
|
1544 var inst = color(), |
|
1545 rgba = inst._rgba = []; |
|
1546 |
|
1547 string = string.toLowerCase(); |
|
1548 |
|
1549 each( stringParsers, function( _i, parser ) { |
|
1550 var parsed, |
|
1551 match = parser.re.exec( string ), |
|
1552 values = match && parser.parse( match ), |
|
1553 spaceName = parser.space || "rgba"; |
|
1554 |
|
1555 if ( values ) { |
|
1556 parsed = inst[ spaceName ]( values ); |
|
1557 |
|
1558 // if this was an rgba parse the assignment might happen twice |
|
1559 // oh well.... |
|
1560 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; |
|
1561 rgba = inst._rgba = parsed._rgba; |
|
1562 |
|
1563 // exit each( stringParsers ) here because we matched |
|
1564 return false; |
|
1565 } |
|
1566 } ); |
|
1567 |
|
1568 // Found a stringParser that handled it |
|
1569 if ( rgba.length ) { |
|
1570 |
|
1571 // if this came from a parsed string, force "transparent" when alpha is 0 |
|
1572 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) |
|
1573 if ( rgba.join() === "0,0,0,0" ) { |
|
1574 jQuery.extend( rgba, colors.transparent ); |
|
1575 } |
|
1576 return inst; |
|
1577 } |
|
1578 |
|
1579 // named colors |
|
1580 return colors[ string ]; |
|
1581 } |
|
1582 |
|
1583 color.fn = jQuery.extend( color.prototype, { |
|
1584 parse: function( red, green, blue, alpha ) { |
|
1585 if ( red === undefined ) { |
|
1586 this._rgba = [ null, null, null, null ]; |
|
1587 return this; |
|
1588 } |
|
1589 if ( red.jquery || red.nodeType ) { |
|
1590 red = jQuery( red ).css( green ); |
|
1591 green = undefined; |
|
1592 } |
|
1593 |
|
1594 var inst = this, |
|
1595 type = getType( red ), |
|
1596 rgba = this._rgba = []; |
|
1597 |
|
1598 // more than 1 argument specified - assume ( red, green, blue, alpha ) |
|
1599 if ( green !== undefined ) { |
|
1600 red = [ red, green, blue, alpha ]; |
|
1601 type = "array"; |
|
1602 } |
|
1603 |
|
1604 if ( type === "string" ) { |
|
1605 return this.parse( stringParse( red ) || colors._default ); |
|
1606 } |
|
1607 |
|
1608 if ( type === "array" ) { |
|
1609 each( spaces.rgba.props, function( _key, prop ) { |
|
1610 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); |
|
1611 } ); |
|
1612 return this; |
|
1613 } |
|
1614 |
|
1615 if ( type === "object" ) { |
|
1616 if ( red instanceof color ) { |
|
1617 each( spaces, function( _spaceName, space ) { |
|
1618 if ( red[ space.cache ] ) { |
|
1619 inst[ space.cache ] = red[ space.cache ].slice(); |
|
1620 } |
|
1621 } ); |
|
1622 } else { |
|
1623 each( spaces, function( _spaceName, space ) { |
|
1624 var cache = space.cache; |
|
1625 each( space.props, function( key, prop ) { |
|
1626 |
|
1627 // if the cache doesn't exist, and we know how to convert |
|
1628 if ( !inst[ cache ] && space.to ) { |
|
1629 |
|
1630 // if the value was null, we don't need to copy it |
|
1631 // if the key was alpha, we don't need to copy it either |
|
1632 if ( key === "alpha" || red[ key ] == null ) { |
|
1633 return; |
|
1634 } |
|
1635 inst[ cache ] = space.to( inst._rgba ); |
|
1636 } |
|
1637 |
|
1638 // this is the only case where we allow nulls for ALL properties. |
|
1639 // call clamp with alwaysAllowEmpty |
|
1640 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); |
|
1641 } ); |
|
1642 |
|
1643 // everything defined but alpha? |
|
1644 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { |
|
1645 |
|
1646 // use the default of 1 |
|
1647 if ( inst[ cache ][ 3 ] == null ) { |
|
1648 inst[ cache ][ 3 ] = 1; |
|
1649 } |
|
1650 |
|
1651 if ( space.from ) { |
|
1652 inst._rgba = space.from( inst[ cache ] ); |
|
1653 } |
|
1654 } |
|
1655 } ); |
|
1656 } |
|
1657 return this; |
|
1658 } |
|
1659 }, |
|
1660 is: function( compare ) { |
|
1661 var is = color( compare ), |
|
1662 same = true, |
|
1663 inst = this; |
|
1664 |
|
1665 each( spaces, function( _, space ) { |
|
1666 var localCache, |
|
1667 isCache = is[ space.cache ]; |
|
1668 if ( isCache ) { |
|
1669 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; |
|
1670 each( space.props, function( _, prop ) { |
|
1671 if ( isCache[ prop.idx ] != null ) { |
|
1672 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); |
|
1673 return same; |
|
1674 } |
|
1675 } ); |
|
1676 } |
|
1677 return same; |
|
1678 } ); |
|
1679 return same; |
|
1680 }, |
|
1681 _space: function() { |
|
1682 var used = [], |
|
1683 inst = this; |
|
1684 each( spaces, function( spaceName, space ) { |
|
1685 if ( inst[ space.cache ] ) { |
|
1686 used.push( spaceName ); |
|
1687 } |
|
1688 } ); |
|
1689 return used.pop(); |
|
1690 }, |
|
1691 transition: function( other, distance ) { |
|
1692 var end = color( other ), |
|
1693 spaceName = end._space(), |
|
1694 space = spaces[ spaceName ], |
|
1695 startColor = this.alpha() === 0 ? color( "transparent" ) : this, |
|
1696 start = startColor[ space.cache ] || space.to( startColor._rgba ), |
|
1697 result = start.slice(); |
|
1698 |
|
1699 end = end[ space.cache ]; |
|
1700 each( space.props, function( _key, prop ) { |
|
1701 var index = prop.idx, |
|
1702 startValue = start[ index ], |
|
1703 endValue = end[ index ], |
|
1704 type = propTypes[ prop.type ] || {}; |
|
1705 |
|
1706 // if null, don't override start value |
|
1707 if ( endValue === null ) { |
|
1708 return; |
|
1709 } |
|
1710 |
|
1711 // if null - use end |
|
1712 if ( startValue === null ) { |
|
1713 result[ index ] = endValue; |
|
1714 } else { |
|
1715 if ( type.mod ) { |
|
1716 if ( endValue - startValue > type.mod / 2 ) { |
|
1717 startValue += type.mod; |
|
1718 } else if ( startValue - endValue > type.mod / 2 ) { |
|
1719 startValue -= type.mod; |
|
1720 } |
|
1721 } |
|
1722 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); |
|
1723 } |
|
1724 } ); |
|
1725 return this[ spaceName ]( result ); |
|
1726 }, |
|
1727 blend: function( opaque ) { |
|
1728 |
|
1729 // if we are already opaque - return ourself |
|
1730 if ( this._rgba[ 3 ] === 1 ) { |
|
1731 return this; |
|
1732 } |
|
1733 |
|
1734 var rgb = this._rgba.slice(), |
|
1735 a = rgb.pop(), |
|
1736 blend = color( opaque )._rgba; |
|
1737 |
|
1738 return color( jQuery.map( rgb, function( v, i ) { |
|
1739 return ( 1 - a ) * blend[ i ] + a * v; |
|
1740 } ) ); |
|
1741 }, |
|
1742 toRgbaString: function() { |
|
1743 var prefix = "rgba(", |
|
1744 rgba = jQuery.map( this._rgba, function( v, i ) { |
|
1745 if ( v != null ) { |
|
1746 return v; |
|
1747 } |
|
1748 return i > 2 ? 1 : 0; |
|
1749 } ); |
|
1750 |
|
1751 if ( rgba[ 3 ] === 1 ) { |
|
1752 rgba.pop(); |
|
1753 prefix = "rgb("; |
|
1754 } |
|
1755 |
|
1756 return prefix + rgba.join() + ")"; |
|
1757 }, |
|
1758 toHslaString: function() { |
|
1759 var prefix = "hsla(", |
|
1760 hsla = jQuery.map( this.hsla(), function( v, i ) { |
|
1761 if ( v == null ) { |
|
1762 v = i > 2 ? 1 : 0; |
|
1763 } |
|
1764 |
|
1765 // catch 1 and 2 |
|
1766 if ( i && i < 3 ) { |
|
1767 v = Math.round( v * 100 ) + "%"; |
|
1768 } |
|
1769 return v; |
|
1770 } ); |
|
1771 |
|
1772 if ( hsla[ 3 ] === 1 ) { |
|
1773 hsla.pop(); |
|
1774 prefix = "hsl("; |
|
1775 } |
|
1776 return prefix + hsla.join() + ")"; |
|
1777 }, |
|
1778 toHexString: function( includeAlpha ) { |
|
1779 var rgba = this._rgba.slice(), |
|
1780 alpha = rgba.pop(); |
|
1781 |
|
1782 if ( includeAlpha ) { |
|
1783 rgba.push( ~~( alpha * 255 ) ); |
|
1784 } |
|
1785 |
|
1786 return "#" + jQuery.map( rgba, function( v ) { |
|
1787 |
|
1788 // default to 0 when nulls exist |
|
1789 v = ( v || 0 ).toString( 16 ); |
|
1790 return v.length === 1 ? "0" + v : v; |
|
1791 } ).join( "" ); |
|
1792 }, |
|
1793 toString: function() { |
|
1794 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); |
|
1795 } |
|
1796 } ); |
|
1797 color.fn.parse.prototype = color.fn; |
|
1798 |
|
1799 // hsla conversions adapted from: |
|
1800 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 |
|
1801 |
|
1802 function hue2rgb( p, q, h ) { |
|
1803 h = ( h + 1 ) % 1; |
|
1804 if ( h * 6 < 1 ) { |
|
1805 return p + ( q - p ) * h * 6; |
|
1806 } |
|
1807 if ( h * 2 < 1 ) { |
|
1808 return q; |
|
1809 } |
|
1810 if ( h * 3 < 2 ) { |
|
1811 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; |
|
1812 } |
|
1813 return p; |
|
1814 } |
|
1815 |
|
1816 spaces.hsla.to = function( rgba ) { |
|
1817 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { |
|
1818 return [ null, null, null, rgba[ 3 ] ]; |
|
1819 } |
|
1820 var r = rgba[ 0 ] / 255, |
|
1821 g = rgba[ 1 ] / 255, |
|
1822 b = rgba[ 2 ] / 255, |
|
1823 a = rgba[ 3 ], |
|
1824 max = Math.max( r, g, b ), |
|
1825 min = Math.min( r, g, b ), |
|
1826 diff = max - min, |
|
1827 add = max + min, |
|
1828 l = add * 0.5, |
|
1829 h, s; |
|
1830 |
|
1831 if ( min === max ) { |
|
1832 h = 0; |
|
1833 } else if ( r === max ) { |
|
1834 h = ( 60 * ( g - b ) / diff ) + 360; |
|
1835 } else if ( g === max ) { |
|
1836 h = ( 60 * ( b - r ) / diff ) + 120; |
|
1837 } else { |
|
1838 h = ( 60 * ( r - g ) / diff ) + 240; |
|
1839 } |
|
1840 |
|
1841 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% |
|
1842 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) |
|
1843 if ( diff === 0 ) { |
|
1844 s = 0; |
|
1845 } else if ( l <= 0.5 ) { |
|
1846 s = diff / add; |
|
1847 } else { |
|
1848 s = diff / ( 2 - add ); |
|
1849 } |
|
1850 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; |
|
1851 }; |
|
1852 |
|
1853 spaces.hsla.from = function( hsla ) { |
|
1854 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { |
|
1855 return [ null, null, null, hsla[ 3 ] ]; |
|
1856 } |
|
1857 var h = hsla[ 0 ] / 360, |
|
1858 s = hsla[ 1 ], |
|
1859 l = hsla[ 2 ], |
|
1860 a = hsla[ 3 ], |
|
1861 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, |
|
1862 p = 2 * l - q; |
|
1863 |
|
1864 return [ |
|
1865 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), |
|
1866 Math.round( hue2rgb( p, q, h ) * 255 ), |
|
1867 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), |
|
1868 a |
|
1869 ]; |
|
1870 }; |
|
1871 |
|
1872 |
|
1873 each( spaces, function( spaceName, space ) { |
|
1874 var props = space.props, |
|
1875 cache = space.cache, |
|
1876 to = space.to, |
|
1877 from = space.from; |
|
1878 |
|
1879 // makes rgba() and hsla() |
|
1880 color.fn[ spaceName ] = function( value ) { |
|
1881 |
|
1882 // generate a cache for this space if it doesn't exist |
|
1883 if ( to && !this[ cache ] ) { |
|
1884 this[ cache ] = to( this._rgba ); |
|
1885 } |
|
1886 if ( value === undefined ) { |
|
1887 return this[ cache ].slice(); |
|
1888 } |
|
1889 |
|
1890 var ret, |
|
1891 type = getType( value ), |
|
1892 arr = ( type === "array" || type === "object" ) ? value : arguments, |
|
1893 local = this[ cache ].slice(); |
|
1894 |
|
1895 each( props, function( key, prop ) { |
|
1896 var val = arr[ type === "object" ? key : prop.idx ]; |
|
1897 if ( val == null ) { |
|
1898 val = local[ prop.idx ]; |
|
1899 } |
|
1900 local[ prop.idx ] = clamp( val, prop ); |
|
1901 } ); |
|
1902 |
|
1903 if ( from ) { |
|
1904 ret = color( from( local ) ); |
|
1905 ret[ cache ] = local; |
|
1906 return ret; |
|
1907 } else { |
|
1908 return color( local ); |
|
1909 } |
|
1910 }; |
|
1911 |
|
1912 // makes red() green() blue() alpha() hue() saturation() lightness() |
|
1913 each( props, function( key, prop ) { |
|
1914 |
|
1915 // alpha is included in more than one space |
|
1916 if ( color.fn[ key ] ) { |
|
1917 return; |
|
1918 } |
|
1919 color.fn[ key ] = function( value ) { |
|
1920 var local, cur, match, fn, |
|
1921 vtype = getType( value ); |
|
1922 |
|
1923 if ( key === "alpha" ) { |
|
1924 fn = this._hsla ? "hsla" : "rgba"; |
|
1925 } else { |
|
1926 fn = spaceName; |
|
1927 } |
|
1928 local = this[ fn ](); |
|
1929 cur = local[ prop.idx ]; |
|
1930 |
|
1931 if ( vtype === "undefined" ) { |
|
1932 return cur; |
|
1933 } |
|
1934 |
|
1935 if ( vtype === "function" ) { |
|
1936 value = value.call( this, cur ); |
|
1937 vtype = getType( value ); |
|
1938 } |
|
1939 if ( value == null && prop.empty ) { |
|
1940 return this; |
|
1941 } |
|
1942 if ( vtype === "string" ) { |
|
1943 match = rplusequals.exec( value ); |
|
1944 if ( match ) { |
|
1945 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); |
|
1946 } |
|
1947 } |
|
1948 local[ prop.idx ] = value; |
|
1949 return this[ fn ]( local ); |
|
1950 }; |
|
1951 } ); |
|
1952 } ); |
|
1953 |
|
1954 // add cssHook and .fx.step function for each named hook. |
|
1955 // accept a space separated string of properties |
|
1956 color.hook = function( hook ) { |
|
1957 var hooks = hook.split( " " ); |
|
1958 each( hooks, function( _i, hook ) { |
|
1959 jQuery.cssHooks[ hook ] = { |
|
1960 set: function( elem, value ) { |
|
1961 var parsed, curElem, |
|
1962 backgroundColor = ""; |
|
1963 |
|
1964 if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { |
|
1965 value = color( parsed || value ); |
|
1966 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { |
|
1967 curElem = hook === "backgroundColor" ? elem.parentNode : elem; |
|
1968 while ( |
|
1969 ( backgroundColor === "" || backgroundColor === "transparent" ) && |
|
1970 curElem && curElem.style |
|
1971 ) { |
|
1972 try { |
|
1973 backgroundColor = jQuery.css( curElem, "backgroundColor" ); |
|
1974 curElem = curElem.parentNode; |
|
1975 } catch ( e ) { |
|
1976 } |
|
1977 } |
|
1978 |
|
1979 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? |
|
1980 backgroundColor : |
|
1981 "_default" ); |
|
1982 } |
|
1983 |
|
1984 value = value.toRgbaString(); |
|
1985 } |
|
1986 try { |
|
1987 elem.style[ hook ] = value; |
|
1988 } catch ( e ) { |
|
1989 |
|
1990 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' |
|
1991 } |
|
1992 } |
|
1993 }; |
|
1994 jQuery.fx.step[ hook ] = function( fx ) { |
|
1995 if ( !fx.colorInit ) { |
|
1996 fx.start = color( fx.elem, hook ); |
|
1997 fx.end = color( fx.end ); |
|
1998 fx.colorInit = true; |
|
1999 } |
|
2000 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); |
|
2001 }; |
|
2002 } ); |
|
2003 |
|
2004 }; |
|
2005 |
|
2006 color.hook( stepHooks ); |
|
2007 |
|
2008 jQuery.cssHooks.borderColor = { |
|
2009 expand: function( value ) { |
|
2010 var expanded = {}; |
|
2011 |
|
2012 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { |
|
2013 expanded[ "border" + part + "Color" ] = value; |
|
2014 } ); |
|
2015 return expanded; |
|
2016 } |
|
2017 }; |
|
2018 |
|
2019 // Basic color names only. |
|
2020 // Usage of any of the other color names requires adding yourself or including |
|
2021 // jquery.color.svg-names.js. |
|
2022 colors = jQuery.Color.names = { |
|
2023 |
|
2024 // 4.1. Basic color keywords |
|
2025 aqua: "#00ffff", |
|
2026 black: "#000000", |
|
2027 blue: "#0000ff", |
|
2028 fuchsia: "#ff00ff", |
|
2029 gray: "#808080", |
|
2030 green: "#008000", |
|
2031 lime: "#00ff00", |
|
2032 maroon: "#800000", |
|
2033 navy: "#000080", |
|
2034 olive: "#808000", |
|
2035 purple: "#800080", |
|
2036 red: "#ff0000", |
|
2037 silver: "#c0c0c0", |
|
2038 teal: "#008080", |
|
2039 white: "#ffffff", |
|
2040 yellow: "#ffff00", |
|
2041 |
|
2042 // 4.2.3. "transparent" color keyword |
|
2043 transparent: [ null, null, null, 0 ], |
|
2044 |
|
2045 _default: "#ffffff" |
|
2046 }; |
|
2047 |
|
2048 |
|
2049 /*! |
|
2050 * jQuery UI Effects 1.13.2 |
|
2051 * http://jqueryui.com |
36 * |
2052 * |
37 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) |
2053 * Copyright jQuery Foundation and other contributors |
38 * Dual licensed under the MIT or GPL Version 2 licenses. |
2054 * Released under the MIT license. |
|
2055 * http://jquery.org/license |
|
2056 */ |
|
2057 |
|
2058 //>>label: Effects Core |
|
2059 //>>group: Effects |
|
2060 /* eslint-disable max-len */ |
|
2061 //>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. |
|
2062 /* eslint-enable max-len */ |
|
2063 //>>docs: http://api.jqueryui.com/category/effects-core/ |
|
2064 //>>demos: http://jqueryui.com/effect/ |
|
2065 |
|
2066 |
|
2067 var dataSpace = "ui-effects-", |
|
2068 dataSpaceStyle = "ui-effects-style", |
|
2069 dataSpaceAnimated = "ui-effects-animated"; |
|
2070 |
|
2071 $.effects = { |
|
2072 effect: {} |
|
2073 }; |
|
2074 |
|
2075 /******************************************************************************/ |
|
2076 /****************************** CLASS ANIMATIONS ******************************/ |
|
2077 /******************************************************************************/ |
|
2078 ( function() { |
|
2079 |
|
2080 var classAnimationActions = [ "add", "remove", "toggle" ], |
|
2081 shorthandStyles = { |
|
2082 border: 1, |
|
2083 borderBottom: 1, |
|
2084 borderColor: 1, |
|
2085 borderLeft: 1, |
|
2086 borderRight: 1, |
|
2087 borderTop: 1, |
|
2088 borderWidth: 1, |
|
2089 margin: 1, |
|
2090 padding: 1 |
|
2091 }; |
|
2092 |
|
2093 $.each( |
|
2094 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], |
|
2095 function( _, prop ) { |
|
2096 $.fx.step[ prop ] = function( fx ) { |
|
2097 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { |
|
2098 jQuery.style( fx.elem, prop, fx.end ); |
|
2099 fx.setAttr = true; |
|
2100 } |
|
2101 }; |
|
2102 } |
|
2103 ); |
|
2104 |
|
2105 function camelCase( string ) { |
|
2106 return string.replace( /-([\da-z])/gi, function( all, letter ) { |
|
2107 return letter.toUpperCase(); |
|
2108 } ); |
|
2109 } |
|
2110 |
|
2111 function getElementStyles( elem ) { |
|
2112 var key, len, |
|
2113 style = elem.ownerDocument.defaultView ? |
|
2114 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : |
|
2115 elem.currentStyle, |
|
2116 styles = {}; |
|
2117 |
|
2118 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { |
|
2119 len = style.length; |
|
2120 while ( len-- ) { |
|
2121 key = style[ len ]; |
|
2122 if ( typeof style[ key ] === "string" ) { |
|
2123 styles[ camelCase( key ) ] = style[ key ]; |
|
2124 } |
|
2125 } |
|
2126 |
|
2127 // Support: Opera, IE <9 |
|
2128 } else { |
|
2129 for ( key in style ) { |
|
2130 if ( typeof style[ key ] === "string" ) { |
|
2131 styles[ key ] = style[ key ]; |
|
2132 } |
|
2133 } |
|
2134 } |
|
2135 |
|
2136 return styles; |
|
2137 } |
|
2138 |
|
2139 function styleDifference( oldStyle, newStyle ) { |
|
2140 var diff = {}, |
|
2141 name, value; |
|
2142 |
|
2143 for ( name in newStyle ) { |
|
2144 value = newStyle[ name ]; |
|
2145 if ( oldStyle[ name ] !== value ) { |
|
2146 if ( !shorthandStyles[ name ] ) { |
|
2147 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { |
|
2148 diff[ name ] = value; |
|
2149 } |
|
2150 } |
|
2151 } |
|
2152 } |
|
2153 |
|
2154 return diff; |
|
2155 } |
|
2156 |
|
2157 // Support: jQuery <1.8 |
|
2158 if ( !$.fn.addBack ) { |
|
2159 $.fn.addBack = function( selector ) { |
|
2160 return this.add( selector == null ? |
|
2161 this.prevObject : this.prevObject.filter( selector ) |
|
2162 ); |
|
2163 }; |
|
2164 } |
|
2165 |
|
2166 $.effects.animateClass = function( value, duration, easing, callback ) { |
|
2167 var o = $.speed( duration, easing, callback ); |
|
2168 |
|
2169 return this.queue( function() { |
|
2170 var animated = $( this ), |
|
2171 baseClass = animated.attr( "class" ) || "", |
|
2172 applyClassChange, |
|
2173 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; |
|
2174 |
|
2175 // Map the animated objects to store the original styles. |
|
2176 allAnimations = allAnimations.map( function() { |
|
2177 var el = $( this ); |
|
2178 return { |
|
2179 el: el, |
|
2180 start: getElementStyles( this ) |
|
2181 }; |
|
2182 } ); |
|
2183 |
|
2184 // Apply class change |
|
2185 applyClassChange = function() { |
|
2186 $.each( classAnimationActions, function( i, action ) { |
|
2187 if ( value[ action ] ) { |
|
2188 animated[ action + "Class" ]( value[ action ] ); |
|
2189 } |
|
2190 } ); |
|
2191 }; |
|
2192 applyClassChange(); |
|
2193 |
|
2194 // Map all animated objects again - calculate new styles and diff |
|
2195 allAnimations = allAnimations.map( function() { |
|
2196 this.end = getElementStyles( this.el[ 0 ] ); |
|
2197 this.diff = styleDifference( this.start, this.end ); |
|
2198 return this; |
|
2199 } ); |
|
2200 |
|
2201 // Apply original class |
|
2202 animated.attr( "class", baseClass ); |
|
2203 |
|
2204 // Map all animated objects again - this time collecting a promise |
|
2205 allAnimations = allAnimations.map( function() { |
|
2206 var styleInfo = this, |
|
2207 dfd = $.Deferred(), |
|
2208 opts = $.extend( {}, o, { |
|
2209 queue: false, |
|
2210 complete: function() { |
|
2211 dfd.resolve( styleInfo ); |
|
2212 } |
|
2213 } ); |
|
2214 |
|
2215 this.el.animate( this.diff, opts ); |
|
2216 return dfd.promise(); |
|
2217 } ); |
|
2218 |
|
2219 // Once all animations have completed: |
|
2220 $.when.apply( $, allAnimations.get() ).done( function() { |
|
2221 |
|
2222 // Set the final class |
|
2223 applyClassChange(); |
|
2224 |
|
2225 // For each animated element, |
|
2226 // clear all css properties that were animated |
|
2227 $.each( arguments, function() { |
|
2228 var el = this.el; |
|
2229 $.each( this.diff, function( key ) { |
|
2230 el.css( key, "" ); |
|
2231 } ); |
|
2232 } ); |
|
2233 |
|
2234 // This is guarnteed to be there if you use jQuery.speed() |
|
2235 // it also handles dequeuing the next anim... |
|
2236 o.complete.call( animated[ 0 ] ); |
|
2237 } ); |
|
2238 } ); |
|
2239 }; |
|
2240 |
|
2241 $.fn.extend( { |
|
2242 addClass: ( function( orig ) { |
|
2243 return function( classNames, speed, easing, callback ) { |
|
2244 return speed ? |
|
2245 $.effects.animateClass.call( this, |
|
2246 { add: classNames }, speed, easing, callback ) : |
|
2247 orig.apply( this, arguments ); |
|
2248 }; |
|
2249 } )( $.fn.addClass ), |
|
2250 |
|
2251 removeClass: ( function( orig ) { |
|
2252 return function( classNames, speed, easing, callback ) { |
|
2253 return arguments.length > 1 ? |
|
2254 $.effects.animateClass.call( this, |
|
2255 { remove: classNames }, speed, easing, callback ) : |
|
2256 orig.apply( this, arguments ); |
|
2257 }; |
|
2258 } )( $.fn.removeClass ), |
|
2259 |
|
2260 toggleClass: ( function( orig ) { |
|
2261 return function( classNames, force, speed, easing, callback ) { |
|
2262 if ( typeof force === "boolean" || force === undefined ) { |
|
2263 if ( !speed ) { |
|
2264 |
|
2265 // Without speed parameter |
|
2266 return orig.apply( this, arguments ); |
|
2267 } else { |
|
2268 return $.effects.animateClass.call( this, |
|
2269 ( force ? { add: classNames } : { remove: classNames } ), |
|
2270 speed, easing, callback ); |
|
2271 } |
|
2272 } else { |
|
2273 |
|
2274 // Without force parameter |
|
2275 return $.effects.animateClass.call( this, |
|
2276 { toggle: classNames }, force, speed, easing ); |
|
2277 } |
|
2278 }; |
|
2279 } )( $.fn.toggleClass ), |
|
2280 |
|
2281 switchClass: function( remove, add, speed, easing, callback ) { |
|
2282 return $.effects.animateClass.call( this, { |
|
2283 add: add, |
|
2284 remove: remove |
|
2285 }, speed, easing, callback ); |
|
2286 } |
|
2287 } ); |
|
2288 |
|
2289 } )(); |
|
2290 |
|
2291 /******************************************************************************/ |
|
2292 /*********************************** EFFECTS **********************************/ |
|
2293 /******************************************************************************/ |
|
2294 |
|
2295 ( function() { |
|
2296 |
|
2297 if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { |
|
2298 $.expr.pseudos.animated = ( function( orig ) { |
|
2299 return function( elem ) { |
|
2300 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); |
|
2301 }; |
|
2302 } )( $.expr.pseudos.animated ); |
|
2303 } |
|
2304 |
|
2305 if ( $.uiBackCompat !== false ) { |
|
2306 $.extend( $.effects, { |
|
2307 |
|
2308 // Saves a set of properties in a data storage |
|
2309 save: function( element, set ) { |
|
2310 var i = 0, length = set.length; |
|
2311 for ( ; i < length; i++ ) { |
|
2312 if ( set[ i ] !== null ) { |
|
2313 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); |
|
2314 } |
|
2315 } |
|
2316 }, |
|
2317 |
|
2318 // Restores a set of previously saved properties from a data storage |
|
2319 restore: function( element, set ) { |
|
2320 var val, i = 0, length = set.length; |
|
2321 for ( ; i < length; i++ ) { |
|
2322 if ( set[ i ] !== null ) { |
|
2323 val = element.data( dataSpace + set[ i ] ); |
|
2324 element.css( set[ i ], val ); |
|
2325 } |
|
2326 } |
|
2327 }, |
|
2328 |
|
2329 setMode: function( el, mode ) { |
|
2330 if ( mode === "toggle" ) { |
|
2331 mode = el.is( ":hidden" ) ? "show" : "hide"; |
|
2332 } |
|
2333 return mode; |
|
2334 }, |
|
2335 |
|
2336 // Wraps the element around a wrapper that copies position properties |
|
2337 createWrapper: function( element ) { |
|
2338 |
|
2339 // If the element is already wrapped, return it |
|
2340 if ( element.parent().is( ".ui-effects-wrapper" ) ) { |
|
2341 return element.parent(); |
|
2342 } |
|
2343 |
|
2344 // Wrap the element |
|
2345 var props = { |
|
2346 width: element.outerWidth( true ), |
|
2347 height: element.outerHeight( true ), |
|
2348 "float": element.css( "float" ) |
|
2349 }, |
|
2350 wrapper = $( "<div></div>" ) |
|
2351 .addClass( "ui-effects-wrapper" ) |
|
2352 .css( { |
|
2353 fontSize: "100%", |
|
2354 background: "transparent", |
|
2355 border: "none", |
|
2356 margin: 0, |
|
2357 padding: 0 |
|
2358 } ), |
|
2359 |
|
2360 // Store the size in case width/height are defined in % - Fixes #5245 |
|
2361 size = { |
|
2362 width: element.width(), |
|
2363 height: element.height() |
|
2364 }, |
|
2365 active = document.activeElement; |
|
2366 |
|
2367 // Support: Firefox |
|
2368 // Firefox incorrectly exposes anonymous content |
|
2369 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 |
|
2370 try { |
|
2371 // eslint-disable-next-line no-unused-expressions |
|
2372 active.id; |
|
2373 } catch ( e ) { |
|
2374 active = document.body; |
|
2375 } |
|
2376 |
|
2377 element.wrap( wrapper ); |
|
2378 |
|
2379 // Fixes #7595 - Elements lose focus when wrapped. |
|
2380 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { |
|
2381 $( active ).trigger( "focus" ); |
|
2382 } |
|
2383 |
|
2384 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually |
|
2385 // lose the reference to the wrapped element |
|
2386 wrapper = element.parent(); |
|
2387 |
|
2388 // Transfer positioning properties to the wrapper |
|
2389 if ( element.css( "position" ) === "static" ) { |
|
2390 wrapper.css( { position: "relative" } ); |
|
2391 element.css( { position: "relative" } ); |
|
2392 } else { |
|
2393 $.extend( props, { |
|
2394 position: element.css( "position" ), |
|
2395 zIndex: element.css( "z-index" ) |
|
2396 } ); |
|
2397 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { |
|
2398 props[ pos ] = element.css( pos ); |
|
2399 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { |
|
2400 props[ pos ] = "auto"; |
|
2401 } |
|
2402 } ); |
|
2403 element.css( { |
|
2404 position: "relative", |
|
2405 top: 0, |
|
2406 left: 0, |
|
2407 right: "auto", |
|
2408 bottom: "auto" |
|
2409 } ); |
|
2410 } |
|
2411 element.css( size ); |
|
2412 |
|
2413 return wrapper.css( props ).show(); |
|
2414 }, |
|
2415 |
|
2416 removeWrapper: function( element ) { |
|
2417 var active = document.activeElement; |
|
2418 |
|
2419 if ( element.parent().is( ".ui-effects-wrapper" ) ) { |
|
2420 element.parent().replaceWith( element ); |
|
2421 |
|
2422 // Fixes #7595 - Elements lose focus when wrapped. |
|
2423 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { |
|
2424 $( active ).trigger( "focus" ); |
|
2425 } |
|
2426 } |
|
2427 |
|
2428 return element; |
|
2429 } |
|
2430 } ); |
|
2431 } |
|
2432 |
|
2433 $.extend( $.effects, { |
|
2434 version: "1.13.2", |
|
2435 |
|
2436 define: function( name, mode, effect ) { |
|
2437 if ( !effect ) { |
|
2438 effect = mode; |
|
2439 mode = "effect"; |
|
2440 } |
|
2441 |
|
2442 $.effects.effect[ name ] = effect; |
|
2443 $.effects.effect[ name ].mode = mode; |
|
2444 |
|
2445 return effect; |
|
2446 }, |
|
2447 |
|
2448 scaledDimensions: function( element, percent, direction ) { |
|
2449 if ( percent === 0 ) { |
|
2450 return { |
|
2451 height: 0, |
|
2452 width: 0, |
|
2453 outerHeight: 0, |
|
2454 outerWidth: 0 |
|
2455 }; |
|
2456 } |
|
2457 |
|
2458 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, |
|
2459 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; |
|
2460 |
|
2461 return { |
|
2462 height: element.height() * y, |
|
2463 width: element.width() * x, |
|
2464 outerHeight: element.outerHeight() * y, |
|
2465 outerWidth: element.outerWidth() * x |
|
2466 }; |
|
2467 |
|
2468 }, |
|
2469 |
|
2470 clipToBox: function( animation ) { |
|
2471 return { |
|
2472 width: animation.clip.right - animation.clip.left, |
|
2473 height: animation.clip.bottom - animation.clip.top, |
|
2474 left: animation.clip.left, |
|
2475 top: animation.clip.top |
|
2476 }; |
|
2477 }, |
|
2478 |
|
2479 // Injects recently queued functions to be first in line (after "inprogress") |
|
2480 unshift: function( element, queueLength, count ) { |
|
2481 var queue = element.queue(); |
|
2482 |
|
2483 if ( queueLength > 1 ) { |
|
2484 queue.splice.apply( queue, |
|
2485 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); |
|
2486 } |
|
2487 element.dequeue(); |
|
2488 }, |
|
2489 |
|
2490 saveStyle: function( element ) { |
|
2491 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); |
|
2492 }, |
|
2493 |
|
2494 restoreStyle: function( element ) { |
|
2495 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; |
|
2496 element.removeData( dataSpaceStyle ); |
|
2497 }, |
|
2498 |
|
2499 mode: function( element, mode ) { |
|
2500 var hidden = element.is( ":hidden" ); |
|
2501 |
|
2502 if ( mode === "toggle" ) { |
|
2503 mode = hidden ? "show" : "hide"; |
|
2504 } |
|
2505 if ( hidden ? mode === "hide" : mode === "show" ) { |
|
2506 mode = "none"; |
|
2507 } |
|
2508 return mode; |
|
2509 }, |
|
2510 |
|
2511 // Translates a [top,left] array into a baseline value |
|
2512 getBaseline: function( origin, original ) { |
|
2513 var y, x; |
|
2514 |
|
2515 switch ( origin[ 0 ] ) { |
|
2516 case "top": |
|
2517 y = 0; |
|
2518 break; |
|
2519 case "middle": |
|
2520 y = 0.5; |
|
2521 break; |
|
2522 case "bottom": |
|
2523 y = 1; |
|
2524 break; |
|
2525 default: |
|
2526 y = origin[ 0 ] / original.height; |
|
2527 } |
|
2528 |
|
2529 switch ( origin[ 1 ] ) { |
|
2530 case "left": |
|
2531 x = 0; |
|
2532 break; |
|
2533 case "center": |
|
2534 x = 0.5; |
|
2535 break; |
|
2536 case "right": |
|
2537 x = 1; |
|
2538 break; |
|
2539 default: |
|
2540 x = origin[ 1 ] / original.width; |
|
2541 } |
|
2542 |
|
2543 return { |
|
2544 x: x, |
|
2545 y: y |
|
2546 }; |
|
2547 }, |
|
2548 |
|
2549 // Creates a placeholder element so that the original element can be made absolute |
|
2550 createPlaceholder: function( element ) { |
|
2551 var placeholder, |
|
2552 cssPosition = element.css( "position" ), |
|
2553 position = element.position(); |
|
2554 |
|
2555 // Lock in margins first to account for form elements, which |
|
2556 // will change margin if you explicitly set height |
|
2557 // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 |
|
2558 // Support: Safari |
|
2559 element.css( { |
|
2560 marginTop: element.css( "marginTop" ), |
|
2561 marginBottom: element.css( "marginBottom" ), |
|
2562 marginLeft: element.css( "marginLeft" ), |
|
2563 marginRight: element.css( "marginRight" ) |
|
2564 } ) |
|
2565 .outerWidth( element.outerWidth() ) |
|
2566 .outerHeight( element.outerHeight() ); |
|
2567 |
|
2568 if ( /^(static|relative)/.test( cssPosition ) ) { |
|
2569 cssPosition = "absolute"; |
|
2570 |
|
2571 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { |
|
2572 |
|
2573 // Convert inline to inline block to account for inline elements |
|
2574 // that turn to inline block based on content (like img) |
|
2575 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? |
|
2576 "inline-block" : |
|
2577 "block", |
|
2578 visibility: "hidden", |
|
2579 |
|
2580 // Margins need to be set to account for margin collapse |
|
2581 marginTop: element.css( "marginTop" ), |
|
2582 marginBottom: element.css( "marginBottom" ), |
|
2583 marginLeft: element.css( "marginLeft" ), |
|
2584 marginRight: element.css( "marginRight" ), |
|
2585 "float": element.css( "float" ) |
|
2586 } ) |
|
2587 .outerWidth( element.outerWidth() ) |
|
2588 .outerHeight( element.outerHeight() ) |
|
2589 .addClass( "ui-effects-placeholder" ); |
|
2590 |
|
2591 element.data( dataSpace + "placeholder", placeholder ); |
|
2592 } |
|
2593 |
|
2594 element.css( { |
|
2595 position: cssPosition, |
|
2596 left: position.left, |
|
2597 top: position.top |
|
2598 } ); |
|
2599 |
|
2600 return placeholder; |
|
2601 }, |
|
2602 |
|
2603 removePlaceholder: function( element ) { |
|
2604 var dataKey = dataSpace + "placeholder", |
|
2605 placeholder = element.data( dataKey ); |
|
2606 |
|
2607 if ( placeholder ) { |
|
2608 placeholder.remove(); |
|
2609 element.removeData( dataKey ); |
|
2610 } |
|
2611 }, |
|
2612 |
|
2613 // Removes a placeholder if it exists and restores |
|
2614 // properties that were modified during placeholder creation |
|
2615 cleanUp: function( element ) { |
|
2616 $.effects.restoreStyle( element ); |
|
2617 $.effects.removePlaceholder( element ); |
|
2618 }, |
|
2619 |
|
2620 setTransition: function( element, list, factor, value ) { |
|
2621 value = value || {}; |
|
2622 $.each( list, function( i, x ) { |
|
2623 var unit = element.cssUnit( x ); |
|
2624 if ( unit[ 0 ] > 0 ) { |
|
2625 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; |
|
2626 } |
|
2627 } ); |
|
2628 return value; |
|
2629 } |
|
2630 } ); |
|
2631 |
|
2632 // Return an effect options object for the given parameters: |
|
2633 function _normalizeArguments( effect, options, speed, callback ) { |
|
2634 |
|
2635 // Allow passing all options as the first parameter |
|
2636 if ( $.isPlainObject( effect ) ) { |
|
2637 options = effect; |
|
2638 effect = effect.effect; |
|
2639 } |
|
2640 |
|
2641 // Convert to an object |
|
2642 effect = { effect: effect }; |
|
2643 |
|
2644 // Catch (effect, null, ...) |
|
2645 if ( options == null ) { |
|
2646 options = {}; |
|
2647 } |
|
2648 |
|
2649 // Catch (effect, callback) |
|
2650 if ( typeof options === "function" ) { |
|
2651 callback = options; |
|
2652 speed = null; |
|
2653 options = {}; |
|
2654 } |
|
2655 |
|
2656 // Catch (effect, speed, ?) |
|
2657 if ( typeof options === "number" || $.fx.speeds[ options ] ) { |
|
2658 callback = speed; |
|
2659 speed = options; |
|
2660 options = {}; |
|
2661 } |
|
2662 |
|
2663 // Catch (effect, options, callback) |
|
2664 if ( typeof speed === "function" ) { |
|
2665 callback = speed; |
|
2666 speed = null; |
|
2667 } |
|
2668 |
|
2669 // Add options to effect |
|
2670 if ( options ) { |
|
2671 $.extend( effect, options ); |
|
2672 } |
|
2673 |
|
2674 speed = speed || options.duration; |
|
2675 effect.duration = $.fx.off ? 0 : |
|
2676 typeof speed === "number" ? speed : |
|
2677 speed in $.fx.speeds ? $.fx.speeds[ speed ] : |
|
2678 $.fx.speeds._default; |
|
2679 |
|
2680 effect.complete = callback || options.complete; |
|
2681 |
|
2682 return effect; |
|
2683 } |
|
2684 |
|
2685 function standardAnimationOption( option ) { |
|
2686 |
|
2687 // Valid standard speeds (nothing, number, named speed) |
|
2688 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { |
|
2689 return true; |
|
2690 } |
|
2691 |
|
2692 // Invalid strings - treat as "normal" speed |
|
2693 if ( typeof option === "string" && !$.effects.effect[ option ] ) { |
|
2694 return true; |
|
2695 } |
|
2696 |
|
2697 // Complete callback |
|
2698 if ( typeof option === "function" ) { |
|
2699 return true; |
|
2700 } |
|
2701 |
|
2702 // Options hash (but not naming an effect) |
|
2703 if ( typeof option === "object" && !option.effect ) { |
|
2704 return true; |
|
2705 } |
|
2706 |
|
2707 // Didn't match any standard API |
|
2708 return false; |
|
2709 } |
|
2710 |
|
2711 $.fn.extend( { |
|
2712 effect: function( /* effect, options, speed, callback */ ) { |
|
2713 var args = _normalizeArguments.apply( this, arguments ), |
|
2714 effectMethod = $.effects.effect[ args.effect ], |
|
2715 defaultMode = effectMethod.mode, |
|
2716 queue = args.queue, |
|
2717 queueName = queue || "fx", |
|
2718 complete = args.complete, |
|
2719 mode = args.mode, |
|
2720 modes = [], |
|
2721 prefilter = function( next ) { |
|
2722 var el = $( this ), |
|
2723 normalizedMode = $.effects.mode( el, mode ) || defaultMode; |
|
2724 |
|
2725 // Sentinel for duck-punching the :animated pseudo-selector |
|
2726 el.data( dataSpaceAnimated, true ); |
|
2727 |
|
2728 // Save effect mode for later use, |
|
2729 // we can't just call $.effects.mode again later, |
|
2730 // as the .show() below destroys the initial state |
|
2731 modes.push( normalizedMode ); |
|
2732 |
|
2733 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 |
|
2734 if ( defaultMode && ( normalizedMode === "show" || |
|
2735 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { |
|
2736 el.show(); |
|
2737 } |
|
2738 |
|
2739 if ( !defaultMode || normalizedMode !== "none" ) { |
|
2740 $.effects.saveStyle( el ); |
|
2741 } |
|
2742 |
|
2743 if ( typeof next === "function" ) { |
|
2744 next(); |
|
2745 } |
|
2746 }; |
|
2747 |
|
2748 if ( $.fx.off || !effectMethod ) { |
|
2749 |
|
2750 // Delegate to the original method (e.g., .show()) if possible |
|
2751 if ( mode ) { |
|
2752 return this[ mode ]( args.duration, complete ); |
|
2753 } else { |
|
2754 return this.each( function() { |
|
2755 if ( complete ) { |
|
2756 complete.call( this ); |
|
2757 } |
|
2758 } ); |
|
2759 } |
|
2760 } |
|
2761 |
|
2762 function run( next ) { |
|
2763 var elem = $( this ); |
|
2764 |
|
2765 function cleanup() { |
|
2766 elem.removeData( dataSpaceAnimated ); |
|
2767 |
|
2768 $.effects.cleanUp( elem ); |
|
2769 |
|
2770 if ( args.mode === "hide" ) { |
|
2771 elem.hide(); |
|
2772 } |
|
2773 |
|
2774 done(); |
|
2775 } |
|
2776 |
|
2777 function done() { |
|
2778 if ( typeof complete === "function" ) { |
|
2779 complete.call( elem[ 0 ] ); |
|
2780 } |
|
2781 |
|
2782 if ( typeof next === "function" ) { |
|
2783 next(); |
|
2784 } |
|
2785 } |
|
2786 |
|
2787 // Override mode option on a per element basis, |
|
2788 // as toggle can be either show or hide depending on element state |
|
2789 args.mode = modes.shift(); |
|
2790 |
|
2791 if ( $.uiBackCompat !== false && !defaultMode ) { |
|
2792 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { |
|
2793 |
|
2794 // Call the core method to track "olddisplay" properly |
|
2795 elem[ mode ](); |
|
2796 done(); |
|
2797 } else { |
|
2798 effectMethod.call( elem[ 0 ], args, done ); |
|
2799 } |
|
2800 } else { |
|
2801 if ( args.mode === "none" ) { |
|
2802 |
|
2803 // Call the core method to track "olddisplay" properly |
|
2804 elem[ mode ](); |
|
2805 done(); |
|
2806 } else { |
|
2807 effectMethod.call( elem[ 0 ], args, cleanup ); |
|
2808 } |
|
2809 } |
|
2810 } |
|
2811 |
|
2812 // Run prefilter on all elements first to ensure that |
|
2813 // any showing or hiding happens before placeholder creation, |
|
2814 // which ensures that any layout changes are correctly captured. |
|
2815 return queue === false ? |
|
2816 this.each( prefilter ).each( run ) : |
|
2817 this.queue( queueName, prefilter ).queue( queueName, run ); |
|
2818 }, |
|
2819 |
|
2820 show: ( function( orig ) { |
|
2821 return function( option ) { |
|
2822 if ( standardAnimationOption( option ) ) { |
|
2823 return orig.apply( this, arguments ); |
|
2824 } else { |
|
2825 var args = _normalizeArguments.apply( this, arguments ); |
|
2826 args.mode = "show"; |
|
2827 return this.effect.call( this, args ); |
|
2828 } |
|
2829 }; |
|
2830 } )( $.fn.show ), |
|
2831 |
|
2832 hide: ( function( orig ) { |
|
2833 return function( option ) { |
|
2834 if ( standardAnimationOption( option ) ) { |
|
2835 return orig.apply( this, arguments ); |
|
2836 } else { |
|
2837 var args = _normalizeArguments.apply( this, arguments ); |
|
2838 args.mode = "hide"; |
|
2839 return this.effect.call( this, args ); |
|
2840 } |
|
2841 }; |
|
2842 } )( $.fn.hide ), |
|
2843 |
|
2844 toggle: ( function( orig ) { |
|
2845 return function( option ) { |
|
2846 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { |
|
2847 return orig.apply( this, arguments ); |
|
2848 } else { |
|
2849 var args = _normalizeArguments.apply( this, arguments ); |
|
2850 args.mode = "toggle"; |
|
2851 return this.effect.call( this, args ); |
|
2852 } |
|
2853 }; |
|
2854 } )( $.fn.toggle ), |
|
2855 |
|
2856 cssUnit: function( key ) { |
|
2857 var style = this.css( key ), |
|
2858 val = []; |
|
2859 |
|
2860 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { |
|
2861 if ( style.indexOf( unit ) > 0 ) { |
|
2862 val = [ parseFloat( style ), unit ]; |
|
2863 } |
|
2864 } ); |
|
2865 return val; |
|
2866 }, |
|
2867 |
|
2868 cssClip: function( clipObj ) { |
|
2869 if ( clipObj ) { |
|
2870 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + |
|
2871 clipObj.bottom + "px " + clipObj.left + "px)" ); |
|
2872 } |
|
2873 return parseClip( this.css( "clip" ), this ); |
|
2874 }, |
|
2875 |
|
2876 transfer: function( options, done ) { |
|
2877 var element = $( this ), |
|
2878 target = $( options.to ), |
|
2879 targetFixed = target.css( "position" ) === "fixed", |
|
2880 body = $( "body" ), |
|
2881 fixTop = targetFixed ? body.scrollTop() : 0, |
|
2882 fixLeft = targetFixed ? body.scrollLeft() : 0, |
|
2883 endPosition = target.offset(), |
|
2884 animation = { |
|
2885 top: endPosition.top - fixTop, |
|
2886 left: endPosition.left - fixLeft, |
|
2887 height: target.innerHeight(), |
|
2888 width: target.innerWidth() |
|
2889 }, |
|
2890 startPosition = element.offset(), |
|
2891 transfer = $( "<div class='ui-effects-transfer'></div>" ); |
|
2892 |
|
2893 transfer |
|
2894 .appendTo( "body" ) |
|
2895 .addClass( options.className ) |
|
2896 .css( { |
|
2897 top: startPosition.top - fixTop, |
|
2898 left: startPosition.left - fixLeft, |
|
2899 height: element.innerHeight(), |
|
2900 width: element.innerWidth(), |
|
2901 position: targetFixed ? "fixed" : "absolute" |
|
2902 } ) |
|
2903 .animate( animation, options.duration, options.easing, function() { |
|
2904 transfer.remove(); |
|
2905 if ( typeof done === "function" ) { |
|
2906 done(); |
|
2907 } |
|
2908 } ); |
|
2909 } |
|
2910 } ); |
|
2911 |
|
2912 function parseClip( str, element ) { |
|
2913 var outerWidth = element.outerWidth(), |
|
2914 outerHeight = element.outerHeight(), |
|
2915 clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, |
|
2916 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; |
|
2917 |
|
2918 return { |
|
2919 top: parseFloat( values[ 1 ] ) || 0, |
|
2920 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), |
|
2921 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), |
|
2922 left: parseFloat( values[ 4 ] ) || 0 |
|
2923 }; |
|
2924 } |
|
2925 |
|
2926 $.fx.step.clip = function( fx ) { |
|
2927 if ( !fx.clipInit ) { |
|
2928 fx.start = $( fx.elem ).cssClip(); |
|
2929 if ( typeof fx.end === "string" ) { |
|
2930 fx.end = parseClip( fx.end, fx.elem ); |
|
2931 } |
|
2932 fx.clipInit = true; |
|
2933 } |
|
2934 |
|
2935 $( fx.elem ).cssClip( { |
|
2936 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, |
|
2937 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, |
|
2938 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, |
|
2939 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left |
|
2940 } ); |
|
2941 }; |
|
2942 |
|
2943 } )(); |
|
2944 |
|
2945 /******************************************************************************/ |
|
2946 /*********************************** EASING ***********************************/ |
|
2947 /******************************************************************************/ |
|
2948 |
|
2949 ( function() { |
|
2950 |
|
2951 // Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) |
|
2952 |
|
2953 var baseEasings = {}; |
|
2954 |
|
2955 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { |
|
2956 baseEasings[ name ] = function( p ) { |
|
2957 return Math.pow( p, i + 2 ); |
|
2958 }; |
|
2959 } ); |
|
2960 |
|
2961 $.extend( baseEasings, { |
|
2962 Sine: function( p ) { |
|
2963 return 1 - Math.cos( p * Math.PI / 2 ); |
|
2964 }, |
|
2965 Circ: function( p ) { |
|
2966 return 1 - Math.sqrt( 1 - p * p ); |
|
2967 }, |
|
2968 Elastic: function( p ) { |
|
2969 return p === 0 || p === 1 ? p : |
|
2970 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); |
|
2971 }, |
|
2972 Back: function( p ) { |
|
2973 return p * p * ( 3 * p - 2 ); |
|
2974 }, |
|
2975 Bounce: function( p ) { |
|
2976 var pow2, |
|
2977 bounce = 4; |
|
2978 |
|
2979 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} |
|
2980 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); |
|
2981 } |
|
2982 } ); |
|
2983 |
|
2984 $.each( baseEasings, function( name, easeIn ) { |
|
2985 $.easing[ "easeIn" + name ] = easeIn; |
|
2986 $.easing[ "easeOut" + name ] = function( p ) { |
|
2987 return 1 - easeIn( 1 - p ); |
|
2988 }; |
|
2989 $.easing[ "easeInOut" + name ] = function( p ) { |
|
2990 return p < 0.5 ? |
|
2991 easeIn( p * 2 ) / 2 : |
|
2992 1 - easeIn( p * -2 + 2 ) / 2; |
|
2993 }; |
|
2994 } ); |
|
2995 |
|
2996 } )(); |
|
2997 |
|
2998 var effect = $.effects; |
|
2999 |
|
3000 |
|
3001 /*! |
|
3002 * jQuery UI Effects Blind 1.13.2 |
|
3003 * http://jqueryui.com |
|
3004 * |
|
3005 * Copyright jQuery Foundation and other contributors |
|
3006 * Released under the MIT license. |
|
3007 * http://jquery.org/license |
|
3008 */ |
|
3009 |
|
3010 //>>label: Blind Effect |
|
3011 //>>group: Effects |
|
3012 //>>description: Blinds the element. |
|
3013 //>>docs: http://api.jqueryui.com/blind-effect/ |
|
3014 //>>demos: http://jqueryui.com/effect/ |
|
3015 |
|
3016 |
|
3017 var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { |
|
3018 var map = { |
|
3019 up: [ "bottom", "top" ], |
|
3020 vertical: [ "bottom", "top" ], |
|
3021 down: [ "top", "bottom" ], |
|
3022 left: [ "right", "left" ], |
|
3023 horizontal: [ "right", "left" ], |
|
3024 right: [ "left", "right" ] |
|
3025 }, |
|
3026 element = $( this ), |
|
3027 direction = options.direction || "up", |
|
3028 start = element.cssClip(), |
|
3029 animate = { clip: $.extend( {}, start ) }, |
|
3030 placeholder = $.effects.createPlaceholder( element ); |
|
3031 |
|
3032 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; |
|
3033 |
|
3034 if ( options.mode === "show" ) { |
|
3035 element.cssClip( animate.clip ); |
|
3036 if ( placeholder ) { |
|
3037 placeholder.css( $.effects.clipToBox( animate ) ); |
|
3038 } |
|
3039 |
|
3040 animate.clip = start; |
|
3041 } |
|
3042 |
|
3043 if ( placeholder ) { |
|
3044 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); |
|
3045 } |
|
3046 |
|
3047 element.animate( animate, { |
|
3048 queue: false, |
|
3049 duration: options.duration, |
|
3050 easing: options.easing, |
|
3051 complete: done |
|
3052 } ); |
|
3053 } ); |
|
3054 |
|
3055 |
|
3056 /*! |
|
3057 * jQuery UI Effects Bounce 1.13.2 |
|
3058 * http://jqueryui.com |
|
3059 * |
|
3060 * Copyright jQuery Foundation and other contributors |
|
3061 * Released under the MIT license. |
|
3062 * http://jquery.org/license |
|
3063 */ |
|
3064 |
|
3065 //>>label: Bounce Effect |
|
3066 //>>group: Effects |
|
3067 //>>description: Bounces an element horizontally or vertically n times. |
|
3068 //>>docs: http://api.jqueryui.com/bounce-effect/ |
|
3069 //>>demos: http://jqueryui.com/effect/ |
|
3070 |
|
3071 |
|
3072 var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { |
|
3073 var upAnim, downAnim, refValue, |
|
3074 element = $( this ), |
|
3075 |
|
3076 // Defaults: |
|
3077 mode = options.mode, |
|
3078 hide = mode === "hide", |
|
3079 show = mode === "show", |
|
3080 direction = options.direction || "up", |
|
3081 distance = options.distance, |
|
3082 times = options.times || 5, |
|
3083 |
|
3084 // Number of internal animations |
|
3085 anims = times * 2 + ( show || hide ? 1 : 0 ), |
|
3086 speed = options.duration / anims, |
|
3087 easing = options.easing, |
|
3088 |
|
3089 // Utility: |
|
3090 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", |
|
3091 motion = ( direction === "up" || direction === "left" ), |
|
3092 i = 0, |
|
3093 |
|
3094 queuelen = element.queue().length; |
|
3095 |
|
3096 $.effects.createPlaceholder( element ); |
|
3097 |
|
3098 refValue = element.css( ref ); |
|
3099 |
|
3100 // Default distance for the BIGGEST bounce is the outer Distance / 3 |
|
3101 if ( !distance ) { |
|
3102 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; |
|
3103 } |
|
3104 |
|
3105 if ( show ) { |
|
3106 downAnim = { opacity: 1 }; |
|
3107 downAnim[ ref ] = refValue; |
|
3108 |
|
3109 // If we are showing, force opacity 0 and set the initial position |
|
3110 // then do the "first" animation |
|
3111 element |
|
3112 .css( "opacity", 0 ) |
|
3113 .css( ref, motion ? -distance * 2 : distance * 2 ) |
|
3114 .animate( downAnim, speed, easing ); |
|
3115 } |
|
3116 |
|
3117 // Start at the smallest distance if we are hiding |
|
3118 if ( hide ) { |
|
3119 distance = distance / Math.pow( 2, times - 1 ); |
|
3120 } |
|
3121 |
|
3122 downAnim = {}; |
|
3123 downAnim[ ref ] = refValue; |
|
3124 |
|
3125 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here |
|
3126 for ( ; i < times; i++ ) { |
|
3127 upAnim = {}; |
|
3128 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; |
|
3129 |
|
3130 element |
|
3131 .animate( upAnim, speed, easing ) |
|
3132 .animate( downAnim, speed, easing ); |
|
3133 |
|
3134 distance = hide ? distance * 2 : distance / 2; |
|
3135 } |
|
3136 |
|
3137 // Last Bounce when Hiding |
|
3138 if ( hide ) { |
|
3139 upAnim = { opacity: 0 }; |
|
3140 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; |
|
3141 |
|
3142 element.animate( upAnim, speed, easing ); |
|
3143 } |
|
3144 |
|
3145 element.queue( done ); |
|
3146 |
|
3147 $.effects.unshift( element, queuelen, anims + 1 ); |
|
3148 } ); |
|
3149 |
|
3150 |
|
3151 /*! |
|
3152 * jQuery UI Effects Clip 1.13.2 |
|
3153 * http://jqueryui.com |
|
3154 * |
|
3155 * Copyright jQuery Foundation and other contributors |
|
3156 * Released under the MIT license. |
|
3157 * http://jquery.org/license |
|
3158 */ |
|
3159 |
|
3160 //>>label: Clip Effect |
|
3161 //>>group: Effects |
|
3162 //>>description: Clips the element on and off like an old TV. |
|
3163 //>>docs: http://api.jqueryui.com/clip-effect/ |
|
3164 //>>demos: http://jqueryui.com/effect/ |
|
3165 |
|
3166 |
|
3167 var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { |
|
3168 var start, |
|
3169 animate = {}, |
|
3170 element = $( this ), |
|
3171 direction = options.direction || "vertical", |
|
3172 both = direction === "both", |
|
3173 horizontal = both || direction === "horizontal", |
|
3174 vertical = both || direction === "vertical"; |
|
3175 |
|
3176 start = element.cssClip(); |
|
3177 animate.clip = { |
|
3178 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, |
|
3179 right: horizontal ? ( start.right - start.left ) / 2 : start.right, |
|
3180 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, |
|
3181 left: horizontal ? ( start.right - start.left ) / 2 : start.left |
|
3182 }; |
|
3183 |
|
3184 $.effects.createPlaceholder( element ); |
|
3185 |
|
3186 if ( options.mode === "show" ) { |
|
3187 element.cssClip( animate.clip ); |
|
3188 animate.clip = start; |
|
3189 } |
|
3190 |
|
3191 element.animate( animate, { |
|
3192 queue: false, |
|
3193 duration: options.duration, |
|
3194 easing: options.easing, |
|
3195 complete: done |
|
3196 } ); |
|
3197 |
|
3198 } ); |
|
3199 |
|
3200 |
|
3201 /*! |
|
3202 * jQuery UI Effects Drop 1.13.2 |
|
3203 * http://jqueryui.com |
|
3204 * |
|
3205 * Copyright jQuery Foundation and other contributors |
|
3206 * Released under the MIT license. |
|
3207 * http://jquery.org/license |
|
3208 */ |
|
3209 |
|
3210 //>>label: Drop Effect |
|
3211 //>>group: Effects |
|
3212 //>>description: Moves an element in one direction and hides it at the same time. |
|
3213 //>>docs: http://api.jqueryui.com/drop-effect/ |
|
3214 //>>demos: http://jqueryui.com/effect/ |
|
3215 |
|
3216 |
|
3217 var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { |
|
3218 |
|
3219 var distance, |
|
3220 element = $( this ), |
|
3221 mode = options.mode, |
|
3222 show = mode === "show", |
|
3223 direction = options.direction || "left", |
|
3224 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", |
|
3225 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", |
|
3226 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", |
|
3227 animation = { |
|
3228 opacity: 0 |
|
3229 }; |
|
3230 |
|
3231 $.effects.createPlaceholder( element ); |
|
3232 |
|
3233 distance = options.distance || |
|
3234 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; |
|
3235 |
|
3236 animation[ ref ] = motion + distance; |
|
3237 |
|
3238 if ( show ) { |
|
3239 element.css( animation ); |
|
3240 |
|
3241 animation[ ref ] = oppositeMotion + distance; |
|
3242 animation.opacity = 1; |
|
3243 } |
|
3244 |
|
3245 // Animate |
|
3246 element.animate( animation, { |
|
3247 queue: false, |
|
3248 duration: options.duration, |
|
3249 easing: options.easing, |
|
3250 complete: done |
|
3251 } ); |
|
3252 } ); |
|
3253 |
|
3254 |
|
3255 /*! |
|
3256 * jQuery UI Effects Explode 1.13.2 |
|
3257 * http://jqueryui.com |
|
3258 * |
|
3259 * Copyright jQuery Foundation and other contributors |
|
3260 * Released under the MIT license. |
|
3261 * http://jquery.org/license |
|
3262 */ |
|
3263 |
|
3264 //>>label: Explode Effect |
|
3265 //>>group: Effects |
|
3266 /* eslint-disable max-len */ |
|
3267 //>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. |
|
3268 /* eslint-enable max-len */ |
|
3269 //>>docs: http://api.jqueryui.com/explode-effect/ |
|
3270 //>>demos: http://jqueryui.com/effect/ |
|
3271 |
|
3272 |
|
3273 var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { |
|
3274 |
|
3275 var i, j, left, top, mx, my, |
|
3276 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, |
|
3277 cells = rows, |
|
3278 element = $( this ), |
|
3279 mode = options.mode, |
|
3280 show = mode === "show", |
|
3281 |
|
3282 // Show and then visibility:hidden the element before calculating offset |
|
3283 offset = element.show().css( "visibility", "hidden" ).offset(), |
|
3284 |
|
3285 // Width and height of a piece |
|
3286 width = Math.ceil( element.outerWidth() / cells ), |
|
3287 height = Math.ceil( element.outerHeight() / rows ), |
|
3288 pieces = []; |
|
3289 |
|
3290 // Children animate complete: |
|
3291 function childComplete() { |
|
3292 pieces.push( this ); |
|
3293 if ( pieces.length === rows * cells ) { |
|
3294 animComplete(); |
|
3295 } |
|
3296 } |
|
3297 |
|
3298 // Clone the element for each row and cell. |
|
3299 for ( i = 0; i < rows; i++ ) { // ===> |
|
3300 top = offset.top + i * height; |
|
3301 my = i - ( rows - 1 ) / 2; |
|
3302 |
|
3303 for ( j = 0; j < cells; j++ ) { // ||| |
|
3304 left = offset.left + j * width; |
|
3305 mx = j - ( cells - 1 ) / 2; |
|
3306 |
|
3307 // Create a clone of the now hidden main element that will be absolute positioned |
|
3308 // within a wrapper div off the -left and -top equal to size of our pieces |
|
3309 element |
|
3310 .clone() |
|
3311 .appendTo( "body" ) |
|
3312 .wrap( "<div></div>" ) |
|
3313 .css( { |
|
3314 position: "absolute", |
|
3315 visibility: "visible", |
|
3316 left: -j * width, |
|
3317 top: -i * height |
|
3318 } ) |
|
3319 |
|
3320 // Select the wrapper - make it overflow: hidden and absolute positioned based on |
|
3321 // where the original was located +left and +top equal to the size of pieces |
|
3322 .parent() |
|
3323 .addClass( "ui-effects-explode" ) |
|
3324 .css( { |
|
3325 position: "absolute", |
|
3326 overflow: "hidden", |
|
3327 width: width, |
|
3328 height: height, |
|
3329 left: left + ( show ? mx * width : 0 ), |
|
3330 top: top + ( show ? my * height : 0 ), |
|
3331 opacity: show ? 0 : 1 |
|
3332 } ) |
|
3333 .animate( { |
|
3334 left: left + ( show ? 0 : mx * width ), |
|
3335 top: top + ( show ? 0 : my * height ), |
|
3336 opacity: show ? 1 : 0 |
|
3337 }, options.duration || 500, options.easing, childComplete ); |
|
3338 } |
|
3339 } |
|
3340 |
|
3341 function animComplete() { |
|
3342 element.css( { |
|
3343 visibility: "visible" |
|
3344 } ); |
|
3345 $( pieces ).remove(); |
|
3346 done(); |
|
3347 } |
|
3348 } ); |
|
3349 |
|
3350 |
|
3351 /*! |
|
3352 * jQuery UI Effects Fade 1.13.2 |
|
3353 * http://jqueryui.com |
|
3354 * |
|
3355 * Copyright jQuery Foundation and other contributors |
|
3356 * Released under the MIT license. |
|
3357 * http://jquery.org/license |
|
3358 */ |
|
3359 |
|
3360 //>>label: Fade Effect |
|
3361 //>>group: Effects |
|
3362 //>>description: Fades the element. |
|
3363 //>>docs: http://api.jqueryui.com/fade-effect/ |
|
3364 //>>demos: http://jqueryui.com/effect/ |
|
3365 |
|
3366 |
|
3367 var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { |
|
3368 var show = options.mode === "show"; |
|
3369 |
|
3370 $( this ) |
|
3371 .css( "opacity", show ? 0 : 1 ) |
|
3372 .animate( { |
|
3373 opacity: show ? 1 : 0 |
|
3374 }, { |
|
3375 queue: false, |
|
3376 duration: options.duration, |
|
3377 easing: options.easing, |
|
3378 complete: done |
|
3379 } ); |
|
3380 } ); |
|
3381 |
|
3382 |
|
3383 /*! |
|
3384 * jQuery UI Effects Fold 1.13.2 |
|
3385 * http://jqueryui.com |
|
3386 * |
|
3387 * Copyright jQuery Foundation and other contributors |
|
3388 * Released under the MIT license. |
|
3389 * http://jquery.org/license |
|
3390 */ |
|
3391 |
|
3392 //>>label: Fold Effect |
|
3393 //>>group: Effects |
|
3394 //>>description: Folds an element first horizontally and then vertically. |
|
3395 //>>docs: http://api.jqueryui.com/fold-effect/ |
|
3396 //>>demos: http://jqueryui.com/effect/ |
|
3397 |
|
3398 |
|
3399 var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { |
|
3400 |
|
3401 // Create element |
|
3402 var element = $( this ), |
|
3403 mode = options.mode, |
|
3404 show = mode === "show", |
|
3405 hide = mode === "hide", |
|
3406 size = options.size || 15, |
|
3407 percent = /([0-9]+)%/.exec( size ), |
|
3408 horizFirst = !!options.horizFirst, |
|
3409 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], |
|
3410 duration = options.duration / 2, |
|
3411 |
|
3412 placeholder = $.effects.createPlaceholder( element ), |
|
3413 |
|
3414 start = element.cssClip(), |
|
3415 animation1 = { clip: $.extend( {}, start ) }, |
|
3416 animation2 = { clip: $.extend( {}, start ) }, |
|
3417 |
|
3418 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], |
|
3419 |
|
3420 queuelen = element.queue().length; |
|
3421 |
|
3422 if ( percent ) { |
|
3423 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; |
|
3424 } |
|
3425 animation1.clip[ ref[ 0 ] ] = size; |
|
3426 animation2.clip[ ref[ 0 ] ] = size; |
|
3427 animation2.clip[ ref[ 1 ] ] = 0; |
|
3428 |
|
3429 if ( show ) { |
|
3430 element.cssClip( animation2.clip ); |
|
3431 if ( placeholder ) { |
|
3432 placeholder.css( $.effects.clipToBox( animation2 ) ); |
|
3433 } |
|
3434 |
|
3435 animation2.clip = start; |
|
3436 } |
|
3437 |
|
3438 // Animate |
|
3439 element |
|
3440 .queue( function( next ) { |
|
3441 if ( placeholder ) { |
|
3442 placeholder |
|
3443 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) |
|
3444 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); |
|
3445 } |
|
3446 |
|
3447 next(); |
|
3448 } ) |
|
3449 .animate( animation1, duration, options.easing ) |
|
3450 .animate( animation2, duration, options.easing ) |
|
3451 .queue( done ); |
|
3452 |
|
3453 $.effects.unshift( element, queuelen, 4 ); |
|
3454 } ); |
|
3455 |
|
3456 |
|
3457 /*! |
|
3458 * jQuery UI Effects Highlight 1.13.2 |
|
3459 * http://jqueryui.com |
|
3460 * |
|
3461 * Copyright jQuery Foundation and other contributors |
|
3462 * Released under the MIT license. |
|
3463 * http://jquery.org/license |
|
3464 */ |
|
3465 |
|
3466 //>>label: Highlight Effect |
|
3467 //>>group: Effects |
|
3468 //>>description: Highlights the background of an element in a defined color for a custom duration. |
|
3469 //>>docs: http://api.jqueryui.com/highlight-effect/ |
|
3470 //>>demos: http://jqueryui.com/effect/ |
|
3471 |
|
3472 |
|
3473 var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { |
|
3474 var element = $( this ), |
|
3475 animation = { |
|
3476 backgroundColor: element.css( "backgroundColor" ) |
|
3477 }; |
|
3478 |
|
3479 if ( options.mode === "hide" ) { |
|
3480 animation.opacity = 0; |
|
3481 } |
|
3482 |
|
3483 $.effects.saveStyle( element ); |
|
3484 |
|
3485 element |
|
3486 .css( { |
|
3487 backgroundImage: "none", |
|
3488 backgroundColor: options.color || "#ffff99" |
|
3489 } ) |
|
3490 .animate( animation, { |
|
3491 queue: false, |
|
3492 duration: options.duration, |
|
3493 easing: options.easing, |
|
3494 complete: done |
|
3495 } ); |
|
3496 } ); |
|
3497 |
|
3498 |
|
3499 /*! |
|
3500 * jQuery UI Effects Size 1.13.2 |
|
3501 * http://jqueryui.com |
|
3502 * |
|
3503 * Copyright jQuery Foundation and other contributors |
|
3504 * Released under the MIT license. |
|
3505 * http://jquery.org/license |
|
3506 */ |
|
3507 |
|
3508 //>>label: Size Effect |
|
3509 //>>group: Effects |
|
3510 //>>description: Resize an element to a specified width and height. |
|
3511 //>>docs: http://api.jqueryui.com/size-effect/ |
|
3512 //>>demos: http://jqueryui.com/effect/ |
|
3513 |
|
3514 |
|
3515 var effectsEffectSize = $.effects.define( "size", function( options, done ) { |
|
3516 |
|
3517 // Create element |
|
3518 var baseline, factor, temp, |
|
3519 element = $( this ), |
|
3520 |
|
3521 // Copy for children |
|
3522 cProps = [ "fontSize" ], |
|
3523 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], |
|
3524 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], |
|
3525 |
|
3526 // Set options |
|
3527 mode = options.mode, |
|
3528 restore = mode !== "effect", |
|
3529 scale = options.scale || "both", |
|
3530 origin = options.origin || [ "middle", "center" ], |
|
3531 position = element.css( "position" ), |
|
3532 pos = element.position(), |
|
3533 original = $.effects.scaledDimensions( element ), |
|
3534 from = options.from || original, |
|
3535 to = options.to || $.effects.scaledDimensions( element, 0 ); |
|
3536 |
|
3537 $.effects.createPlaceholder( element ); |
|
3538 |
|
3539 if ( mode === "show" ) { |
|
3540 temp = from; |
|
3541 from = to; |
|
3542 to = temp; |
|
3543 } |
|
3544 |
|
3545 // Set scaling factor |
|
3546 factor = { |
|
3547 from: { |
|
3548 y: from.height / original.height, |
|
3549 x: from.width / original.width |
|
3550 }, |
|
3551 to: { |
|
3552 y: to.height / original.height, |
|
3553 x: to.width / original.width |
|
3554 } |
|
3555 }; |
|
3556 |
|
3557 // Scale the css box |
|
3558 if ( scale === "box" || scale === "both" ) { |
|
3559 |
|
3560 // Vertical props scaling |
|
3561 if ( factor.from.y !== factor.to.y ) { |
|
3562 from = $.effects.setTransition( element, vProps, factor.from.y, from ); |
|
3563 to = $.effects.setTransition( element, vProps, factor.to.y, to ); |
|
3564 } |
|
3565 |
|
3566 // Horizontal props scaling |
|
3567 if ( factor.from.x !== factor.to.x ) { |
|
3568 from = $.effects.setTransition( element, hProps, factor.from.x, from ); |
|
3569 to = $.effects.setTransition( element, hProps, factor.to.x, to ); |
|
3570 } |
|
3571 } |
|
3572 |
|
3573 // Scale the content |
|
3574 if ( scale === "content" || scale === "both" ) { |
|
3575 |
|
3576 // Vertical props scaling |
|
3577 if ( factor.from.y !== factor.to.y ) { |
|
3578 from = $.effects.setTransition( element, cProps, factor.from.y, from ); |
|
3579 to = $.effects.setTransition( element, cProps, factor.to.y, to ); |
|
3580 } |
|
3581 } |
|
3582 |
|
3583 // Adjust the position properties based on the provided origin points |
|
3584 if ( origin ) { |
|
3585 baseline = $.effects.getBaseline( origin, original ); |
|
3586 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; |
|
3587 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; |
|
3588 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; |
|
3589 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; |
|
3590 } |
|
3591 delete from.outerHeight; |
|
3592 delete from.outerWidth; |
|
3593 element.css( from ); |
|
3594 |
|
3595 // Animate the children if desired |
|
3596 if ( scale === "content" || scale === "both" ) { |
|
3597 |
|
3598 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); |
|
3599 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); |
|
3600 |
|
3601 // Only animate children with width attributes specified |
|
3602 // TODO: is this right? should we include anything with css width specified as well |
|
3603 element.find( "*[width]" ).each( function() { |
|
3604 var child = $( this ), |
|
3605 childOriginal = $.effects.scaledDimensions( child ), |
|
3606 childFrom = { |
|
3607 height: childOriginal.height * factor.from.y, |
|
3608 width: childOriginal.width * factor.from.x, |
|
3609 outerHeight: childOriginal.outerHeight * factor.from.y, |
|
3610 outerWidth: childOriginal.outerWidth * factor.from.x |
|
3611 }, |
|
3612 childTo = { |
|
3613 height: childOriginal.height * factor.to.y, |
|
3614 width: childOriginal.width * factor.to.x, |
|
3615 outerHeight: childOriginal.height * factor.to.y, |
|
3616 outerWidth: childOriginal.width * factor.to.x |
|
3617 }; |
|
3618 |
|
3619 // Vertical props scaling |
|
3620 if ( factor.from.y !== factor.to.y ) { |
|
3621 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); |
|
3622 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); |
|
3623 } |
|
3624 |
|
3625 // Horizontal props scaling |
|
3626 if ( factor.from.x !== factor.to.x ) { |
|
3627 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); |
|
3628 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); |
|
3629 } |
|
3630 |
|
3631 if ( restore ) { |
|
3632 $.effects.saveStyle( child ); |
|
3633 } |
|
3634 |
|
3635 // Animate children |
|
3636 child.css( childFrom ); |
|
3637 child.animate( childTo, options.duration, options.easing, function() { |
|
3638 |
|
3639 // Restore children |
|
3640 if ( restore ) { |
|
3641 $.effects.restoreStyle( child ); |
|
3642 } |
|
3643 } ); |
|
3644 } ); |
|
3645 } |
|
3646 |
|
3647 // Animate |
|
3648 element.animate( to, { |
|
3649 queue: false, |
|
3650 duration: options.duration, |
|
3651 easing: options.easing, |
|
3652 complete: function() { |
|
3653 |
|
3654 var offset = element.offset(); |
|
3655 |
|
3656 if ( to.opacity === 0 ) { |
|
3657 element.css( "opacity", from.opacity ); |
|
3658 } |
|
3659 |
|
3660 if ( !restore ) { |
|
3661 element |
|
3662 .css( "position", position === "static" ? "relative" : position ) |
|
3663 .offset( offset ); |
|
3664 |
|
3665 // Need to save style here so that automatic style restoration |
|
3666 // doesn't restore to the original styles from before the animation. |
|
3667 $.effects.saveStyle( element ); |
|
3668 } |
|
3669 |
|
3670 done(); |
|
3671 } |
|
3672 } ); |
|
3673 |
|
3674 } ); |
|
3675 |
|
3676 |
|
3677 /*! |
|
3678 * jQuery UI Effects Scale 1.13.2 |
|
3679 * http://jqueryui.com |
|
3680 * |
|
3681 * Copyright jQuery Foundation and other contributors |
|
3682 * Released under the MIT license. |
|
3683 * http://jquery.org/license |
|
3684 */ |
|
3685 |
|
3686 //>>label: Scale Effect |
|
3687 //>>group: Effects |
|
3688 //>>description: Grows or shrinks an element and its content. |
|
3689 //>>docs: http://api.jqueryui.com/scale-effect/ |
|
3690 //>>demos: http://jqueryui.com/effect/ |
|
3691 |
|
3692 |
|
3693 var effectsEffectScale = $.effects.define( "scale", function( options, done ) { |
|
3694 |
|
3695 // Create element |
|
3696 var el = $( this ), |
|
3697 mode = options.mode, |
|
3698 percent = parseInt( options.percent, 10 ) || |
|
3699 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), |
|
3700 |
|
3701 newOptions = $.extend( true, { |
|
3702 from: $.effects.scaledDimensions( el ), |
|
3703 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), |
|
3704 origin: options.origin || [ "middle", "center" ] |
|
3705 }, options ); |
|
3706 |
|
3707 // Fade option to support puff |
|
3708 if ( options.fade ) { |
|
3709 newOptions.from.opacity = 1; |
|
3710 newOptions.to.opacity = 0; |
|
3711 } |
|
3712 |
|
3713 $.effects.effect.size.call( this, newOptions, done ); |
|
3714 } ); |
|
3715 |
|
3716 |
|
3717 /*! |
|
3718 * jQuery UI Effects Puff 1.13.2 |
|
3719 * http://jqueryui.com |
|
3720 * |
|
3721 * Copyright jQuery Foundation and other contributors |
|
3722 * Released under the MIT license. |
|
3723 * http://jquery.org/license |
|
3724 */ |
|
3725 |
|
3726 //>>label: Puff Effect |
|
3727 //>>group: Effects |
|
3728 //>>description: Creates a puff effect by scaling the element up and hiding it at the same time. |
|
3729 //>>docs: http://api.jqueryui.com/puff-effect/ |
|
3730 //>>demos: http://jqueryui.com/effect/ |
|
3731 |
|
3732 |
|
3733 var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { |
|
3734 var newOptions = $.extend( true, {}, options, { |
|
3735 fade: true, |
|
3736 percent: parseInt( options.percent, 10 ) || 150 |
|
3737 } ); |
|
3738 |
|
3739 $.effects.effect.scale.call( this, newOptions, done ); |
|
3740 } ); |
|
3741 |
|
3742 |
|
3743 /*! |
|
3744 * jQuery UI Effects Pulsate 1.13.2 |
|
3745 * http://jqueryui.com |
|
3746 * |
|
3747 * Copyright jQuery Foundation and other contributors |
|
3748 * Released under the MIT license. |
|
3749 * http://jquery.org/license |
|
3750 */ |
|
3751 |
|
3752 //>>label: Pulsate Effect |
|
3753 //>>group: Effects |
|
3754 //>>description: Pulsates an element n times by changing the opacity to zero and back. |
|
3755 //>>docs: http://api.jqueryui.com/pulsate-effect/ |
|
3756 //>>demos: http://jqueryui.com/effect/ |
|
3757 |
|
3758 |
|
3759 var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { |
|
3760 var element = $( this ), |
|
3761 mode = options.mode, |
|
3762 show = mode === "show", |
|
3763 hide = mode === "hide", |
|
3764 showhide = show || hide, |
|
3765 |
|
3766 // Showing or hiding leaves off the "last" animation |
|
3767 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), |
|
3768 duration = options.duration / anims, |
|
3769 animateTo = 0, |
|
3770 i = 1, |
|
3771 queuelen = element.queue().length; |
|
3772 |
|
3773 if ( show || !element.is( ":visible" ) ) { |
|
3774 element.css( "opacity", 0 ).show(); |
|
3775 animateTo = 1; |
|
3776 } |
|
3777 |
|
3778 // Anims - 1 opacity "toggles" |
|
3779 for ( ; i < anims; i++ ) { |
|
3780 element.animate( { opacity: animateTo }, duration, options.easing ); |
|
3781 animateTo = 1 - animateTo; |
|
3782 } |
|
3783 |
|
3784 element.animate( { opacity: animateTo }, duration, options.easing ); |
|
3785 |
|
3786 element.queue( done ); |
|
3787 |
|
3788 $.effects.unshift( element, queuelen, anims + 1 ); |
|
3789 } ); |
|
3790 |
|
3791 |
|
3792 /*! |
|
3793 * jQuery UI Effects Shake 1.13.2 |
|
3794 * http://jqueryui.com |
|
3795 * |
|
3796 * Copyright jQuery Foundation and other contributors |
|
3797 * Released under the MIT license. |
|
3798 * http://jquery.org/license |
|
3799 */ |
|
3800 |
|
3801 //>>label: Shake Effect |
|
3802 //>>group: Effects |
|
3803 //>>description: Shakes an element horizontally or vertically n times. |
|
3804 //>>docs: http://api.jqueryui.com/shake-effect/ |
|
3805 //>>demos: http://jqueryui.com/effect/ |
|
3806 |
|
3807 |
|
3808 var effectsEffectShake = $.effects.define( "shake", function( options, done ) { |
|
3809 |
|
3810 var i = 1, |
|
3811 element = $( this ), |
|
3812 direction = options.direction || "left", |
|
3813 distance = options.distance || 20, |
|
3814 times = options.times || 3, |
|
3815 anims = times * 2 + 1, |
|
3816 speed = Math.round( options.duration / anims ), |
|
3817 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", |
|
3818 positiveMotion = ( direction === "up" || direction === "left" ), |
|
3819 animation = {}, |
|
3820 animation1 = {}, |
|
3821 animation2 = {}, |
|
3822 |
|
3823 queuelen = element.queue().length; |
|
3824 |
|
3825 $.effects.createPlaceholder( element ); |
|
3826 |
|
3827 // Animation |
|
3828 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; |
|
3829 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; |
|
3830 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; |
|
3831 |
|
3832 // Animate |
|
3833 element.animate( animation, speed, options.easing ); |
|
3834 |
|
3835 // Shakes |
|
3836 for ( ; i < times; i++ ) { |
|
3837 element |
|
3838 .animate( animation1, speed, options.easing ) |
|
3839 .animate( animation2, speed, options.easing ); |
|
3840 } |
|
3841 |
|
3842 element |
|
3843 .animate( animation1, speed, options.easing ) |
|
3844 .animate( animation, speed / 2, options.easing ) |
|
3845 .queue( done ); |
|
3846 |
|
3847 $.effects.unshift( element, queuelen, anims + 1 ); |
|
3848 } ); |
|
3849 |
|
3850 |
|
3851 /*! |
|
3852 * jQuery UI Effects Slide 1.13.2 |
|
3853 * http://jqueryui.com |
|
3854 * |
|
3855 * Copyright jQuery Foundation and other contributors |
|
3856 * Released under the MIT license. |
|
3857 * http://jquery.org/license |
|
3858 */ |
|
3859 |
|
3860 //>>label: Slide Effect |
|
3861 //>>group: Effects |
|
3862 //>>description: Slides an element in and out of the viewport. |
|
3863 //>>docs: http://api.jqueryui.com/slide-effect/ |
|
3864 //>>demos: http://jqueryui.com/effect/ |
|
3865 |
|
3866 |
|
3867 var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { |
|
3868 var startClip, startRef, |
|
3869 element = $( this ), |
|
3870 map = { |
|
3871 up: [ "bottom", "top" ], |
|
3872 down: [ "top", "bottom" ], |
|
3873 left: [ "right", "left" ], |
|
3874 right: [ "left", "right" ] |
|
3875 }, |
|
3876 mode = options.mode, |
|
3877 direction = options.direction || "left", |
|
3878 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", |
|
3879 positiveMotion = ( direction === "up" || direction === "left" ), |
|
3880 distance = options.distance || |
|
3881 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), |
|
3882 animation = {}; |
|
3883 |
|
3884 $.effects.createPlaceholder( element ); |
|
3885 |
|
3886 startClip = element.cssClip(); |
|
3887 startRef = element.position()[ ref ]; |
|
3888 |
|
3889 // Define hide animation |
|
3890 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; |
|
3891 animation.clip = element.cssClip(); |
|
3892 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; |
|
3893 |
|
3894 // Reverse the animation if we're showing |
|
3895 if ( mode === "show" ) { |
|
3896 element.cssClip( animation.clip ); |
|
3897 element.css( ref, animation[ ref ] ); |
|
3898 animation.clip = startClip; |
|
3899 animation[ ref ] = startRef; |
|
3900 } |
|
3901 |
|
3902 // Actually animate |
|
3903 element.animate( animation, { |
|
3904 queue: false, |
|
3905 duration: options.duration, |
|
3906 easing: options.easing, |
|
3907 complete: done |
|
3908 } ); |
|
3909 } ); |
|
3910 |
|
3911 |
|
3912 /*! |
|
3913 * jQuery UI Effects Transfer 1.13.2 |
|
3914 * http://jqueryui.com |
|
3915 * |
|
3916 * Copyright jQuery Foundation and other contributors |
|
3917 * Released under the MIT license. |
|
3918 * http://jquery.org/license |
|
3919 */ |
|
3920 |
|
3921 //>>label: Transfer Effect |
|
3922 //>>group: Effects |
|
3923 //>>description: Displays a transfer effect from one element to another. |
|
3924 //>>docs: http://api.jqueryui.com/transfer-effect/ |
|
3925 //>>demos: http://jqueryui.com/effect/ |
|
3926 |
|
3927 |
|
3928 var effect; |
|
3929 if ( $.uiBackCompat !== false ) { |
|
3930 effect = $.effects.define( "transfer", function( options, done ) { |
|
3931 $( this ).transfer( options, done ); |
|
3932 } ); |
|
3933 } |
|
3934 var effectsEffectTransfer = effect; |
|
3935 |
|
3936 |
|
3937 /*! |
|
3938 * jQuery UI Focusable 1.13.2 |
|
3939 * http://jqueryui.com |
|
3940 * |
|
3941 * Copyright jQuery Foundation and other contributors |
|
3942 * Released under the MIT license. |
|
3943 * http://jquery.org/license |
|
3944 */ |
|
3945 |
|
3946 //>>label: :focusable Selector |
|
3947 //>>group: Core |
|
3948 //>>description: Selects elements which can be focused. |
|
3949 //>>docs: http://api.jqueryui.com/focusable-selector/ |
|
3950 |
|
3951 |
|
3952 // Selectors |
|
3953 $.ui.focusable = function( element, hasTabindex ) { |
|
3954 var map, mapName, img, focusableIfVisible, fieldset, |
|
3955 nodeName = element.nodeName.toLowerCase(); |
|
3956 |
|
3957 if ( "area" === nodeName ) { |
|
3958 map = element.parentNode; |
|
3959 mapName = map.name; |
|
3960 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { |
|
3961 return false; |
|
3962 } |
|
3963 img = $( "img[usemap='#" + mapName + "']" ); |
|
3964 return img.length > 0 && img.is( ":visible" ); |
|
3965 } |
|
3966 |
|
3967 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { |
|
3968 focusableIfVisible = !element.disabled; |
|
3969 |
|
3970 if ( focusableIfVisible ) { |
|
3971 |
|
3972 // Form controls within a disabled fieldset are disabled. |
|
3973 // However, controls within the fieldset's legend do not get disabled. |
|
3974 // Since controls generally aren't placed inside legends, we skip |
|
3975 // this portion of the check. |
|
3976 fieldset = $( element ).closest( "fieldset" )[ 0 ]; |
|
3977 if ( fieldset ) { |
|
3978 focusableIfVisible = !fieldset.disabled; |
|
3979 } |
|
3980 } |
|
3981 } else if ( "a" === nodeName ) { |
|
3982 focusableIfVisible = element.href || hasTabindex; |
|
3983 } else { |
|
3984 focusableIfVisible = hasTabindex; |
|
3985 } |
|
3986 |
|
3987 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); |
|
3988 }; |
|
3989 |
|
3990 // Support: IE 8 only |
|
3991 // IE 8 doesn't resolve inherit to visible/hidden for computed values |
|
3992 function visible( element ) { |
|
3993 var visibility = element.css( "visibility" ); |
|
3994 while ( visibility === "inherit" ) { |
|
3995 element = element.parent(); |
|
3996 visibility = element.css( "visibility" ); |
|
3997 } |
|
3998 return visibility === "visible"; |
|
3999 } |
|
4000 |
|
4001 $.extend( $.expr.pseudos, { |
|
4002 focusable: function( element ) { |
|
4003 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); |
|
4004 } |
|
4005 } ); |
|
4006 |
|
4007 var focusable = $.ui.focusable; |
|
4008 |
|
4009 |
|
4010 |
|
4011 // Support: IE8 Only |
|
4012 // IE8 does not support the form attribute and when it is supplied. It overwrites the form prop |
|
4013 // with a string, so we need to find the proper form. |
|
4014 var form = $.fn._form = function() { |
|
4015 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); |
|
4016 }; |
|
4017 |
|
4018 |
|
4019 /*! |
|
4020 * jQuery UI Form Reset Mixin 1.13.2 |
|
4021 * http://jqueryui.com |
|
4022 * |
|
4023 * Copyright jQuery Foundation and other contributors |
|
4024 * Released under the MIT license. |
|
4025 * http://jquery.org/license |
|
4026 */ |
|
4027 |
|
4028 //>>label: Form Reset Mixin |
|
4029 //>>group: Core |
|
4030 //>>description: Refresh input widgets when their form is reset |
|
4031 //>>docs: http://api.jqueryui.com/form-reset-mixin/ |
|
4032 |
|
4033 |
|
4034 var formResetMixin = $.ui.formResetMixin = { |
|
4035 _formResetHandler: function() { |
|
4036 var form = $( this ); |
|
4037 |
|
4038 // Wait for the form reset to actually happen before refreshing |
|
4039 setTimeout( function() { |
|
4040 var instances = form.data( "ui-form-reset-instances" ); |
|
4041 $.each( instances, function() { |
|
4042 this.refresh(); |
|
4043 } ); |
|
4044 } ); |
|
4045 }, |
|
4046 |
|
4047 _bindFormResetHandler: function() { |
|
4048 this.form = this.element._form(); |
|
4049 if ( !this.form.length ) { |
|
4050 return; |
|
4051 } |
|
4052 |
|
4053 var instances = this.form.data( "ui-form-reset-instances" ) || []; |
|
4054 if ( !instances.length ) { |
|
4055 |
|
4056 // We don't use _on() here because we use a single event handler per form |
|
4057 this.form.on( "reset.ui-form-reset", this._formResetHandler ); |
|
4058 } |
|
4059 instances.push( this ); |
|
4060 this.form.data( "ui-form-reset-instances", instances ); |
|
4061 }, |
|
4062 |
|
4063 _unbindFormResetHandler: function() { |
|
4064 if ( !this.form.length ) { |
|
4065 return; |
|
4066 } |
|
4067 |
|
4068 var instances = this.form.data( "ui-form-reset-instances" ); |
|
4069 instances.splice( $.inArray( this, instances ), 1 ); |
|
4070 if ( instances.length ) { |
|
4071 this.form.data( "ui-form-reset-instances", instances ); |
|
4072 } else { |
|
4073 this.form |
|
4074 .removeData( "ui-form-reset-instances" ) |
|
4075 .off( "reset.ui-form-reset" ); |
|
4076 } |
|
4077 } |
|
4078 }; |
|
4079 |
|
4080 |
|
4081 /*! |
|
4082 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 |
|
4083 * http://jqueryui.com |
|
4084 * |
|
4085 * Copyright jQuery Foundation and other contributors |
|
4086 * Released under the MIT license. |
39 * http://jquery.org/license |
4087 * http://jquery.org/license |
40 * |
4088 * |
41 * http://docs.jquery.com/UI/Mouse |
4089 */ |
|
4090 |
|
4091 //>>label: jQuery 1.8+ Support |
|
4092 //>>group: Core |
|
4093 //>>description: Support version 1.8.x and newer of jQuery core |
|
4094 |
|
4095 |
|
4096 // Support: jQuery 1.9.x or older |
|
4097 // $.expr[ ":" ] is deprecated. |
|
4098 if ( !$.expr.pseudos ) { |
|
4099 $.expr.pseudos = $.expr[ ":" ]; |
|
4100 } |
|
4101 |
|
4102 // Support: jQuery 1.11.x or older |
|
4103 // $.unique has been renamed to $.uniqueSort |
|
4104 if ( !$.uniqueSort ) { |
|
4105 $.uniqueSort = $.unique; |
|
4106 } |
|
4107 |
|
4108 // Support: jQuery 2.2.x or older. |
|
4109 // This method has been defined in jQuery 3.0.0. |
|
4110 // Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js |
|
4111 if ( !$.escapeSelector ) { |
|
4112 |
|
4113 // CSS string/identifier serialization |
|
4114 // https://drafts.csswg.org/cssom/#common-serializing-idioms |
|
4115 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; |
|
4116 |
|
4117 var fcssescape = function( ch, asCodePoint ) { |
|
4118 if ( asCodePoint ) { |
|
4119 |
|
4120 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER |
|
4121 if ( ch === "\0" ) { |
|
4122 return "\uFFFD"; |
|
4123 } |
|
4124 |
|
4125 // Control characters and (dependent upon position) numbers get escaped as code points |
|
4126 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; |
|
4127 } |
|
4128 |
|
4129 // Other potentially-special ASCII characters get backslash-escaped |
|
4130 return "\\" + ch; |
|
4131 }; |
|
4132 |
|
4133 $.escapeSelector = function( sel ) { |
|
4134 return ( sel + "" ).replace( rcssescape, fcssescape ); |
|
4135 }; |
|
4136 } |
|
4137 |
|
4138 // Support: jQuery 3.4.x or older |
|
4139 // These methods have been defined in jQuery 3.5.0. |
|
4140 if ( !$.fn.even || !$.fn.odd ) { |
|
4141 $.fn.extend( { |
|
4142 even: function() { |
|
4143 return this.filter( function( i ) { |
|
4144 return i % 2 === 0; |
|
4145 } ); |
|
4146 }, |
|
4147 odd: function() { |
|
4148 return this.filter( function( i ) { |
|
4149 return i % 2 === 1; |
|
4150 } ); |
|
4151 } |
|
4152 } ); |
|
4153 } |
|
4154 |
|
4155 ; |
|
4156 /*! |
|
4157 * jQuery UI Keycode 1.13.2 |
|
4158 * http://jqueryui.com |
42 * |
4159 * |
43 * Depends: |
4160 * Copyright jQuery Foundation and other contributors |
44 * jquery.ui.widget.js |
4161 * Released under the MIT license. |
|
4162 * http://jquery.org/license |
45 */ |
4163 */ |
46 (function(b){var d=false;b(document).mouseup(function(){d=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(c){return a._mouseDown(c)}).bind("click."+this.widgetName,function(c){if(true===b.data(c.target,a.widgetName+".preventClickEvent")){b.removeData(c.target,a.widgetName+".preventClickEvent");c.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+ |
4164 |
47 this.widgetName)},_mouseDown:function(a){if(!d){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var c=this,f=a.which==1,g=typeof this.options.cancel=="string"&&a.target.nodeName?b(a.target).closest(this.options.cancel).length:false;if(!f||g||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){c.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted= |
4165 //>>label: Keycode |
48 this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();return true}}true===b.data(a.target,this.widgetName+".preventClickEvent")&&b.removeData(a.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(e){return c._mouseMove(e)};this._mouseUpDelegate=function(e){return c._mouseUp(e)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return d=true}},_mouseMove:function(a){if(b.browser.msie&& |
4166 //>>group: Core |
49 !(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted= |
4167 //>>description: Provide keycodes as keynames |
50 false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); |
4168 //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ |
51 ;/* |
4169 |
52 * jQuery UI Sortable 1.8.16 |
4170 |
|
4171 var keycode = $.ui.keyCode = { |
|
4172 BACKSPACE: 8, |
|
4173 COMMA: 188, |
|
4174 DELETE: 46, |
|
4175 DOWN: 40, |
|
4176 END: 35, |
|
4177 ENTER: 13, |
|
4178 ESCAPE: 27, |
|
4179 HOME: 36, |
|
4180 LEFT: 37, |
|
4181 PAGE_DOWN: 34, |
|
4182 PAGE_UP: 33, |
|
4183 PERIOD: 190, |
|
4184 RIGHT: 39, |
|
4185 SPACE: 32, |
|
4186 TAB: 9, |
|
4187 UP: 38 |
|
4188 }; |
|
4189 |
|
4190 |
|
4191 /*! |
|
4192 * jQuery UI Labels 1.13.2 |
|
4193 * http://jqueryui.com |
53 * |
4194 * |
54 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) |
4195 * Copyright jQuery Foundation and other contributors |
55 * Dual licensed under the MIT or GPL Version 2 licenses. |
4196 * Released under the MIT license. |
56 * http://jquery.org/license |
4197 * http://jquery.org/license |
|
4198 */ |
|
4199 |
|
4200 //>>label: labels |
|
4201 //>>group: Core |
|
4202 //>>description: Find all the labels associated with a given input |
|
4203 //>>docs: http://api.jqueryui.com/labels/ |
|
4204 |
|
4205 |
|
4206 var labels = $.fn.labels = function() { |
|
4207 var ancestor, selector, id, labels, ancestors; |
|
4208 |
|
4209 if ( !this.length ) { |
|
4210 return this.pushStack( [] ); |
|
4211 } |
|
4212 |
|
4213 // Check control.labels first |
|
4214 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { |
|
4215 return this.pushStack( this[ 0 ].labels ); |
|
4216 } |
|
4217 |
|
4218 // Support: IE <= 11, FF <= 37, Android <= 2.3 only |
|
4219 // Above browsers do not support control.labels. Everything below is to support them |
|
4220 // as well as document fragments. control.labels does not work on document fragments |
|
4221 labels = this.eq( 0 ).parents( "label" ); |
|
4222 |
|
4223 // Look for the label based on the id |
|
4224 id = this.attr( "id" ); |
|
4225 if ( id ) { |
|
4226 |
|
4227 // We don't search against the document in case the element |
|
4228 // is disconnected from the DOM |
|
4229 ancestor = this.eq( 0 ).parents().last(); |
|
4230 |
|
4231 // Get a full set of top level ancestors |
|
4232 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); |
|
4233 |
|
4234 // Create a selector for the label based on the id |
|
4235 selector = "label[for='" + $.escapeSelector( id ) + "']"; |
|
4236 |
|
4237 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); |
|
4238 |
|
4239 } |
|
4240 |
|
4241 // Return whatever we have found for labels |
|
4242 return this.pushStack( labels ); |
|
4243 }; |
|
4244 |
|
4245 |
|
4246 /*! |
|
4247 * jQuery UI Scroll Parent 1.13.2 |
|
4248 * http://jqueryui.com |
57 * |
4249 * |
58 * http://docs.jquery.com/UI/Sortables |
4250 * Copyright jQuery Foundation and other contributors |
|
4251 * Released under the MIT license. |
|
4252 * http://jquery.org/license |
|
4253 */ |
|
4254 |
|
4255 //>>label: scrollParent |
|
4256 //>>group: Core |
|
4257 //>>description: Get the closest ancestor element that is scrollable. |
|
4258 //>>docs: http://api.jqueryui.com/scrollParent/ |
|
4259 |
|
4260 |
|
4261 var scrollParent = $.fn.scrollParent = function( includeHidden ) { |
|
4262 var position = this.css( "position" ), |
|
4263 excludeStaticParent = position === "absolute", |
|
4264 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, |
|
4265 scrollParent = this.parents().filter( function() { |
|
4266 var parent = $( this ); |
|
4267 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { |
|
4268 return false; |
|
4269 } |
|
4270 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + |
|
4271 parent.css( "overflow-x" ) ); |
|
4272 } ).eq( 0 ); |
|
4273 |
|
4274 return position === "fixed" || !scrollParent.length ? |
|
4275 $( this[ 0 ].ownerDocument || document ) : |
|
4276 scrollParent; |
|
4277 }; |
|
4278 |
|
4279 |
|
4280 /*! |
|
4281 * jQuery UI Tabbable 1.13.2 |
|
4282 * http://jqueryui.com |
59 * |
4283 * |
60 * Depends: |
4284 * Copyright jQuery Foundation and other contributors |
61 * jquery.ui.core.js |
4285 * Released under the MIT license. |
62 * jquery.ui.mouse.js |
4286 * http://jquery.org/license |
63 * jquery.ui.widget.js |
|
64 */ |
4287 */ |
65 (function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable"); |
4288 |
66 this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a=== |
4289 //>>label: :tabbable Selector |
67 "disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&& |
4290 //>>group: Core |
68 !b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top, |
4291 //>>description: Selects elements which can be tabbed to. |
69 left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; |
4292 //>>docs: http://api.jqueryui.com/tabbable-selector/ |
70 this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!= |
4293 |
71 document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a); |
4294 |
72 return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top< |
4295 var tabbable = $.extend( $.expr.pseudos, { |
73 b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()- |
4296 tabbable: function( element ) { |
74 b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this, |
4297 var tabIndex = $.attr( element, "tabindex" ), |
75 a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0], |
4298 hasTabindex = tabIndex != null; |
76 e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset(); |
4299 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); |
77 c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): |
4300 } |
78 this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null, |
4301 } ); |
79 dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")}, |
4302 |
80 toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers|| |
4303 |
81 this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection(); |
4304 /*! |
82 var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)}, |
4305 * jQuery UI Unique ID 1.13.2 |
83 _getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith(); |
4306 * http://jqueryui.com |
84 if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), |
4307 * |
85 this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element), |
4308 * Copyright jQuery Foundation and other contributors |
86 this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&& |
4309 * Released under the MIT license. |
87 this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b= |
4310 * http://jquery.org/license |
88 this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f= |
4311 */ |
89 d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")|| |
4312 |
90 0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out", |
4313 //>>label: uniqueId |
91 a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h- |
4314 //>>group: Core |
92 f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b= |
4315 //>>description: Functions to generate and remove uniqueId's |
93 this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width== |
4316 //>>docs: http://api.jqueryui.com/uniqueId/ |
94 ""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top= |
4317 |
95 this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a= |
4318 |
96 {top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"), |
4319 var uniqueId = $.fn.extend( { |
97 10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"? |
4320 uniqueId: ( function() { |
98 document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"), |
4321 var uuid = 0; |
99 10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b= |
4322 |
100 this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&& |
4323 return function() { |
101 this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset(); |
4324 return this.each( function() { |
102 var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g- |
4325 if ( !this.id ) { |
103 this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g- |
4326 this.id = "ui-id-" + ( ++uuid ); |
104 this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0], |
4327 } |
105 this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]= |
4328 } ); |
106 "";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove", |
4329 }; |
107 f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this, |
4330 } )(), |
108 this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop", |
4331 |
109 a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()}, |
4332 removeUniqueId: function() { |
110 _uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.16"})})(jQuery); |
4333 return this.each( function() { |
111 ; |
4334 if ( /^ui-id-\d+$/.test( this.id ) ) { |
|
4335 $( this ).removeAttr( "id" ); |
|
4336 } |
|
4337 } ); |
|
4338 } |
|
4339 } ); |
|
4340 |
|
4341 |
|
4342 /*! |
|
4343 * jQuery UI Accordion 1.13.2 |
|
4344 * http://jqueryui.com |
|
4345 * |
|
4346 * Copyright jQuery Foundation and other contributors |
|
4347 * Released under the MIT license. |
|
4348 * http://jquery.org/license |
|
4349 */ |
|
4350 |
|
4351 //>>label: Accordion |
|
4352 //>>group: Widgets |
|
4353 /* eslint-disable max-len */ |
|
4354 //>>description: Displays collapsible content panels for presenting information in a limited amount of space. |
|
4355 /* eslint-enable max-len */ |
|
4356 //>>docs: http://api.jqueryui.com/accordion/ |
|
4357 //>>demos: http://jqueryui.com/accordion/ |
|
4358 //>>css.structure: ../../themes/base/core.css |
|
4359 //>>css.structure: ../../themes/base/accordion.css |
|
4360 //>>css.theme: ../../themes/base/theme.css |
|
4361 |
|
4362 |
|
4363 var widgetsAccordion = $.widget( "ui.accordion", { |
|
4364 version: "1.13.2", |
|
4365 options: { |
|
4366 active: 0, |
|
4367 animate: {}, |
|
4368 classes: { |
|
4369 "ui-accordion-header": "ui-corner-top", |
|
4370 "ui-accordion-header-collapsed": "ui-corner-all", |
|
4371 "ui-accordion-content": "ui-corner-bottom" |
|
4372 }, |
|
4373 collapsible: false, |
|
4374 event: "click", |
|
4375 header: function( elem ) { |
|
4376 return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); |
|
4377 }, |
|
4378 heightStyle: "auto", |
|
4379 icons: { |
|
4380 activeHeader: "ui-icon-triangle-1-s", |
|
4381 header: "ui-icon-triangle-1-e" |
|
4382 }, |
|
4383 |
|
4384 // Callbacks |
|
4385 activate: null, |
|
4386 beforeActivate: null |
|
4387 }, |
|
4388 |
|
4389 hideProps: { |
|
4390 borderTopWidth: "hide", |
|
4391 borderBottomWidth: "hide", |
|
4392 paddingTop: "hide", |
|
4393 paddingBottom: "hide", |
|
4394 height: "hide" |
|
4395 }, |
|
4396 |
|
4397 showProps: { |
|
4398 borderTopWidth: "show", |
|
4399 borderBottomWidth: "show", |
|
4400 paddingTop: "show", |
|
4401 paddingBottom: "show", |
|
4402 height: "show" |
|
4403 }, |
|
4404 |
|
4405 _create: function() { |
|
4406 var options = this.options; |
|
4407 |
|
4408 this.prevShow = this.prevHide = $(); |
|
4409 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); |
|
4410 this.element.attr( "role", "tablist" ); |
|
4411 |
|
4412 // Don't allow collapsible: false and active: false / null |
|
4413 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { |
|
4414 options.active = 0; |
|
4415 } |
|
4416 |
|
4417 this._processPanels(); |
|
4418 |
|
4419 // handle negative values |
|
4420 if ( options.active < 0 ) { |
|
4421 options.active += this.headers.length; |
|
4422 } |
|
4423 this._refresh(); |
|
4424 }, |
|
4425 |
|
4426 _getCreateEventData: function() { |
|
4427 return { |
|
4428 header: this.active, |
|
4429 panel: !this.active.length ? $() : this.active.next() |
|
4430 }; |
|
4431 }, |
|
4432 |
|
4433 _createIcons: function() { |
|
4434 var icon, children, |
|
4435 icons = this.options.icons; |
|
4436 |
|
4437 if ( icons ) { |
|
4438 icon = $( "<span>" ); |
|
4439 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); |
|
4440 icon.prependTo( this.headers ); |
|
4441 children = this.active.children( ".ui-accordion-header-icon" ); |
|
4442 this._removeClass( children, icons.header ) |
|
4443 ._addClass( children, null, icons.activeHeader ) |
|
4444 ._addClass( this.headers, "ui-accordion-icons" ); |
|
4445 } |
|
4446 }, |
|
4447 |
|
4448 _destroyIcons: function() { |
|
4449 this._removeClass( this.headers, "ui-accordion-icons" ); |
|
4450 this.headers.children( ".ui-accordion-header-icon" ).remove(); |
|
4451 }, |
|
4452 |
|
4453 _destroy: function() { |
|
4454 var contents; |
|
4455 |
|
4456 // Clean up main element |
|
4457 this.element.removeAttr( "role" ); |
|
4458 |
|
4459 // Clean up headers |
|
4460 this.headers |
|
4461 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) |
|
4462 .removeUniqueId(); |
|
4463 |
|
4464 this._destroyIcons(); |
|
4465 |
|
4466 // Clean up content panels |
|
4467 contents = this.headers.next() |
|
4468 .css( "display", "" ) |
|
4469 .removeAttr( "role aria-hidden aria-labelledby" ) |
|
4470 .removeUniqueId(); |
|
4471 |
|
4472 if ( this.options.heightStyle !== "content" ) { |
|
4473 contents.css( "height", "" ); |
|
4474 } |
|
4475 }, |
|
4476 |
|
4477 _setOption: function( key, value ) { |
|
4478 if ( key === "active" ) { |
|
4479 |
|
4480 // _activate() will handle invalid values and update this.options |
|
4481 this._activate( value ); |
|
4482 return; |
|
4483 } |
|
4484 |
|
4485 if ( key === "event" ) { |
|
4486 if ( this.options.event ) { |
|
4487 this._off( this.headers, this.options.event ); |
|
4488 } |
|
4489 this._setupEvents( value ); |
|
4490 } |
|
4491 |
|
4492 this._super( key, value ); |
|
4493 |
|
4494 // Setting collapsible: false while collapsed; open first panel |
|
4495 if ( key === "collapsible" && !value && this.options.active === false ) { |
|
4496 this._activate( 0 ); |
|
4497 } |
|
4498 |
|
4499 if ( key === "icons" ) { |
|
4500 this._destroyIcons(); |
|
4501 if ( value ) { |
|
4502 this._createIcons(); |
|
4503 } |
|
4504 } |
|
4505 }, |
|
4506 |
|
4507 _setOptionDisabled: function( value ) { |
|
4508 this._super( value ); |
|
4509 |
|
4510 this.element.attr( "aria-disabled", value ); |
|
4511 |
|
4512 // Support: IE8 Only |
|
4513 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE |
|
4514 // so we need to add the disabled class to the headers and panels |
|
4515 this._toggleClass( null, "ui-state-disabled", !!value ); |
|
4516 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", |
|
4517 !!value ); |
|
4518 }, |
|
4519 |
|
4520 _keydown: function( event ) { |
|
4521 if ( event.altKey || event.ctrlKey ) { |
|
4522 return; |
|
4523 } |
|
4524 |
|
4525 var keyCode = $.ui.keyCode, |
|
4526 length = this.headers.length, |
|
4527 currentIndex = this.headers.index( event.target ), |
|
4528 toFocus = false; |
|
4529 |
|
4530 switch ( event.keyCode ) { |
|
4531 case keyCode.RIGHT: |
|
4532 case keyCode.DOWN: |
|
4533 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; |
|
4534 break; |
|
4535 case keyCode.LEFT: |
|
4536 case keyCode.UP: |
|
4537 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; |
|
4538 break; |
|
4539 case keyCode.SPACE: |
|
4540 case keyCode.ENTER: |
|
4541 this._eventHandler( event ); |
|
4542 break; |
|
4543 case keyCode.HOME: |
|
4544 toFocus = this.headers[ 0 ]; |
|
4545 break; |
|
4546 case keyCode.END: |
|
4547 toFocus = this.headers[ length - 1 ]; |
|
4548 break; |
|
4549 } |
|
4550 |
|
4551 if ( toFocus ) { |
|
4552 $( event.target ).attr( "tabIndex", -1 ); |
|
4553 $( toFocus ).attr( "tabIndex", 0 ); |
|
4554 $( toFocus ).trigger( "focus" ); |
|
4555 event.preventDefault(); |
|
4556 } |
|
4557 }, |
|
4558 |
|
4559 _panelKeyDown: function( event ) { |
|
4560 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { |
|
4561 $( event.currentTarget ).prev().trigger( "focus" ); |
|
4562 } |
|
4563 }, |
|
4564 |
|
4565 refresh: function() { |
|
4566 var options = this.options; |
|
4567 this._processPanels(); |
|
4568 |
|
4569 // Was collapsed or no panel |
|
4570 if ( ( options.active === false && options.collapsible === true ) || |
|
4571 !this.headers.length ) { |
|
4572 options.active = false; |
|
4573 this.active = $(); |
|
4574 |
|
4575 // active false only when collapsible is true |
|
4576 } else if ( options.active === false ) { |
|
4577 this._activate( 0 ); |
|
4578 |
|
4579 // was active, but active panel is gone |
|
4580 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { |
|
4581 |
|
4582 // all remaining panel are disabled |
|
4583 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { |
|
4584 options.active = false; |
|
4585 this.active = $(); |
|
4586 |
|
4587 // activate previous panel |
|
4588 } else { |
|
4589 this._activate( Math.max( 0, options.active - 1 ) ); |
|
4590 } |
|
4591 |
|
4592 // was active, active panel still exists |
|
4593 } else { |
|
4594 |
|
4595 // make sure active index is correct |
|
4596 options.active = this.headers.index( this.active ); |
|
4597 } |
|
4598 |
|
4599 this._destroyIcons(); |
|
4600 |
|
4601 this._refresh(); |
|
4602 }, |
|
4603 |
|
4604 _processPanels: function() { |
|
4605 var prevHeaders = this.headers, |
|
4606 prevPanels = this.panels; |
|
4607 |
|
4608 if ( typeof this.options.header === "function" ) { |
|
4609 this.headers = this.options.header( this.element ); |
|
4610 } else { |
|
4611 this.headers = this.element.find( this.options.header ); |
|
4612 } |
|
4613 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", |
|
4614 "ui-state-default" ); |
|
4615 |
|
4616 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); |
|
4617 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); |
|
4618 |
|
4619 // Avoid memory leaks (#10056) |
|
4620 if ( prevPanels ) { |
|
4621 this._off( prevHeaders.not( this.headers ) ); |
|
4622 this._off( prevPanels.not( this.panels ) ); |
|
4623 } |
|
4624 }, |
|
4625 |
|
4626 _refresh: function() { |
|
4627 var maxHeight, |
|
4628 options = this.options, |
|
4629 heightStyle = options.heightStyle, |
|
4630 parent = this.element.parent(); |
|
4631 |
|
4632 this.active = this._findActive( options.active ); |
|
4633 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) |
|
4634 ._removeClass( this.active, "ui-accordion-header-collapsed" ); |
|
4635 this._addClass( this.active.next(), "ui-accordion-content-active" ); |
|
4636 this.active.next().show(); |
|
4637 |
|
4638 this.headers |
|
4639 .attr( "role", "tab" ) |
|
4640 .each( function() { |
|
4641 var header = $( this ), |
|
4642 headerId = header.uniqueId().attr( "id" ), |
|
4643 panel = header.next(), |
|
4644 panelId = panel.uniqueId().attr( "id" ); |
|
4645 header.attr( "aria-controls", panelId ); |
|
4646 panel.attr( "aria-labelledby", headerId ); |
|
4647 } ) |
|
4648 .next() |
|
4649 .attr( "role", "tabpanel" ); |
|
4650 |
|
4651 this.headers |
|
4652 .not( this.active ) |
|
4653 .attr( { |
|
4654 "aria-selected": "false", |
|
4655 "aria-expanded": "false", |
|
4656 tabIndex: -1 |
|
4657 } ) |
|
4658 .next() |
|
4659 .attr( { |
|
4660 "aria-hidden": "true" |
|
4661 } ) |
|
4662 .hide(); |
|
4663 |
|
4664 // Make sure at least one header is in the tab order |
|
4665 if ( !this.active.length ) { |
|
4666 this.headers.eq( 0 ).attr( "tabIndex", 0 ); |
|
4667 } else { |
|
4668 this.active.attr( { |
|
4669 "aria-selected": "true", |
|
4670 "aria-expanded": "true", |
|
4671 tabIndex: 0 |
|
4672 } ) |
|
4673 .next() |
|
4674 .attr( { |
|
4675 "aria-hidden": "false" |
|
4676 } ); |
|
4677 } |
|
4678 |
|
4679 this._createIcons(); |
|
4680 |
|
4681 this._setupEvents( options.event ); |
|
4682 |
|
4683 if ( heightStyle === "fill" ) { |
|
4684 maxHeight = parent.height(); |
|
4685 this.element.siblings( ":visible" ).each( function() { |
|
4686 var elem = $( this ), |
|
4687 position = elem.css( "position" ); |
|
4688 |
|
4689 if ( position === "absolute" || position === "fixed" ) { |
|
4690 return; |
|
4691 } |
|
4692 maxHeight -= elem.outerHeight( true ); |
|
4693 } ); |
|
4694 |
|
4695 this.headers.each( function() { |
|
4696 maxHeight -= $( this ).outerHeight( true ); |
|
4697 } ); |
|
4698 |
|
4699 this.headers.next() |
|
4700 .each( function() { |
|
4701 $( this ).height( Math.max( 0, maxHeight - |
|
4702 $( this ).innerHeight() + $( this ).height() ) ); |
|
4703 } ) |
|
4704 .css( "overflow", "auto" ); |
|
4705 } else if ( heightStyle === "auto" ) { |
|
4706 maxHeight = 0; |
|
4707 this.headers.next() |
|
4708 .each( function() { |
|
4709 var isVisible = $( this ).is( ":visible" ); |
|
4710 if ( !isVisible ) { |
|
4711 $( this ).show(); |
|
4712 } |
|
4713 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); |
|
4714 if ( !isVisible ) { |
|
4715 $( this ).hide(); |
|
4716 } |
|
4717 } ) |
|
4718 .height( maxHeight ); |
|
4719 } |
|
4720 }, |
|
4721 |
|
4722 _activate: function( index ) { |
|
4723 var active = this._findActive( index )[ 0 ]; |
|
4724 |
|
4725 // Trying to activate the already active panel |
|
4726 if ( active === this.active[ 0 ] ) { |
|
4727 return; |
|
4728 } |
|
4729 |
|
4730 // Trying to collapse, simulate a click on the currently active header |
|
4731 active = active || this.active[ 0 ]; |
|
4732 |
|
4733 this._eventHandler( { |
|
4734 target: active, |
|
4735 currentTarget: active, |
|
4736 preventDefault: $.noop |
|
4737 } ); |
|
4738 }, |
|
4739 |
|
4740 _findActive: function( selector ) { |
|
4741 return typeof selector === "number" ? this.headers.eq( selector ) : $(); |
|
4742 }, |
|
4743 |
|
4744 _setupEvents: function( event ) { |
|
4745 var events = { |
|
4746 keydown: "_keydown" |
|
4747 }; |
|
4748 if ( event ) { |
|
4749 $.each( event.split( " " ), function( index, eventName ) { |
|
4750 events[ eventName ] = "_eventHandler"; |
|
4751 } ); |
|
4752 } |
|
4753 |
|
4754 this._off( this.headers.add( this.headers.next() ) ); |
|
4755 this._on( this.headers, events ); |
|
4756 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); |
|
4757 this._hoverable( this.headers ); |
|
4758 this._focusable( this.headers ); |
|
4759 }, |
|
4760 |
|
4761 _eventHandler: function( event ) { |
|
4762 var activeChildren, clickedChildren, |
|
4763 options = this.options, |
|
4764 active = this.active, |
|
4765 clicked = $( event.currentTarget ), |
|
4766 clickedIsActive = clicked[ 0 ] === active[ 0 ], |
|
4767 collapsing = clickedIsActive && options.collapsible, |
|
4768 toShow = collapsing ? $() : clicked.next(), |
|
4769 toHide = active.next(), |
|
4770 eventData = { |
|
4771 oldHeader: active, |
|
4772 oldPanel: toHide, |
|
4773 newHeader: collapsing ? $() : clicked, |
|
4774 newPanel: toShow |
|
4775 }; |
|
4776 |
|
4777 event.preventDefault(); |
|
4778 |
|
4779 if ( |
|
4780 |
|
4781 // click on active header, but not collapsible |
|
4782 ( clickedIsActive && !options.collapsible ) || |
|
4783 |
|
4784 // allow canceling activation |
|
4785 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { |
|
4786 return; |
|
4787 } |
|
4788 |
|
4789 options.active = collapsing ? false : this.headers.index( clicked ); |
|
4790 |
|
4791 // When the call to ._toggle() comes after the class changes |
|
4792 // it causes a very odd bug in IE 8 (see #6720) |
|
4793 this.active = clickedIsActive ? $() : clicked; |
|
4794 this._toggle( eventData ); |
|
4795 |
|
4796 // Switch classes |
|
4797 // corner classes on the previously active header stay after the animation |
|
4798 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); |
|
4799 if ( options.icons ) { |
|
4800 activeChildren = active.children( ".ui-accordion-header-icon" ); |
|
4801 this._removeClass( activeChildren, null, options.icons.activeHeader ) |
|
4802 ._addClass( activeChildren, null, options.icons.header ); |
|
4803 } |
|
4804 |
|
4805 if ( !clickedIsActive ) { |
|
4806 this._removeClass( clicked, "ui-accordion-header-collapsed" ) |
|
4807 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); |
|
4808 if ( options.icons ) { |
|
4809 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); |
|
4810 this._removeClass( clickedChildren, null, options.icons.header ) |
|
4811 ._addClass( clickedChildren, null, options.icons.activeHeader ); |
|
4812 } |
|
4813 |
|
4814 this._addClass( clicked.next(), "ui-accordion-content-active" ); |
|
4815 } |
|
4816 }, |
|
4817 |
|
4818 _toggle: function( data ) { |
|
4819 var toShow = data.newPanel, |
|
4820 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; |
|
4821 |
|
4822 // Handle activating a panel during the animation for another activation |
|
4823 this.prevShow.add( this.prevHide ).stop( true, true ); |
|
4824 this.prevShow = toShow; |
|
4825 this.prevHide = toHide; |
|
4826 |
|
4827 if ( this.options.animate ) { |
|
4828 this._animate( toShow, toHide, data ); |
|
4829 } else { |
|
4830 toHide.hide(); |
|
4831 toShow.show(); |
|
4832 this._toggleComplete( data ); |
|
4833 } |
|
4834 |
|
4835 toHide.attr( { |
|
4836 "aria-hidden": "true" |
|
4837 } ); |
|
4838 toHide.prev().attr( { |
|
4839 "aria-selected": "false", |
|
4840 "aria-expanded": "false" |
|
4841 } ); |
|
4842 |
|
4843 // if we're switching panels, remove the old header from the tab order |
|
4844 // if we're opening from collapsed state, remove the previous header from the tab order |
|
4845 // if we're collapsing, then keep the collapsing header in the tab order |
|
4846 if ( toShow.length && toHide.length ) { |
|
4847 toHide.prev().attr( { |
|
4848 "tabIndex": -1, |
|
4849 "aria-expanded": "false" |
|
4850 } ); |
|
4851 } else if ( toShow.length ) { |
|
4852 this.headers.filter( function() { |
|
4853 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; |
|
4854 } ) |
|
4855 .attr( "tabIndex", -1 ); |
|
4856 } |
|
4857 |
|
4858 toShow |
|
4859 .attr( "aria-hidden", "false" ) |
|
4860 .prev() |
|
4861 .attr( { |
|
4862 "aria-selected": "true", |
|
4863 "aria-expanded": "true", |
|
4864 tabIndex: 0 |
|
4865 } ); |
|
4866 }, |
|
4867 |
|
4868 _animate: function( toShow, toHide, data ) { |
|
4869 var total, easing, duration, |
|
4870 that = this, |
|
4871 adjust = 0, |
|
4872 boxSizing = toShow.css( "box-sizing" ), |
|
4873 down = toShow.length && |
|
4874 ( !toHide.length || ( toShow.index() < toHide.index() ) ), |
|
4875 animate = this.options.animate || {}, |
|
4876 options = down && animate.down || animate, |
|
4877 complete = function() { |
|
4878 that._toggleComplete( data ); |
|
4879 }; |
|
4880 |
|
4881 if ( typeof options === "number" ) { |
|
4882 duration = options; |
|
4883 } |
|
4884 if ( typeof options === "string" ) { |
|
4885 easing = options; |
|
4886 } |
|
4887 |
|
4888 // fall back from options to animation in case of partial down settings |
|
4889 easing = easing || options.easing || animate.easing; |
|
4890 duration = duration || options.duration || animate.duration; |
|
4891 |
|
4892 if ( !toHide.length ) { |
|
4893 return toShow.animate( this.showProps, duration, easing, complete ); |
|
4894 } |
|
4895 if ( !toShow.length ) { |
|
4896 return toHide.animate( this.hideProps, duration, easing, complete ); |
|
4897 } |
|
4898 |
|
4899 total = toShow.show().outerHeight(); |
|
4900 toHide.animate( this.hideProps, { |
|
4901 duration: duration, |
|
4902 easing: easing, |
|
4903 step: function( now, fx ) { |
|
4904 fx.now = Math.round( now ); |
|
4905 } |
|
4906 } ); |
|
4907 toShow |
|
4908 .hide() |
|
4909 .animate( this.showProps, { |
|
4910 duration: duration, |
|
4911 easing: easing, |
|
4912 complete: complete, |
|
4913 step: function( now, fx ) { |
|
4914 fx.now = Math.round( now ); |
|
4915 if ( fx.prop !== "height" ) { |
|
4916 if ( boxSizing === "content-box" ) { |
|
4917 adjust += fx.now; |
|
4918 } |
|
4919 } else if ( that.options.heightStyle !== "content" ) { |
|
4920 fx.now = Math.round( total - toHide.outerHeight() - adjust ); |
|
4921 adjust = 0; |
|
4922 } |
|
4923 } |
|
4924 } ); |
|
4925 }, |
|
4926 |
|
4927 _toggleComplete: function( data ) { |
|
4928 var toHide = data.oldPanel, |
|
4929 prev = toHide.prev(); |
|
4930 |
|
4931 this._removeClass( toHide, "ui-accordion-content-active" ); |
|
4932 this._removeClass( prev, "ui-accordion-header-active" ) |
|
4933 ._addClass( prev, "ui-accordion-header-collapsed" ); |
|
4934 |
|
4935 // Work around for rendering bug in IE (#5421) |
|
4936 if ( toHide.length ) { |
|
4937 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; |
|
4938 } |
|
4939 this._trigger( "activate", null, data ); |
|
4940 } |
|
4941 } ); |
|
4942 |
|
4943 |
|
4944 |
|
4945 var safeActiveElement = $.ui.safeActiveElement = function( document ) { |
|
4946 var activeElement; |
|
4947 |
|
4948 // Support: IE 9 only |
|
4949 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> |
|
4950 try { |
|
4951 activeElement = document.activeElement; |
|
4952 } catch ( error ) { |
|
4953 activeElement = document.body; |
|
4954 } |
|
4955 |
|
4956 // Support: IE 9 - 11 only |
|
4957 // IE may return null instead of an element |
|
4958 // Interestingly, this only seems to occur when NOT in an iframe |
|
4959 if ( !activeElement ) { |
|
4960 activeElement = document.body; |
|
4961 } |
|
4962 |
|
4963 // Support: IE 11 only |
|
4964 // IE11 returns a seemingly empty object in some cases when accessing |
|
4965 // document.activeElement from an <iframe> |
|
4966 if ( !activeElement.nodeName ) { |
|
4967 activeElement = document.body; |
|
4968 } |
|
4969 |
|
4970 return activeElement; |
|
4971 }; |
|
4972 |
|
4973 |
|
4974 /*! |
|
4975 * jQuery UI Menu 1.13.2 |
|
4976 * http://jqueryui.com |
|
4977 * |
|
4978 * Copyright jQuery Foundation and other contributors |
|
4979 * Released under the MIT license. |
|
4980 * http://jquery.org/license |
|
4981 */ |
|
4982 |
|
4983 //>>label: Menu |
|
4984 //>>group: Widgets |
|
4985 //>>description: Creates nestable menus. |
|
4986 //>>docs: http://api.jqueryui.com/menu/ |
|
4987 //>>demos: http://jqueryui.com/menu/ |
|
4988 //>>css.structure: ../../themes/base/core.css |
|
4989 //>>css.structure: ../../themes/base/menu.css |
|
4990 //>>css.theme: ../../themes/base/theme.css |
|
4991 |
|
4992 |
|
4993 var widgetsMenu = $.widget( "ui.menu", { |
|
4994 version: "1.13.2", |
|
4995 defaultElement: "<ul>", |
|
4996 delay: 300, |
|
4997 options: { |
|
4998 icons: { |
|
4999 submenu: "ui-icon-caret-1-e" |
|
5000 }, |
|
5001 items: "> *", |
|
5002 menus: "ul", |
|
5003 position: { |
|
5004 my: "left top", |
|
5005 at: "right top" |
|
5006 }, |
|
5007 role: "menu", |
|
5008 |
|
5009 // Callbacks |
|
5010 blur: null, |
|
5011 focus: null, |
|
5012 select: null |
|
5013 }, |
|
5014 |
|
5015 _create: function() { |
|
5016 this.activeMenu = this.element; |
|
5017 |
|
5018 // Flag used to prevent firing of the click handler |
|
5019 // as the event bubbles up through nested menus |
|
5020 this.mouseHandled = false; |
|
5021 this.lastMousePosition = { x: null, y: null }; |
|
5022 this.element |
|
5023 .uniqueId() |
|
5024 .attr( { |
|
5025 role: this.options.role, |
|
5026 tabIndex: 0 |
|
5027 } ); |
|
5028 |
|
5029 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); |
|
5030 this._on( { |
|
5031 |
|
5032 // Prevent focus from sticking to links inside menu after clicking |
|
5033 // them (focus should always stay on UL during navigation). |
|
5034 "mousedown .ui-menu-item": function( event ) { |
|
5035 event.preventDefault(); |
|
5036 |
|
5037 this._activateItem( event ); |
|
5038 }, |
|
5039 "click .ui-menu-item": function( event ) { |
|
5040 var target = $( event.target ); |
|
5041 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); |
|
5042 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { |
|
5043 this.select( event ); |
|
5044 |
|
5045 // Only set the mouseHandled flag if the event will bubble, see #9469. |
|
5046 if ( !event.isPropagationStopped() ) { |
|
5047 this.mouseHandled = true; |
|
5048 } |
|
5049 |
|
5050 // Open submenu on click |
|
5051 if ( target.has( ".ui-menu" ).length ) { |
|
5052 this.expand( event ); |
|
5053 } else if ( !this.element.is( ":focus" ) && |
|
5054 active.closest( ".ui-menu" ).length ) { |
|
5055 |
|
5056 // Redirect focus to the menu |
|
5057 this.element.trigger( "focus", [ true ] ); |
|
5058 |
|
5059 // If the active item is on the top level, let it stay active. |
|
5060 // Otherwise, blur the active item since it is no longer visible. |
|
5061 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { |
|
5062 clearTimeout( this.timer ); |
|
5063 } |
|
5064 } |
|
5065 } |
|
5066 }, |
|
5067 "mouseenter .ui-menu-item": "_activateItem", |
|
5068 "mousemove .ui-menu-item": "_activateItem", |
|
5069 mouseleave: "collapseAll", |
|
5070 "mouseleave .ui-menu": "collapseAll", |
|
5071 focus: function( event, keepActiveItem ) { |
|
5072 |
|
5073 // If there's already an active item, keep it active |
|
5074 // If not, activate the first item |
|
5075 var item = this.active || this._menuItems().first(); |
|
5076 |
|
5077 if ( !keepActiveItem ) { |
|
5078 this.focus( event, item ); |
|
5079 } |
|
5080 }, |
|
5081 blur: function( event ) { |
|
5082 this._delay( function() { |
|
5083 var notContained = !$.contains( |
|
5084 this.element[ 0 ], |
|
5085 $.ui.safeActiveElement( this.document[ 0 ] ) |
|
5086 ); |
|
5087 if ( notContained ) { |
|
5088 this.collapseAll( event ); |
|
5089 } |
|
5090 } ); |
|
5091 }, |
|
5092 keydown: "_keydown" |
|
5093 } ); |
|
5094 |
|
5095 this.refresh(); |
|
5096 |
|
5097 // Clicks outside of a menu collapse any open menus |
|
5098 this._on( this.document, { |
|
5099 click: function( event ) { |
|
5100 if ( this._closeOnDocumentClick( event ) ) { |
|
5101 this.collapseAll( event, true ); |
|
5102 } |
|
5103 |
|
5104 // Reset the mouseHandled flag |
|
5105 this.mouseHandled = false; |
|
5106 } |
|
5107 } ); |
|
5108 }, |
|
5109 |
|
5110 _activateItem: function( event ) { |
|
5111 |
|
5112 // Ignore mouse events while typeahead is active, see #10458. |
|
5113 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse |
|
5114 // is over an item in the menu |
|
5115 if ( this.previousFilter ) { |
|
5116 return; |
|
5117 } |
|
5118 |
|
5119 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) |
|
5120 if ( event.clientX === this.lastMousePosition.x && |
|
5121 event.clientY === this.lastMousePosition.y ) { |
|
5122 return; |
|
5123 } |
|
5124 |
|
5125 this.lastMousePosition = { |
|
5126 x: event.clientX, |
|
5127 y: event.clientY |
|
5128 }; |
|
5129 |
|
5130 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), |
|
5131 target = $( event.currentTarget ); |
|
5132 |
|
5133 // Ignore bubbled events on parent items, see #11641 |
|
5134 if ( actualTarget[ 0 ] !== target[ 0 ] ) { |
|
5135 return; |
|
5136 } |
|
5137 |
|
5138 // If the item is already active, there's nothing to do |
|
5139 if ( target.is( ".ui-state-active" ) ) { |
|
5140 return; |
|
5141 } |
|
5142 |
|
5143 // Remove ui-state-active class from siblings of the newly focused menu item |
|
5144 // to avoid a jump caused by adjacent elements both having a class with a border |
|
5145 this._removeClass( target.siblings().children( ".ui-state-active" ), |
|
5146 null, "ui-state-active" ); |
|
5147 this.focus( event, target ); |
|
5148 }, |
|
5149 |
|
5150 _destroy: function() { |
|
5151 var items = this.element.find( ".ui-menu-item" ) |
|
5152 .removeAttr( "role aria-disabled" ), |
|
5153 submenus = items.children( ".ui-menu-item-wrapper" ) |
|
5154 .removeUniqueId() |
|
5155 .removeAttr( "tabIndex role aria-haspopup" ); |
|
5156 |
|
5157 // Destroy (sub)menus |
|
5158 this.element |
|
5159 .removeAttr( "aria-activedescendant" ) |
|
5160 .find( ".ui-menu" ).addBack() |
|
5161 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + |
|
5162 "tabIndex" ) |
|
5163 .removeUniqueId() |
|
5164 .show(); |
|
5165 |
|
5166 submenus.children().each( function() { |
|
5167 var elem = $( this ); |
|
5168 if ( elem.data( "ui-menu-submenu-caret" ) ) { |
|
5169 elem.remove(); |
|
5170 } |
|
5171 } ); |
|
5172 }, |
|
5173 |
|
5174 _keydown: function( event ) { |
|
5175 var match, prev, character, skip, |
|
5176 preventDefault = true; |
|
5177 |
|
5178 switch ( event.keyCode ) { |
|
5179 case $.ui.keyCode.PAGE_UP: |
|
5180 this.previousPage( event ); |
|
5181 break; |
|
5182 case $.ui.keyCode.PAGE_DOWN: |
|
5183 this.nextPage( event ); |
|
5184 break; |
|
5185 case $.ui.keyCode.HOME: |
|
5186 this._move( "first", "first", event ); |
|
5187 break; |
|
5188 case $.ui.keyCode.END: |
|
5189 this._move( "last", "last", event ); |
|
5190 break; |
|
5191 case $.ui.keyCode.UP: |
|
5192 this.previous( event ); |
|
5193 break; |
|
5194 case $.ui.keyCode.DOWN: |
|
5195 this.next( event ); |
|
5196 break; |
|
5197 case $.ui.keyCode.LEFT: |
|
5198 this.collapse( event ); |
|
5199 break; |
|
5200 case $.ui.keyCode.RIGHT: |
|
5201 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { |
|
5202 this.expand( event ); |
|
5203 } |
|
5204 break; |
|
5205 case $.ui.keyCode.ENTER: |
|
5206 case $.ui.keyCode.SPACE: |
|
5207 this._activate( event ); |
|
5208 break; |
|
5209 case $.ui.keyCode.ESCAPE: |
|
5210 this.collapse( event ); |
|
5211 break; |
|
5212 default: |
|
5213 preventDefault = false; |
|
5214 prev = this.previousFilter || ""; |
|
5215 skip = false; |
|
5216 |
|
5217 // Support number pad values |
|
5218 character = event.keyCode >= 96 && event.keyCode <= 105 ? |
|
5219 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); |
|
5220 |
|
5221 clearTimeout( this.filterTimer ); |
|
5222 |
|
5223 if ( character === prev ) { |
|
5224 skip = true; |
|
5225 } else { |
|
5226 character = prev + character; |
|
5227 } |
|
5228 |
|
5229 match = this._filterMenuItems( character ); |
|
5230 match = skip && match.index( this.active.next() ) !== -1 ? |
|
5231 this.active.nextAll( ".ui-menu-item" ) : |
|
5232 match; |
|
5233 |
|
5234 // If no matches on the current filter, reset to the last character pressed |
|
5235 // to move down the menu to the first item that starts with that character |
|
5236 if ( !match.length ) { |
|
5237 character = String.fromCharCode( event.keyCode ); |
|
5238 match = this._filterMenuItems( character ); |
|
5239 } |
|
5240 |
|
5241 if ( match.length ) { |
|
5242 this.focus( event, match ); |
|
5243 this.previousFilter = character; |
|
5244 this.filterTimer = this._delay( function() { |
|
5245 delete this.previousFilter; |
|
5246 }, 1000 ); |
|
5247 } else { |
|
5248 delete this.previousFilter; |
|
5249 } |
|
5250 } |
|
5251 |
|
5252 if ( preventDefault ) { |
|
5253 event.preventDefault(); |
|
5254 } |
|
5255 }, |
|
5256 |
|
5257 _activate: function( event ) { |
|
5258 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { |
|
5259 if ( this.active.children( "[aria-haspopup='true']" ).length ) { |
|
5260 this.expand( event ); |
|
5261 } else { |
|
5262 this.select( event ); |
|
5263 } |
|
5264 } |
|
5265 }, |
|
5266 |
|
5267 refresh: function() { |
|
5268 var menus, items, newSubmenus, newItems, newWrappers, |
|
5269 that = this, |
|
5270 icon = this.options.icons.submenu, |
|
5271 submenus = this.element.find( this.options.menus ); |
|
5272 |
|
5273 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); |
|
5274 |
|
5275 // Initialize nested menus |
|
5276 newSubmenus = submenus.filter( ":not(.ui-menu)" ) |
|
5277 .hide() |
|
5278 .attr( { |
|
5279 role: this.options.role, |
|
5280 "aria-hidden": "true", |
|
5281 "aria-expanded": "false" |
|
5282 } ) |
|
5283 .each( function() { |
|
5284 var menu = $( this ), |
|
5285 item = menu.prev(), |
|
5286 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); |
|
5287 |
|
5288 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); |
|
5289 item |
|
5290 .attr( "aria-haspopup", "true" ) |
|
5291 .prepend( submenuCaret ); |
|
5292 menu.attr( "aria-labelledby", item.attr( "id" ) ); |
|
5293 } ); |
|
5294 |
|
5295 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); |
|
5296 |
|
5297 menus = submenus.add( this.element ); |
|
5298 items = menus.find( this.options.items ); |
|
5299 |
|
5300 // Initialize menu-items containing spaces and/or dashes only as dividers |
|
5301 items.not( ".ui-menu-item" ).each( function() { |
|
5302 var item = $( this ); |
|
5303 if ( that._isDivider( item ) ) { |
|
5304 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); |
|
5305 } |
|
5306 } ); |
|
5307 |
|
5308 // Don't refresh list items that are already adapted |
|
5309 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); |
|
5310 newWrappers = newItems.children() |
|
5311 .not( ".ui-menu" ) |
|
5312 .uniqueId() |
|
5313 .attr( { |
|
5314 tabIndex: -1, |
|
5315 role: this._itemRole() |
|
5316 } ); |
|
5317 this._addClass( newItems, "ui-menu-item" ) |
|
5318 ._addClass( newWrappers, "ui-menu-item-wrapper" ); |
|
5319 |
|
5320 // Add aria-disabled attribute to any disabled menu item |
|
5321 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); |
|
5322 |
|
5323 // If the active item has been removed, blur the menu |
|
5324 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { |
|
5325 this.blur(); |
|
5326 } |
|
5327 }, |
|
5328 |
|
5329 _itemRole: function() { |
|
5330 return { |
|
5331 menu: "menuitem", |
|
5332 listbox: "option" |
|
5333 }[ this.options.role ]; |
|
5334 }, |
|
5335 |
|
5336 _setOption: function( key, value ) { |
|
5337 if ( key === "icons" ) { |
|
5338 var icons = this.element.find( ".ui-menu-icon" ); |
|
5339 this._removeClass( icons, null, this.options.icons.submenu ) |
|
5340 ._addClass( icons, null, value.submenu ); |
|
5341 } |
|
5342 this._super( key, value ); |
|
5343 }, |
|
5344 |
|
5345 _setOptionDisabled: function( value ) { |
|
5346 this._super( value ); |
|
5347 |
|
5348 this.element.attr( "aria-disabled", String( value ) ); |
|
5349 this._toggleClass( null, "ui-state-disabled", !!value ); |
|
5350 }, |
|
5351 |
|
5352 focus: function( event, item ) { |
|
5353 var nested, focused, activeParent; |
|
5354 this.blur( event, event && event.type === "focus" ); |
|
5355 |
|
5356 this._scrollIntoView( item ); |
|
5357 |
|
5358 this.active = item.first(); |
|
5359 |
|
5360 focused = this.active.children( ".ui-menu-item-wrapper" ); |
|
5361 this._addClass( focused, null, "ui-state-active" ); |
|
5362 |
|
5363 // Only update aria-activedescendant if there's a role |
|
5364 // otherwise we assume focus is managed elsewhere |
|
5365 if ( this.options.role ) { |
|
5366 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); |
|
5367 } |
|
5368 |
|
5369 // Highlight active parent menu item, if any |
|
5370 activeParent = this.active |
|
5371 .parent() |
|
5372 .closest( ".ui-menu-item" ) |
|
5373 .children( ".ui-menu-item-wrapper" ); |
|
5374 this._addClass( activeParent, null, "ui-state-active" ); |
|
5375 |
|
5376 if ( event && event.type === "keydown" ) { |
|
5377 this._close(); |
|
5378 } else { |
|
5379 this.timer = this._delay( function() { |
|
5380 this._close(); |
|
5381 }, this.delay ); |
|
5382 } |
|
5383 |
|
5384 nested = item.children( ".ui-menu" ); |
|
5385 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { |
|
5386 this._startOpening( nested ); |
|
5387 } |
|
5388 this.activeMenu = item.parent(); |
|
5389 |
|
5390 this._trigger( "focus", event, { item: item } ); |
|
5391 }, |
|
5392 |
|
5393 _scrollIntoView: function( item ) { |
|
5394 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; |
|
5395 if ( this._hasScroll() ) { |
|
5396 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; |
|
5397 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; |
|
5398 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; |
|
5399 scroll = this.activeMenu.scrollTop(); |
|
5400 elementHeight = this.activeMenu.height(); |
|
5401 itemHeight = item.outerHeight(); |
|
5402 |
|
5403 if ( offset < 0 ) { |
|
5404 this.activeMenu.scrollTop( scroll + offset ); |
|
5405 } else if ( offset + itemHeight > elementHeight ) { |
|
5406 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); |
|
5407 } |
|
5408 } |
|
5409 }, |
|
5410 |
|
5411 blur: function( event, fromFocus ) { |
|
5412 if ( !fromFocus ) { |
|
5413 clearTimeout( this.timer ); |
|
5414 } |
|
5415 |
|
5416 if ( !this.active ) { |
|
5417 return; |
|
5418 } |
|
5419 |
|
5420 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), |
|
5421 null, "ui-state-active" ); |
|
5422 |
|
5423 this._trigger( "blur", event, { item: this.active } ); |
|
5424 this.active = null; |
|
5425 }, |
|
5426 |
|
5427 _startOpening: function( submenu ) { |
|
5428 clearTimeout( this.timer ); |
|
5429 |
|
5430 // Don't open if already open fixes a Firefox bug that caused a .5 pixel |
|
5431 // shift in the submenu position when mousing over the caret icon |
|
5432 if ( submenu.attr( "aria-hidden" ) !== "true" ) { |
|
5433 return; |
|
5434 } |
|
5435 |
|
5436 this.timer = this._delay( function() { |
|
5437 this._close(); |
|
5438 this._open( submenu ); |
|
5439 }, this.delay ); |
|
5440 }, |
|
5441 |
|
5442 _open: function( submenu ) { |
|
5443 var position = $.extend( { |
|
5444 of: this.active |
|
5445 }, this.options.position ); |
|
5446 |
|
5447 clearTimeout( this.timer ); |
|
5448 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) |
|
5449 .hide() |
|
5450 .attr( "aria-hidden", "true" ); |
|
5451 |
|
5452 submenu |
|
5453 .show() |
|
5454 .removeAttr( "aria-hidden" ) |
|
5455 .attr( "aria-expanded", "true" ) |
|
5456 .position( position ); |
|
5457 }, |
|
5458 |
|
5459 collapseAll: function( event, all ) { |
|
5460 clearTimeout( this.timer ); |
|
5461 this.timer = this._delay( function() { |
|
5462 |
|
5463 // If we were passed an event, look for the submenu that contains the event |
|
5464 var currentMenu = all ? this.element : |
|
5465 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); |
|
5466 |
|
5467 // If we found no valid submenu ancestor, use the main menu to close all |
|
5468 // sub menus anyway |
|
5469 if ( !currentMenu.length ) { |
|
5470 currentMenu = this.element; |
|
5471 } |
|
5472 |
|
5473 this._close( currentMenu ); |
|
5474 |
|
5475 this.blur( event ); |
|
5476 |
|
5477 // Work around active item staying active after menu is blurred |
|
5478 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); |
|
5479 |
|
5480 this.activeMenu = currentMenu; |
|
5481 }, all ? 0 : this.delay ); |
|
5482 }, |
|
5483 |
|
5484 // With no arguments, closes the currently active menu - if nothing is active |
|
5485 // it closes all menus. If passed an argument, it will search for menus BELOW |
|
5486 _close: function( startMenu ) { |
|
5487 if ( !startMenu ) { |
|
5488 startMenu = this.active ? this.active.parent() : this.element; |
|
5489 } |
|
5490 |
|
5491 startMenu.find( ".ui-menu" ) |
|
5492 .hide() |
|
5493 .attr( "aria-hidden", "true" ) |
|
5494 .attr( "aria-expanded", "false" ); |
|
5495 }, |
|
5496 |
|
5497 _closeOnDocumentClick: function( event ) { |
|
5498 return !$( event.target ).closest( ".ui-menu" ).length; |
|
5499 }, |
|
5500 |
|
5501 _isDivider: function( item ) { |
|
5502 |
|
5503 // Match hyphen, em dash, en dash |
|
5504 return !/[^\-\u2014\u2013\s]/.test( item.text() ); |
|
5505 }, |
|
5506 |
|
5507 collapse: function( event ) { |
|
5508 var newItem = this.active && |
|
5509 this.active.parent().closest( ".ui-menu-item", this.element ); |
|
5510 if ( newItem && newItem.length ) { |
|
5511 this._close(); |
|
5512 this.focus( event, newItem ); |
|
5513 } |
|
5514 }, |
|
5515 |
|
5516 expand: function( event ) { |
|
5517 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); |
|
5518 |
|
5519 if ( newItem && newItem.length ) { |
|
5520 this._open( newItem.parent() ); |
|
5521 |
|
5522 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT |
|
5523 this._delay( function() { |
|
5524 this.focus( event, newItem ); |
|
5525 } ); |
|
5526 } |
|
5527 }, |
|
5528 |
|
5529 next: function( event ) { |
|
5530 this._move( "next", "first", event ); |
|
5531 }, |
|
5532 |
|
5533 previous: function( event ) { |
|
5534 this._move( "prev", "last", event ); |
|
5535 }, |
|
5536 |
|
5537 isFirstItem: function() { |
|
5538 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; |
|
5539 }, |
|
5540 |
|
5541 isLastItem: function() { |
|
5542 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; |
|
5543 }, |
|
5544 |
|
5545 _menuItems: function( menu ) { |
|
5546 return ( menu || this.element ) |
|
5547 .find( this.options.items ) |
|
5548 .filter( ".ui-menu-item" ); |
|
5549 }, |
|
5550 |
|
5551 _move: function( direction, filter, event ) { |
|
5552 var next; |
|
5553 if ( this.active ) { |
|
5554 if ( direction === "first" || direction === "last" ) { |
|
5555 next = this.active |
|
5556 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) |
|
5557 .last(); |
|
5558 } else { |
|
5559 next = this.active |
|
5560 [ direction + "All" ]( ".ui-menu-item" ) |
|
5561 .first(); |
|
5562 } |
|
5563 } |
|
5564 if ( !next || !next.length || !this.active ) { |
|
5565 next = this._menuItems( this.activeMenu )[ filter ](); |
|
5566 } |
|
5567 |
|
5568 this.focus( event, next ); |
|
5569 }, |
|
5570 |
|
5571 nextPage: function( event ) { |
|
5572 var item, base, height; |
|
5573 |
|
5574 if ( !this.active ) { |
|
5575 this.next( event ); |
|
5576 return; |
|
5577 } |
|
5578 if ( this.isLastItem() ) { |
|
5579 return; |
|
5580 } |
|
5581 if ( this._hasScroll() ) { |
|
5582 base = this.active.offset().top; |
|
5583 height = this.element.innerHeight(); |
|
5584 |
|
5585 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. |
|
5586 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { |
|
5587 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); |
|
5588 } |
|
5589 |
|
5590 this.active.nextAll( ".ui-menu-item" ).each( function() { |
|
5591 item = $( this ); |
|
5592 return item.offset().top - base - height < 0; |
|
5593 } ); |
|
5594 |
|
5595 this.focus( event, item ); |
|
5596 } else { |
|
5597 this.focus( event, this._menuItems( this.activeMenu ) |
|
5598 [ !this.active ? "first" : "last" ]() ); |
|
5599 } |
|
5600 }, |
|
5601 |
|
5602 previousPage: function( event ) { |
|
5603 var item, base, height; |
|
5604 if ( !this.active ) { |
|
5605 this.next( event ); |
|
5606 return; |
|
5607 } |
|
5608 if ( this.isFirstItem() ) { |
|
5609 return; |
|
5610 } |
|
5611 if ( this._hasScroll() ) { |
|
5612 base = this.active.offset().top; |
|
5613 height = this.element.innerHeight(); |
|
5614 |
|
5615 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. |
|
5616 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { |
|
5617 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); |
|
5618 } |
|
5619 |
|
5620 this.active.prevAll( ".ui-menu-item" ).each( function() { |
|
5621 item = $( this ); |
|
5622 return item.offset().top - base + height > 0; |
|
5623 } ); |
|
5624 |
|
5625 this.focus( event, item ); |
|
5626 } else { |
|
5627 this.focus( event, this._menuItems( this.activeMenu ).first() ); |
|
5628 } |
|
5629 }, |
|
5630 |
|
5631 _hasScroll: function() { |
|
5632 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); |
|
5633 }, |
|
5634 |
|
5635 select: function( event ) { |
|
5636 |
|
5637 // TODO: It should never be possible to not have an active item at this |
|
5638 // point, but the tests don't trigger mouseenter before click. |
|
5639 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); |
|
5640 var ui = { item: this.active }; |
|
5641 if ( !this.active.has( ".ui-menu" ).length ) { |
|
5642 this.collapseAll( event, true ); |
|
5643 } |
|
5644 this._trigger( "select", event, ui ); |
|
5645 }, |
|
5646 |
|
5647 _filterMenuItems: function( character ) { |
|
5648 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), |
|
5649 regex = new RegExp( "^" + escapedCharacter, "i" ); |
|
5650 |
|
5651 return this.activeMenu |
|
5652 .find( this.options.items ) |
|
5653 |
|
5654 // Only match on items, not dividers or other content (#10571) |
|
5655 .filter( ".ui-menu-item" ) |
|
5656 .filter( function() { |
|
5657 return regex.test( |
|
5658 String.prototype.trim.call( |
|
5659 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); |
|
5660 } ); |
|
5661 } |
|
5662 } ); |
|
5663 |
|
5664 |
|
5665 /*! |
|
5666 * jQuery UI Autocomplete 1.13.2 |
|
5667 * http://jqueryui.com |
|
5668 * |
|
5669 * Copyright jQuery Foundation and other contributors |
|
5670 * Released under the MIT license. |
|
5671 * http://jquery.org/license |
|
5672 */ |
|
5673 |
|
5674 //>>label: Autocomplete |
|
5675 //>>group: Widgets |
|
5676 //>>description: Lists suggested words as the user is typing. |
|
5677 //>>docs: http://api.jqueryui.com/autocomplete/ |
|
5678 //>>demos: http://jqueryui.com/autocomplete/ |
|
5679 //>>css.structure: ../../themes/base/core.css |
|
5680 //>>css.structure: ../../themes/base/autocomplete.css |
|
5681 //>>css.theme: ../../themes/base/theme.css |
|
5682 |
|
5683 |
|
5684 $.widget( "ui.autocomplete", { |
|
5685 version: "1.13.2", |
|
5686 defaultElement: "<input>", |
|
5687 options: { |
|
5688 appendTo: null, |
|
5689 autoFocus: false, |
|
5690 delay: 300, |
|
5691 minLength: 1, |
|
5692 position: { |
|
5693 my: "left top", |
|
5694 at: "left bottom", |
|
5695 collision: "none" |
|
5696 }, |
|
5697 source: null, |
|
5698 |
|
5699 // Callbacks |
|
5700 change: null, |
|
5701 close: null, |
|
5702 focus: null, |
|
5703 open: null, |
|
5704 response: null, |
|
5705 search: null, |
|
5706 select: null |
|
5707 }, |
|
5708 |
|
5709 requestIndex: 0, |
|
5710 pending: 0, |
|
5711 liveRegionTimer: null, |
|
5712 |
|
5713 _create: function() { |
|
5714 |
|
5715 // Some browsers only repeat keydown events, not keypress events, |
|
5716 // so we use the suppressKeyPress flag to determine if we've already |
|
5717 // handled the keydown event. #7269 |
|
5718 // Unfortunately the code for & in keypress is the same as the up arrow, |
|
5719 // so we use the suppressKeyPressRepeat flag to avoid handling keypress |
|
5720 // events when we know the keydown event was used to modify the |
|
5721 // search term. #7799 |
|
5722 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, |
|
5723 nodeName = this.element[ 0 ].nodeName.toLowerCase(), |
|
5724 isTextarea = nodeName === "textarea", |
|
5725 isInput = nodeName === "input"; |
|
5726 |
|
5727 // Textareas are always multi-line |
|
5728 // Inputs are always single-line, even if inside a contentEditable element |
|
5729 // IE also treats inputs as contentEditable |
|
5730 // All other element types are determined by whether or not they're contentEditable |
|
5731 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); |
|
5732 |
|
5733 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; |
|
5734 this.isNewMenu = true; |
|
5735 |
|
5736 this._addClass( "ui-autocomplete-input" ); |
|
5737 this.element.attr( "autocomplete", "off" ); |
|
5738 |
|
5739 this._on( this.element, { |
|
5740 keydown: function( event ) { |
|
5741 if ( this.element.prop( "readOnly" ) ) { |
|
5742 suppressKeyPress = true; |
|
5743 suppressInput = true; |
|
5744 suppressKeyPressRepeat = true; |
|
5745 return; |
|
5746 } |
|
5747 |
|
5748 suppressKeyPress = false; |
|
5749 suppressInput = false; |
|
5750 suppressKeyPressRepeat = false; |
|
5751 var keyCode = $.ui.keyCode; |
|
5752 switch ( event.keyCode ) { |
|
5753 case keyCode.PAGE_UP: |
|
5754 suppressKeyPress = true; |
|
5755 this._move( "previousPage", event ); |
|
5756 break; |
|
5757 case keyCode.PAGE_DOWN: |
|
5758 suppressKeyPress = true; |
|
5759 this._move( "nextPage", event ); |
|
5760 break; |
|
5761 case keyCode.UP: |
|
5762 suppressKeyPress = true; |
|
5763 this._keyEvent( "previous", event ); |
|
5764 break; |
|
5765 case keyCode.DOWN: |
|
5766 suppressKeyPress = true; |
|
5767 this._keyEvent( "next", event ); |
|
5768 break; |
|
5769 case keyCode.ENTER: |
|
5770 |
|
5771 // when menu is open and has focus |
|
5772 if ( this.menu.active ) { |
|
5773 |
|
5774 // #6055 - Opera still allows the keypress to occur |
|
5775 // which causes forms to submit |
|
5776 suppressKeyPress = true; |
|
5777 event.preventDefault(); |
|
5778 this.menu.select( event ); |
|
5779 } |
|
5780 break; |
|
5781 case keyCode.TAB: |
|
5782 if ( this.menu.active ) { |
|
5783 this.menu.select( event ); |
|
5784 } |
|
5785 break; |
|
5786 case keyCode.ESCAPE: |
|
5787 if ( this.menu.element.is( ":visible" ) ) { |
|
5788 if ( !this.isMultiLine ) { |
|
5789 this._value( this.term ); |
|
5790 } |
|
5791 this.close( event ); |
|
5792 |
|
5793 // Different browsers have different default behavior for escape |
|
5794 // Single press can mean undo or clear |
|
5795 // Double press in IE means clear the whole form |
|
5796 event.preventDefault(); |
|
5797 } |
|
5798 break; |
|
5799 default: |
|
5800 suppressKeyPressRepeat = true; |
|
5801 |
|
5802 // search timeout should be triggered before the input value is changed |
|
5803 this._searchTimeout( event ); |
|
5804 break; |
|
5805 } |
|
5806 }, |
|
5807 keypress: function( event ) { |
|
5808 if ( suppressKeyPress ) { |
|
5809 suppressKeyPress = false; |
|
5810 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { |
|
5811 event.preventDefault(); |
|
5812 } |
|
5813 return; |
|
5814 } |
|
5815 if ( suppressKeyPressRepeat ) { |
|
5816 return; |
|
5817 } |
|
5818 |
|
5819 // Replicate some key handlers to allow them to repeat in Firefox and Opera |
|
5820 var keyCode = $.ui.keyCode; |
|
5821 switch ( event.keyCode ) { |
|
5822 case keyCode.PAGE_UP: |
|
5823 this._move( "previousPage", event ); |
|
5824 break; |
|
5825 case keyCode.PAGE_DOWN: |
|
5826 this._move( "nextPage", event ); |
|
5827 break; |
|
5828 case keyCode.UP: |
|
5829 this._keyEvent( "previous", event ); |
|
5830 break; |
|
5831 case keyCode.DOWN: |
|
5832 this._keyEvent( "next", event ); |
|
5833 break; |
|
5834 } |
|
5835 }, |
|
5836 input: function( event ) { |
|
5837 if ( suppressInput ) { |
|
5838 suppressInput = false; |
|
5839 event.preventDefault(); |
|
5840 return; |
|
5841 } |
|
5842 this._searchTimeout( event ); |
|
5843 }, |
|
5844 focus: function() { |
|
5845 this.selectedItem = null; |
|
5846 this.previous = this._value(); |
|
5847 }, |
|
5848 blur: function( event ) { |
|
5849 clearTimeout( this.searching ); |
|
5850 this.close( event ); |
|
5851 this._change( event ); |
|
5852 } |
|
5853 } ); |
|
5854 |
|
5855 this._initSource(); |
|
5856 this.menu = $( "<ul>" ) |
|
5857 .appendTo( this._appendTo() ) |
|
5858 .menu( { |
|
5859 |
|
5860 // disable ARIA support, the live region takes care of that |
|
5861 role: null |
|
5862 } ) |
|
5863 .hide() |
|
5864 |
|
5865 // Support: IE 11 only, Edge <= 14 |
|
5866 // For other browsers, we preventDefault() on the mousedown event |
|
5867 // to keep the dropdown from taking focus from the input. This doesn't |
|
5868 // work for IE/Edge, causing problems with selection and scrolling (#9638) |
|
5869 // Happily, IE and Edge support an "unselectable" attribute that |
|
5870 // prevents an element from receiving focus, exactly what we want here. |
|
5871 .attr( { |
|
5872 "unselectable": "on" |
|
5873 } ) |
|
5874 .menu( "instance" ); |
|
5875 |
|
5876 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); |
|
5877 this._on( this.menu.element, { |
|
5878 mousedown: function( event ) { |
|
5879 |
|
5880 // Prevent moving focus out of the text field |
|
5881 event.preventDefault(); |
|
5882 }, |
|
5883 menufocus: function( event, ui ) { |
|
5884 var label, item; |
|
5885 |
|
5886 // support: Firefox |
|
5887 // Prevent accidental activation of menu items in Firefox (#7024 #9118) |
|
5888 if ( this.isNewMenu ) { |
|
5889 this.isNewMenu = false; |
|
5890 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { |
|
5891 this.menu.blur(); |
|
5892 |
|
5893 this.document.one( "mousemove", function() { |
|
5894 $( event.target ).trigger( event.originalEvent ); |
|
5895 } ); |
|
5896 |
|
5897 return; |
|
5898 } |
|
5899 } |
|
5900 |
|
5901 item = ui.item.data( "ui-autocomplete-item" ); |
|
5902 if ( false !== this._trigger( "focus", event, { item: item } ) ) { |
|
5903 |
|
5904 // use value to match what will end up in the input, if it was a key event |
|
5905 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { |
|
5906 this._value( item.value ); |
|
5907 } |
|
5908 } |
|
5909 |
|
5910 // Announce the value in the liveRegion |
|
5911 label = ui.item.attr( "aria-label" ) || item.value; |
|
5912 if ( label && String.prototype.trim.call( label ).length ) { |
|
5913 clearTimeout( this.liveRegionTimer ); |
|
5914 this.liveRegionTimer = this._delay( function() { |
|
5915 this.liveRegion.html( $( "<div>" ).text( label ) ); |
|
5916 }, 100 ); |
|
5917 } |
|
5918 }, |
|
5919 menuselect: function( event, ui ) { |
|
5920 var item = ui.item.data( "ui-autocomplete-item" ), |
|
5921 previous = this.previous; |
|
5922 |
|
5923 // Only trigger when focus was lost (click on menu) |
|
5924 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { |
|
5925 this.element.trigger( "focus" ); |
|
5926 this.previous = previous; |
|
5927 |
|
5928 // #6109 - IE triggers two focus events and the second |
|
5929 // is asynchronous, so we need to reset the previous |
|
5930 // term synchronously and asynchronously :-( |
|
5931 this._delay( function() { |
|
5932 this.previous = previous; |
|
5933 this.selectedItem = item; |
|
5934 } ); |
|
5935 } |
|
5936 |
|
5937 if ( false !== this._trigger( "select", event, { item: item } ) ) { |
|
5938 this._value( item.value ); |
|
5939 } |
|
5940 |
|
5941 // reset the term after the select event |
|
5942 // this allows custom select handling to work properly |
|
5943 this.term = this._value(); |
|
5944 |
|
5945 this.close( event ); |
|
5946 this.selectedItem = item; |
|
5947 } |
|
5948 } ); |
|
5949 |
|
5950 this.liveRegion = $( "<div>", { |
|
5951 role: "status", |
|
5952 "aria-live": "assertive", |
|
5953 "aria-relevant": "additions" |
|
5954 } ) |
|
5955 .appendTo( this.document[ 0 ].body ); |
|
5956 |
|
5957 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); |
|
5958 |
|
5959 // Turning off autocomplete prevents the browser from remembering the |
|
5960 // value when navigating through history, so we re-enable autocomplete |
|
5961 // if the page is unloaded before the widget is destroyed. #7790 |
|
5962 this._on( this.window, { |
|
5963 beforeunload: function() { |
|
5964 this.element.removeAttr( "autocomplete" ); |
|
5965 } |
|
5966 } ); |
|
5967 }, |
|
5968 |
|
5969 _destroy: function() { |
|
5970 clearTimeout( this.searching ); |
|
5971 this.element.removeAttr( "autocomplete" ); |
|
5972 this.menu.element.remove(); |
|
5973 this.liveRegion.remove(); |
|
5974 }, |
|
5975 |
|
5976 _setOption: function( key, value ) { |
|
5977 this._super( key, value ); |
|
5978 if ( key === "source" ) { |
|
5979 this._initSource(); |
|
5980 } |
|
5981 if ( key === "appendTo" ) { |
|
5982 this.menu.element.appendTo( this._appendTo() ); |
|
5983 } |
|
5984 if ( key === "disabled" && value && this.xhr ) { |
|
5985 this.xhr.abort(); |
|
5986 } |
|
5987 }, |
|
5988 |
|
5989 _isEventTargetInWidget: function( event ) { |
|
5990 var menuElement = this.menu.element[ 0 ]; |
|
5991 |
|
5992 return event.target === this.element[ 0 ] || |
|
5993 event.target === menuElement || |
|
5994 $.contains( menuElement, event.target ); |
|
5995 }, |
|
5996 |
|
5997 _closeOnClickOutside: function( event ) { |
|
5998 if ( !this._isEventTargetInWidget( event ) ) { |
|
5999 this.close(); |
|
6000 } |
|
6001 }, |
|
6002 |
|
6003 _appendTo: function() { |
|
6004 var element = this.options.appendTo; |
|
6005 |
|
6006 if ( element ) { |
|
6007 element = element.jquery || element.nodeType ? |
|
6008 $( element ) : |
|
6009 this.document.find( element ).eq( 0 ); |
|
6010 } |
|
6011 |
|
6012 if ( !element || !element[ 0 ] ) { |
|
6013 element = this.element.closest( ".ui-front, dialog" ); |
|
6014 } |
|
6015 |
|
6016 if ( !element.length ) { |
|
6017 element = this.document[ 0 ].body; |
|
6018 } |
|
6019 |
|
6020 return element; |
|
6021 }, |
|
6022 |
|
6023 _initSource: function() { |
|
6024 var array, url, |
|
6025 that = this; |
|
6026 if ( Array.isArray( this.options.source ) ) { |
|
6027 array = this.options.source; |
|
6028 this.source = function( request, response ) { |
|
6029 response( $.ui.autocomplete.filter( array, request.term ) ); |
|
6030 }; |
|
6031 } else if ( typeof this.options.source === "string" ) { |
|
6032 url = this.options.source; |
|
6033 this.source = function( request, response ) { |
|
6034 if ( that.xhr ) { |
|
6035 that.xhr.abort(); |
|
6036 } |
|
6037 that.xhr = $.ajax( { |
|
6038 url: url, |
|
6039 data: request, |
|
6040 dataType: "json", |
|
6041 success: function( data ) { |
|
6042 response( data ); |
|
6043 }, |
|
6044 error: function() { |
|
6045 response( [] ); |
|
6046 } |
|
6047 } ); |
|
6048 }; |
|
6049 } else { |
|
6050 this.source = this.options.source; |
|
6051 } |
|
6052 }, |
|
6053 |
|
6054 _searchTimeout: function( event ) { |
|
6055 clearTimeout( this.searching ); |
|
6056 this.searching = this._delay( function() { |
|
6057 |
|
6058 // Search if the value has changed, or if the user retypes the same value (see #7434) |
|
6059 var equalValues = this.term === this._value(), |
|
6060 menuVisible = this.menu.element.is( ":visible" ), |
|
6061 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; |
|
6062 |
|
6063 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { |
|
6064 this.selectedItem = null; |
|
6065 this.search( null, event ); |
|
6066 } |
|
6067 }, this.options.delay ); |
|
6068 }, |
|
6069 |
|
6070 search: function( value, event ) { |
|
6071 value = value != null ? value : this._value(); |
|
6072 |
|
6073 // Always save the actual value, not the one passed as an argument |
|
6074 this.term = this._value(); |
|
6075 |
|
6076 if ( value.length < this.options.minLength ) { |
|
6077 return this.close( event ); |
|
6078 } |
|
6079 |
|
6080 if ( this._trigger( "search", event ) === false ) { |
|
6081 return; |
|
6082 } |
|
6083 |
|
6084 return this._search( value ); |
|
6085 }, |
|
6086 |
|
6087 _search: function( value ) { |
|
6088 this.pending++; |
|
6089 this._addClass( "ui-autocomplete-loading" ); |
|
6090 this.cancelSearch = false; |
|
6091 |
|
6092 this.source( { term: value }, this._response() ); |
|
6093 }, |
|
6094 |
|
6095 _response: function() { |
|
6096 var index = ++this.requestIndex; |
|
6097 |
|
6098 return function( content ) { |
|
6099 if ( index === this.requestIndex ) { |
|
6100 this.__response( content ); |
|
6101 } |
|
6102 |
|
6103 this.pending--; |
|
6104 if ( !this.pending ) { |
|
6105 this._removeClass( "ui-autocomplete-loading" ); |
|
6106 } |
|
6107 }.bind( this ); |
|
6108 }, |
|
6109 |
|
6110 __response: function( content ) { |
|
6111 if ( content ) { |
|
6112 content = this._normalize( content ); |
|
6113 } |
|
6114 this._trigger( "response", null, { content: content } ); |
|
6115 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { |
|
6116 this._suggest( content ); |
|
6117 this._trigger( "open" ); |
|
6118 } else { |
|
6119 |
|
6120 // use ._close() instead of .close() so we don't cancel future searches |
|
6121 this._close(); |
|
6122 } |
|
6123 }, |
|
6124 |
|
6125 close: function( event ) { |
|
6126 this.cancelSearch = true; |
|
6127 this._close( event ); |
|
6128 }, |
|
6129 |
|
6130 _close: function( event ) { |
|
6131 |
|
6132 // Remove the handler that closes the menu on outside clicks |
|
6133 this._off( this.document, "mousedown" ); |
|
6134 |
|
6135 if ( this.menu.element.is( ":visible" ) ) { |
|
6136 this.menu.element.hide(); |
|
6137 this.menu.blur(); |
|
6138 this.isNewMenu = true; |
|
6139 this._trigger( "close", event ); |
|
6140 } |
|
6141 }, |
|
6142 |
|
6143 _change: function( event ) { |
|
6144 if ( this.previous !== this._value() ) { |
|
6145 this._trigger( "change", event, { item: this.selectedItem } ); |
|
6146 } |
|
6147 }, |
|
6148 |
|
6149 _normalize: function( items ) { |
|
6150 |
|
6151 // assume all items have the right format when the first item is complete |
|
6152 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { |
|
6153 return items; |
|
6154 } |
|
6155 return $.map( items, function( item ) { |
|
6156 if ( typeof item === "string" ) { |
|
6157 return { |
|
6158 label: item, |
|
6159 value: item |
|
6160 }; |
|
6161 } |
|
6162 return $.extend( {}, item, { |
|
6163 label: item.label || item.value, |
|
6164 value: item.value || item.label |
|
6165 } ); |
|
6166 } ); |
|
6167 }, |
|
6168 |
|
6169 _suggest: function( items ) { |
|
6170 var ul = this.menu.element.empty(); |
|
6171 this._renderMenu( ul, items ); |
|
6172 this.isNewMenu = true; |
|
6173 this.menu.refresh(); |
|
6174 |
|
6175 // Size and position menu |
|
6176 ul.show(); |
|
6177 this._resizeMenu(); |
|
6178 ul.position( $.extend( { |
|
6179 of: this.element |
|
6180 }, this.options.position ) ); |
|
6181 |
|
6182 if ( this.options.autoFocus ) { |
|
6183 this.menu.next(); |
|
6184 } |
|
6185 |
|
6186 // Listen for interactions outside of the widget (#6642) |
|
6187 this._on( this.document, { |
|
6188 mousedown: "_closeOnClickOutside" |
|
6189 } ); |
|
6190 }, |
|
6191 |
|
6192 _resizeMenu: function() { |
|
6193 var ul = this.menu.element; |
|
6194 ul.outerWidth( Math.max( |
|
6195 |
|
6196 // Firefox wraps long text (possibly a rounding bug) |
|
6197 // so we add 1px to avoid the wrapping (#7513) |
|
6198 ul.width( "" ).outerWidth() + 1, |
|
6199 this.element.outerWidth() |
|
6200 ) ); |
|
6201 }, |
|
6202 |
|
6203 _renderMenu: function( ul, items ) { |
|
6204 var that = this; |
|
6205 $.each( items, function( index, item ) { |
|
6206 that._renderItemData( ul, item ); |
|
6207 } ); |
|
6208 }, |
|
6209 |
|
6210 _renderItemData: function( ul, item ) { |
|
6211 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); |
|
6212 }, |
|
6213 |
|
6214 _renderItem: function( ul, item ) { |
|
6215 return $( "<li>" ) |
|
6216 .append( $( "<div>" ).text( item.label ) ) |
|
6217 .appendTo( ul ); |
|
6218 }, |
|
6219 |
|
6220 _move: function( direction, event ) { |
|
6221 if ( !this.menu.element.is( ":visible" ) ) { |
|
6222 this.search( null, event ); |
|
6223 return; |
|
6224 } |
|
6225 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || |
|
6226 this.menu.isLastItem() && /^next/.test( direction ) ) { |
|
6227 |
|
6228 if ( !this.isMultiLine ) { |
|
6229 this._value( this.term ); |
|
6230 } |
|
6231 |
|
6232 this.menu.blur(); |
|
6233 return; |
|
6234 } |
|
6235 this.menu[ direction ]( event ); |
|
6236 }, |
|
6237 |
|
6238 widget: function() { |
|
6239 return this.menu.element; |
|
6240 }, |
|
6241 |
|
6242 _value: function() { |
|
6243 return this.valueMethod.apply( this.element, arguments ); |
|
6244 }, |
|
6245 |
|
6246 _keyEvent: function( keyEvent, event ) { |
|
6247 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { |
|
6248 this._move( keyEvent, event ); |
|
6249 |
|
6250 // Prevents moving cursor to beginning/end of the text field in some browsers |
|
6251 event.preventDefault(); |
|
6252 } |
|
6253 }, |
|
6254 |
|
6255 // Support: Chrome <=50 |
|
6256 // We should be able to just use this.element.prop( "isContentEditable" ) |
|
6257 // but hidden elements always report false in Chrome. |
|
6258 // https://code.google.com/p/chromium/issues/detail?id=313082 |
|
6259 _isContentEditable: function( element ) { |
|
6260 if ( !element.length ) { |
|
6261 return false; |
|
6262 } |
|
6263 |
|
6264 var editable = element.prop( "contentEditable" ); |
|
6265 |
|
6266 if ( editable === "inherit" ) { |
|
6267 return this._isContentEditable( element.parent() ); |
|
6268 } |
|
6269 |
|
6270 return editable === "true"; |
|
6271 } |
|
6272 } ); |
|
6273 |
|
6274 $.extend( $.ui.autocomplete, { |
|
6275 escapeRegex: function( value ) { |
|
6276 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); |
|
6277 }, |
|
6278 filter: function( array, term ) { |
|
6279 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); |
|
6280 return $.grep( array, function( value ) { |
|
6281 return matcher.test( value.label || value.value || value ); |
|
6282 } ); |
|
6283 } |
|
6284 } ); |
|
6285 |
|
6286 // Live region extension, adding a `messages` option |
|
6287 // NOTE: This is an experimental API. We are still investigating |
|
6288 // a full solution for string manipulation and internationalization. |
|
6289 $.widget( "ui.autocomplete", $.ui.autocomplete, { |
|
6290 options: { |
|
6291 messages: { |
|
6292 noResults: "No search results.", |
|
6293 results: function( amount ) { |
|
6294 return amount + ( amount > 1 ? " results are" : " result is" ) + |
|
6295 " available, use up and down arrow keys to navigate."; |
|
6296 } |
|
6297 } |
|
6298 }, |
|
6299 |
|
6300 __response: function( content ) { |
|
6301 var message; |
|
6302 this._superApply( arguments ); |
|
6303 if ( this.options.disabled || this.cancelSearch ) { |
|
6304 return; |
|
6305 } |
|
6306 if ( content && content.length ) { |
|
6307 message = this.options.messages.results( content.length ); |
|
6308 } else { |
|
6309 message = this.options.messages.noResults; |
|
6310 } |
|
6311 clearTimeout( this.liveRegionTimer ); |
|
6312 this.liveRegionTimer = this._delay( function() { |
|
6313 this.liveRegion.html( $( "<div>" ).text( message ) ); |
|
6314 }, 100 ); |
|
6315 } |
|
6316 } ); |
|
6317 |
|
6318 var widgetsAutocomplete = $.ui.autocomplete; |
|
6319 |
|
6320 |
|
6321 /*! |
|
6322 * jQuery UI Controlgroup 1.13.2 |
|
6323 * http://jqueryui.com |
|
6324 * |
|
6325 * Copyright jQuery Foundation and other contributors |
|
6326 * Released under the MIT license. |
|
6327 * http://jquery.org/license |
|
6328 */ |
|
6329 |
|
6330 //>>label: Controlgroup |
|
6331 //>>group: Widgets |
|
6332 //>>description: Visually groups form control widgets |
|
6333 //>>docs: http://api.jqueryui.com/controlgroup/ |
|
6334 //>>demos: http://jqueryui.com/controlgroup/ |
|
6335 //>>css.structure: ../../themes/base/core.css |
|
6336 //>>css.structure: ../../themes/base/controlgroup.css |
|
6337 //>>css.theme: ../../themes/base/theme.css |
|
6338 |
|
6339 |
|
6340 var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; |
|
6341 |
|
6342 var widgetsControlgroup = $.widget( "ui.controlgroup", { |
|
6343 version: "1.13.2", |
|
6344 defaultElement: "<div>", |
|
6345 options: { |
|
6346 direction: "horizontal", |
|
6347 disabled: null, |
|
6348 onlyVisible: true, |
|
6349 items: { |
|
6350 "button": "input[type=button], input[type=submit], input[type=reset], button, a", |
|
6351 "controlgroupLabel": ".ui-controlgroup-label", |
|
6352 "checkboxradio": "input[type='checkbox'], input[type='radio']", |
|
6353 "selectmenu": "select", |
|
6354 "spinner": ".ui-spinner-input" |
|
6355 } |
|
6356 }, |
|
6357 |
|
6358 _create: function() { |
|
6359 this._enhance(); |
|
6360 }, |
|
6361 |
|
6362 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation |
|
6363 _enhance: function() { |
|
6364 this.element.attr( "role", "toolbar" ); |
|
6365 this.refresh(); |
|
6366 }, |
|
6367 |
|
6368 _destroy: function() { |
|
6369 this._callChildMethod( "destroy" ); |
|
6370 this.childWidgets.removeData( "ui-controlgroup-data" ); |
|
6371 this.element.removeAttr( "role" ); |
|
6372 if ( this.options.items.controlgroupLabel ) { |
|
6373 this.element |
|
6374 .find( this.options.items.controlgroupLabel ) |
|
6375 .find( ".ui-controlgroup-label-contents" ) |
|
6376 .contents().unwrap(); |
|
6377 } |
|
6378 }, |
|
6379 |
|
6380 _initWidgets: function() { |
|
6381 var that = this, |
|
6382 childWidgets = []; |
|
6383 |
|
6384 // First we iterate over each of the items options |
|
6385 $.each( this.options.items, function( widget, selector ) { |
|
6386 var labels; |
|
6387 var options = {}; |
|
6388 |
|
6389 // Make sure the widget has a selector set |
|
6390 if ( !selector ) { |
|
6391 return; |
|
6392 } |
|
6393 |
|
6394 if ( widget === "controlgroupLabel" ) { |
|
6395 labels = that.element.find( selector ); |
|
6396 labels.each( function() { |
|
6397 var element = $( this ); |
|
6398 |
|
6399 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { |
|
6400 return; |
|
6401 } |
|
6402 element.contents() |
|
6403 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); |
|
6404 } ); |
|
6405 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); |
|
6406 childWidgets = childWidgets.concat( labels.get() ); |
|
6407 return; |
|
6408 } |
|
6409 |
|
6410 // Make sure the widget actually exists |
|
6411 if ( !$.fn[ widget ] ) { |
|
6412 return; |
|
6413 } |
|
6414 |
|
6415 // We assume everything is in the middle to start because we can't determine |
|
6416 // first / last elements until all enhancments are done. |
|
6417 if ( that[ "_" + widget + "Options" ] ) { |
|
6418 options = that[ "_" + widget + "Options" ]( "middle" ); |
|
6419 } else { |
|
6420 options = { classes: {} }; |
|
6421 } |
|
6422 |
|
6423 // Find instances of this widget inside controlgroup and init them |
|
6424 that.element |
|
6425 .find( selector ) |
|
6426 .each( function() { |
|
6427 var element = $( this ); |
|
6428 var instance = element[ widget ]( "instance" ); |
|
6429 |
|
6430 // We need to clone the default options for this type of widget to avoid |
|
6431 // polluting the variable options which has a wider scope than a single widget. |
|
6432 var instanceOptions = $.widget.extend( {}, options ); |
|
6433 |
|
6434 // If the button is the child of a spinner ignore it |
|
6435 // TODO: Find a more generic solution |
|
6436 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { |
|
6437 return; |
|
6438 } |
|
6439 |
|
6440 // Create the widget if it doesn't exist |
|
6441 if ( !instance ) { |
|
6442 instance = element[ widget ]()[ widget ]( "instance" ); |
|
6443 } |
|
6444 if ( instance ) { |
|
6445 instanceOptions.classes = |
|
6446 that._resolveClassesValues( instanceOptions.classes, instance ); |
|
6447 } |
|
6448 element[ widget ]( instanceOptions ); |
|
6449 |
|
6450 // Store an instance of the controlgroup to be able to reference |
|
6451 // from the outermost element for changing options and refresh |
|
6452 var widgetElement = element[ widget ]( "widget" ); |
|
6453 $.data( widgetElement[ 0 ], "ui-controlgroup-data", |
|
6454 instance ? instance : element[ widget ]( "instance" ) ); |
|
6455 |
|
6456 childWidgets.push( widgetElement[ 0 ] ); |
|
6457 } ); |
|
6458 } ); |
|
6459 |
|
6460 this.childWidgets = $( $.uniqueSort( childWidgets ) ); |
|
6461 this._addClass( this.childWidgets, "ui-controlgroup-item" ); |
|
6462 }, |
|
6463 |
|
6464 _callChildMethod: function( method ) { |
|
6465 this.childWidgets.each( function() { |
|
6466 var element = $( this ), |
|
6467 data = element.data( "ui-controlgroup-data" ); |
|
6468 if ( data && data[ method ] ) { |
|
6469 data[ method ](); |
|
6470 } |
|
6471 } ); |
|
6472 }, |
|
6473 |
|
6474 _updateCornerClass: function( element, position ) { |
|
6475 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; |
|
6476 var add = this._buildSimpleOptions( position, "label" ).classes.label; |
|
6477 |
|
6478 this._removeClass( element, null, remove ); |
|
6479 this._addClass( element, null, add ); |
|
6480 }, |
|
6481 |
|
6482 _buildSimpleOptions: function( position, key ) { |
|
6483 var direction = this.options.direction === "vertical"; |
|
6484 var result = { |
|
6485 classes: {} |
|
6486 }; |
|
6487 result.classes[ key ] = { |
|
6488 "middle": "", |
|
6489 "first": "ui-corner-" + ( direction ? "top" : "left" ), |
|
6490 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), |
|
6491 "only": "ui-corner-all" |
|
6492 }[ position ]; |
|
6493 |
|
6494 return result; |
|
6495 }, |
|
6496 |
|
6497 _spinnerOptions: function( position ) { |
|
6498 var options = this._buildSimpleOptions( position, "ui-spinner" ); |
|
6499 |
|
6500 options.classes[ "ui-spinner-up" ] = ""; |
|
6501 options.classes[ "ui-spinner-down" ] = ""; |
|
6502 |
|
6503 return options; |
|
6504 }, |
|
6505 |
|
6506 _buttonOptions: function( position ) { |
|
6507 return this._buildSimpleOptions( position, "ui-button" ); |
|
6508 }, |
|
6509 |
|
6510 _checkboxradioOptions: function( position ) { |
|
6511 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); |
|
6512 }, |
|
6513 |
|
6514 _selectmenuOptions: function( position ) { |
|
6515 var direction = this.options.direction === "vertical"; |
|
6516 return { |
|
6517 width: direction ? "auto" : false, |
|
6518 classes: { |
|
6519 middle: { |
|
6520 "ui-selectmenu-button-open": "", |
|
6521 "ui-selectmenu-button-closed": "" |
|
6522 }, |
|
6523 first: { |
|
6524 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), |
|
6525 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) |
|
6526 }, |
|
6527 last: { |
|
6528 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", |
|
6529 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) |
|
6530 }, |
|
6531 only: { |
|
6532 "ui-selectmenu-button-open": "ui-corner-top", |
|
6533 "ui-selectmenu-button-closed": "ui-corner-all" |
|
6534 } |
|
6535 |
|
6536 }[ position ] |
|
6537 }; |
|
6538 }, |
|
6539 |
|
6540 _resolveClassesValues: function( classes, instance ) { |
|
6541 var result = {}; |
|
6542 $.each( classes, function( key ) { |
|
6543 var current = instance.options.classes[ key ] || ""; |
|
6544 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); |
|
6545 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); |
|
6546 } ); |
|
6547 return result; |
|
6548 }, |
|
6549 |
|
6550 _setOption: function( key, value ) { |
|
6551 if ( key === "direction" ) { |
|
6552 this._removeClass( "ui-controlgroup-" + this.options.direction ); |
|
6553 } |
|
6554 |
|
6555 this._super( key, value ); |
|
6556 if ( key === "disabled" ) { |
|
6557 this._callChildMethod( value ? "disable" : "enable" ); |
|
6558 return; |
|
6559 } |
|
6560 |
|
6561 this.refresh(); |
|
6562 }, |
|
6563 |
|
6564 refresh: function() { |
|
6565 var children, |
|
6566 that = this; |
|
6567 |
|
6568 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); |
|
6569 |
|
6570 if ( this.options.direction === "horizontal" ) { |
|
6571 this._addClass( null, "ui-helper-clearfix" ); |
|
6572 } |
|
6573 this._initWidgets(); |
|
6574 |
|
6575 children = this.childWidgets; |
|
6576 |
|
6577 // We filter here because we need to track all childWidgets not just the visible ones |
|
6578 if ( this.options.onlyVisible ) { |
|
6579 children = children.filter( ":visible" ); |
|
6580 } |
|
6581 |
|
6582 if ( children.length ) { |
|
6583 |
|
6584 // We do this last because we need to make sure all enhancment is done |
|
6585 // before determining first and last |
|
6586 $.each( [ "first", "last" ], function( index, value ) { |
|
6587 var instance = children[ value ]().data( "ui-controlgroup-data" ); |
|
6588 |
|
6589 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { |
|
6590 var options = that[ "_" + instance.widgetName + "Options" ]( |
|
6591 children.length === 1 ? "only" : value |
|
6592 ); |
|
6593 options.classes = that._resolveClassesValues( options.classes, instance ); |
|
6594 instance.element[ instance.widgetName ]( options ); |
|
6595 } else { |
|
6596 that._updateCornerClass( children[ value ](), value ); |
|
6597 } |
|
6598 } ); |
|
6599 |
|
6600 // Finally call the refresh method on each of the child widgets. |
|
6601 this._callChildMethod( "refresh" ); |
|
6602 } |
|
6603 } |
|
6604 } ); |
|
6605 |
|
6606 /*! |
|
6607 * jQuery UI Checkboxradio 1.13.2 |
|
6608 * http://jqueryui.com |
|
6609 * |
|
6610 * Copyright jQuery Foundation and other contributors |
|
6611 * Released under the MIT license. |
|
6612 * http://jquery.org/license |
|
6613 */ |
|
6614 |
|
6615 //>>label: Checkboxradio |
|
6616 //>>group: Widgets |
|
6617 //>>description: Enhances a form with multiple themeable checkboxes or radio buttons. |
|
6618 //>>docs: http://api.jqueryui.com/checkboxradio/ |
|
6619 //>>demos: http://jqueryui.com/checkboxradio/ |
|
6620 //>>css.structure: ../../themes/base/core.css |
|
6621 //>>css.structure: ../../themes/base/button.css |
|
6622 //>>css.structure: ../../themes/base/checkboxradio.css |
|
6623 //>>css.theme: ../../themes/base/theme.css |
|
6624 |
|
6625 |
|
6626 $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { |
|
6627 version: "1.13.2", |
|
6628 options: { |
|
6629 disabled: null, |
|
6630 label: null, |
|
6631 icon: true, |
|
6632 classes: { |
|
6633 "ui-checkboxradio-label": "ui-corner-all", |
|
6634 "ui-checkboxradio-icon": "ui-corner-all" |
|
6635 } |
|
6636 }, |
|
6637 |
|
6638 _getCreateOptions: function() { |
|
6639 var disabled, labels, labelContents; |
|
6640 var options = this._super() || {}; |
|
6641 |
|
6642 // We read the type here, because it makes more sense to throw a element type error first, |
|
6643 // rather then the error for lack of a label. Often if its the wrong type, it |
|
6644 // won't have a label (e.g. calling on a div, btn, etc) |
|
6645 this._readType(); |
|
6646 |
|
6647 labels = this.element.labels(); |
|
6648 |
|
6649 // If there are multiple labels, use the last one |
|
6650 this.label = $( labels[ labels.length - 1 ] ); |
|
6651 if ( !this.label.length ) { |
|
6652 $.error( "No label found for checkboxradio widget" ); |
|
6653 } |
|
6654 |
|
6655 this.originalLabel = ""; |
|
6656 |
|
6657 // We need to get the label text but this may also need to make sure it does not contain the |
|
6658 // input itself. |
|
6659 // The label contents could be text, html, or a mix. We wrap all elements |
|
6660 // and read the wrapper's `innerHTML` to get a string representation of |
|
6661 // the label, without the input as part of it. |
|
6662 labelContents = this.label.contents().not( this.element[ 0 ] ); |
|
6663 |
|
6664 if ( labelContents.length ) { |
|
6665 this.originalLabel += labelContents |
|
6666 .clone() |
|
6667 .wrapAll( "<div></div>" ) |
|
6668 .parent() |
|
6669 .html(); |
|
6670 } |
|
6671 |
|
6672 // Set the label option if we found label text |
|
6673 if ( this.originalLabel ) { |
|
6674 options.label = this.originalLabel; |
|
6675 } |
|
6676 |
|
6677 disabled = this.element[ 0 ].disabled; |
|
6678 if ( disabled != null ) { |
|
6679 options.disabled = disabled; |
|
6680 } |
|
6681 return options; |
|
6682 }, |
|
6683 |
|
6684 _create: function() { |
|
6685 var checked = this.element[ 0 ].checked; |
|
6686 |
|
6687 this._bindFormResetHandler(); |
|
6688 |
|
6689 if ( this.options.disabled == null ) { |
|
6690 this.options.disabled = this.element[ 0 ].disabled; |
|
6691 } |
|
6692 |
|
6693 this._setOption( "disabled", this.options.disabled ); |
|
6694 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); |
|
6695 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); |
|
6696 |
|
6697 if ( this.type === "radio" ) { |
|
6698 this._addClass( this.label, "ui-checkboxradio-radio-label" ); |
|
6699 } |
|
6700 |
|
6701 if ( this.options.label && this.options.label !== this.originalLabel ) { |
|
6702 this._updateLabel(); |
|
6703 } else if ( this.originalLabel ) { |
|
6704 this.options.label = this.originalLabel; |
|
6705 } |
|
6706 |
|
6707 this._enhance(); |
|
6708 |
|
6709 if ( checked ) { |
|
6710 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); |
|
6711 } |
|
6712 |
|
6713 this._on( { |
|
6714 change: "_toggleClasses", |
|
6715 focus: function() { |
|
6716 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); |
|
6717 }, |
|
6718 blur: function() { |
|
6719 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); |
|
6720 } |
|
6721 } ); |
|
6722 }, |
|
6723 |
|
6724 _readType: function() { |
|
6725 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); |
|
6726 this.type = this.element[ 0 ].type; |
|
6727 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { |
|
6728 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + |
|
6729 " and element.type=" + this.type ); |
|
6730 } |
|
6731 }, |
|
6732 |
|
6733 // Support jQuery Mobile enhanced option |
|
6734 _enhance: function() { |
|
6735 this._updateIcon( this.element[ 0 ].checked ); |
|
6736 }, |
|
6737 |
|
6738 widget: function() { |
|
6739 return this.label; |
|
6740 }, |
|
6741 |
|
6742 _getRadioGroup: function() { |
|
6743 var group; |
|
6744 var name = this.element[ 0 ].name; |
|
6745 var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; |
|
6746 |
|
6747 if ( !name ) { |
|
6748 return $( [] ); |
|
6749 } |
|
6750 |
|
6751 if ( this.form.length ) { |
|
6752 group = $( this.form[ 0 ].elements ).filter( nameSelector ); |
|
6753 } else { |
|
6754 |
|
6755 // Not inside a form, check all inputs that also are not inside a form |
|
6756 group = $( nameSelector ).filter( function() { |
|
6757 return $( this )._form().length === 0; |
|
6758 } ); |
|
6759 } |
|
6760 |
|
6761 return group.not( this.element ); |
|
6762 }, |
|
6763 |
|
6764 _toggleClasses: function() { |
|
6765 var checked = this.element[ 0 ].checked; |
|
6766 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); |
|
6767 |
|
6768 if ( this.options.icon && this.type === "checkbox" ) { |
|
6769 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) |
|
6770 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); |
|
6771 } |
|
6772 |
|
6773 if ( this.type === "radio" ) { |
|
6774 this._getRadioGroup() |
|
6775 .each( function() { |
|
6776 var instance = $( this ).checkboxradio( "instance" ); |
|
6777 |
|
6778 if ( instance ) { |
|
6779 instance._removeClass( instance.label, |
|
6780 "ui-checkboxradio-checked", "ui-state-active" ); |
|
6781 } |
|
6782 } ); |
|
6783 } |
|
6784 }, |
|
6785 |
|
6786 _destroy: function() { |
|
6787 this._unbindFormResetHandler(); |
|
6788 |
|
6789 if ( this.icon ) { |
|
6790 this.icon.remove(); |
|
6791 this.iconSpace.remove(); |
|
6792 } |
|
6793 }, |
|
6794 |
|
6795 _setOption: function( key, value ) { |
|
6796 |
|
6797 // We don't allow the value to be set to nothing |
|
6798 if ( key === "label" && !value ) { |
|
6799 return; |
|
6800 } |
|
6801 |
|
6802 this._super( key, value ); |
|
6803 |
|
6804 if ( key === "disabled" ) { |
|
6805 this._toggleClass( this.label, null, "ui-state-disabled", value ); |
|
6806 this.element[ 0 ].disabled = value; |
|
6807 |
|
6808 // Don't refresh when setting disabled |
|
6809 return; |
|
6810 } |
|
6811 this.refresh(); |
|
6812 }, |
|
6813 |
|
6814 _updateIcon: function( checked ) { |
|
6815 var toAdd = "ui-icon ui-icon-background "; |
|
6816 |
|
6817 if ( this.options.icon ) { |
|
6818 if ( !this.icon ) { |
|
6819 this.icon = $( "<span>" ); |
|
6820 this.iconSpace = $( "<span> </span>" ); |
|
6821 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); |
|
6822 } |
|
6823 |
|
6824 if ( this.type === "checkbox" ) { |
|
6825 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; |
|
6826 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); |
|
6827 } else { |
|
6828 toAdd += "ui-icon-blank"; |
|
6829 } |
|
6830 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); |
|
6831 if ( !checked ) { |
|
6832 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); |
|
6833 } |
|
6834 this.icon.prependTo( this.label ).after( this.iconSpace ); |
|
6835 } else if ( this.icon !== undefined ) { |
|
6836 this.icon.remove(); |
|
6837 this.iconSpace.remove(); |
|
6838 delete this.icon; |
|
6839 } |
|
6840 }, |
|
6841 |
|
6842 _updateLabel: function() { |
|
6843 |
|
6844 // Remove the contents of the label ( minus the icon, icon space, and input ) |
|
6845 var contents = this.label.contents().not( this.element[ 0 ] ); |
|
6846 if ( this.icon ) { |
|
6847 contents = contents.not( this.icon[ 0 ] ); |
|
6848 } |
|
6849 if ( this.iconSpace ) { |
|
6850 contents = contents.not( this.iconSpace[ 0 ] ); |
|
6851 } |
|
6852 contents.remove(); |
|
6853 |
|
6854 this.label.append( this.options.label ); |
|
6855 }, |
|
6856 |
|
6857 refresh: function() { |
|
6858 var checked = this.element[ 0 ].checked, |
|
6859 isDisabled = this.element[ 0 ].disabled; |
|
6860 |
|
6861 this._updateIcon( checked ); |
|
6862 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); |
|
6863 if ( this.options.label !== null ) { |
|
6864 this._updateLabel(); |
|
6865 } |
|
6866 |
|
6867 if ( isDisabled !== this.options.disabled ) { |
|
6868 this._setOptions( { "disabled": isDisabled } ); |
|
6869 } |
|
6870 } |
|
6871 |
|
6872 } ] ); |
|
6873 |
|
6874 var widgetsCheckboxradio = $.ui.checkboxradio; |
|
6875 |
|
6876 |
|
6877 /*! |
|
6878 * jQuery UI Button 1.13.2 |
|
6879 * http://jqueryui.com |
|
6880 * |
|
6881 * Copyright jQuery Foundation and other contributors |
|
6882 * Released under the MIT license. |
|
6883 * http://jquery.org/license |
|
6884 */ |
|
6885 |
|
6886 //>>label: Button |
|
6887 //>>group: Widgets |
|
6888 //>>description: Enhances a form with themeable buttons. |
|
6889 //>>docs: http://api.jqueryui.com/button/ |
|
6890 //>>demos: http://jqueryui.com/button/ |
|
6891 //>>css.structure: ../../themes/base/core.css |
|
6892 //>>css.structure: ../../themes/base/button.css |
|
6893 //>>css.theme: ../../themes/base/theme.css |
|
6894 |
|
6895 |
|
6896 $.widget( "ui.button", { |
|
6897 version: "1.13.2", |
|
6898 defaultElement: "<button>", |
|
6899 options: { |
|
6900 classes: { |
|
6901 "ui-button": "ui-corner-all" |
|
6902 }, |
|
6903 disabled: null, |
|
6904 icon: null, |
|
6905 iconPosition: "beginning", |
|
6906 label: null, |
|
6907 showLabel: true |
|
6908 }, |
|
6909 |
|
6910 _getCreateOptions: function() { |
|
6911 var disabled, |
|
6912 |
|
6913 // This is to support cases like in jQuery Mobile where the base widget does have |
|
6914 // an implementation of _getCreateOptions |
|
6915 options = this._super() || {}; |
|
6916 |
|
6917 this.isInput = this.element.is( "input" ); |
|
6918 |
|
6919 disabled = this.element[ 0 ].disabled; |
|
6920 if ( disabled != null ) { |
|
6921 options.disabled = disabled; |
|
6922 } |
|
6923 |
|
6924 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); |
|
6925 if ( this.originalLabel ) { |
|
6926 options.label = this.originalLabel; |
|
6927 } |
|
6928 |
|
6929 return options; |
|
6930 }, |
|
6931 |
|
6932 _create: function() { |
|
6933 if ( !this.option.showLabel & !this.options.icon ) { |
|
6934 this.options.showLabel = true; |
|
6935 } |
|
6936 |
|
6937 // We have to check the option again here even though we did in _getCreateOptions, |
|
6938 // because null may have been passed on init which would override what was set in |
|
6939 // _getCreateOptions |
|
6940 if ( this.options.disabled == null ) { |
|
6941 this.options.disabled = this.element[ 0 ].disabled || false; |
|
6942 } |
|
6943 |
|
6944 this.hasTitle = !!this.element.attr( "title" ); |
|
6945 |
|
6946 // Check to see if the label needs to be set or if its already correct |
|
6947 if ( this.options.label && this.options.label !== this.originalLabel ) { |
|
6948 if ( this.isInput ) { |
|
6949 this.element.val( this.options.label ); |
|
6950 } else { |
|
6951 this.element.html( this.options.label ); |
|
6952 } |
|
6953 } |
|
6954 this._addClass( "ui-button", "ui-widget" ); |
|
6955 this._setOption( "disabled", this.options.disabled ); |
|
6956 this._enhance(); |
|
6957 |
|
6958 if ( this.element.is( "a" ) ) { |
|
6959 this._on( { |
|
6960 "keyup": function( event ) { |
|
6961 if ( event.keyCode === $.ui.keyCode.SPACE ) { |
|
6962 event.preventDefault(); |
|
6963 |
|
6964 // Support: PhantomJS <= 1.9, IE 8 Only |
|
6965 // If a native click is available use it so we actually cause navigation |
|
6966 // otherwise just trigger a click event |
|
6967 if ( this.element[ 0 ].click ) { |
|
6968 this.element[ 0 ].click(); |
|
6969 } else { |
|
6970 this.element.trigger( "click" ); |
|
6971 } |
|
6972 } |
|
6973 } |
|
6974 } ); |
|
6975 } |
|
6976 }, |
|
6977 |
|
6978 _enhance: function() { |
|
6979 if ( !this.element.is( "button" ) ) { |
|
6980 this.element.attr( "role", "button" ); |
|
6981 } |
|
6982 |
|
6983 if ( this.options.icon ) { |
|
6984 this._updateIcon( "icon", this.options.icon ); |
|
6985 this._updateTooltip(); |
|
6986 } |
|
6987 }, |
|
6988 |
|
6989 _updateTooltip: function() { |
|
6990 this.title = this.element.attr( "title" ); |
|
6991 |
|
6992 if ( !this.options.showLabel && !this.title ) { |
|
6993 this.element.attr( "title", this.options.label ); |
|
6994 } |
|
6995 }, |
|
6996 |
|
6997 _updateIcon: function( option, value ) { |
|
6998 var icon = option !== "iconPosition", |
|
6999 position = icon ? this.options.iconPosition : value, |
|
7000 displayBlock = position === "top" || position === "bottom"; |
|
7001 |
|
7002 // Create icon |
|
7003 if ( !this.icon ) { |
|
7004 this.icon = $( "<span>" ); |
|
7005 |
|
7006 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); |
|
7007 |
|
7008 if ( !this.options.showLabel ) { |
|
7009 this._addClass( "ui-button-icon-only" ); |
|
7010 } |
|
7011 } else if ( icon ) { |
|
7012 |
|
7013 // If we are updating the icon remove the old icon class |
|
7014 this._removeClass( this.icon, null, this.options.icon ); |
|
7015 } |
|
7016 |
|
7017 // If we are updating the icon add the new icon class |
|
7018 if ( icon ) { |
|
7019 this._addClass( this.icon, null, value ); |
|
7020 } |
|
7021 |
|
7022 this._attachIcon( position ); |
|
7023 |
|
7024 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove |
|
7025 // the iconSpace if there is one. |
|
7026 if ( displayBlock ) { |
|
7027 this._addClass( this.icon, null, "ui-widget-icon-block" ); |
|
7028 if ( this.iconSpace ) { |
|
7029 this.iconSpace.remove(); |
|
7030 } |
|
7031 } else { |
|
7032 |
|
7033 // Position is beginning or end so remove the ui-widget-icon-block class and add the |
|
7034 // space if it does not exist |
|
7035 if ( !this.iconSpace ) { |
|
7036 this.iconSpace = $( "<span> </span>" ); |
|
7037 this._addClass( this.iconSpace, "ui-button-icon-space" ); |
|
7038 } |
|
7039 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); |
|
7040 this._attachIconSpace( position ); |
|
7041 } |
|
7042 }, |
|
7043 |
|
7044 _destroy: function() { |
|
7045 this.element.removeAttr( "role" ); |
|
7046 |
|
7047 if ( this.icon ) { |
|
7048 this.icon.remove(); |
|
7049 } |
|
7050 if ( this.iconSpace ) { |
|
7051 this.iconSpace.remove(); |
|
7052 } |
|
7053 if ( !this.hasTitle ) { |
|
7054 this.element.removeAttr( "title" ); |
|
7055 } |
|
7056 }, |
|
7057 |
|
7058 _attachIconSpace: function( iconPosition ) { |
|
7059 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); |
|
7060 }, |
|
7061 |
|
7062 _attachIcon: function( iconPosition ) { |
|
7063 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); |
|
7064 }, |
|
7065 |
|
7066 _setOptions: function( options ) { |
|
7067 var newShowLabel = options.showLabel === undefined ? |
|
7068 this.options.showLabel : |
|
7069 options.showLabel, |
|
7070 newIcon = options.icon === undefined ? this.options.icon : options.icon; |
|
7071 |
|
7072 if ( !newShowLabel && !newIcon ) { |
|
7073 options.showLabel = true; |
|
7074 } |
|
7075 this._super( options ); |
|
7076 }, |
|
7077 |
|
7078 _setOption: function( key, value ) { |
|
7079 if ( key === "icon" ) { |
|
7080 if ( value ) { |
|
7081 this._updateIcon( key, value ); |
|
7082 } else if ( this.icon ) { |
|
7083 this.icon.remove(); |
|
7084 if ( this.iconSpace ) { |
|
7085 this.iconSpace.remove(); |
|
7086 } |
|
7087 } |
|
7088 } |
|
7089 |
|
7090 if ( key === "iconPosition" ) { |
|
7091 this._updateIcon( key, value ); |
|
7092 } |
|
7093 |
|
7094 // Make sure we can't end up with a button that has neither text nor icon |
|
7095 if ( key === "showLabel" ) { |
|
7096 this._toggleClass( "ui-button-icon-only", null, !value ); |
|
7097 this._updateTooltip(); |
|
7098 } |
|
7099 |
|
7100 if ( key === "label" ) { |
|
7101 if ( this.isInput ) { |
|
7102 this.element.val( value ); |
|
7103 } else { |
|
7104 |
|
7105 // If there is an icon, append it, else nothing then append the value |
|
7106 // this avoids removal of the icon when setting label text |
|
7107 this.element.html( value ); |
|
7108 if ( this.icon ) { |
|
7109 this._attachIcon( this.options.iconPosition ); |
|
7110 this._attachIconSpace( this.options.iconPosition ); |
|
7111 } |
|
7112 } |
|
7113 } |
|
7114 |
|
7115 this._super( key, value ); |
|
7116 |
|
7117 if ( key === "disabled" ) { |
|
7118 this._toggleClass( null, "ui-state-disabled", value ); |
|
7119 this.element[ 0 ].disabled = value; |
|
7120 if ( value ) { |
|
7121 this.element.trigger( "blur" ); |
|
7122 } |
|
7123 } |
|
7124 }, |
|
7125 |
|
7126 refresh: function() { |
|
7127 |
|
7128 // Make sure to only check disabled if its an element that supports this otherwise |
|
7129 // check for the disabled class to determine state |
|
7130 var isDisabled = this.element.is( "input, button" ) ? |
|
7131 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); |
|
7132 |
|
7133 if ( isDisabled !== this.options.disabled ) { |
|
7134 this._setOptions( { disabled: isDisabled } ); |
|
7135 } |
|
7136 |
|
7137 this._updateTooltip(); |
|
7138 } |
|
7139 } ); |
|
7140 |
|
7141 // DEPRECATED |
|
7142 if ( $.uiBackCompat !== false ) { |
|
7143 |
|
7144 // Text and Icons options |
|
7145 $.widget( "ui.button", $.ui.button, { |
|
7146 options: { |
|
7147 text: true, |
|
7148 icons: { |
|
7149 primary: null, |
|
7150 secondary: null |
|
7151 } |
|
7152 }, |
|
7153 |
|
7154 _create: function() { |
|
7155 if ( this.options.showLabel && !this.options.text ) { |
|
7156 this.options.showLabel = this.options.text; |
|
7157 } |
|
7158 if ( !this.options.showLabel && this.options.text ) { |
|
7159 this.options.text = this.options.showLabel; |
|
7160 } |
|
7161 if ( !this.options.icon && ( this.options.icons.primary || |
|
7162 this.options.icons.secondary ) ) { |
|
7163 if ( this.options.icons.primary ) { |
|
7164 this.options.icon = this.options.icons.primary; |
|
7165 } else { |
|
7166 this.options.icon = this.options.icons.secondary; |
|
7167 this.options.iconPosition = "end"; |
|
7168 } |
|
7169 } else if ( this.options.icon ) { |
|
7170 this.options.icons.primary = this.options.icon; |
|
7171 } |
|
7172 this._super(); |
|
7173 }, |
|
7174 |
|
7175 _setOption: function( key, value ) { |
|
7176 if ( key === "text" ) { |
|
7177 this._super( "showLabel", value ); |
|
7178 return; |
|
7179 } |
|
7180 if ( key === "showLabel" ) { |
|
7181 this.options.text = value; |
|
7182 } |
|
7183 if ( key === "icon" ) { |
|
7184 this.options.icons.primary = value; |
|
7185 } |
|
7186 if ( key === "icons" ) { |
|
7187 if ( value.primary ) { |
|
7188 this._super( "icon", value.primary ); |
|
7189 this._super( "iconPosition", "beginning" ); |
|
7190 } else if ( value.secondary ) { |
|
7191 this._super( "icon", value.secondary ); |
|
7192 this._super( "iconPosition", "end" ); |
|
7193 } |
|
7194 } |
|
7195 this._superApply( arguments ); |
|
7196 } |
|
7197 } ); |
|
7198 |
|
7199 $.fn.button = ( function( orig ) { |
|
7200 return function( options ) { |
|
7201 var isMethodCall = typeof options === "string"; |
|
7202 var args = Array.prototype.slice.call( arguments, 1 ); |
|
7203 var returnValue = this; |
|
7204 |
|
7205 if ( isMethodCall ) { |
|
7206 |
|
7207 // If this is an empty collection, we need to have the instance method |
|
7208 // return undefined instead of the jQuery instance |
|
7209 if ( !this.length && options === "instance" ) { |
|
7210 returnValue = undefined; |
|
7211 } else { |
|
7212 this.each( function() { |
|
7213 var methodValue; |
|
7214 var type = $( this ).attr( "type" ); |
|
7215 var name = type !== "checkbox" && type !== "radio" ? |
|
7216 "button" : |
|
7217 "checkboxradio"; |
|
7218 var instance = $.data( this, "ui-" + name ); |
|
7219 |
|
7220 if ( options === "instance" ) { |
|
7221 returnValue = instance; |
|
7222 return false; |
|
7223 } |
|
7224 |
|
7225 if ( !instance ) { |
|
7226 return $.error( "cannot call methods on button" + |
|
7227 " prior to initialization; " + |
|
7228 "attempted to call method '" + options + "'" ); |
|
7229 } |
|
7230 |
|
7231 if ( typeof instance[ options ] !== "function" || |
|
7232 options.charAt( 0 ) === "_" ) { |
|
7233 return $.error( "no such method '" + options + "' for button" + |
|
7234 " widget instance" ); |
|
7235 } |
|
7236 |
|
7237 methodValue = instance[ options ].apply( instance, args ); |
|
7238 |
|
7239 if ( methodValue !== instance && methodValue !== undefined ) { |
|
7240 returnValue = methodValue && methodValue.jquery ? |
|
7241 returnValue.pushStack( methodValue.get() ) : |
|
7242 methodValue; |
|
7243 return false; |
|
7244 } |
|
7245 } ); |
|
7246 } |
|
7247 } else { |
|
7248 |
|
7249 // Allow multiple hashes to be passed on init |
|
7250 if ( args.length ) { |
|
7251 options = $.widget.extend.apply( null, [ options ].concat( args ) ); |
|
7252 } |
|
7253 |
|
7254 this.each( function() { |
|
7255 var type = $( this ).attr( "type" ); |
|
7256 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; |
|
7257 var instance = $.data( this, "ui-" + name ); |
|
7258 |
|
7259 if ( instance ) { |
|
7260 instance.option( options || {} ); |
|
7261 if ( instance._init ) { |
|
7262 instance._init(); |
|
7263 } |
|
7264 } else { |
|
7265 if ( name === "button" ) { |
|
7266 orig.call( $( this ), options ); |
|
7267 return; |
|
7268 } |
|
7269 |
|
7270 $( this ).checkboxradio( $.extend( { icon: false }, options ) ); |
|
7271 } |
|
7272 } ); |
|
7273 } |
|
7274 |
|
7275 return returnValue; |
|
7276 }; |
|
7277 } )( $.fn.button ); |
|
7278 |
|
7279 $.fn.buttonset = function() { |
|
7280 if ( !$.ui.controlgroup ) { |
|
7281 $.error( "Controlgroup widget missing" ); |
|
7282 } |
|
7283 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { |
|
7284 return this.controlgroup.apply( this, |
|
7285 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); |
|
7286 } |
|
7287 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { |
|
7288 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); |
|
7289 } |
|
7290 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { |
|
7291 arguments[ 0 ].items = { |
|
7292 button: arguments[ 0 ].items |
|
7293 }; |
|
7294 } |
|
7295 return this.controlgroup.apply( this, arguments ); |
|
7296 }; |
|
7297 } |
|
7298 |
|
7299 var widgetsButton = $.ui.button; |
|
7300 |
|
7301 |
|
7302 /* eslint-disable max-len, camelcase */ |
|
7303 /*! |
|
7304 * jQuery UI Datepicker 1.13.2 |
|
7305 * http://jqueryui.com |
|
7306 * |
|
7307 * Copyright jQuery Foundation and other contributors |
|
7308 * Released under the MIT license. |
|
7309 * http://jquery.org/license |
|
7310 */ |
|
7311 |
|
7312 //>>label: Datepicker |
|
7313 //>>group: Widgets |
|
7314 //>>description: Displays a calendar from an input or inline for selecting dates. |
|
7315 //>>docs: http://api.jqueryui.com/datepicker/ |
|
7316 //>>demos: http://jqueryui.com/datepicker/ |
|
7317 //>>css.structure: ../../themes/base/core.css |
|
7318 //>>css.structure: ../../themes/base/datepicker.css |
|
7319 //>>css.theme: ../../themes/base/theme.css |
|
7320 |
|
7321 |
|
7322 $.extend( $.ui, { datepicker: { version: "1.13.2" } } ); |
|
7323 |
|
7324 var datepicker_instActive; |
|
7325 |
|
7326 function datepicker_getZindex( elem ) { |
|
7327 var position, value; |
|
7328 while ( elem.length && elem[ 0 ] !== document ) { |
|
7329 |
|
7330 // Ignore z-index if position is set to a value where z-index is ignored by the browser |
|
7331 // This makes behavior of this function consistent across browsers |
|
7332 // WebKit always returns auto if the element is positioned |
|
7333 position = elem.css( "position" ); |
|
7334 if ( position === "absolute" || position === "relative" || position === "fixed" ) { |
|
7335 |
|
7336 // IE returns 0 when zIndex is not specified |
|
7337 // other browsers return a string |
|
7338 // we ignore the case of nested elements with an explicit value of 0 |
|
7339 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> |
|
7340 value = parseInt( elem.css( "zIndex" ), 10 ); |
|
7341 if ( !isNaN( value ) && value !== 0 ) { |
|
7342 return value; |
|
7343 } |
|
7344 } |
|
7345 elem = elem.parent(); |
|
7346 } |
|
7347 |
|
7348 return 0; |
|
7349 } |
|
7350 |
|
7351 /* Date picker manager. |
|
7352 Use the singleton instance of this class, $.datepicker, to interact with the date picker. |
|
7353 Settings for (groups of) date pickers are maintained in an instance object, |
|
7354 allowing multiple different settings on the same page. */ |
|
7355 |
|
7356 function Datepicker() { |
|
7357 this._curInst = null; // The current instance in use |
|
7358 this._keyEvent = false; // If the last event was a key event |
|
7359 this._disabledInputs = []; // List of date picker inputs that have been disabled |
|
7360 this._datepickerShowing = false; // True if the popup picker is showing , false if not |
|
7361 this._inDialog = false; // True if showing within a "dialog", false if not |
|
7362 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division |
|
7363 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class |
|
7364 this._appendClass = "ui-datepicker-append"; // The name of the append marker class |
|
7365 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class |
|
7366 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class |
|
7367 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class |
|
7368 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class |
|
7369 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class |
|
7370 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class |
|
7371 this.regional = []; // Available regional settings, indexed by language code |
|
7372 this.regional[ "" ] = { // Default regional settings |
|
7373 closeText: "Done", // Display text for close link |
|
7374 prevText: "Prev", // Display text for previous month link |
|
7375 nextText: "Next", // Display text for next month link |
|
7376 currentText: "Today", // Display text for current month link |
|
7377 monthNames: [ "January", "February", "March", "April", "May", "June", |
|
7378 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting |
|
7379 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting |
|
7380 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting |
|
7381 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting |
|
7382 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday |
|
7383 weekHeader: "Wk", // Column header for week of the year |
|
7384 dateFormat: "mm/dd/yy", // See format options on parseDate |
|
7385 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... |
|
7386 isRTL: false, // True if right-to-left language, false if left-to-right |
|
7387 showMonthAfterYear: false, // True if the year select precedes month, false for month then year |
|
7388 yearSuffix: "", // Additional text to append to the year in the month headers, |
|
7389 selectMonthLabel: "Select month", // Invisible label for month selector |
|
7390 selectYearLabel: "Select year" // Invisible label for year selector |
|
7391 }; |
|
7392 this._defaults = { // Global defaults for all the date picker instances |
|
7393 showOn: "focus", // "focus" for popup on focus, |
|
7394 // "button" for trigger button, or "both" for either |
|
7395 showAnim: "fadeIn", // Name of jQuery animation for popup |
|
7396 showOptions: {}, // Options for enhanced animations |
|
7397 defaultDate: null, // Used when field is blank: actual date, |
|
7398 // +/-number for offset from today, null for today |
|
7399 appendText: "", // Display text following the input box, e.g. showing the format |
|
7400 buttonText: "...", // Text for trigger button |
|
7401 buttonImage: "", // URL for trigger button image |
|
7402 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button |
|
7403 hideIfNoPrevNext: false, // True to hide next/previous month links |
|
7404 // if not applicable, false to just disable them |
|
7405 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links |
|
7406 gotoCurrent: false, // True if today link goes back to current selection instead |
|
7407 changeMonth: false, // True if month can be selected directly, false if only prev/next |
|
7408 changeYear: false, // True if year can be selected directly, false if only prev/next |
|
7409 yearRange: "c-10:c+10", // Range of years to display in drop-down, |
|
7410 // either relative to today's year (-nn:+nn), relative to currently displayed year |
|
7411 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) |
|
7412 showOtherMonths: false, // True to show dates in other months, false to leave blank |
|
7413 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable |
|
7414 showWeek: false, // True to show week of the year, false to not show it |
|
7415 calculateWeek: this.iso8601Week, // How to calculate the week of the year, |
|
7416 // takes a Date and returns the number of the week for it |
|
7417 shortYearCutoff: "+10", // Short year values < this are in the current century, |
|
7418 // > this are in the previous century, |
|
7419 // string value starting with "+" for current year + value |
|
7420 minDate: null, // The earliest selectable date, or null for no limit |
|
7421 maxDate: null, // The latest selectable date, or null for no limit |
|
7422 duration: "fast", // Duration of display/closure |
|
7423 beforeShowDay: null, // Function that takes a date and returns an array with |
|
7424 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", |
|
7425 // [2] = cell title (optional), e.g. $.datepicker.noWeekends |
|
7426 beforeShow: null, // Function that takes an input field and |
|
7427 // returns a set of custom settings for the date picker |
|
7428 onSelect: null, // Define a callback function when a date is selected |
|
7429 onChangeMonthYear: null, // Define a callback function when the month or year is changed |
|
7430 onClose: null, // Define a callback function when the datepicker is closed |
|
7431 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated |
|
7432 numberOfMonths: 1, // Number of months to show at a time |
|
7433 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) |
|
7434 stepMonths: 1, // Number of months to step back/forward |
|
7435 stepBigMonths: 12, // Number of months to step back/forward for the big links |
|
7436 altField: "", // Selector for an alternate field to store selected dates into |
|
7437 altFormat: "", // The date format to use for the alternate field |
|
7438 constrainInput: true, // The input is constrained by the current date format |
|
7439 showButtonPanel: false, // True to show button panel, false to not show it |
|
7440 autoSize: false, // True to size the input for the date format, false to leave as is |
|
7441 disabled: false // The initial disabled state |
|
7442 }; |
|
7443 $.extend( this._defaults, this.regional[ "" ] ); |
|
7444 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); |
|
7445 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); |
|
7446 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); |
|
7447 } |
|
7448 |
|
7449 $.extend( Datepicker.prototype, { |
|
7450 |
|
7451 /* Class name added to elements to indicate already configured with a date picker. */ |
|
7452 markerClassName: "hasDatepicker", |
|
7453 |
|
7454 //Keep track of the maximum number of rows displayed (see #7043) |
|
7455 maxRows: 4, |
|
7456 |
|
7457 // TODO rename to "widget" when switching to widget factory |
|
7458 _widgetDatepicker: function() { |
|
7459 return this.dpDiv; |
|
7460 }, |
|
7461 |
|
7462 /* Override the default settings for all instances of the date picker. |
|
7463 * @param settings object - the new settings to use as defaults (anonymous object) |
|
7464 * @return the manager object |
|
7465 */ |
|
7466 setDefaults: function( settings ) { |
|
7467 datepicker_extendRemove( this._defaults, settings || {} ); |
|
7468 return this; |
|
7469 }, |
|
7470 |
|
7471 /* Attach the date picker to a jQuery selection. |
|
7472 * @param target element - the target input field or division or span |
|
7473 * @param settings object - the new settings to use for this date picker instance (anonymous) |
|
7474 */ |
|
7475 _attachDatepicker: function( target, settings ) { |
|
7476 var nodeName, inline, inst; |
|
7477 nodeName = target.nodeName.toLowerCase(); |
|
7478 inline = ( nodeName === "div" || nodeName === "span" ); |
|
7479 if ( !target.id ) { |
|
7480 this.uuid += 1; |
|
7481 target.id = "dp" + this.uuid; |
|
7482 } |
|
7483 inst = this._newInst( $( target ), inline ); |
|
7484 inst.settings = $.extend( {}, settings || {} ); |
|
7485 if ( nodeName === "input" ) { |
|
7486 this._connectDatepicker( target, inst ); |
|
7487 } else if ( inline ) { |
|
7488 this._inlineDatepicker( target, inst ); |
|
7489 } |
|
7490 }, |
|
7491 |
|
7492 /* Create a new instance object. */ |
|
7493 _newInst: function( target, inline ) { |
|
7494 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars |
|
7495 return { id: id, input: target, // associated target |
|
7496 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection |
|
7497 drawMonth: 0, drawYear: 0, // month being drawn |
|
7498 inline: inline, // is datepicker inline or not |
|
7499 dpDiv: ( !inline ? this.dpDiv : // presentation div |
|
7500 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; |
|
7501 }, |
|
7502 |
|
7503 /* Attach the date picker to an input field. */ |
|
7504 _connectDatepicker: function( target, inst ) { |
|
7505 var input = $( target ); |
|
7506 inst.append = $( [] ); |
|
7507 inst.trigger = $( [] ); |
|
7508 if ( input.hasClass( this.markerClassName ) ) { |
|
7509 return; |
|
7510 } |
|
7511 this._attachments( input, inst ); |
|
7512 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). |
|
7513 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); |
|
7514 this._autoSize( inst ); |
|
7515 $.data( target, "datepicker", inst ); |
|
7516 |
|
7517 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) |
|
7518 if ( inst.settings.disabled ) { |
|
7519 this._disableDatepicker( target ); |
|
7520 } |
|
7521 }, |
|
7522 |
|
7523 /* Make attachments based on settings. */ |
|
7524 _attachments: function( input, inst ) { |
|
7525 var showOn, buttonText, buttonImage, |
|
7526 appendText = this._get( inst, "appendText" ), |
|
7527 isRTL = this._get( inst, "isRTL" ); |
|
7528 |
|
7529 if ( inst.append ) { |
|
7530 inst.append.remove(); |
|
7531 } |
|
7532 if ( appendText ) { |
|
7533 inst.append = $( "<span>" ) |
|
7534 .addClass( this._appendClass ) |
|
7535 .text( appendText ); |
|
7536 input[ isRTL ? "before" : "after" ]( inst.append ); |
|
7537 } |
|
7538 |
|
7539 input.off( "focus", this._showDatepicker ); |
|
7540 |
|
7541 if ( inst.trigger ) { |
|
7542 inst.trigger.remove(); |
|
7543 } |
|
7544 |
|
7545 showOn = this._get( inst, "showOn" ); |
|
7546 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field |
|
7547 input.on( "focus", this._showDatepicker ); |
|
7548 } |
|
7549 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked |
|
7550 buttonText = this._get( inst, "buttonText" ); |
|
7551 buttonImage = this._get( inst, "buttonImage" ); |
|
7552 |
|
7553 if ( this._get( inst, "buttonImageOnly" ) ) { |
|
7554 inst.trigger = $( "<img>" ) |
|
7555 .addClass( this._triggerClass ) |
|
7556 .attr( { |
|
7557 src: buttonImage, |
|
7558 alt: buttonText, |
|
7559 title: buttonText |
|
7560 } ); |
|
7561 } else { |
|
7562 inst.trigger = $( "<button type='button'>" ) |
|
7563 .addClass( this._triggerClass ); |
|
7564 if ( buttonImage ) { |
|
7565 inst.trigger.html( |
|
7566 $( "<img>" ) |
|
7567 .attr( { |
|
7568 src: buttonImage, |
|
7569 alt: buttonText, |
|
7570 title: buttonText |
|
7571 } ) |
|
7572 ); |
|
7573 } else { |
|
7574 inst.trigger.text( buttonText ); |
|
7575 } |
|
7576 } |
|
7577 |
|
7578 input[ isRTL ? "before" : "after" ]( inst.trigger ); |
|
7579 inst.trigger.on( "click", function() { |
|
7580 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { |
|
7581 $.datepicker._hideDatepicker(); |
|
7582 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { |
|
7583 $.datepicker._hideDatepicker(); |
|
7584 $.datepicker._showDatepicker( input[ 0 ] ); |
|
7585 } else { |
|
7586 $.datepicker._showDatepicker( input[ 0 ] ); |
|
7587 } |
|
7588 return false; |
|
7589 } ); |
|
7590 } |
|
7591 }, |
|
7592 |
|
7593 /* Apply the maximum length for the date format. */ |
|
7594 _autoSize: function( inst ) { |
|
7595 if ( this._get( inst, "autoSize" ) && !inst.inline ) { |
|
7596 var findMax, max, maxI, i, |
|
7597 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits |
|
7598 dateFormat = this._get( inst, "dateFormat" ); |
|
7599 |
|
7600 if ( dateFormat.match( /[DM]/ ) ) { |
|
7601 findMax = function( names ) { |
|
7602 max = 0; |
|
7603 maxI = 0; |
|
7604 for ( i = 0; i < names.length; i++ ) { |
|
7605 if ( names[ i ].length > max ) { |
|
7606 max = names[ i ].length; |
|
7607 maxI = i; |
|
7608 } |
|
7609 } |
|
7610 return maxI; |
|
7611 }; |
|
7612 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? |
|
7613 "monthNames" : "monthNamesShort" ) ) ) ); |
|
7614 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? |
|
7615 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); |
|
7616 } |
|
7617 inst.input.attr( "size", this._formatDate( inst, date ).length ); |
|
7618 } |
|
7619 }, |
|
7620 |
|
7621 /* Attach an inline date picker to a div. */ |
|
7622 _inlineDatepicker: function( target, inst ) { |
|
7623 var divSpan = $( target ); |
|
7624 if ( divSpan.hasClass( this.markerClassName ) ) { |
|
7625 return; |
|
7626 } |
|
7627 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); |
|
7628 $.data( target, "datepicker", inst ); |
|
7629 this._setDate( inst, this._getDefaultDate( inst ), true ); |
|
7630 this._updateDatepicker( inst ); |
|
7631 this._updateAlternate( inst ); |
|
7632 |
|
7633 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) |
|
7634 if ( inst.settings.disabled ) { |
|
7635 this._disableDatepicker( target ); |
|
7636 } |
|
7637 |
|
7638 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements |
|
7639 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height |
|
7640 inst.dpDiv.css( "display", "block" ); |
|
7641 }, |
|
7642 |
|
7643 /* Pop-up the date picker in a "dialog" box. |
|
7644 * @param input element - ignored |
|
7645 * @param date string or Date - the initial date to display |
|
7646 * @param onSelect function - the function to call when a date is selected |
|
7647 * @param settings object - update the dialog date picker instance's settings (anonymous object) |
|
7648 * @param pos int[2] - coordinates for the dialog's position within the screen or |
|
7649 * event - with x/y coordinates or |
|
7650 * leave empty for default (screen centre) |
|
7651 * @return the manager object |
|
7652 */ |
|
7653 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { |
|
7654 var id, browserWidth, browserHeight, scrollX, scrollY, |
|
7655 inst = this._dialogInst; // internal instance |
|
7656 |
|
7657 if ( !inst ) { |
|
7658 this.uuid += 1; |
|
7659 id = "dp" + this.uuid; |
|
7660 this._dialogInput = $( "<input type='text' id='" + id + |
|
7661 "' style='position: absolute; top: -100px; width: 0px;'/>" ); |
|
7662 this._dialogInput.on( "keydown", this._doKeyDown ); |
|
7663 $( "body" ).append( this._dialogInput ); |
|
7664 inst = this._dialogInst = this._newInst( this._dialogInput, false ); |
|
7665 inst.settings = {}; |
|
7666 $.data( this._dialogInput[ 0 ], "datepicker", inst ); |
|
7667 } |
|
7668 datepicker_extendRemove( inst.settings, settings || {} ); |
|
7669 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); |
|
7670 this._dialogInput.val( date ); |
|
7671 |
|
7672 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); |
|
7673 if ( !this._pos ) { |
|
7674 browserWidth = document.documentElement.clientWidth; |
|
7675 browserHeight = document.documentElement.clientHeight; |
|
7676 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; |
|
7677 scrollY = document.documentElement.scrollTop || document.body.scrollTop; |
|
7678 this._pos = // should use actual width/height below |
|
7679 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; |
|
7680 } |
|
7681 |
|
7682 // Move input on screen for focus, but hidden behind dialog |
|
7683 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); |
|
7684 inst.settings.onSelect = onSelect; |
|
7685 this._inDialog = true; |
|
7686 this.dpDiv.addClass( this._dialogClass ); |
|
7687 this._showDatepicker( this._dialogInput[ 0 ] ); |
|
7688 if ( $.blockUI ) { |
|
7689 $.blockUI( this.dpDiv ); |
|
7690 } |
|
7691 $.data( this._dialogInput[ 0 ], "datepicker", inst ); |
|
7692 return this; |
|
7693 }, |
|
7694 |
|
7695 /* Detach a datepicker from its control. |
|
7696 * @param target element - the target input field or division or span |
|
7697 */ |
|
7698 _destroyDatepicker: function( target ) { |
|
7699 var nodeName, |
|
7700 $target = $( target ), |
|
7701 inst = $.data( target, "datepicker" ); |
|
7702 |
|
7703 if ( !$target.hasClass( this.markerClassName ) ) { |
|
7704 return; |
|
7705 } |
|
7706 |
|
7707 nodeName = target.nodeName.toLowerCase(); |
|
7708 $.removeData( target, "datepicker" ); |
|
7709 if ( nodeName === "input" ) { |
|
7710 inst.append.remove(); |
|
7711 inst.trigger.remove(); |
|
7712 $target.removeClass( this.markerClassName ). |
|
7713 off( "focus", this._showDatepicker ). |
|
7714 off( "keydown", this._doKeyDown ). |
|
7715 off( "keypress", this._doKeyPress ). |
|
7716 off( "keyup", this._doKeyUp ); |
|
7717 } else if ( nodeName === "div" || nodeName === "span" ) { |
|
7718 $target.removeClass( this.markerClassName ).empty(); |
|
7719 } |
|
7720 |
|
7721 if ( datepicker_instActive === inst ) { |
|
7722 datepicker_instActive = null; |
|
7723 this._curInst = null; |
|
7724 } |
|
7725 }, |
|
7726 |
|
7727 /* Enable the date picker to a jQuery selection. |
|
7728 * @param target element - the target input field or division or span |
|
7729 */ |
|
7730 _enableDatepicker: function( target ) { |
|
7731 var nodeName, inline, |
|
7732 $target = $( target ), |
|
7733 inst = $.data( target, "datepicker" ); |
|
7734 |
|
7735 if ( !$target.hasClass( this.markerClassName ) ) { |
|
7736 return; |
|
7737 } |
|
7738 |
|
7739 nodeName = target.nodeName.toLowerCase(); |
|
7740 if ( nodeName === "input" ) { |
|
7741 target.disabled = false; |
|
7742 inst.trigger.filter( "button" ). |
|
7743 each( function() { |
|
7744 this.disabled = false; |
|
7745 } ).end(). |
|
7746 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); |
|
7747 } else if ( nodeName === "div" || nodeName === "span" ) { |
|
7748 inline = $target.children( "." + this._inlineClass ); |
|
7749 inline.children().removeClass( "ui-state-disabled" ); |
|
7750 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). |
|
7751 prop( "disabled", false ); |
|
7752 } |
|
7753 this._disabledInputs = $.map( this._disabledInputs, |
|
7754 |
|
7755 // Delete entry |
|
7756 function( value ) { |
|
7757 return ( value === target ? null : value ); |
|
7758 } ); |
|
7759 }, |
|
7760 |
|
7761 /* Disable the date picker to a jQuery selection. |
|
7762 * @param target element - the target input field or division or span |
|
7763 */ |
|
7764 _disableDatepicker: function( target ) { |
|
7765 var nodeName, inline, |
|
7766 $target = $( target ), |
|
7767 inst = $.data( target, "datepicker" ); |
|
7768 |
|
7769 if ( !$target.hasClass( this.markerClassName ) ) { |
|
7770 return; |
|
7771 } |
|
7772 |
|
7773 nodeName = target.nodeName.toLowerCase(); |
|
7774 if ( nodeName === "input" ) { |
|
7775 target.disabled = true; |
|
7776 inst.trigger.filter( "button" ). |
|
7777 each( function() { |
|
7778 this.disabled = true; |
|
7779 } ).end(). |
|
7780 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); |
|
7781 } else if ( nodeName === "div" || nodeName === "span" ) { |
|
7782 inline = $target.children( "." + this._inlineClass ); |
|
7783 inline.children().addClass( "ui-state-disabled" ); |
|
7784 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). |
|
7785 prop( "disabled", true ); |
|
7786 } |
|
7787 this._disabledInputs = $.map( this._disabledInputs, |
|
7788 |
|
7789 // Delete entry |
|
7790 function( value ) { |
|
7791 return ( value === target ? null : value ); |
|
7792 } ); |
|
7793 this._disabledInputs[ this._disabledInputs.length ] = target; |
|
7794 }, |
|
7795 |
|
7796 /* Is the first field in a jQuery collection disabled as a datepicker? |
|
7797 * @param target element - the target input field or division or span |
|
7798 * @return boolean - true if disabled, false if enabled |
|
7799 */ |
|
7800 _isDisabledDatepicker: function( target ) { |
|
7801 if ( !target ) { |
|
7802 return false; |
|
7803 } |
|
7804 for ( var i = 0; i < this._disabledInputs.length; i++ ) { |
|
7805 if ( this._disabledInputs[ i ] === target ) { |
|
7806 return true; |
|
7807 } |
|
7808 } |
|
7809 return false; |
|
7810 }, |
|
7811 |
|
7812 /* Retrieve the instance data for the target control. |
|
7813 * @param target element - the target input field or division or span |
|
7814 * @return object - the associated instance data |
|
7815 * @throws error if a jQuery problem getting data |
|
7816 */ |
|
7817 _getInst: function( target ) { |
|
7818 try { |
|
7819 return $.data( target, "datepicker" ); |
|
7820 } catch ( err ) { |
|
7821 throw "Missing instance data for this datepicker"; |
|
7822 } |
|
7823 }, |
|
7824 |
|
7825 /* Update or retrieve the settings for a date picker attached to an input field or division. |
|
7826 * @param target element - the target input field or division or span |
|
7827 * @param name object - the new settings to update or |
|
7828 * string - the name of the setting to change or retrieve, |
|
7829 * when retrieving also "all" for all instance settings or |
|
7830 * "defaults" for all global defaults |
|
7831 * @param value any - the new value for the setting |
|
7832 * (omit if above is an object or to retrieve a value) |
|
7833 */ |
|
7834 _optionDatepicker: function( target, name, value ) { |
|
7835 var settings, date, minDate, maxDate, |
|
7836 inst = this._getInst( target ); |
|
7837 |
|
7838 if ( arguments.length === 2 && typeof name === "string" ) { |
|
7839 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : |
|
7840 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : |
|
7841 this._get( inst, name ) ) : null ) ); |
|
7842 } |
|
7843 |
|
7844 settings = name || {}; |
|
7845 if ( typeof name === "string" ) { |
|
7846 settings = {}; |
|
7847 settings[ name ] = value; |
|
7848 } |
|
7849 |
|
7850 if ( inst ) { |
|
7851 if ( this._curInst === inst ) { |
|
7852 this._hideDatepicker(); |
|
7853 } |
|
7854 |
|
7855 date = this._getDateDatepicker( target, true ); |
|
7856 minDate = this._getMinMaxDate( inst, "min" ); |
|
7857 maxDate = this._getMinMaxDate( inst, "max" ); |
|
7858 datepicker_extendRemove( inst.settings, settings ); |
|
7859 |
|
7860 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided |
|
7861 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { |
|
7862 inst.settings.minDate = this._formatDate( inst, minDate ); |
|
7863 } |
|
7864 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { |
|
7865 inst.settings.maxDate = this._formatDate( inst, maxDate ); |
|
7866 } |
|
7867 if ( "disabled" in settings ) { |
|
7868 if ( settings.disabled ) { |
|
7869 this._disableDatepicker( target ); |
|
7870 } else { |
|
7871 this._enableDatepicker( target ); |
|
7872 } |
|
7873 } |
|
7874 this._attachments( $( target ), inst ); |
|
7875 this._autoSize( inst ); |
|
7876 this._setDate( inst, date ); |
|
7877 this._updateAlternate( inst ); |
|
7878 this._updateDatepicker( inst ); |
|
7879 } |
|
7880 }, |
|
7881 |
|
7882 // Change method deprecated |
|
7883 _changeDatepicker: function( target, name, value ) { |
|
7884 this._optionDatepicker( target, name, value ); |
|
7885 }, |
|
7886 |
|
7887 /* Redraw the date picker attached to an input field or division. |
|
7888 * @param target element - the target input field or division or span |
|
7889 */ |
|
7890 _refreshDatepicker: function( target ) { |
|
7891 var inst = this._getInst( target ); |
|
7892 if ( inst ) { |
|
7893 this._updateDatepicker( inst ); |
|
7894 } |
|
7895 }, |
|
7896 |
|
7897 /* Set the dates for a jQuery selection. |
|
7898 * @param target element - the target input field or division or span |
|
7899 * @param date Date - the new date |
|
7900 */ |
|
7901 _setDateDatepicker: function( target, date ) { |
|
7902 var inst = this._getInst( target ); |
|
7903 if ( inst ) { |
|
7904 this._setDate( inst, date ); |
|
7905 this._updateDatepicker( inst ); |
|
7906 this._updateAlternate( inst ); |
|
7907 } |
|
7908 }, |
|
7909 |
|
7910 /* Get the date(s) for the first entry in a jQuery selection. |
|
7911 * @param target element - the target input field or division or span |
|
7912 * @param noDefault boolean - true if no default date is to be used |
|
7913 * @return Date - the current date |
|
7914 */ |
|
7915 _getDateDatepicker: function( target, noDefault ) { |
|
7916 var inst = this._getInst( target ); |
|
7917 if ( inst && !inst.inline ) { |
|
7918 this._setDateFromField( inst, noDefault ); |
|
7919 } |
|
7920 return ( inst ? this._getDate( inst ) : null ); |
|
7921 }, |
|
7922 |
|
7923 /* Handle keystrokes. */ |
|
7924 _doKeyDown: function( event ) { |
|
7925 var onSelect, dateStr, sel, |
|
7926 inst = $.datepicker._getInst( event.target ), |
|
7927 handled = true, |
|
7928 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); |
|
7929 |
|
7930 inst._keyEvent = true; |
|
7931 if ( $.datepicker._datepickerShowing ) { |
|
7932 switch ( event.keyCode ) { |
|
7933 case 9: $.datepicker._hideDatepicker(); |
|
7934 handled = false; |
|
7935 break; // hide on tab out |
|
7936 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + |
|
7937 $.datepicker._currentClass + ")", inst.dpDiv ); |
|
7938 if ( sel[ 0 ] ) { |
|
7939 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); |
|
7940 } |
|
7941 |
|
7942 onSelect = $.datepicker._get( inst, "onSelect" ); |
|
7943 if ( onSelect ) { |
|
7944 dateStr = $.datepicker._formatDate( inst ); |
|
7945 |
|
7946 // Trigger custom callback |
|
7947 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); |
|
7948 } else { |
|
7949 $.datepicker._hideDatepicker(); |
|
7950 } |
|
7951 |
|
7952 return false; // don't submit the form |
|
7953 case 27: $.datepicker._hideDatepicker(); |
|
7954 break; // hide on escape |
|
7955 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
|
7956 -$.datepicker._get( inst, "stepBigMonths" ) : |
|
7957 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
|
7958 break; // previous month/year on page up/+ ctrl |
|
7959 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
|
7960 +$.datepicker._get( inst, "stepBigMonths" ) : |
|
7961 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
|
7962 break; // next month/year on page down/+ ctrl |
|
7963 case 35: if ( event.ctrlKey || event.metaKey ) { |
|
7964 $.datepicker._clearDate( event.target ); |
|
7965 } |
|
7966 handled = event.ctrlKey || event.metaKey; |
|
7967 break; // clear on ctrl or command +end |
|
7968 case 36: if ( event.ctrlKey || event.metaKey ) { |
|
7969 $.datepicker._gotoToday( event.target ); |
|
7970 } |
|
7971 handled = event.ctrlKey || event.metaKey; |
|
7972 break; // current on ctrl or command +home |
|
7973 case 37: if ( event.ctrlKey || event.metaKey ) { |
|
7974 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); |
|
7975 } |
|
7976 handled = event.ctrlKey || event.metaKey; |
|
7977 |
|
7978 // -1 day on ctrl or command +left |
|
7979 if ( event.originalEvent.altKey ) { |
|
7980 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
|
7981 -$.datepicker._get( inst, "stepBigMonths" ) : |
|
7982 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
|
7983 } |
|
7984 |
|
7985 // next month/year on alt +left on Mac |
|
7986 break; |
|
7987 case 38: if ( event.ctrlKey || event.metaKey ) { |
|
7988 $.datepicker._adjustDate( event.target, -7, "D" ); |
|
7989 } |
|
7990 handled = event.ctrlKey || event.metaKey; |
|
7991 break; // -1 week on ctrl or command +up |
|
7992 case 39: if ( event.ctrlKey || event.metaKey ) { |
|
7993 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); |
|
7994 } |
|
7995 handled = event.ctrlKey || event.metaKey; |
|
7996 |
|
7997 // +1 day on ctrl or command +right |
|
7998 if ( event.originalEvent.altKey ) { |
|
7999 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
|
8000 +$.datepicker._get( inst, "stepBigMonths" ) : |
|
8001 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
|
8002 } |
|
8003 |
|
8004 // next month/year on alt +right |
|
8005 break; |
|
8006 case 40: if ( event.ctrlKey || event.metaKey ) { |
|
8007 $.datepicker._adjustDate( event.target, +7, "D" ); |
|
8008 } |
|
8009 handled = event.ctrlKey || event.metaKey; |
|
8010 break; // +1 week on ctrl or command +down |
|
8011 default: handled = false; |
|
8012 } |
|
8013 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home |
|
8014 $.datepicker._showDatepicker( this ); |
|
8015 } else { |
|
8016 handled = false; |
|
8017 } |
|
8018 |
|
8019 if ( handled ) { |
|
8020 event.preventDefault(); |
|
8021 event.stopPropagation(); |
|
8022 } |
|
8023 }, |
|
8024 |
|
8025 /* Filter entered characters - based on date format. */ |
|
8026 _doKeyPress: function( event ) { |
|
8027 var chars, chr, |
|
8028 inst = $.datepicker._getInst( event.target ); |
|
8029 |
|
8030 if ( $.datepicker._get( inst, "constrainInput" ) ) { |
|
8031 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); |
|
8032 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); |
|
8033 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); |
|
8034 } |
|
8035 }, |
|
8036 |
|
8037 /* Synchronise manual entry and field/alternate field. */ |
|
8038 _doKeyUp: function( event ) { |
|
8039 var date, |
|
8040 inst = $.datepicker._getInst( event.target ); |
|
8041 |
|
8042 if ( inst.input.val() !== inst.lastVal ) { |
|
8043 try { |
|
8044 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), |
|
8045 ( inst.input ? inst.input.val() : null ), |
|
8046 $.datepicker._getFormatConfig( inst ) ); |
|
8047 |
|
8048 if ( date ) { // only if valid |
|
8049 $.datepicker._setDateFromField( inst ); |
|
8050 $.datepicker._updateAlternate( inst ); |
|
8051 $.datepicker._updateDatepicker( inst ); |
|
8052 } |
|
8053 } catch ( err ) { |
|
8054 } |
|
8055 } |
|
8056 return true; |
|
8057 }, |
|
8058 |
|
8059 /* Pop-up the date picker for a given input field. |
|
8060 * If false returned from beforeShow event handler do not show. |
|
8061 * @param input element - the input field attached to the date picker or |
|
8062 * event - if triggered by focus |
|
8063 */ |
|
8064 _showDatepicker: function( input ) { |
|
8065 input = input.target || input; |
|
8066 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger |
|
8067 input = $( "input", input.parentNode )[ 0 ]; |
|
8068 } |
|
8069 |
|
8070 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here |
|
8071 return; |
|
8072 } |
|
8073 |
|
8074 var inst, beforeShow, beforeShowSettings, isFixed, |
|
8075 offset, showAnim, duration; |
|
8076 |
|
8077 inst = $.datepicker._getInst( input ); |
|
8078 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { |
|
8079 $.datepicker._curInst.dpDiv.stop( true, true ); |
|
8080 if ( inst && $.datepicker._datepickerShowing ) { |
|
8081 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); |
|
8082 } |
|
8083 } |
|
8084 |
|
8085 beforeShow = $.datepicker._get( inst, "beforeShow" ); |
|
8086 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; |
|
8087 if ( beforeShowSettings === false ) { |
|
8088 return; |
|
8089 } |
|
8090 datepicker_extendRemove( inst.settings, beforeShowSettings ); |
|
8091 |
|
8092 inst.lastVal = null; |
|
8093 $.datepicker._lastInput = input; |
|
8094 $.datepicker._setDateFromField( inst ); |
|
8095 |
|
8096 if ( $.datepicker._inDialog ) { // hide cursor |
|
8097 input.value = ""; |
|
8098 } |
|
8099 if ( !$.datepicker._pos ) { // position below input |
|
8100 $.datepicker._pos = $.datepicker._findPos( input ); |
|
8101 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height |
|
8102 } |
|
8103 |
|
8104 isFixed = false; |
|
8105 $( input ).parents().each( function() { |
|
8106 isFixed |= $( this ).css( "position" ) === "fixed"; |
|
8107 return !isFixed; |
|
8108 } ); |
|
8109 |
|
8110 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; |
|
8111 $.datepicker._pos = null; |
|
8112 |
|
8113 //to avoid flashes on Firefox |
|
8114 inst.dpDiv.empty(); |
|
8115 |
|
8116 // determine sizing offscreen |
|
8117 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); |
|
8118 $.datepicker._updateDatepicker( inst ); |
|
8119 |
|
8120 // fix width for dynamic number of date pickers |
|
8121 // and adjust position before showing |
|
8122 offset = $.datepicker._checkOffset( inst, offset, isFixed ); |
|
8123 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? |
|
8124 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", |
|
8125 left: offset.left + "px", top: offset.top + "px" } ); |
|
8126 |
|
8127 if ( !inst.inline ) { |
|
8128 showAnim = $.datepicker._get( inst, "showAnim" ); |
|
8129 duration = $.datepicker._get( inst, "duration" ); |
|
8130 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); |
|
8131 $.datepicker._datepickerShowing = true; |
|
8132 |
|
8133 if ( $.effects && $.effects.effect[ showAnim ] ) { |
|
8134 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); |
|
8135 } else { |
|
8136 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); |
|
8137 } |
|
8138 |
|
8139 if ( $.datepicker._shouldFocusInput( inst ) ) { |
|
8140 inst.input.trigger( "focus" ); |
|
8141 } |
|
8142 |
|
8143 $.datepicker._curInst = inst; |
|
8144 } |
|
8145 }, |
|
8146 |
|
8147 /* Generate the date picker content. */ |
|
8148 _updateDatepicker: function( inst ) { |
|
8149 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) |
|
8150 datepicker_instActive = inst; // for delegate hover events |
|
8151 inst.dpDiv.empty().append( this._generateHTML( inst ) ); |
|
8152 this._attachHandlers( inst ); |
|
8153 |
|
8154 var origyearshtml, |
|
8155 numMonths = this._getNumberOfMonths( inst ), |
|
8156 cols = numMonths[ 1 ], |
|
8157 width = 17, |
|
8158 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), |
|
8159 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); |
|
8160 |
|
8161 if ( activeCell.length > 0 ) { |
|
8162 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); |
|
8163 } |
|
8164 |
|
8165 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); |
|
8166 if ( cols > 1 ) { |
|
8167 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); |
|
8168 } |
|
8169 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + |
|
8170 "Class" ]( "ui-datepicker-multi" ); |
|
8171 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + |
|
8172 "Class" ]( "ui-datepicker-rtl" ); |
|
8173 |
|
8174 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { |
|
8175 inst.input.trigger( "focus" ); |
|
8176 } |
|
8177 |
|
8178 // Deffered render of the years select (to avoid flashes on Firefox) |
|
8179 if ( inst.yearshtml ) { |
|
8180 origyearshtml = inst.yearshtml; |
|
8181 setTimeout( function() { |
|
8182 |
|
8183 //assure that inst.yearshtml didn't change. |
|
8184 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { |
|
8185 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); |
|
8186 } |
|
8187 origyearshtml = inst.yearshtml = null; |
|
8188 }, 0 ); |
|
8189 } |
|
8190 |
|
8191 if ( onUpdateDatepicker ) { |
|
8192 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); |
|
8193 } |
|
8194 }, |
|
8195 |
|
8196 // #6694 - don't focus the input if it's already focused |
|
8197 // this breaks the change event in IE |
|
8198 // Support: IE and jQuery <1.9 |
|
8199 _shouldFocusInput: function( inst ) { |
|
8200 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); |
|
8201 }, |
|
8202 |
|
8203 /* Check positioning to remain on screen. */ |
|
8204 _checkOffset: function( inst, offset, isFixed ) { |
|
8205 var dpWidth = inst.dpDiv.outerWidth(), |
|
8206 dpHeight = inst.dpDiv.outerHeight(), |
|
8207 inputWidth = inst.input ? inst.input.outerWidth() : 0, |
|
8208 inputHeight = inst.input ? inst.input.outerHeight() : 0, |
|
8209 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), |
|
8210 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); |
|
8211 |
|
8212 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); |
|
8213 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; |
|
8214 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; |
|
8215 |
|
8216 // Now check if datepicker is showing outside window viewport - move to a better place if so. |
|
8217 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? |
|
8218 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); |
|
8219 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? |
|
8220 Math.abs( dpHeight + inputHeight ) : 0 ); |
|
8221 |
|
8222 return offset; |
|
8223 }, |
|
8224 |
|
8225 /* Find an object's position on the screen. */ |
|
8226 _findPos: function( obj ) { |
|
8227 var position, |
|
8228 inst = this._getInst( obj ), |
|
8229 isRTL = this._get( inst, "isRTL" ); |
|
8230 |
|
8231 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { |
|
8232 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; |
|
8233 } |
|
8234 |
|
8235 position = $( obj ).offset(); |
|
8236 return [ position.left, position.top ]; |
|
8237 }, |
|
8238 |
|
8239 /* Hide the date picker from view. |
|
8240 * @param input element - the input field attached to the date picker |
|
8241 */ |
|
8242 _hideDatepicker: function( input ) { |
|
8243 var showAnim, duration, postProcess, onClose, |
|
8244 inst = this._curInst; |
|
8245 |
|
8246 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { |
|
8247 return; |
|
8248 } |
|
8249 |
|
8250 if ( this._datepickerShowing ) { |
|
8251 showAnim = this._get( inst, "showAnim" ); |
|
8252 duration = this._get( inst, "duration" ); |
|
8253 postProcess = function() { |
|
8254 $.datepicker._tidyDialog( inst ); |
|
8255 }; |
|
8256 |
|
8257 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed |
|
8258 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { |
|
8259 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); |
|
8260 } else { |
|
8261 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : |
|
8262 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); |
|
8263 } |
|
8264 |
|
8265 if ( !showAnim ) { |
|
8266 postProcess(); |
|
8267 } |
|
8268 this._datepickerShowing = false; |
|
8269 |
|
8270 onClose = this._get( inst, "onClose" ); |
|
8271 if ( onClose ) { |
|
8272 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); |
|
8273 } |
|
8274 |
|
8275 this._lastInput = null; |
|
8276 if ( this._inDialog ) { |
|
8277 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); |
|
8278 if ( $.blockUI ) { |
|
8279 $.unblockUI(); |
|
8280 $( "body" ).append( this.dpDiv ); |
|
8281 } |
|
8282 } |
|
8283 this._inDialog = false; |
|
8284 } |
|
8285 }, |
|
8286 |
|
8287 /* Tidy up after a dialog display. */ |
|
8288 _tidyDialog: function( inst ) { |
|
8289 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); |
|
8290 }, |
|
8291 |
|
8292 /* Close date picker if clicked elsewhere. */ |
|
8293 _checkExternalClick: function( event ) { |
|
8294 if ( !$.datepicker._curInst ) { |
|
8295 return; |
|
8296 } |
|
8297 |
|
8298 var $target = $( event.target ), |
|
8299 inst = $.datepicker._getInst( $target[ 0 ] ); |
|
8300 |
|
8301 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && |
|
8302 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && |
|
8303 !$target.hasClass( $.datepicker.markerClassName ) && |
|
8304 !$target.closest( "." + $.datepicker._triggerClass ).length && |
|
8305 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || |
|
8306 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { |
|
8307 $.datepicker._hideDatepicker(); |
|
8308 } |
|
8309 }, |
|
8310 |
|
8311 /* Adjust one of the date sub-fields. */ |
|
8312 _adjustDate: function( id, offset, period ) { |
|
8313 var target = $( id ), |
|
8314 inst = this._getInst( target[ 0 ] ); |
|
8315 |
|
8316 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { |
|
8317 return; |
|
8318 } |
|
8319 this._adjustInstDate( inst, offset, period ); |
|
8320 this._updateDatepicker( inst ); |
|
8321 }, |
|
8322 |
|
8323 /* Action for current link. */ |
|
8324 _gotoToday: function( id ) { |
|
8325 var date, |
|
8326 target = $( id ), |
|
8327 inst = this._getInst( target[ 0 ] ); |
|
8328 |
|
8329 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { |
|
8330 inst.selectedDay = inst.currentDay; |
|
8331 inst.drawMonth = inst.selectedMonth = inst.currentMonth; |
|
8332 inst.drawYear = inst.selectedYear = inst.currentYear; |
|
8333 } else { |
|
8334 date = new Date(); |
|
8335 inst.selectedDay = date.getDate(); |
|
8336 inst.drawMonth = inst.selectedMonth = date.getMonth(); |
|
8337 inst.drawYear = inst.selectedYear = date.getFullYear(); |
|
8338 } |
|
8339 this._notifyChange( inst ); |
|
8340 this._adjustDate( target ); |
|
8341 }, |
|
8342 |
|
8343 /* Action for selecting a new month/year. */ |
|
8344 _selectMonthYear: function( id, select, period ) { |
|
8345 var target = $( id ), |
|
8346 inst = this._getInst( target[ 0 ] ); |
|
8347 |
|
8348 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = |
|
8349 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = |
|
8350 parseInt( select.options[ select.selectedIndex ].value, 10 ); |
|
8351 |
|
8352 this._notifyChange( inst ); |
|
8353 this._adjustDate( target ); |
|
8354 }, |
|
8355 |
|
8356 /* Action for selecting a day. */ |
|
8357 _selectDay: function( id, month, year, td ) { |
|
8358 var inst, |
|
8359 target = $( id ); |
|
8360 |
|
8361 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { |
|
8362 return; |
|
8363 } |
|
8364 |
|
8365 inst = this._getInst( target[ 0 ] ); |
|
8366 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); |
|
8367 inst.selectedMonth = inst.currentMonth = month; |
|
8368 inst.selectedYear = inst.currentYear = year; |
|
8369 this._selectDate( id, this._formatDate( inst, |
|
8370 inst.currentDay, inst.currentMonth, inst.currentYear ) ); |
|
8371 }, |
|
8372 |
|
8373 /* Erase the input field and hide the date picker. */ |
|
8374 _clearDate: function( id ) { |
|
8375 var target = $( id ); |
|
8376 this._selectDate( target, "" ); |
|
8377 }, |
|
8378 |
|
8379 /* Update the input field with the selected date. */ |
|
8380 _selectDate: function( id, dateStr ) { |
|
8381 var onSelect, |
|
8382 target = $( id ), |
|
8383 inst = this._getInst( target[ 0 ] ); |
|
8384 |
|
8385 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); |
|
8386 if ( inst.input ) { |
|
8387 inst.input.val( dateStr ); |
|
8388 } |
|
8389 this._updateAlternate( inst ); |
|
8390 |
|
8391 onSelect = this._get( inst, "onSelect" ); |
|
8392 if ( onSelect ) { |
|
8393 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback |
|
8394 } else if ( inst.input ) { |
|
8395 inst.input.trigger( "change" ); // fire the change event |
|
8396 } |
|
8397 |
|
8398 if ( inst.inline ) { |
|
8399 this._updateDatepicker( inst ); |
|
8400 } else { |
|
8401 this._hideDatepicker(); |
|
8402 this._lastInput = inst.input[ 0 ]; |
|
8403 if ( typeof( inst.input[ 0 ] ) !== "object" ) { |
|
8404 inst.input.trigger( "focus" ); // restore focus |
|
8405 } |
|
8406 this._lastInput = null; |
|
8407 } |
|
8408 }, |
|
8409 |
|
8410 /* Update any alternate field to synchronise with the main field. */ |
|
8411 _updateAlternate: function( inst ) { |
|
8412 var altFormat, date, dateStr, |
|
8413 altField = this._get( inst, "altField" ); |
|
8414 |
|
8415 if ( altField ) { // update alternate field too |
|
8416 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); |
|
8417 date = this._getDate( inst ); |
|
8418 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); |
|
8419 $( document ).find( altField ).val( dateStr ); |
|
8420 } |
|
8421 }, |
|
8422 |
|
8423 /* Set as beforeShowDay function to prevent selection of weekends. |
|
8424 * @param date Date - the date to customise |
|
8425 * @return [boolean, string] - is this date selectable?, what is its CSS class? |
|
8426 */ |
|
8427 noWeekends: function( date ) { |
|
8428 var day = date.getDay(); |
|
8429 return [ ( day > 0 && day < 6 ), "" ]; |
|
8430 }, |
|
8431 |
|
8432 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. |
|
8433 * @param date Date - the date to get the week for |
|
8434 * @return number - the number of the week within the year that contains this date |
|
8435 */ |
|
8436 iso8601Week: function( date ) { |
|
8437 var time, |
|
8438 checkDate = new Date( date.getTime() ); |
|
8439 |
|
8440 // Find Thursday of this week starting on Monday |
|
8441 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); |
|
8442 |
|
8443 time = checkDate.getTime(); |
|
8444 checkDate.setMonth( 0 ); // Compare with Jan 1 |
|
8445 checkDate.setDate( 1 ); |
|
8446 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; |
|
8447 }, |
|
8448 |
|
8449 /* Parse a string value into a date object. |
|
8450 * See formatDate below for the possible formats. |
|
8451 * |
|
8452 * @param format string - the expected format of the date |
|
8453 * @param value string - the date in the above format |
|
8454 * @param settings Object - attributes include: |
|
8455 * shortYearCutoff number - the cutoff year for determining the century (optional) |
|
8456 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
|
8457 * dayNames string[7] - names of the days from Sunday (optional) |
|
8458 * monthNamesShort string[12] - abbreviated names of the months (optional) |
|
8459 * monthNames string[12] - names of the months (optional) |
|
8460 * @return Date - the extracted date value or null if value is blank |
|
8461 */ |
|
8462 parseDate: function( format, value, settings ) { |
|
8463 if ( format == null || value == null ) { |
|
8464 throw "Invalid arguments"; |
|
8465 } |
|
8466 |
|
8467 value = ( typeof value === "object" ? value.toString() : value + "" ); |
|
8468 if ( value === "" ) { |
|
8469 return null; |
|
8470 } |
|
8471 |
|
8472 var iFormat, dim, extra, |
|
8473 iValue = 0, |
|
8474 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, |
|
8475 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : |
|
8476 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), |
|
8477 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, |
|
8478 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, |
|
8479 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, |
|
8480 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, |
|
8481 year = -1, |
|
8482 month = -1, |
|
8483 day = -1, |
|
8484 doy = -1, |
|
8485 literal = false, |
|
8486 date, |
|
8487 |
|
8488 // Check whether a format character is doubled |
|
8489 lookAhead = function( match ) { |
|
8490 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); |
|
8491 if ( matches ) { |
|
8492 iFormat++; |
|
8493 } |
|
8494 return matches; |
|
8495 }, |
|
8496 |
|
8497 // Extract a number from the string value |
|
8498 getNumber = function( match ) { |
|
8499 var isDoubled = lookAhead( match ), |
|
8500 size = ( match === "@" ? 14 : ( match === "!" ? 20 : |
|
8501 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), |
|
8502 minSize = ( match === "y" ? size : 1 ), |
|
8503 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), |
|
8504 num = value.substring( iValue ).match( digits ); |
|
8505 if ( !num ) { |
|
8506 throw "Missing number at position " + iValue; |
|
8507 } |
|
8508 iValue += num[ 0 ].length; |
|
8509 return parseInt( num[ 0 ], 10 ); |
|
8510 }, |
|
8511 |
|
8512 // Extract a name from the string value and convert to an index |
|
8513 getName = function( match, shortNames, longNames ) { |
|
8514 var index = -1, |
|
8515 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { |
|
8516 return [ [ k, v ] ]; |
|
8517 } ).sort( function( a, b ) { |
|
8518 return -( a[ 1 ].length - b[ 1 ].length ); |
|
8519 } ); |
|
8520 |
|
8521 $.each( names, function( i, pair ) { |
|
8522 var name = pair[ 1 ]; |
|
8523 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { |
|
8524 index = pair[ 0 ]; |
|
8525 iValue += name.length; |
|
8526 return false; |
|
8527 } |
|
8528 } ); |
|
8529 if ( index !== -1 ) { |
|
8530 return index + 1; |
|
8531 } else { |
|
8532 throw "Unknown name at position " + iValue; |
|
8533 } |
|
8534 }, |
|
8535 |
|
8536 // Confirm that a literal character matches the string value |
|
8537 checkLiteral = function() { |
|
8538 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { |
|
8539 throw "Unexpected literal at position " + iValue; |
|
8540 } |
|
8541 iValue++; |
|
8542 }; |
|
8543 |
|
8544 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { |
|
8545 if ( literal ) { |
|
8546 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { |
|
8547 literal = false; |
|
8548 } else { |
|
8549 checkLiteral(); |
|
8550 } |
|
8551 } else { |
|
8552 switch ( format.charAt( iFormat ) ) { |
|
8553 case "d": |
|
8554 day = getNumber( "d" ); |
|
8555 break; |
|
8556 case "D": |
|
8557 getName( "D", dayNamesShort, dayNames ); |
|
8558 break; |
|
8559 case "o": |
|
8560 doy = getNumber( "o" ); |
|
8561 break; |
|
8562 case "m": |
|
8563 month = getNumber( "m" ); |
|
8564 break; |
|
8565 case "M": |
|
8566 month = getName( "M", monthNamesShort, monthNames ); |
|
8567 break; |
|
8568 case "y": |
|
8569 year = getNumber( "y" ); |
|
8570 break; |
|
8571 case "@": |
|
8572 date = new Date( getNumber( "@" ) ); |
|
8573 year = date.getFullYear(); |
|
8574 month = date.getMonth() + 1; |
|
8575 day = date.getDate(); |
|
8576 break; |
|
8577 case "!": |
|
8578 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); |
|
8579 year = date.getFullYear(); |
|
8580 month = date.getMonth() + 1; |
|
8581 day = date.getDate(); |
|
8582 break; |
|
8583 case "'": |
|
8584 if ( lookAhead( "'" ) ) { |
|
8585 checkLiteral(); |
|
8586 } else { |
|
8587 literal = true; |
|
8588 } |
|
8589 break; |
|
8590 default: |
|
8591 checkLiteral(); |
|
8592 } |
|
8593 } |
|
8594 } |
|
8595 |
|
8596 if ( iValue < value.length ) { |
|
8597 extra = value.substr( iValue ); |
|
8598 if ( !/^\s+/.test( extra ) ) { |
|
8599 throw "Extra/unparsed characters found in date: " + extra; |
|
8600 } |
|
8601 } |
|
8602 |
|
8603 if ( year === -1 ) { |
|
8604 year = new Date().getFullYear(); |
|
8605 } else if ( year < 100 ) { |
|
8606 year += new Date().getFullYear() - new Date().getFullYear() % 100 + |
|
8607 ( year <= shortYearCutoff ? 0 : -100 ); |
|
8608 } |
|
8609 |
|
8610 if ( doy > -1 ) { |
|
8611 month = 1; |
|
8612 day = doy; |
|
8613 do { |
|
8614 dim = this._getDaysInMonth( year, month - 1 ); |
|
8615 if ( day <= dim ) { |
|
8616 break; |
|
8617 } |
|
8618 month++; |
|
8619 day -= dim; |
|
8620 } while ( true ); |
|
8621 } |
|
8622 |
|
8623 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); |
|
8624 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { |
|
8625 throw "Invalid date"; // E.g. 31/02/00 |
|
8626 } |
|
8627 return date; |
|
8628 }, |
|
8629 |
|
8630 /* Standard date formats. */ |
|
8631 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) |
|
8632 COOKIE: "D, dd M yy", |
|
8633 ISO_8601: "yy-mm-dd", |
|
8634 RFC_822: "D, d M y", |
|
8635 RFC_850: "DD, dd-M-y", |
|
8636 RFC_1036: "D, d M y", |
|
8637 RFC_1123: "D, d M yy", |
|
8638 RFC_2822: "D, d M yy", |
|
8639 RSS: "D, d M y", // RFC 822 |
|
8640 TICKS: "!", |
|
8641 TIMESTAMP: "@", |
|
8642 W3C: "yy-mm-dd", // ISO 8601 |
|
8643 |
|
8644 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + |
|
8645 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), |
|
8646 |
|
8647 /* Format a date object into a string value. |
|
8648 * The format can be combinations of the following: |
|
8649 * d - day of month (no leading zero) |
|
8650 * dd - day of month (two digit) |
|
8651 * o - day of year (no leading zeros) |
|
8652 * oo - day of year (three digit) |
|
8653 * D - day name short |
|
8654 * DD - day name long |
|
8655 * m - month of year (no leading zero) |
|
8656 * mm - month of year (two digit) |
|
8657 * M - month name short |
|
8658 * MM - month name long |
|
8659 * y - year (two digit) |
|
8660 * yy - year (four digit) |
|
8661 * @ - Unix timestamp (ms since 01/01/1970) |
|
8662 * ! - Windows ticks (100ns since 01/01/0001) |
|
8663 * "..." - literal text |
|
8664 * '' - single quote |
|
8665 * |
|
8666 * @param format string - the desired format of the date |
|
8667 * @param date Date - the date value to format |
|
8668 * @param settings Object - attributes include: |
|
8669 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
|
8670 * dayNames string[7] - names of the days from Sunday (optional) |
|
8671 * monthNamesShort string[12] - abbreviated names of the months (optional) |
|
8672 * monthNames string[12] - names of the months (optional) |
|
8673 * @return string - the date in the above format |
|
8674 */ |
|
8675 formatDate: function( format, date, settings ) { |
|
8676 if ( !date ) { |
|
8677 return ""; |
|
8678 } |
|
8679 |
|
8680 var iFormat, |
|
8681 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, |
|
8682 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, |
|
8683 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, |
|
8684 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, |
|
8685 |
|
8686 // Check whether a format character is doubled |
|
8687 lookAhead = function( match ) { |
|
8688 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); |
|
8689 if ( matches ) { |
|
8690 iFormat++; |
|
8691 } |
|
8692 return matches; |
|
8693 }, |
|
8694 |
|
8695 // Format a number, with leading zero if necessary |
|
8696 formatNumber = function( match, value, len ) { |
|
8697 var num = "" + value; |
|
8698 if ( lookAhead( match ) ) { |
|
8699 while ( num.length < len ) { |
|
8700 num = "0" + num; |
|
8701 } |
|
8702 } |
|
8703 return num; |
|
8704 }, |
|
8705 |
|
8706 // Format a name, short or long as requested |
|
8707 formatName = function( match, value, shortNames, longNames ) { |
|
8708 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); |
|
8709 }, |
|
8710 output = "", |
|
8711 literal = false; |
|
8712 |
|
8713 if ( date ) { |
|
8714 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { |
|
8715 if ( literal ) { |
|
8716 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { |
|
8717 literal = false; |
|
8718 } else { |
|
8719 output += format.charAt( iFormat ); |
|
8720 } |
|
8721 } else { |
|
8722 switch ( format.charAt( iFormat ) ) { |
|
8723 case "d": |
|
8724 output += formatNumber( "d", date.getDate(), 2 ); |
|
8725 break; |
|
8726 case "D": |
|
8727 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); |
|
8728 break; |
|
8729 case "o": |
|
8730 output += formatNumber( "o", |
|
8731 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); |
|
8732 break; |
|
8733 case "m": |
|
8734 output += formatNumber( "m", date.getMonth() + 1, 2 ); |
|
8735 break; |
|
8736 case "M": |
|
8737 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); |
|
8738 break; |
|
8739 case "y": |
|
8740 output += ( lookAhead( "y" ) ? date.getFullYear() : |
|
8741 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); |
|
8742 break; |
|
8743 case "@": |
|
8744 output += date.getTime(); |
|
8745 break; |
|
8746 case "!": |
|
8747 output += date.getTime() * 10000 + this._ticksTo1970; |
|
8748 break; |
|
8749 case "'": |
|
8750 if ( lookAhead( "'" ) ) { |
|
8751 output += "'"; |
|
8752 } else { |
|
8753 literal = true; |
|
8754 } |
|
8755 break; |
|
8756 default: |
|
8757 output += format.charAt( iFormat ); |
|
8758 } |
|
8759 } |
|
8760 } |
|
8761 } |
|
8762 return output; |
|
8763 }, |
|
8764 |
|
8765 /* Extract all possible characters from the date format. */ |
|
8766 _possibleChars: function( format ) { |
|
8767 var iFormat, |
|
8768 chars = "", |
|
8769 literal = false, |
|
8770 |
|
8771 // Check whether a format character is doubled |
|
8772 lookAhead = function( match ) { |
|
8773 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); |
|
8774 if ( matches ) { |
|
8775 iFormat++; |
|
8776 } |
|
8777 return matches; |
|
8778 }; |
|
8779 |
|
8780 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { |
|
8781 if ( literal ) { |
|
8782 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { |
|
8783 literal = false; |
|
8784 } else { |
|
8785 chars += format.charAt( iFormat ); |
|
8786 } |
|
8787 } else { |
|
8788 switch ( format.charAt( iFormat ) ) { |
|
8789 case "d": case "m": case "y": case "@": |
|
8790 chars += "0123456789"; |
|
8791 break; |
|
8792 case "D": case "M": |
|
8793 return null; // Accept anything |
|
8794 case "'": |
|
8795 if ( lookAhead( "'" ) ) { |
|
8796 chars += "'"; |
|
8797 } else { |
|
8798 literal = true; |
|
8799 } |
|
8800 break; |
|
8801 default: |
|
8802 chars += format.charAt( iFormat ); |
|
8803 } |
|
8804 } |
|
8805 } |
|
8806 return chars; |
|
8807 }, |
|
8808 |
|
8809 /* Get a setting value, defaulting if necessary. */ |
|
8810 _get: function( inst, name ) { |
|
8811 return inst.settings[ name ] !== undefined ? |
|
8812 inst.settings[ name ] : this._defaults[ name ]; |
|
8813 }, |
|
8814 |
|
8815 /* Parse existing date and initialise date picker. */ |
|
8816 _setDateFromField: function( inst, noDefault ) { |
|
8817 if ( inst.input.val() === inst.lastVal ) { |
|
8818 return; |
|
8819 } |
|
8820 |
|
8821 var dateFormat = this._get( inst, "dateFormat" ), |
|
8822 dates = inst.lastVal = inst.input ? inst.input.val() : null, |
|
8823 defaultDate = this._getDefaultDate( inst ), |
|
8824 date = defaultDate, |
|
8825 settings = this._getFormatConfig( inst ); |
|
8826 |
|
8827 try { |
|
8828 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; |
|
8829 } catch ( event ) { |
|
8830 dates = ( noDefault ? "" : dates ); |
|
8831 } |
|
8832 inst.selectedDay = date.getDate(); |
|
8833 inst.drawMonth = inst.selectedMonth = date.getMonth(); |
|
8834 inst.drawYear = inst.selectedYear = date.getFullYear(); |
|
8835 inst.currentDay = ( dates ? date.getDate() : 0 ); |
|
8836 inst.currentMonth = ( dates ? date.getMonth() : 0 ); |
|
8837 inst.currentYear = ( dates ? date.getFullYear() : 0 ); |
|
8838 this._adjustInstDate( inst ); |
|
8839 }, |
|
8840 |
|
8841 /* Retrieve the default date shown on opening. */ |
|
8842 _getDefaultDate: function( inst ) { |
|
8843 return this._restrictMinMax( inst, |
|
8844 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); |
|
8845 }, |
|
8846 |
|
8847 /* A date may be specified as an exact value or a relative one. */ |
|
8848 _determineDate: function( inst, date, defaultDate ) { |
|
8849 var offsetNumeric = function( offset ) { |
|
8850 var date = new Date(); |
|
8851 date.setDate( date.getDate() + offset ); |
|
8852 return date; |
|
8853 }, |
|
8854 offsetString = function( offset ) { |
|
8855 try { |
|
8856 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), |
|
8857 offset, $.datepicker._getFormatConfig( inst ) ); |
|
8858 } catch ( e ) { |
|
8859 |
|
8860 // Ignore |
|
8861 } |
|
8862 |
|
8863 var date = ( offset.toLowerCase().match( /^c/ ) ? |
|
8864 $.datepicker._getDate( inst ) : null ) || new Date(), |
|
8865 year = date.getFullYear(), |
|
8866 month = date.getMonth(), |
|
8867 day = date.getDate(), |
|
8868 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, |
|
8869 matches = pattern.exec( offset ); |
|
8870 |
|
8871 while ( matches ) { |
|
8872 switch ( matches[ 2 ] || "d" ) { |
|
8873 case "d" : case "D" : |
|
8874 day += parseInt( matches[ 1 ], 10 ); break; |
|
8875 case "w" : case "W" : |
|
8876 day += parseInt( matches[ 1 ], 10 ) * 7; break; |
|
8877 case "m" : case "M" : |
|
8878 month += parseInt( matches[ 1 ], 10 ); |
|
8879 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); |
|
8880 break; |
|
8881 case "y": case "Y" : |
|
8882 year += parseInt( matches[ 1 ], 10 ); |
|
8883 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); |
|
8884 break; |
|
8885 } |
|
8886 matches = pattern.exec( offset ); |
|
8887 } |
|
8888 return new Date( year, month, day ); |
|
8889 }, |
|
8890 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : |
|
8891 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); |
|
8892 |
|
8893 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); |
|
8894 if ( newDate ) { |
|
8895 newDate.setHours( 0 ); |
|
8896 newDate.setMinutes( 0 ); |
|
8897 newDate.setSeconds( 0 ); |
|
8898 newDate.setMilliseconds( 0 ); |
|
8899 } |
|
8900 return this._daylightSavingAdjust( newDate ); |
|
8901 }, |
|
8902 |
|
8903 /* Handle switch to/from daylight saving. |
|
8904 * Hours may be non-zero on daylight saving cut-over: |
|
8905 * > 12 when midnight changeover, but then cannot generate |
|
8906 * midnight datetime, so jump to 1AM, otherwise reset. |
|
8907 * @param date (Date) the date to check |
|
8908 * @return (Date) the corrected date |
|
8909 */ |
|
8910 _daylightSavingAdjust: function( date ) { |
|
8911 if ( !date ) { |
|
8912 return null; |
|
8913 } |
|
8914 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); |
|
8915 return date; |
|
8916 }, |
|
8917 |
|
8918 /* Set the date(s) directly. */ |
|
8919 _setDate: function( inst, date, noChange ) { |
|
8920 var clear = !date, |
|
8921 origMonth = inst.selectedMonth, |
|
8922 origYear = inst.selectedYear, |
|
8923 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); |
|
8924 |
|
8925 inst.selectedDay = inst.currentDay = newDate.getDate(); |
|
8926 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); |
|
8927 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); |
|
8928 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { |
|
8929 this._notifyChange( inst ); |
|
8930 } |
|
8931 this._adjustInstDate( inst ); |
|
8932 if ( inst.input ) { |
|
8933 inst.input.val( clear ? "" : this._formatDate( inst ) ); |
|
8934 } |
|
8935 }, |
|
8936 |
|
8937 /* Retrieve the date(s) directly. */ |
|
8938 _getDate: function( inst ) { |
|
8939 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : |
|
8940 this._daylightSavingAdjust( new Date( |
|
8941 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); |
|
8942 return startDate; |
|
8943 }, |
|
8944 |
|
8945 /* Attach the onxxx handlers. These are declared statically so |
|
8946 * they work with static code transformers like Caja. |
|
8947 */ |
|
8948 _attachHandlers: function( inst ) { |
|
8949 var stepMonths = this._get( inst, "stepMonths" ), |
|
8950 id = "#" + inst.id.replace( /\\\\/g, "\\" ); |
|
8951 inst.dpDiv.find( "[data-handler]" ).map( function() { |
|
8952 var handler = { |
|
8953 prev: function() { |
|
8954 $.datepicker._adjustDate( id, -stepMonths, "M" ); |
|
8955 }, |
|
8956 next: function() { |
|
8957 $.datepicker._adjustDate( id, +stepMonths, "M" ); |
|
8958 }, |
|
8959 hide: function() { |
|
8960 $.datepicker._hideDatepicker(); |
|
8961 }, |
|
8962 today: function() { |
|
8963 $.datepicker._gotoToday( id ); |
|
8964 }, |
|
8965 selectDay: function() { |
|
8966 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); |
|
8967 return false; |
|
8968 }, |
|
8969 selectMonth: function() { |
|
8970 $.datepicker._selectMonthYear( id, this, "M" ); |
|
8971 return false; |
|
8972 }, |
|
8973 selectYear: function() { |
|
8974 $.datepicker._selectMonthYear( id, this, "Y" ); |
|
8975 return false; |
|
8976 } |
|
8977 }; |
|
8978 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); |
|
8979 } ); |
|
8980 }, |
|
8981 |
|
8982 /* Generate the HTML for the current state of the date picker. */ |
|
8983 _generateHTML: function( inst ) { |
|
8984 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, |
|
8985 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, |
|
8986 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, |
|
8987 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, |
|
8988 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, |
|
8989 printDate, dRow, tbody, daySettings, otherMonth, unselectable, |
|
8990 tempDate = new Date(), |
|
8991 today = this._daylightSavingAdjust( |
|
8992 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time |
|
8993 isRTL = this._get( inst, "isRTL" ), |
|
8994 showButtonPanel = this._get( inst, "showButtonPanel" ), |
|
8995 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), |
|
8996 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), |
|
8997 numMonths = this._getNumberOfMonths( inst ), |
|
8998 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), |
|
8999 stepMonths = this._get( inst, "stepMonths" ), |
|
9000 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), |
|
9001 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : |
|
9002 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), |
|
9003 minDate = this._getMinMaxDate( inst, "min" ), |
|
9004 maxDate = this._getMinMaxDate( inst, "max" ), |
|
9005 drawMonth = inst.drawMonth - showCurrentAtPos, |
|
9006 drawYear = inst.drawYear; |
|
9007 |
|
9008 if ( drawMonth < 0 ) { |
|
9009 drawMonth += 12; |
|
9010 drawYear--; |
|
9011 } |
|
9012 if ( maxDate ) { |
|
9013 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), |
|
9014 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); |
|
9015 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); |
|
9016 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { |
|
9017 drawMonth--; |
|
9018 if ( drawMonth < 0 ) { |
|
9019 drawMonth = 11; |
|
9020 drawYear--; |
|
9021 } |
|
9022 } |
|
9023 } |
|
9024 inst.drawMonth = drawMonth; |
|
9025 inst.drawYear = drawYear; |
|
9026 |
|
9027 prevText = this._get( inst, "prevText" ); |
|
9028 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, |
|
9029 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), |
|
9030 this._getFormatConfig( inst ) ) ); |
|
9031 |
|
9032 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { |
|
9033 prev = $( "<a>" ) |
|
9034 .attr( { |
|
9035 "class": "ui-datepicker-prev ui-corner-all", |
|
9036 "data-handler": "prev", |
|
9037 "data-event": "click", |
|
9038 title: prevText |
|
9039 } ) |
|
9040 .append( |
|
9041 $( "<span>" ) |
|
9042 .addClass( "ui-icon ui-icon-circle-triangle-" + |
|
9043 ( isRTL ? "e" : "w" ) ) |
|
9044 .text( prevText ) |
|
9045 )[ 0 ].outerHTML; |
|
9046 } else if ( hideIfNoPrevNext ) { |
|
9047 prev = ""; |
|
9048 } else { |
|
9049 prev = $( "<a>" ) |
|
9050 .attr( { |
|
9051 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", |
|
9052 title: prevText |
|
9053 } ) |
|
9054 .append( |
|
9055 $( "<span>" ) |
|
9056 .addClass( "ui-icon ui-icon-circle-triangle-" + |
|
9057 ( isRTL ? "e" : "w" ) ) |
|
9058 .text( prevText ) |
|
9059 )[ 0 ].outerHTML; |
|
9060 } |
|
9061 |
|
9062 nextText = this._get( inst, "nextText" ); |
|
9063 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, |
|
9064 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), |
|
9065 this._getFormatConfig( inst ) ) ); |
|
9066 |
|
9067 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { |
|
9068 next = $( "<a>" ) |
|
9069 .attr( { |
|
9070 "class": "ui-datepicker-next ui-corner-all", |
|
9071 "data-handler": "next", |
|
9072 "data-event": "click", |
|
9073 title: nextText |
|
9074 } ) |
|
9075 .append( |
|
9076 $( "<span>" ) |
|
9077 .addClass( "ui-icon ui-icon-circle-triangle-" + |
|
9078 ( isRTL ? "w" : "e" ) ) |
|
9079 .text( nextText ) |
|
9080 )[ 0 ].outerHTML; |
|
9081 } else if ( hideIfNoPrevNext ) { |
|
9082 next = ""; |
|
9083 } else { |
|
9084 next = $( "<a>" ) |
|
9085 .attr( { |
|
9086 "class": "ui-datepicker-next ui-corner-all ui-state-disabled", |
|
9087 title: nextText |
|
9088 } ) |
|
9089 .append( |
|
9090 $( "<span>" ) |
|
9091 .attr( "class", "ui-icon ui-icon-circle-triangle-" + |
|
9092 ( isRTL ? "w" : "e" ) ) |
|
9093 .text( nextText ) |
|
9094 )[ 0 ].outerHTML; |
|
9095 } |
|
9096 |
|
9097 currentText = this._get( inst, "currentText" ); |
|
9098 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); |
|
9099 currentText = ( !navigationAsDateFormat ? currentText : |
|
9100 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); |
|
9101 |
|
9102 controls = ""; |
|
9103 if ( !inst.inline ) { |
|
9104 controls = $( "<button>" ) |
|
9105 .attr( { |
|
9106 type: "button", |
|
9107 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", |
|
9108 "data-handler": "hide", |
|
9109 "data-event": "click" |
|
9110 } ) |
|
9111 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; |
|
9112 } |
|
9113 |
|
9114 buttonPanel = ""; |
|
9115 if ( showButtonPanel ) { |
|
9116 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) |
|
9117 .append( isRTL ? controls : "" ) |
|
9118 .append( this._isInRange( inst, gotoDate ) ? |
|
9119 $( "<button>" ) |
|
9120 .attr( { |
|
9121 type: "button", |
|
9122 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", |
|
9123 "data-handler": "today", |
|
9124 "data-event": "click" |
|
9125 } ) |
|
9126 .text( currentText ) : |
|
9127 "" ) |
|
9128 .append( isRTL ? "" : controls )[ 0 ].outerHTML; |
|
9129 } |
|
9130 |
|
9131 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); |
|
9132 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); |
|
9133 |
|
9134 showWeek = this._get( inst, "showWeek" ); |
|
9135 dayNames = this._get( inst, "dayNames" ); |
|
9136 dayNamesMin = this._get( inst, "dayNamesMin" ); |
|
9137 monthNames = this._get( inst, "monthNames" ); |
|
9138 monthNamesShort = this._get( inst, "monthNamesShort" ); |
|
9139 beforeShowDay = this._get( inst, "beforeShowDay" ); |
|
9140 showOtherMonths = this._get( inst, "showOtherMonths" ); |
|
9141 selectOtherMonths = this._get( inst, "selectOtherMonths" ); |
|
9142 defaultDate = this._getDefaultDate( inst ); |
|
9143 html = ""; |
|
9144 |
|
9145 for ( row = 0; row < numMonths[ 0 ]; row++ ) { |
|
9146 group = ""; |
|
9147 this.maxRows = 4; |
|
9148 for ( col = 0; col < numMonths[ 1 ]; col++ ) { |
|
9149 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); |
|
9150 cornerClass = " ui-corner-all"; |
|
9151 calender = ""; |
|
9152 if ( isMultiMonth ) { |
|
9153 calender += "<div class='ui-datepicker-group"; |
|
9154 if ( numMonths[ 1 ] > 1 ) { |
|
9155 switch ( col ) { |
|
9156 case 0: calender += " ui-datepicker-group-first"; |
|
9157 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; |
|
9158 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; |
|
9159 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; |
|
9160 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; |
|
9161 } |
|
9162 } |
|
9163 calender += "'>"; |
|
9164 } |
|
9165 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + |
|
9166 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + |
|
9167 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + |
|
9168 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, |
|
9169 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers |
|
9170 "</div><table class='ui-datepicker-calendar'><thead>" + |
|
9171 "<tr>"; |
|
9172 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); |
|
9173 for ( dow = 0; dow < 7; dow++ ) { // days of the week |
|
9174 day = ( dow + firstDay ) % 7; |
|
9175 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + |
|
9176 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; |
|
9177 } |
|
9178 calender += thead + "</tr></thead><tbody>"; |
|
9179 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); |
|
9180 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { |
|
9181 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); |
|
9182 } |
|
9183 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; |
|
9184 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate |
|
9185 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) |
|
9186 this.maxRows = numRows; |
|
9187 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); |
|
9188 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows |
|
9189 calender += "<tr>"; |
|
9190 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + |
|
9191 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); |
|
9192 for ( dow = 0; dow < 7; dow++ ) { // create date picker days |
|
9193 daySettings = ( beforeShowDay ? |
|
9194 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); |
|
9195 otherMonth = ( printDate.getMonth() !== drawMonth ); |
|
9196 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || |
|
9197 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); |
|
9198 tbody += "<td class='" + |
|
9199 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends |
|
9200 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months |
|
9201 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key |
|
9202 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? |
|
9203 |
|
9204 // or defaultDate is current printedDate and defaultDate is selectedDate |
|
9205 " " + this._dayOverClass : "" ) + // highlight selected day |
|
9206 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days |
|
9207 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates |
|
9208 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day |
|
9209 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) |
|
9210 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title |
|
9211 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions |
|
9212 ( otherMonth && !showOtherMonths ? " " : // display for other months |
|
9213 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + |
|
9214 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + |
|
9215 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day |
|
9216 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months |
|
9217 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader |
|
9218 "' data-date='" + printDate.getDate() + // store date as data |
|
9219 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date |
|
9220 printDate.setDate( printDate.getDate() + 1 ); |
|
9221 printDate = this._daylightSavingAdjust( printDate ); |
|
9222 } |
|
9223 calender += tbody + "</tr>"; |
|
9224 } |
|
9225 drawMonth++; |
|
9226 if ( drawMonth > 11 ) { |
|
9227 drawMonth = 0; |
|
9228 drawYear++; |
|
9229 } |
|
9230 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + |
|
9231 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); |
|
9232 group += calender; |
|
9233 } |
|
9234 html += group; |
|
9235 } |
|
9236 html += buttonPanel; |
|
9237 inst._keyEvent = false; |
|
9238 return html; |
|
9239 }, |
|
9240 |
|
9241 /* Generate the month and year header. */ |
|
9242 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, |
|
9243 secondary, monthNames, monthNamesShort ) { |
|
9244 |
|
9245 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, |
|
9246 changeMonth = this._get( inst, "changeMonth" ), |
|
9247 changeYear = this._get( inst, "changeYear" ), |
|
9248 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), |
|
9249 selectMonthLabel = this._get( inst, "selectMonthLabel" ), |
|
9250 selectYearLabel = this._get( inst, "selectYearLabel" ), |
|
9251 html = "<div class='ui-datepicker-title'>", |
|
9252 monthHtml = ""; |
|
9253 |
|
9254 // Month selection |
|
9255 if ( secondary || !changeMonth ) { |
|
9256 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; |
|
9257 } else { |
|
9258 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); |
|
9259 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); |
|
9260 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; |
|
9261 for ( month = 0; month < 12; month++ ) { |
|
9262 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { |
|
9263 monthHtml += "<option value='" + month + "'" + |
|
9264 ( month === drawMonth ? " selected='selected'" : "" ) + |
|
9265 ">" + monthNamesShort[ month ] + "</option>"; |
|
9266 } |
|
9267 } |
|
9268 monthHtml += "</select>"; |
|
9269 } |
|
9270 |
|
9271 if ( !showMonthAfterYear ) { |
|
9272 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); |
|
9273 } |
|
9274 |
|
9275 // Year selection |
|
9276 if ( !inst.yearshtml ) { |
|
9277 inst.yearshtml = ""; |
|
9278 if ( secondary || !changeYear ) { |
|
9279 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; |
|
9280 } else { |
|
9281 |
|
9282 // determine range of years to display |
|
9283 years = this._get( inst, "yearRange" ).split( ":" ); |
|
9284 thisYear = new Date().getFullYear(); |
|
9285 determineYear = function( value ) { |
|
9286 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : |
|
9287 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : |
|
9288 parseInt( value, 10 ) ) ); |
|
9289 return ( isNaN( year ) ? thisYear : year ); |
|
9290 }; |
|
9291 year = determineYear( years[ 0 ] ); |
|
9292 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); |
|
9293 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); |
|
9294 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); |
|
9295 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; |
|
9296 for ( ; year <= endYear; year++ ) { |
|
9297 inst.yearshtml += "<option value='" + year + "'" + |
|
9298 ( year === drawYear ? " selected='selected'" : "" ) + |
|
9299 ">" + year + "</option>"; |
|
9300 } |
|
9301 inst.yearshtml += "</select>"; |
|
9302 |
|
9303 html += inst.yearshtml; |
|
9304 inst.yearshtml = null; |
|
9305 } |
|
9306 } |
|
9307 |
|
9308 html += this._get( inst, "yearSuffix" ); |
|
9309 if ( showMonthAfterYear ) { |
|
9310 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; |
|
9311 } |
|
9312 html += "</div>"; // Close datepicker_header |
|
9313 return html; |
|
9314 }, |
|
9315 |
|
9316 /* Adjust one of the date sub-fields. */ |
|
9317 _adjustInstDate: function( inst, offset, period ) { |
|
9318 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), |
|
9319 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), |
|
9320 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), |
|
9321 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); |
|
9322 |
|
9323 inst.selectedDay = date.getDate(); |
|
9324 inst.drawMonth = inst.selectedMonth = date.getMonth(); |
|
9325 inst.drawYear = inst.selectedYear = date.getFullYear(); |
|
9326 if ( period === "M" || period === "Y" ) { |
|
9327 this._notifyChange( inst ); |
|
9328 } |
|
9329 }, |
|
9330 |
|
9331 /* Ensure a date is within any min/max bounds. */ |
|
9332 _restrictMinMax: function( inst, date ) { |
|
9333 var minDate = this._getMinMaxDate( inst, "min" ), |
|
9334 maxDate = this._getMinMaxDate( inst, "max" ), |
|
9335 newDate = ( minDate && date < minDate ? minDate : date ); |
|
9336 return ( maxDate && newDate > maxDate ? maxDate : newDate ); |
|
9337 }, |
|
9338 |
|
9339 /* Notify change of month/year. */ |
|
9340 _notifyChange: function( inst ) { |
|
9341 var onChange = this._get( inst, "onChangeMonthYear" ); |
|
9342 if ( onChange ) { |
|
9343 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), |
|
9344 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); |
|
9345 } |
|
9346 }, |
|
9347 |
|
9348 /* Determine the number of months to show. */ |
|
9349 _getNumberOfMonths: function( inst ) { |
|
9350 var numMonths = this._get( inst, "numberOfMonths" ); |
|
9351 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); |
|
9352 }, |
|
9353 |
|
9354 /* Determine the current maximum date - ensure no time components are set. */ |
|
9355 _getMinMaxDate: function( inst, minMax ) { |
|
9356 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); |
|
9357 }, |
|
9358 |
|
9359 /* Find the number of days in a given month. */ |
|
9360 _getDaysInMonth: function( year, month ) { |
|
9361 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); |
|
9362 }, |
|
9363 |
|
9364 /* Find the day of the week of the first of a month. */ |
|
9365 _getFirstDayOfMonth: function( year, month ) { |
|
9366 return new Date( year, month, 1 ).getDay(); |
|
9367 }, |
|
9368 |
|
9369 /* Determines if we should allow a "next/prev" month display change. */ |
|
9370 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { |
|
9371 var numMonths = this._getNumberOfMonths( inst ), |
|
9372 date = this._daylightSavingAdjust( new Date( curYear, |
|
9373 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); |
|
9374 |
|
9375 if ( offset < 0 ) { |
|
9376 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); |
|
9377 } |
|
9378 return this._isInRange( inst, date ); |
|
9379 }, |
|
9380 |
|
9381 /* Is the given date in the accepted range? */ |
|
9382 _isInRange: function( inst, date ) { |
|
9383 var yearSplit, currentYear, |
|
9384 minDate = this._getMinMaxDate( inst, "min" ), |
|
9385 maxDate = this._getMinMaxDate( inst, "max" ), |
|
9386 minYear = null, |
|
9387 maxYear = null, |
|
9388 years = this._get( inst, "yearRange" ); |
|
9389 if ( years ) { |
|
9390 yearSplit = years.split( ":" ); |
|
9391 currentYear = new Date().getFullYear(); |
|
9392 minYear = parseInt( yearSplit[ 0 ], 10 ); |
|
9393 maxYear = parseInt( yearSplit[ 1 ], 10 ); |
|
9394 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { |
|
9395 minYear += currentYear; |
|
9396 } |
|
9397 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { |
|
9398 maxYear += currentYear; |
|
9399 } |
|
9400 } |
|
9401 |
|
9402 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && |
|
9403 ( !maxDate || date.getTime() <= maxDate.getTime() ) && |
|
9404 ( !minYear || date.getFullYear() >= minYear ) && |
|
9405 ( !maxYear || date.getFullYear() <= maxYear ) ); |
|
9406 }, |
|
9407 |
|
9408 /* Provide the configuration settings for formatting/parsing. */ |
|
9409 _getFormatConfig: function( inst ) { |
|
9410 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); |
|
9411 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : |
|
9412 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); |
|
9413 return { shortYearCutoff: shortYearCutoff, |
|
9414 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), |
|
9415 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; |
|
9416 }, |
|
9417 |
|
9418 /* Format the given date for display. */ |
|
9419 _formatDate: function( inst, day, month, year ) { |
|
9420 if ( !day ) { |
|
9421 inst.currentDay = inst.selectedDay; |
|
9422 inst.currentMonth = inst.selectedMonth; |
|
9423 inst.currentYear = inst.selectedYear; |
|
9424 } |
|
9425 var date = ( day ? ( typeof day === "object" ? day : |
|
9426 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : |
|
9427 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); |
|
9428 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); |
|
9429 } |
|
9430 } ); |
|
9431 |
|
9432 /* |
|
9433 * Bind hover events for datepicker elements. |
|
9434 * Done via delegate so the binding only occurs once in the lifetime of the parent div. |
|
9435 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. |
|
9436 */ |
|
9437 function datepicker_bindHover( dpDiv ) { |
|
9438 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; |
|
9439 return dpDiv.on( "mouseout", selector, function() { |
|
9440 $( this ).removeClass( "ui-state-hover" ); |
|
9441 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { |
|
9442 $( this ).removeClass( "ui-datepicker-prev-hover" ); |
|
9443 } |
|
9444 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { |
|
9445 $( this ).removeClass( "ui-datepicker-next-hover" ); |
|
9446 } |
|
9447 } ) |
|
9448 .on( "mouseover", selector, datepicker_handleMouseover ); |
|
9449 } |
|
9450 |
|
9451 function datepicker_handleMouseover() { |
|
9452 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { |
|
9453 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); |
|
9454 $( this ).addClass( "ui-state-hover" ); |
|
9455 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { |
|
9456 $( this ).addClass( "ui-datepicker-prev-hover" ); |
|
9457 } |
|
9458 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { |
|
9459 $( this ).addClass( "ui-datepicker-next-hover" ); |
|
9460 } |
|
9461 } |
|
9462 } |
|
9463 |
|
9464 /* jQuery extend now ignores nulls! */ |
|
9465 function datepicker_extendRemove( target, props ) { |
|
9466 $.extend( target, props ); |
|
9467 for ( var name in props ) { |
|
9468 if ( props[ name ] == null ) { |
|
9469 target[ name ] = props[ name ]; |
|
9470 } |
|
9471 } |
|
9472 return target; |
|
9473 } |
|
9474 |
|
9475 /* Invoke the datepicker functionality. |
|
9476 @param options string - a command, optionally followed by additional parameters or |
|
9477 Object - settings for attaching new datepicker functionality |
|
9478 @return jQuery object */ |
|
9479 $.fn.datepicker = function( options ) { |
|
9480 |
|
9481 /* Verify an empty collection wasn't passed - Fixes #6976 */ |
|
9482 if ( !this.length ) { |
|
9483 return this; |
|
9484 } |
|
9485 |
|
9486 /* Initialise the date picker. */ |
|
9487 if ( !$.datepicker.initialized ) { |
|
9488 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); |
|
9489 $.datepicker.initialized = true; |
|
9490 } |
|
9491 |
|
9492 /* Append datepicker main container to body if not exist. */ |
|
9493 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { |
|
9494 $( "body" ).append( $.datepicker.dpDiv ); |
|
9495 } |
|
9496 |
|
9497 var otherArgs = Array.prototype.slice.call( arguments, 1 ); |
|
9498 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { |
|
9499 return $.datepicker[ "_" + options + "Datepicker" ]. |
|
9500 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); |
|
9501 } |
|
9502 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { |
|
9503 return $.datepicker[ "_" + options + "Datepicker" ]. |
|
9504 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); |
|
9505 } |
|
9506 return this.each( function() { |
|
9507 if ( typeof options === "string" ) { |
|
9508 $.datepicker[ "_" + options + "Datepicker" ] |
|
9509 .apply( $.datepicker, [ this ].concat( otherArgs ) ); |
|
9510 } else { |
|
9511 $.datepicker._attachDatepicker( this, options ); |
|
9512 } |
|
9513 } ); |
|
9514 }; |
|
9515 |
|
9516 $.datepicker = new Datepicker(); // singleton instance |
|
9517 $.datepicker.initialized = false; |
|
9518 $.datepicker.uuid = new Date().getTime(); |
|
9519 $.datepicker.version = "1.13.2"; |
|
9520 |
|
9521 var widgetsDatepicker = $.datepicker; |
|
9522 |
|
9523 |
|
9524 |
|
9525 // This file is deprecated |
|
9526 var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); |
|
9527 |
|
9528 /*! |
|
9529 * jQuery UI Mouse 1.13.2 |
|
9530 * http://jqueryui.com |
|
9531 * |
|
9532 * Copyright jQuery Foundation and other contributors |
|
9533 * Released under the MIT license. |
|
9534 * http://jquery.org/license |
|
9535 */ |
|
9536 |
|
9537 //>>label: Mouse |
|
9538 //>>group: Widgets |
|
9539 //>>description: Abstracts mouse-based interactions to assist in creating certain widgets. |
|
9540 //>>docs: http://api.jqueryui.com/mouse/ |
|
9541 |
|
9542 |
|
9543 var mouseHandled = false; |
|
9544 $( document ).on( "mouseup", function() { |
|
9545 mouseHandled = false; |
|
9546 } ); |
|
9547 |
|
9548 var widgetsMouse = $.widget( "ui.mouse", { |
|
9549 version: "1.13.2", |
|
9550 options: { |
|
9551 cancel: "input, textarea, button, select, option", |
|
9552 distance: 1, |
|
9553 delay: 0 |
|
9554 }, |
|
9555 _mouseInit: function() { |
|
9556 var that = this; |
|
9557 |
|
9558 this.element |
|
9559 .on( "mousedown." + this.widgetName, function( event ) { |
|
9560 return that._mouseDown( event ); |
|
9561 } ) |
|
9562 .on( "click." + this.widgetName, function( event ) { |
|
9563 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { |
|
9564 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); |
|
9565 event.stopImmediatePropagation(); |
|
9566 return false; |
|
9567 } |
|
9568 } ); |
|
9569 |
|
9570 this.started = false; |
|
9571 }, |
|
9572 |
|
9573 // TODO: make sure destroying one instance of mouse doesn't mess with |
|
9574 // other instances of mouse |
|
9575 _mouseDestroy: function() { |
|
9576 this.element.off( "." + this.widgetName ); |
|
9577 if ( this._mouseMoveDelegate ) { |
|
9578 this.document |
|
9579 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) |
|
9580 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); |
|
9581 } |
|
9582 }, |
|
9583 |
|
9584 _mouseDown: function( event ) { |
|
9585 |
|
9586 // don't let more than one widget handle mouseStart |
|
9587 if ( mouseHandled ) { |
|
9588 return; |
|
9589 } |
|
9590 |
|
9591 this._mouseMoved = false; |
|
9592 |
|
9593 // We may have missed mouseup (out of window) |
|
9594 if ( this._mouseStarted ) { |
|
9595 this._mouseUp( event ); |
|
9596 } |
|
9597 |
|
9598 this._mouseDownEvent = event; |
|
9599 |
|
9600 var that = this, |
|
9601 btnIsLeft = ( event.which === 1 ), |
|
9602 |
|
9603 // event.target.nodeName works around a bug in IE 8 with |
|
9604 // disabled inputs (#7620) |
|
9605 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? |
|
9606 $( event.target ).closest( this.options.cancel ).length : false ); |
|
9607 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { |
|
9608 return true; |
|
9609 } |
|
9610 |
|
9611 this.mouseDelayMet = !this.options.delay; |
|
9612 if ( !this.mouseDelayMet ) { |
|
9613 this._mouseDelayTimer = setTimeout( function() { |
|
9614 that.mouseDelayMet = true; |
|
9615 }, this.options.delay ); |
|
9616 } |
|
9617 |
|
9618 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { |
|
9619 this._mouseStarted = ( this._mouseStart( event ) !== false ); |
|
9620 if ( !this._mouseStarted ) { |
|
9621 event.preventDefault(); |
|
9622 return true; |
|
9623 } |
|
9624 } |
|
9625 |
|
9626 // Click event may never have fired (Gecko & Opera) |
|
9627 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { |
|
9628 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); |
|
9629 } |
|
9630 |
|
9631 // These delegates are required to keep context |
|
9632 this._mouseMoveDelegate = function( event ) { |
|
9633 return that._mouseMove( event ); |
|
9634 }; |
|
9635 this._mouseUpDelegate = function( event ) { |
|
9636 return that._mouseUp( event ); |
|
9637 }; |
|
9638 |
|
9639 this.document |
|
9640 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) |
|
9641 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); |
|
9642 |
|
9643 event.preventDefault(); |
|
9644 |
|
9645 mouseHandled = true; |
|
9646 return true; |
|
9647 }, |
|
9648 |
|
9649 _mouseMove: function( event ) { |
|
9650 |
|
9651 // Only check for mouseups outside the document if you've moved inside the document |
|
9652 // at least once. This prevents the firing of mouseup in the case of IE<9, which will |
|
9653 // fire a mousemove event if content is placed under the cursor. See #7778 |
|
9654 // Support: IE <9 |
|
9655 if ( this._mouseMoved ) { |
|
9656 |
|
9657 // IE mouseup check - mouseup happened when mouse was out of window |
|
9658 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && |
|
9659 !event.button ) { |
|
9660 return this._mouseUp( event ); |
|
9661 |
|
9662 // Iframe mouseup check - mouseup occurred in another document |
|
9663 } else if ( !event.which ) { |
|
9664 |
|
9665 // Support: Safari <=8 - 9 |
|
9666 // Safari sets which to 0 if you press any of the following keys |
|
9667 // during a drag (#14461) |
|
9668 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || |
|
9669 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { |
|
9670 this.ignoreMissingWhich = true; |
|
9671 } else if ( !this.ignoreMissingWhich ) { |
|
9672 return this._mouseUp( event ); |
|
9673 } |
|
9674 } |
|
9675 } |
|
9676 |
|
9677 if ( event.which || event.button ) { |
|
9678 this._mouseMoved = true; |
|
9679 } |
|
9680 |
|
9681 if ( this._mouseStarted ) { |
|
9682 this._mouseDrag( event ); |
|
9683 return event.preventDefault(); |
|
9684 } |
|
9685 |
|
9686 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { |
|
9687 this._mouseStarted = |
|
9688 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); |
|
9689 if ( this._mouseStarted ) { |
|
9690 this._mouseDrag( event ); |
|
9691 } else { |
|
9692 this._mouseUp( event ); |
|
9693 } |
|
9694 } |
|
9695 |
|
9696 return !this._mouseStarted; |
|
9697 }, |
|
9698 |
|
9699 _mouseUp: function( event ) { |
|
9700 this.document |
|
9701 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) |
|
9702 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); |
|
9703 |
|
9704 if ( this._mouseStarted ) { |
|
9705 this._mouseStarted = false; |
|
9706 |
|
9707 if ( event.target === this._mouseDownEvent.target ) { |
|
9708 $.data( event.target, this.widgetName + ".preventClickEvent", true ); |
|
9709 } |
|
9710 |
|
9711 this._mouseStop( event ); |
|
9712 } |
|
9713 |
|
9714 if ( this._mouseDelayTimer ) { |
|
9715 clearTimeout( this._mouseDelayTimer ); |
|
9716 delete this._mouseDelayTimer; |
|
9717 } |
|
9718 |
|
9719 this.ignoreMissingWhich = false; |
|
9720 mouseHandled = false; |
|
9721 event.preventDefault(); |
|
9722 }, |
|
9723 |
|
9724 _mouseDistanceMet: function( event ) { |
|
9725 return ( Math.max( |
|
9726 Math.abs( this._mouseDownEvent.pageX - event.pageX ), |
|
9727 Math.abs( this._mouseDownEvent.pageY - event.pageY ) |
|
9728 ) >= this.options.distance |
|
9729 ); |
|
9730 }, |
|
9731 |
|
9732 _mouseDelayMet: function( /* event */ ) { |
|
9733 return this.mouseDelayMet; |
|
9734 }, |
|
9735 |
|
9736 // These are placeholder methods, to be overriden by extending plugin |
|
9737 _mouseStart: function( /* event */ ) {}, |
|
9738 _mouseDrag: function( /* event */ ) {}, |
|
9739 _mouseStop: function( /* event */ ) {}, |
|
9740 _mouseCapture: function( /* event */ ) { |
|
9741 return true; |
|
9742 } |
|
9743 } ); |
|
9744 |
|
9745 |
|
9746 |
|
9747 // $.ui.plugin is deprecated. Use $.widget() extensions instead. |
|
9748 var plugin = $.ui.plugin = { |
|
9749 add: function( module, option, set ) { |
|
9750 var i, |
|
9751 proto = $.ui[ module ].prototype; |
|
9752 for ( i in set ) { |
|
9753 proto.plugins[ i ] = proto.plugins[ i ] || []; |
|
9754 proto.plugins[ i ].push( [ option, set[ i ] ] ); |
|
9755 } |
|
9756 }, |
|
9757 call: function( instance, name, args, allowDisconnected ) { |
|
9758 var i, |
|
9759 set = instance.plugins[ name ]; |
|
9760 |
|
9761 if ( !set ) { |
|
9762 return; |
|
9763 } |
|
9764 |
|
9765 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || |
|
9766 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { |
|
9767 return; |
|
9768 } |
|
9769 |
|
9770 for ( i = 0; i < set.length; i++ ) { |
|
9771 if ( instance.options[ set[ i ][ 0 ] ] ) { |
|
9772 set[ i ][ 1 ].apply( instance.element, args ); |
|
9773 } |
|
9774 } |
|
9775 } |
|
9776 }; |
|
9777 |
|
9778 |
|
9779 |
|
9780 var safeBlur = $.ui.safeBlur = function( element ) { |
|
9781 |
|
9782 // Support: IE9 - 10 only |
|
9783 // If the <body> is blurred, IE will switch windows, see #9420 |
|
9784 if ( element && element.nodeName.toLowerCase() !== "body" ) { |
|
9785 $( element ).trigger( "blur" ); |
|
9786 } |
|
9787 }; |
|
9788 |
|
9789 |
|
9790 /*! |
|
9791 * jQuery UI Draggable 1.13.2 |
|
9792 * http://jqueryui.com |
|
9793 * |
|
9794 * Copyright jQuery Foundation and other contributors |
|
9795 * Released under the MIT license. |
|
9796 * http://jquery.org/license |
|
9797 */ |
|
9798 |
|
9799 //>>label: Draggable |
|
9800 //>>group: Interactions |
|
9801 //>>description: Enables dragging functionality for any element. |
|
9802 //>>docs: http://api.jqueryui.com/draggable/ |
|
9803 //>>demos: http://jqueryui.com/draggable/ |
|
9804 //>>css.structure: ../../themes/base/draggable.css |
|
9805 |
|
9806 |
|
9807 $.widget( "ui.draggable", $.ui.mouse, { |
|
9808 version: "1.13.2", |
|
9809 widgetEventPrefix: "drag", |
|
9810 options: { |
|
9811 addClasses: true, |
|
9812 appendTo: "parent", |
|
9813 axis: false, |
|
9814 connectToSortable: false, |
|
9815 containment: false, |
|
9816 cursor: "auto", |
|
9817 cursorAt: false, |
|
9818 grid: false, |
|
9819 handle: false, |
|
9820 helper: "original", |
|
9821 iframeFix: false, |
|
9822 opacity: false, |
|
9823 refreshPositions: false, |
|
9824 revert: false, |
|
9825 revertDuration: 500, |
|
9826 scope: "default", |
|
9827 scroll: true, |
|
9828 scrollSensitivity: 20, |
|
9829 scrollSpeed: 20, |
|
9830 snap: false, |
|
9831 snapMode: "both", |
|
9832 snapTolerance: 20, |
|
9833 stack: false, |
|
9834 zIndex: false, |
|
9835 |
|
9836 // Callbacks |
|
9837 drag: null, |
|
9838 start: null, |
|
9839 stop: null |
|
9840 }, |
|
9841 _create: function() { |
|
9842 |
|
9843 if ( this.options.helper === "original" ) { |
|
9844 this._setPositionRelative(); |
|
9845 } |
|
9846 if ( this.options.addClasses ) { |
|
9847 this._addClass( "ui-draggable" ); |
|
9848 } |
|
9849 this._setHandleClassName(); |
|
9850 |
|
9851 this._mouseInit(); |
|
9852 }, |
|
9853 |
|
9854 _setOption: function( key, value ) { |
|
9855 this._super( key, value ); |
|
9856 if ( key === "handle" ) { |
|
9857 this._removeHandleClassName(); |
|
9858 this._setHandleClassName(); |
|
9859 } |
|
9860 }, |
|
9861 |
|
9862 _destroy: function() { |
|
9863 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { |
|
9864 this.destroyOnClear = true; |
|
9865 return; |
|
9866 } |
|
9867 this._removeHandleClassName(); |
|
9868 this._mouseDestroy(); |
|
9869 }, |
|
9870 |
|
9871 _mouseCapture: function( event ) { |
|
9872 var o = this.options; |
|
9873 |
|
9874 // Among others, prevent a drag on a resizable-handle |
|
9875 if ( this.helper || o.disabled || |
|
9876 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { |
|
9877 return false; |
|
9878 } |
|
9879 |
|
9880 //Quit if we're not on a valid handle |
|
9881 this.handle = this._getHandle( event ); |
|
9882 if ( !this.handle ) { |
|
9883 return false; |
|
9884 } |
|
9885 |
|
9886 this._blurActiveElement( event ); |
|
9887 |
|
9888 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); |
|
9889 |
|
9890 return true; |
|
9891 |
|
9892 }, |
|
9893 |
|
9894 _blockFrames: function( selector ) { |
|
9895 this.iframeBlocks = this.document.find( selector ).map( function() { |
|
9896 var iframe = $( this ); |
|
9897 |
|
9898 return $( "<div>" ) |
|
9899 .css( "position", "absolute" ) |
|
9900 .appendTo( iframe.parent() ) |
|
9901 .outerWidth( iframe.outerWidth() ) |
|
9902 .outerHeight( iframe.outerHeight() ) |
|
9903 .offset( iframe.offset() )[ 0 ]; |
|
9904 } ); |
|
9905 }, |
|
9906 |
|
9907 _unblockFrames: function() { |
|
9908 if ( this.iframeBlocks ) { |
|
9909 this.iframeBlocks.remove(); |
|
9910 delete this.iframeBlocks; |
|
9911 } |
|
9912 }, |
|
9913 |
|
9914 _blurActiveElement: function( event ) { |
|
9915 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), |
|
9916 target = $( event.target ); |
|
9917 |
|
9918 // Don't blur if the event occurred on an element that is within |
|
9919 // the currently focused element |
|
9920 // See #10527, #12472 |
|
9921 if ( target.closest( activeElement ).length ) { |
|
9922 return; |
|
9923 } |
|
9924 |
|
9925 // Blur any element that currently has focus, see #4261 |
|
9926 $.ui.safeBlur( activeElement ); |
|
9927 }, |
|
9928 |
|
9929 _mouseStart: function( event ) { |
|
9930 |
|
9931 var o = this.options; |
|
9932 |
|
9933 //Create and append the visible helper |
|
9934 this.helper = this._createHelper( event ); |
|
9935 |
|
9936 this._addClass( this.helper, "ui-draggable-dragging" ); |
|
9937 |
|
9938 //Cache the helper size |
|
9939 this._cacheHelperProportions(); |
|
9940 |
|
9941 //If ddmanager is used for droppables, set the global draggable |
|
9942 if ( $.ui.ddmanager ) { |
|
9943 $.ui.ddmanager.current = this; |
|
9944 } |
|
9945 |
|
9946 /* |
|
9947 * - Position generation - |
|
9948 * This block generates everything position related - it's the core of draggables. |
|
9949 */ |
|
9950 |
|
9951 //Cache the margins of the original element |
|
9952 this._cacheMargins(); |
|
9953 |
|
9954 //Store the helper's css position |
|
9955 this.cssPosition = this.helper.css( "position" ); |
|
9956 this.scrollParent = this.helper.scrollParent( true ); |
|
9957 this.offsetParent = this.helper.offsetParent(); |
|
9958 this.hasFixedAncestor = this.helper.parents().filter( function() { |
|
9959 return $( this ).css( "position" ) === "fixed"; |
|
9960 } ).length > 0; |
|
9961 |
|
9962 //The element's absolute position on the page minus margins |
|
9963 this.positionAbs = this.element.offset(); |
|
9964 this._refreshOffsets( event ); |
|
9965 |
|
9966 //Generate the original position |
|
9967 this.originalPosition = this.position = this._generatePosition( event, false ); |
|
9968 this.originalPageX = event.pageX; |
|
9969 this.originalPageY = event.pageY; |
|
9970 |
|
9971 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied |
|
9972 if ( o.cursorAt ) { |
|
9973 this._adjustOffsetFromHelper( o.cursorAt ); |
|
9974 } |
|
9975 |
|
9976 //Set a containment if given in the options |
|
9977 this._setContainment(); |
|
9978 |
|
9979 //Trigger event + callbacks |
|
9980 if ( this._trigger( "start", event ) === false ) { |
|
9981 this._clear(); |
|
9982 return false; |
|
9983 } |
|
9984 |
|
9985 //Recache the helper size |
|
9986 this._cacheHelperProportions(); |
|
9987 |
|
9988 //Prepare the droppable offsets |
|
9989 if ( $.ui.ddmanager && !o.dropBehaviour ) { |
|
9990 $.ui.ddmanager.prepareOffsets( this, event ); |
|
9991 } |
|
9992 |
|
9993 // Execute the drag once - this causes the helper not to be visible before getting its |
|
9994 // correct position |
|
9995 this._mouseDrag( event, true ); |
|
9996 |
|
9997 // If the ddmanager is used for droppables, inform the manager that dragging has started |
|
9998 // (see #5003) |
|
9999 if ( $.ui.ddmanager ) { |
|
10000 $.ui.ddmanager.dragStart( this, event ); |
|
10001 } |
|
10002 |
|
10003 return true; |
|
10004 }, |
|
10005 |
|
10006 _refreshOffsets: function( event ) { |
|
10007 this.offset = { |
|
10008 top: this.positionAbs.top - this.margins.top, |
|
10009 left: this.positionAbs.left - this.margins.left, |
|
10010 scroll: false, |
|
10011 parent: this._getParentOffset(), |
|
10012 relative: this._getRelativeOffset() |
|
10013 }; |
|
10014 |
|
10015 this.offset.click = { |
|
10016 left: event.pageX - this.offset.left, |
|
10017 top: event.pageY - this.offset.top |
|
10018 }; |
|
10019 }, |
|
10020 |
|
10021 _mouseDrag: function( event, noPropagation ) { |
|
10022 |
|
10023 // reset any necessary cached properties (see #5009) |
|
10024 if ( this.hasFixedAncestor ) { |
|
10025 this.offset.parent = this._getParentOffset(); |
|
10026 } |
|
10027 |
|
10028 //Compute the helpers position |
|
10029 this.position = this._generatePosition( event, true ); |
|
10030 this.positionAbs = this._convertPositionTo( "absolute" ); |
|
10031 |
|
10032 //Call plugins and callbacks and use the resulting position if something is returned |
|
10033 if ( !noPropagation ) { |
|
10034 var ui = this._uiHash(); |
|
10035 if ( this._trigger( "drag", event, ui ) === false ) { |
|
10036 this._mouseUp( new $.Event( "mouseup", event ) ); |
|
10037 return false; |
|
10038 } |
|
10039 this.position = ui.position; |
|
10040 } |
|
10041 |
|
10042 this.helper[ 0 ].style.left = this.position.left + "px"; |
|
10043 this.helper[ 0 ].style.top = this.position.top + "px"; |
|
10044 |
|
10045 if ( $.ui.ddmanager ) { |
|
10046 $.ui.ddmanager.drag( this, event ); |
|
10047 } |
|
10048 |
|
10049 return false; |
|
10050 }, |
|
10051 |
|
10052 _mouseStop: function( event ) { |
|
10053 |
|
10054 //If we are using droppables, inform the manager about the drop |
|
10055 var that = this, |
|
10056 dropped = false; |
|
10057 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { |
|
10058 dropped = $.ui.ddmanager.drop( this, event ); |
|
10059 } |
|
10060 |
|
10061 //if a drop comes from outside (a sortable) |
|
10062 if ( this.dropped ) { |
|
10063 dropped = this.dropped; |
|
10064 this.dropped = false; |
|
10065 } |
|
10066 |
|
10067 if ( ( this.options.revert === "invalid" && !dropped ) || |
|
10068 ( this.options.revert === "valid" && dropped ) || |
|
10069 this.options.revert === true || ( typeof this.options.revert === "function" && |
|
10070 this.options.revert.call( this.element, dropped ) ) |
|
10071 ) { |
|
10072 $( this.helper ).animate( |
|
10073 this.originalPosition, |
|
10074 parseInt( this.options.revertDuration, 10 ), |
|
10075 function() { |
|
10076 if ( that._trigger( "stop", event ) !== false ) { |
|
10077 that._clear(); |
|
10078 } |
|
10079 } |
|
10080 ); |
|
10081 } else { |
|
10082 if ( this._trigger( "stop", event ) !== false ) { |
|
10083 this._clear(); |
|
10084 } |
|
10085 } |
|
10086 |
|
10087 return false; |
|
10088 }, |
|
10089 |
|
10090 _mouseUp: function( event ) { |
|
10091 this._unblockFrames(); |
|
10092 |
|
10093 // If the ddmanager is used for droppables, inform the manager that dragging has stopped |
|
10094 // (see #5003) |
|
10095 if ( $.ui.ddmanager ) { |
|
10096 $.ui.ddmanager.dragStop( this, event ); |
|
10097 } |
|
10098 |
|
10099 // Only need to focus if the event occurred on the draggable itself, see #10527 |
|
10100 if ( this.handleElement.is( event.target ) ) { |
|
10101 |
|
10102 // The interaction is over; whether or not the click resulted in a drag, |
|
10103 // focus the element |
|
10104 this.element.trigger( "focus" ); |
|
10105 } |
|
10106 |
|
10107 return $.ui.mouse.prototype._mouseUp.call( this, event ); |
|
10108 }, |
|
10109 |
|
10110 cancel: function() { |
|
10111 |
|
10112 if ( this.helper.is( ".ui-draggable-dragging" ) ) { |
|
10113 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); |
|
10114 } else { |
|
10115 this._clear(); |
|
10116 } |
|
10117 |
|
10118 return this; |
|
10119 |
|
10120 }, |
|
10121 |
|
10122 _getHandle: function( event ) { |
|
10123 return this.options.handle ? |
|
10124 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : |
|
10125 true; |
|
10126 }, |
|
10127 |
|
10128 _setHandleClassName: function() { |
|
10129 this.handleElement = this.options.handle ? |
|
10130 this.element.find( this.options.handle ) : this.element; |
|
10131 this._addClass( this.handleElement, "ui-draggable-handle" ); |
|
10132 }, |
|
10133 |
|
10134 _removeHandleClassName: function() { |
|
10135 this._removeClass( this.handleElement, "ui-draggable-handle" ); |
|
10136 }, |
|
10137 |
|
10138 _createHelper: function( event ) { |
|
10139 |
|
10140 var o = this.options, |
|
10141 helperIsFunction = typeof o.helper === "function", |
|
10142 helper = helperIsFunction ? |
|
10143 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : |
|
10144 ( o.helper === "clone" ? |
|
10145 this.element.clone().removeAttr( "id" ) : |
|
10146 this.element ); |
|
10147 |
|
10148 if ( !helper.parents( "body" ).length ) { |
|
10149 helper.appendTo( ( o.appendTo === "parent" ? |
|
10150 this.element[ 0 ].parentNode : |
|
10151 o.appendTo ) ); |
|
10152 } |
|
10153 |
|
10154 // Http://bugs.jqueryui.com/ticket/9446 |
|
10155 // a helper function can return the original element |
|
10156 // which wouldn't have been set to relative in _create |
|
10157 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { |
|
10158 this._setPositionRelative(); |
|
10159 } |
|
10160 |
|
10161 if ( helper[ 0 ] !== this.element[ 0 ] && |
|
10162 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { |
|
10163 helper.css( "position", "absolute" ); |
|
10164 } |
|
10165 |
|
10166 return helper; |
|
10167 |
|
10168 }, |
|
10169 |
|
10170 _setPositionRelative: function() { |
|
10171 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { |
|
10172 this.element[ 0 ].style.position = "relative"; |
|
10173 } |
|
10174 }, |
|
10175 |
|
10176 _adjustOffsetFromHelper: function( obj ) { |
|
10177 if ( typeof obj === "string" ) { |
|
10178 obj = obj.split( " " ); |
|
10179 } |
|
10180 if ( Array.isArray( obj ) ) { |
|
10181 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; |
|
10182 } |
|
10183 if ( "left" in obj ) { |
|
10184 this.offset.click.left = obj.left + this.margins.left; |
|
10185 } |
|
10186 if ( "right" in obj ) { |
|
10187 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; |
|
10188 } |
|
10189 if ( "top" in obj ) { |
|
10190 this.offset.click.top = obj.top + this.margins.top; |
|
10191 } |
|
10192 if ( "bottom" in obj ) { |
|
10193 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; |
|
10194 } |
|
10195 }, |
|
10196 |
|
10197 _isRootNode: function( element ) { |
|
10198 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; |
|
10199 }, |
|
10200 |
|
10201 _getParentOffset: function() { |
|
10202 |
|
10203 //Get the offsetParent and cache its position |
|
10204 var po = this.offsetParent.offset(), |
|
10205 document = this.document[ 0 ]; |
|
10206 |
|
10207 // This is a special case where we need to modify a offset calculated on start, since the |
|
10208 // following happened: |
|
10209 // 1. The position of the helper is absolute, so it's position is calculated based on the |
|
10210 // next positioned parent |
|
10211 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't |
|
10212 // the document, which means that the scroll is included in the initial calculation of the |
|
10213 // offset of the parent, and never recalculated upon drag |
|
10214 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && |
|
10215 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { |
|
10216 po.left += this.scrollParent.scrollLeft(); |
|
10217 po.top += this.scrollParent.scrollTop(); |
|
10218 } |
|
10219 |
|
10220 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { |
|
10221 po = { top: 0, left: 0 }; |
|
10222 } |
|
10223 |
|
10224 return { |
|
10225 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), |
|
10226 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) |
|
10227 }; |
|
10228 |
|
10229 }, |
|
10230 |
|
10231 _getRelativeOffset: function() { |
|
10232 if ( this.cssPosition !== "relative" ) { |
|
10233 return { top: 0, left: 0 }; |
|
10234 } |
|
10235 |
|
10236 var p = this.element.position(), |
|
10237 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); |
|
10238 |
|
10239 return { |
|
10240 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + |
|
10241 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), |
|
10242 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + |
|
10243 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) |
|
10244 }; |
|
10245 |
|
10246 }, |
|
10247 |
|
10248 _cacheMargins: function() { |
|
10249 this.margins = { |
|
10250 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), |
|
10251 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), |
|
10252 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), |
|
10253 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) |
|
10254 }; |
|
10255 }, |
|
10256 |
|
10257 _cacheHelperProportions: function() { |
|
10258 this.helperProportions = { |
|
10259 width: this.helper.outerWidth(), |
|
10260 height: this.helper.outerHeight() |
|
10261 }; |
|
10262 }, |
|
10263 |
|
10264 _setContainment: function() { |
|
10265 |
|
10266 var isUserScrollable, c, ce, |
|
10267 o = this.options, |
|
10268 document = this.document[ 0 ]; |
|
10269 |
|
10270 this.relativeContainer = null; |
|
10271 |
|
10272 if ( !o.containment ) { |
|
10273 this.containment = null; |
|
10274 return; |
|
10275 } |
|
10276 |
|
10277 if ( o.containment === "window" ) { |
|
10278 this.containment = [ |
|
10279 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, |
|
10280 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, |
|
10281 $( window ).scrollLeft() + $( window ).width() - |
|
10282 this.helperProportions.width - this.margins.left, |
|
10283 $( window ).scrollTop() + |
|
10284 ( $( window ).height() || document.body.parentNode.scrollHeight ) - |
|
10285 this.helperProportions.height - this.margins.top |
|
10286 ]; |
|
10287 return; |
|
10288 } |
|
10289 |
|
10290 if ( o.containment === "document" ) { |
|
10291 this.containment = [ |
|
10292 0, |
|
10293 0, |
|
10294 $( document ).width() - this.helperProportions.width - this.margins.left, |
|
10295 ( $( document ).height() || document.body.parentNode.scrollHeight ) - |
|
10296 this.helperProportions.height - this.margins.top |
|
10297 ]; |
|
10298 return; |
|
10299 } |
|
10300 |
|
10301 if ( o.containment.constructor === Array ) { |
|
10302 this.containment = o.containment; |
|
10303 return; |
|
10304 } |
|
10305 |
|
10306 if ( o.containment === "parent" ) { |
|
10307 o.containment = this.helper[ 0 ].parentNode; |
|
10308 } |
|
10309 |
|
10310 c = $( o.containment ); |
|
10311 ce = c[ 0 ]; |
|
10312 |
|
10313 if ( !ce ) { |
|
10314 return; |
|
10315 } |
|
10316 |
|
10317 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); |
|
10318 |
|
10319 this.containment = [ |
|
10320 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + |
|
10321 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), |
|
10322 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + |
|
10323 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), |
|
10324 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - |
|
10325 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - |
|
10326 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - |
|
10327 this.helperProportions.width - |
|
10328 this.margins.left - |
|
10329 this.margins.right, |
|
10330 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - |
|
10331 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - |
|
10332 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - |
|
10333 this.helperProportions.height - |
|
10334 this.margins.top - |
|
10335 this.margins.bottom |
|
10336 ]; |
|
10337 this.relativeContainer = c; |
|
10338 }, |
|
10339 |
|
10340 _convertPositionTo: function( d, pos ) { |
|
10341 |
|
10342 if ( !pos ) { |
|
10343 pos = this.position; |
|
10344 } |
|
10345 |
|
10346 var mod = d === "absolute" ? 1 : -1, |
|
10347 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); |
|
10348 |
|
10349 return { |
|
10350 top: ( |
|
10351 |
|
10352 // The absolute mouse position |
|
10353 pos.top + |
|
10354 |
|
10355 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
10356 this.offset.relative.top * mod + |
|
10357 |
|
10358 // The offsetParent's offset without borders (offset + border) |
|
10359 this.offset.parent.top * mod - |
|
10360 ( ( this.cssPosition === "fixed" ? |
|
10361 -this.offset.scroll.top : |
|
10362 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) |
|
10363 ), |
|
10364 left: ( |
|
10365 |
|
10366 // The absolute mouse position |
|
10367 pos.left + |
|
10368 |
|
10369 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
10370 this.offset.relative.left * mod + |
|
10371 |
|
10372 // The offsetParent's offset without borders (offset + border) |
|
10373 this.offset.parent.left * mod - |
|
10374 ( ( this.cssPosition === "fixed" ? |
|
10375 -this.offset.scroll.left : |
|
10376 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) |
|
10377 ) |
|
10378 }; |
|
10379 |
|
10380 }, |
|
10381 |
|
10382 _generatePosition: function( event, constrainPosition ) { |
|
10383 |
|
10384 var containment, co, top, left, |
|
10385 o = this.options, |
|
10386 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), |
|
10387 pageX = event.pageX, |
|
10388 pageY = event.pageY; |
|
10389 |
|
10390 // Cache the scroll |
|
10391 if ( !scrollIsRootNode || !this.offset.scroll ) { |
|
10392 this.offset.scroll = { |
|
10393 top: this.scrollParent.scrollTop(), |
|
10394 left: this.scrollParent.scrollLeft() |
|
10395 }; |
|
10396 } |
|
10397 |
|
10398 /* |
|
10399 * - Position constraining - |
|
10400 * Constrain the position to a mix of grid, containment. |
|
10401 */ |
|
10402 |
|
10403 // If we are not dragging yet, we won't check for options |
|
10404 if ( constrainPosition ) { |
|
10405 if ( this.containment ) { |
|
10406 if ( this.relativeContainer ) { |
|
10407 co = this.relativeContainer.offset(); |
|
10408 containment = [ |
|
10409 this.containment[ 0 ] + co.left, |
|
10410 this.containment[ 1 ] + co.top, |
|
10411 this.containment[ 2 ] + co.left, |
|
10412 this.containment[ 3 ] + co.top |
|
10413 ]; |
|
10414 } else { |
|
10415 containment = this.containment; |
|
10416 } |
|
10417 |
|
10418 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { |
|
10419 pageX = containment[ 0 ] + this.offset.click.left; |
|
10420 } |
|
10421 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { |
|
10422 pageY = containment[ 1 ] + this.offset.click.top; |
|
10423 } |
|
10424 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { |
|
10425 pageX = containment[ 2 ] + this.offset.click.left; |
|
10426 } |
|
10427 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { |
|
10428 pageY = containment[ 3 ] + this.offset.click.top; |
|
10429 } |
|
10430 } |
|
10431 |
|
10432 if ( o.grid ) { |
|
10433 |
|
10434 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid |
|
10435 // argument errors in IE (see ticket #6950) |
|
10436 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - |
|
10437 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; |
|
10438 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || |
|
10439 top - this.offset.click.top > containment[ 3 ] ) ? |
|
10440 top : |
|
10441 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? |
|
10442 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; |
|
10443 |
|
10444 left = o.grid[ 0 ] ? this.originalPageX + |
|
10445 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : |
|
10446 this.originalPageX; |
|
10447 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || |
|
10448 left - this.offset.click.left > containment[ 2 ] ) ? |
|
10449 left : |
|
10450 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? |
|
10451 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; |
|
10452 } |
|
10453 |
|
10454 if ( o.axis === "y" ) { |
|
10455 pageX = this.originalPageX; |
|
10456 } |
|
10457 |
|
10458 if ( o.axis === "x" ) { |
|
10459 pageY = this.originalPageY; |
|
10460 } |
|
10461 } |
|
10462 |
|
10463 return { |
|
10464 top: ( |
|
10465 |
|
10466 // The absolute mouse position |
|
10467 pageY - |
|
10468 |
|
10469 // Click offset (relative to the element) |
|
10470 this.offset.click.top - |
|
10471 |
|
10472 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
10473 this.offset.relative.top - |
|
10474 |
|
10475 // The offsetParent's offset without borders (offset + border) |
|
10476 this.offset.parent.top + |
|
10477 ( this.cssPosition === "fixed" ? |
|
10478 -this.offset.scroll.top : |
|
10479 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) |
|
10480 ), |
|
10481 left: ( |
|
10482 |
|
10483 // The absolute mouse position |
|
10484 pageX - |
|
10485 |
|
10486 // Click offset (relative to the element) |
|
10487 this.offset.click.left - |
|
10488 |
|
10489 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
10490 this.offset.relative.left - |
|
10491 |
|
10492 // The offsetParent's offset without borders (offset + border) |
|
10493 this.offset.parent.left + |
|
10494 ( this.cssPosition === "fixed" ? |
|
10495 -this.offset.scroll.left : |
|
10496 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) |
|
10497 ) |
|
10498 }; |
|
10499 |
|
10500 }, |
|
10501 |
|
10502 _clear: function() { |
|
10503 this._removeClass( this.helper, "ui-draggable-dragging" ); |
|
10504 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { |
|
10505 this.helper.remove(); |
|
10506 } |
|
10507 this.helper = null; |
|
10508 this.cancelHelperRemoval = false; |
|
10509 if ( this.destroyOnClear ) { |
|
10510 this.destroy(); |
|
10511 } |
|
10512 }, |
|
10513 |
|
10514 // From now on bulk stuff - mainly helpers |
|
10515 |
|
10516 _trigger: function( type, event, ui ) { |
|
10517 ui = ui || this._uiHash(); |
|
10518 $.ui.plugin.call( this, type, [ event, ui, this ], true ); |
|
10519 |
|
10520 // Absolute position and offset (see #6884 ) have to be recalculated after plugins |
|
10521 if ( /^(drag|start|stop)/.test( type ) ) { |
|
10522 this.positionAbs = this._convertPositionTo( "absolute" ); |
|
10523 ui.offset = this.positionAbs; |
|
10524 } |
|
10525 return $.Widget.prototype._trigger.call( this, type, event, ui ); |
|
10526 }, |
|
10527 |
|
10528 plugins: {}, |
|
10529 |
|
10530 _uiHash: function() { |
|
10531 return { |
|
10532 helper: this.helper, |
|
10533 position: this.position, |
|
10534 originalPosition: this.originalPosition, |
|
10535 offset: this.positionAbs |
|
10536 }; |
|
10537 } |
|
10538 |
|
10539 } ); |
|
10540 |
|
10541 $.ui.plugin.add( "draggable", "connectToSortable", { |
|
10542 start: function( event, ui, draggable ) { |
|
10543 var uiSortable = $.extend( {}, ui, { |
|
10544 item: draggable.element |
|
10545 } ); |
|
10546 |
|
10547 draggable.sortables = []; |
|
10548 $( draggable.options.connectToSortable ).each( function() { |
|
10549 var sortable = $( this ).sortable( "instance" ); |
|
10550 |
|
10551 if ( sortable && !sortable.options.disabled ) { |
|
10552 draggable.sortables.push( sortable ); |
|
10553 |
|
10554 // RefreshPositions is called at drag start to refresh the containerCache |
|
10555 // which is used in drag. This ensures it's initialized and synchronized |
|
10556 // with any changes that might have happened on the page since initialization. |
|
10557 sortable.refreshPositions(); |
|
10558 sortable._trigger( "activate", event, uiSortable ); |
|
10559 } |
|
10560 } ); |
|
10561 }, |
|
10562 stop: function( event, ui, draggable ) { |
|
10563 var uiSortable = $.extend( {}, ui, { |
|
10564 item: draggable.element |
|
10565 } ); |
|
10566 |
|
10567 draggable.cancelHelperRemoval = false; |
|
10568 |
|
10569 $.each( draggable.sortables, function() { |
|
10570 var sortable = this; |
|
10571 |
|
10572 if ( sortable.isOver ) { |
|
10573 sortable.isOver = 0; |
|
10574 |
|
10575 // Allow this sortable to handle removing the helper |
|
10576 draggable.cancelHelperRemoval = true; |
|
10577 sortable.cancelHelperRemoval = false; |
|
10578 |
|
10579 // Use _storedCSS To restore properties in the sortable, |
|
10580 // as this also handles revert (#9675) since the draggable |
|
10581 // may have modified them in unexpected ways (#8809) |
|
10582 sortable._storedCSS = { |
|
10583 position: sortable.placeholder.css( "position" ), |
|
10584 top: sortable.placeholder.css( "top" ), |
|
10585 left: sortable.placeholder.css( "left" ) |
|
10586 }; |
|
10587 |
|
10588 sortable._mouseStop( event ); |
|
10589 |
|
10590 // Once drag has ended, the sortable should return to using |
|
10591 // its original helper, not the shared helper from draggable |
|
10592 sortable.options.helper = sortable.options._helper; |
|
10593 } else { |
|
10594 |
|
10595 // Prevent this Sortable from removing the helper. |
|
10596 // However, don't set the draggable to remove the helper |
|
10597 // either as another connected Sortable may yet handle the removal. |
|
10598 sortable.cancelHelperRemoval = true; |
|
10599 |
|
10600 sortable._trigger( "deactivate", event, uiSortable ); |
|
10601 } |
|
10602 } ); |
|
10603 }, |
|
10604 drag: function( event, ui, draggable ) { |
|
10605 $.each( draggable.sortables, function() { |
|
10606 var innermostIntersecting = false, |
|
10607 sortable = this; |
|
10608 |
|
10609 // Copy over variables that sortable's _intersectsWith uses |
|
10610 sortable.positionAbs = draggable.positionAbs; |
|
10611 sortable.helperProportions = draggable.helperProportions; |
|
10612 sortable.offset.click = draggable.offset.click; |
|
10613 |
|
10614 if ( sortable._intersectsWith( sortable.containerCache ) ) { |
|
10615 innermostIntersecting = true; |
|
10616 |
|
10617 $.each( draggable.sortables, function() { |
|
10618 |
|
10619 // Copy over variables that sortable's _intersectsWith uses |
|
10620 this.positionAbs = draggable.positionAbs; |
|
10621 this.helperProportions = draggable.helperProportions; |
|
10622 this.offset.click = draggable.offset.click; |
|
10623 |
|
10624 if ( this !== sortable && |
|
10625 this._intersectsWith( this.containerCache ) && |
|
10626 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { |
|
10627 innermostIntersecting = false; |
|
10628 } |
|
10629 |
|
10630 return innermostIntersecting; |
|
10631 } ); |
|
10632 } |
|
10633 |
|
10634 if ( innermostIntersecting ) { |
|
10635 |
|
10636 // If it intersects, we use a little isOver variable and set it once, |
|
10637 // so that the move-in stuff gets fired only once. |
|
10638 if ( !sortable.isOver ) { |
|
10639 sortable.isOver = 1; |
|
10640 |
|
10641 // Store draggable's parent in case we need to reappend to it later. |
|
10642 draggable._parent = ui.helper.parent(); |
|
10643 |
|
10644 sortable.currentItem = ui.helper |
|
10645 .appendTo( sortable.element ) |
|
10646 .data( "ui-sortable-item", true ); |
|
10647 |
|
10648 // Store helper option to later restore it |
|
10649 sortable.options._helper = sortable.options.helper; |
|
10650 |
|
10651 sortable.options.helper = function() { |
|
10652 return ui.helper[ 0 ]; |
|
10653 }; |
|
10654 |
|
10655 // Fire the start events of the sortable with our passed browser event, |
|
10656 // and our own helper (so it doesn't create a new one) |
|
10657 event.target = sortable.currentItem[ 0 ]; |
|
10658 sortable._mouseCapture( event, true ); |
|
10659 sortable._mouseStart( event, true, true ); |
|
10660 |
|
10661 // Because the browser event is way off the new appended portlet, |
|
10662 // modify necessary variables to reflect the changes |
|
10663 sortable.offset.click.top = draggable.offset.click.top; |
|
10664 sortable.offset.click.left = draggable.offset.click.left; |
|
10665 sortable.offset.parent.left -= draggable.offset.parent.left - |
|
10666 sortable.offset.parent.left; |
|
10667 sortable.offset.parent.top -= draggable.offset.parent.top - |
|
10668 sortable.offset.parent.top; |
|
10669 |
|
10670 draggable._trigger( "toSortable", event ); |
|
10671 |
|
10672 // Inform draggable that the helper is in a valid drop zone, |
|
10673 // used solely in the revert option to handle "valid/invalid". |
|
10674 draggable.dropped = sortable.element; |
|
10675 |
|
10676 // Need to refreshPositions of all sortables in the case that |
|
10677 // adding to one sortable changes the location of the other sortables (#9675) |
|
10678 $.each( draggable.sortables, function() { |
|
10679 this.refreshPositions(); |
|
10680 } ); |
|
10681 |
|
10682 // Hack so receive/update callbacks work (mostly) |
|
10683 draggable.currentItem = draggable.element; |
|
10684 sortable.fromOutside = draggable; |
|
10685 } |
|
10686 |
|
10687 if ( sortable.currentItem ) { |
|
10688 sortable._mouseDrag( event ); |
|
10689 |
|
10690 // Copy the sortable's position because the draggable's can potentially reflect |
|
10691 // a relative position, while sortable is always absolute, which the dragged |
|
10692 // element has now become. (#8809) |
|
10693 ui.position = sortable.position; |
|
10694 } |
|
10695 } else { |
|
10696 |
|
10697 // If it doesn't intersect with the sortable, and it intersected before, |
|
10698 // we fake the drag stop of the sortable, but make sure it doesn't remove |
|
10699 // the helper by using cancelHelperRemoval. |
|
10700 if ( sortable.isOver ) { |
|
10701 |
|
10702 sortable.isOver = 0; |
|
10703 sortable.cancelHelperRemoval = true; |
|
10704 |
|
10705 // Calling sortable's mouseStop would trigger a revert, |
|
10706 // so revert must be temporarily false until after mouseStop is called. |
|
10707 sortable.options._revert = sortable.options.revert; |
|
10708 sortable.options.revert = false; |
|
10709 |
|
10710 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); |
|
10711 sortable._mouseStop( event, true ); |
|
10712 |
|
10713 // Restore sortable behaviors that were modfied |
|
10714 // when the draggable entered the sortable area (#9481) |
|
10715 sortable.options.revert = sortable.options._revert; |
|
10716 sortable.options.helper = sortable.options._helper; |
|
10717 |
|
10718 if ( sortable.placeholder ) { |
|
10719 sortable.placeholder.remove(); |
|
10720 } |
|
10721 |
|
10722 // Restore and recalculate the draggable's offset considering the sortable |
|
10723 // may have modified them in unexpected ways. (#8809, #10669) |
|
10724 ui.helper.appendTo( draggable._parent ); |
|
10725 draggable._refreshOffsets( event ); |
|
10726 ui.position = draggable._generatePosition( event, true ); |
|
10727 |
|
10728 draggable._trigger( "fromSortable", event ); |
|
10729 |
|
10730 // Inform draggable that the helper is no longer in a valid drop zone |
|
10731 draggable.dropped = false; |
|
10732 |
|
10733 // Need to refreshPositions of all sortables just in case removing |
|
10734 // from one sortable changes the location of other sortables (#9675) |
|
10735 $.each( draggable.sortables, function() { |
|
10736 this.refreshPositions(); |
|
10737 } ); |
|
10738 } |
|
10739 } |
|
10740 } ); |
|
10741 } |
|
10742 } ); |
|
10743 |
|
10744 $.ui.plugin.add( "draggable", "cursor", { |
|
10745 start: function( event, ui, instance ) { |
|
10746 var t = $( "body" ), |
|
10747 o = instance.options; |
|
10748 |
|
10749 if ( t.css( "cursor" ) ) { |
|
10750 o._cursor = t.css( "cursor" ); |
|
10751 } |
|
10752 t.css( "cursor", o.cursor ); |
|
10753 }, |
|
10754 stop: function( event, ui, instance ) { |
|
10755 var o = instance.options; |
|
10756 if ( o._cursor ) { |
|
10757 $( "body" ).css( "cursor", o._cursor ); |
|
10758 } |
|
10759 } |
|
10760 } ); |
|
10761 |
|
10762 $.ui.plugin.add( "draggable", "opacity", { |
|
10763 start: function( event, ui, instance ) { |
|
10764 var t = $( ui.helper ), |
|
10765 o = instance.options; |
|
10766 if ( t.css( "opacity" ) ) { |
|
10767 o._opacity = t.css( "opacity" ); |
|
10768 } |
|
10769 t.css( "opacity", o.opacity ); |
|
10770 }, |
|
10771 stop: function( event, ui, instance ) { |
|
10772 var o = instance.options; |
|
10773 if ( o._opacity ) { |
|
10774 $( ui.helper ).css( "opacity", o._opacity ); |
|
10775 } |
|
10776 } |
|
10777 } ); |
|
10778 |
|
10779 $.ui.plugin.add( "draggable", "scroll", { |
|
10780 start: function( event, ui, i ) { |
|
10781 if ( !i.scrollParentNotHidden ) { |
|
10782 i.scrollParentNotHidden = i.helper.scrollParent( false ); |
|
10783 } |
|
10784 |
|
10785 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && |
|
10786 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { |
|
10787 i.overflowOffset = i.scrollParentNotHidden.offset(); |
|
10788 } |
|
10789 }, |
|
10790 drag: function( event, ui, i ) { |
|
10791 |
|
10792 var o = i.options, |
|
10793 scrolled = false, |
|
10794 scrollParent = i.scrollParentNotHidden[ 0 ], |
|
10795 document = i.document[ 0 ]; |
|
10796 |
|
10797 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { |
|
10798 if ( !o.axis || o.axis !== "x" ) { |
|
10799 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < |
|
10800 o.scrollSensitivity ) { |
|
10801 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; |
|
10802 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { |
|
10803 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; |
|
10804 } |
|
10805 } |
|
10806 |
|
10807 if ( !o.axis || o.axis !== "y" ) { |
|
10808 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < |
|
10809 o.scrollSensitivity ) { |
|
10810 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; |
|
10811 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { |
|
10812 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; |
|
10813 } |
|
10814 } |
|
10815 |
|
10816 } else { |
|
10817 |
|
10818 if ( !o.axis || o.axis !== "x" ) { |
|
10819 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { |
|
10820 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); |
|
10821 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < |
|
10822 o.scrollSensitivity ) { |
|
10823 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); |
|
10824 } |
|
10825 } |
|
10826 |
|
10827 if ( !o.axis || o.axis !== "y" ) { |
|
10828 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { |
|
10829 scrolled = $( document ).scrollLeft( |
|
10830 $( document ).scrollLeft() - o.scrollSpeed |
|
10831 ); |
|
10832 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < |
|
10833 o.scrollSensitivity ) { |
|
10834 scrolled = $( document ).scrollLeft( |
|
10835 $( document ).scrollLeft() + o.scrollSpeed |
|
10836 ); |
|
10837 } |
|
10838 } |
|
10839 |
|
10840 } |
|
10841 |
|
10842 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { |
|
10843 $.ui.ddmanager.prepareOffsets( i, event ); |
|
10844 } |
|
10845 |
|
10846 } |
|
10847 } ); |
|
10848 |
|
10849 $.ui.plugin.add( "draggable", "snap", { |
|
10850 start: function( event, ui, i ) { |
|
10851 |
|
10852 var o = i.options; |
|
10853 |
|
10854 i.snapElements = []; |
|
10855 |
|
10856 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) |
|
10857 .each( function() { |
|
10858 var $t = $( this ), |
|
10859 $o = $t.offset(); |
|
10860 if ( this !== i.element[ 0 ] ) { |
|
10861 i.snapElements.push( { |
|
10862 item: this, |
|
10863 width: $t.outerWidth(), height: $t.outerHeight(), |
|
10864 top: $o.top, left: $o.left |
|
10865 } ); |
|
10866 } |
|
10867 } ); |
|
10868 |
|
10869 }, |
|
10870 drag: function( event, ui, inst ) { |
|
10871 |
|
10872 var ts, bs, ls, rs, l, r, t, b, i, first, |
|
10873 o = inst.options, |
|
10874 d = o.snapTolerance, |
|
10875 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, |
|
10876 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; |
|
10877 |
|
10878 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { |
|
10879 |
|
10880 l = inst.snapElements[ i ].left - inst.margins.left; |
|
10881 r = l + inst.snapElements[ i ].width; |
|
10882 t = inst.snapElements[ i ].top - inst.margins.top; |
|
10883 b = t + inst.snapElements[ i ].height; |
|
10884 |
|
10885 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || |
|
10886 !$.contains( inst.snapElements[ i ].item.ownerDocument, |
|
10887 inst.snapElements[ i ].item ) ) { |
|
10888 if ( inst.snapElements[ i ].snapping ) { |
|
10889 if ( inst.options.snap.release ) { |
|
10890 inst.options.snap.release.call( |
|
10891 inst.element, |
|
10892 event, |
|
10893 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) |
|
10894 ); |
|
10895 } |
|
10896 } |
|
10897 inst.snapElements[ i ].snapping = false; |
|
10898 continue; |
|
10899 } |
|
10900 |
|
10901 if ( o.snapMode !== "inner" ) { |
|
10902 ts = Math.abs( t - y2 ) <= d; |
|
10903 bs = Math.abs( b - y1 ) <= d; |
|
10904 ls = Math.abs( l - x2 ) <= d; |
|
10905 rs = Math.abs( r - x1 ) <= d; |
|
10906 if ( ts ) { |
|
10907 ui.position.top = inst._convertPositionTo( "relative", { |
|
10908 top: t - inst.helperProportions.height, |
|
10909 left: 0 |
|
10910 } ).top; |
|
10911 } |
|
10912 if ( bs ) { |
|
10913 ui.position.top = inst._convertPositionTo( "relative", { |
|
10914 top: b, |
|
10915 left: 0 |
|
10916 } ).top; |
|
10917 } |
|
10918 if ( ls ) { |
|
10919 ui.position.left = inst._convertPositionTo( "relative", { |
|
10920 top: 0, |
|
10921 left: l - inst.helperProportions.width |
|
10922 } ).left; |
|
10923 } |
|
10924 if ( rs ) { |
|
10925 ui.position.left = inst._convertPositionTo( "relative", { |
|
10926 top: 0, |
|
10927 left: r |
|
10928 } ).left; |
|
10929 } |
|
10930 } |
|
10931 |
|
10932 first = ( ts || bs || ls || rs ); |
|
10933 |
|
10934 if ( o.snapMode !== "outer" ) { |
|
10935 ts = Math.abs( t - y1 ) <= d; |
|
10936 bs = Math.abs( b - y2 ) <= d; |
|
10937 ls = Math.abs( l - x1 ) <= d; |
|
10938 rs = Math.abs( r - x2 ) <= d; |
|
10939 if ( ts ) { |
|
10940 ui.position.top = inst._convertPositionTo( "relative", { |
|
10941 top: t, |
|
10942 left: 0 |
|
10943 } ).top; |
|
10944 } |
|
10945 if ( bs ) { |
|
10946 ui.position.top = inst._convertPositionTo( "relative", { |
|
10947 top: b - inst.helperProportions.height, |
|
10948 left: 0 |
|
10949 } ).top; |
|
10950 } |
|
10951 if ( ls ) { |
|
10952 ui.position.left = inst._convertPositionTo( "relative", { |
|
10953 top: 0, |
|
10954 left: l |
|
10955 } ).left; |
|
10956 } |
|
10957 if ( rs ) { |
|
10958 ui.position.left = inst._convertPositionTo( "relative", { |
|
10959 top: 0, |
|
10960 left: r - inst.helperProportions.width |
|
10961 } ).left; |
|
10962 } |
|
10963 } |
|
10964 |
|
10965 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { |
|
10966 if ( inst.options.snap.snap ) { |
|
10967 inst.options.snap.snap.call( |
|
10968 inst.element, |
|
10969 event, |
|
10970 $.extend( inst._uiHash(), { |
|
10971 snapItem: inst.snapElements[ i ].item |
|
10972 } ) ); |
|
10973 } |
|
10974 } |
|
10975 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); |
|
10976 |
|
10977 } |
|
10978 |
|
10979 } |
|
10980 } ); |
|
10981 |
|
10982 $.ui.plugin.add( "draggable", "stack", { |
|
10983 start: function( event, ui, instance ) { |
|
10984 var min, |
|
10985 o = instance.options, |
|
10986 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { |
|
10987 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - |
|
10988 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); |
|
10989 } ); |
|
10990 |
|
10991 if ( !group.length ) { |
|
10992 return; |
|
10993 } |
|
10994 |
|
10995 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; |
|
10996 $( group ).each( function( i ) { |
|
10997 $( this ).css( "zIndex", min + i ); |
|
10998 } ); |
|
10999 this.css( "zIndex", ( min + group.length ) ); |
|
11000 } |
|
11001 } ); |
|
11002 |
|
11003 $.ui.plugin.add( "draggable", "zIndex", { |
|
11004 start: function( event, ui, instance ) { |
|
11005 var t = $( ui.helper ), |
|
11006 o = instance.options; |
|
11007 |
|
11008 if ( t.css( "zIndex" ) ) { |
|
11009 o._zIndex = t.css( "zIndex" ); |
|
11010 } |
|
11011 t.css( "zIndex", o.zIndex ); |
|
11012 }, |
|
11013 stop: function( event, ui, instance ) { |
|
11014 var o = instance.options; |
|
11015 |
|
11016 if ( o._zIndex ) { |
|
11017 $( ui.helper ).css( "zIndex", o._zIndex ); |
|
11018 } |
|
11019 } |
|
11020 } ); |
|
11021 |
|
11022 var widgetsDraggable = $.ui.draggable; |
|
11023 |
|
11024 |
|
11025 /*! |
|
11026 * jQuery UI Resizable 1.13.2 |
|
11027 * http://jqueryui.com |
|
11028 * |
|
11029 * Copyright jQuery Foundation and other contributors |
|
11030 * Released under the MIT license. |
|
11031 * http://jquery.org/license |
|
11032 */ |
|
11033 |
|
11034 //>>label: Resizable |
|
11035 //>>group: Interactions |
|
11036 //>>description: Enables resize functionality for any element. |
|
11037 //>>docs: http://api.jqueryui.com/resizable/ |
|
11038 //>>demos: http://jqueryui.com/resizable/ |
|
11039 //>>css.structure: ../../themes/base/core.css |
|
11040 //>>css.structure: ../../themes/base/resizable.css |
|
11041 //>>css.theme: ../../themes/base/theme.css |
|
11042 |
|
11043 |
|
11044 $.widget( "ui.resizable", $.ui.mouse, { |
|
11045 version: "1.13.2", |
|
11046 widgetEventPrefix: "resize", |
|
11047 options: { |
|
11048 alsoResize: false, |
|
11049 animate: false, |
|
11050 animateDuration: "slow", |
|
11051 animateEasing: "swing", |
|
11052 aspectRatio: false, |
|
11053 autoHide: false, |
|
11054 classes: { |
|
11055 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" |
|
11056 }, |
|
11057 containment: false, |
|
11058 ghost: false, |
|
11059 grid: false, |
|
11060 handles: "e,s,se", |
|
11061 helper: false, |
|
11062 maxHeight: null, |
|
11063 maxWidth: null, |
|
11064 minHeight: 10, |
|
11065 minWidth: 10, |
|
11066 |
|
11067 // See #7960 |
|
11068 zIndex: 90, |
|
11069 |
|
11070 // Callbacks |
|
11071 resize: null, |
|
11072 start: null, |
|
11073 stop: null |
|
11074 }, |
|
11075 |
|
11076 _num: function( value ) { |
|
11077 return parseFloat( value ) || 0; |
|
11078 }, |
|
11079 |
|
11080 _isNumber: function( value ) { |
|
11081 return !isNaN( parseFloat( value ) ); |
|
11082 }, |
|
11083 |
|
11084 _hasScroll: function( el, a ) { |
|
11085 |
|
11086 if ( $( el ).css( "overflow" ) === "hidden" ) { |
|
11087 return false; |
|
11088 } |
|
11089 |
|
11090 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", |
|
11091 has = false; |
|
11092 |
|
11093 if ( el[ scroll ] > 0 ) { |
|
11094 return true; |
|
11095 } |
|
11096 |
|
11097 // TODO: determine which cases actually cause this to happen |
|
11098 // if the element doesn't have the scroll set, see if it's possible to |
|
11099 // set the scroll |
|
11100 try { |
|
11101 el[ scroll ] = 1; |
|
11102 has = ( el[ scroll ] > 0 ); |
|
11103 el[ scroll ] = 0; |
|
11104 } catch ( e ) { |
|
11105 |
|
11106 // `el` might be a string, then setting `scroll` will throw |
|
11107 // an error in strict mode; ignore it. |
|
11108 } |
|
11109 return has; |
|
11110 }, |
|
11111 |
|
11112 _create: function() { |
|
11113 |
|
11114 var margins, |
|
11115 o = this.options, |
|
11116 that = this; |
|
11117 this._addClass( "ui-resizable" ); |
|
11118 |
|
11119 $.extend( this, { |
|
11120 _aspectRatio: !!( o.aspectRatio ), |
|
11121 aspectRatio: o.aspectRatio, |
|
11122 originalElement: this.element, |
|
11123 _proportionallyResizeElements: [], |
|
11124 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null |
|
11125 } ); |
|
11126 |
|
11127 // Wrap the element if it cannot hold child nodes |
|
11128 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { |
|
11129 |
|
11130 this.element.wrap( |
|
11131 $( "<div class='ui-wrapper'></div>" ).css( { |
|
11132 overflow: "hidden", |
|
11133 position: this.element.css( "position" ), |
|
11134 width: this.element.outerWidth(), |
|
11135 height: this.element.outerHeight(), |
|
11136 top: this.element.css( "top" ), |
|
11137 left: this.element.css( "left" ) |
|
11138 } ) |
|
11139 ); |
|
11140 |
|
11141 this.element = this.element.parent().data( |
|
11142 "ui-resizable", this.element.resizable( "instance" ) |
|
11143 ); |
|
11144 |
|
11145 this.elementIsWrapper = true; |
|
11146 |
|
11147 margins = { |
|
11148 marginTop: this.originalElement.css( "marginTop" ), |
|
11149 marginRight: this.originalElement.css( "marginRight" ), |
|
11150 marginBottom: this.originalElement.css( "marginBottom" ), |
|
11151 marginLeft: this.originalElement.css( "marginLeft" ) |
|
11152 }; |
|
11153 |
|
11154 this.element.css( margins ); |
|
11155 this.originalElement.css( "margin", 0 ); |
|
11156 |
|
11157 // support: Safari |
|
11158 // Prevent Safari textarea resize |
|
11159 this.originalResizeStyle = this.originalElement.css( "resize" ); |
|
11160 this.originalElement.css( "resize", "none" ); |
|
11161 |
|
11162 this._proportionallyResizeElements.push( this.originalElement.css( { |
|
11163 position: "static", |
|
11164 zoom: 1, |
|
11165 display: "block" |
|
11166 } ) ); |
|
11167 |
|
11168 // Support: IE9 |
|
11169 // avoid IE jump (hard set the margin) |
|
11170 this.originalElement.css( margins ); |
|
11171 |
|
11172 this._proportionallyResize(); |
|
11173 } |
|
11174 |
|
11175 this._setupHandles(); |
|
11176 |
|
11177 if ( o.autoHide ) { |
|
11178 $( this.element ) |
|
11179 .on( "mouseenter", function() { |
|
11180 if ( o.disabled ) { |
|
11181 return; |
|
11182 } |
|
11183 that._removeClass( "ui-resizable-autohide" ); |
|
11184 that._handles.show(); |
|
11185 } ) |
|
11186 .on( "mouseleave", function() { |
|
11187 if ( o.disabled ) { |
|
11188 return; |
|
11189 } |
|
11190 if ( !that.resizing ) { |
|
11191 that._addClass( "ui-resizable-autohide" ); |
|
11192 that._handles.hide(); |
|
11193 } |
|
11194 } ); |
|
11195 } |
|
11196 |
|
11197 this._mouseInit(); |
|
11198 }, |
|
11199 |
|
11200 _destroy: function() { |
|
11201 |
|
11202 this._mouseDestroy(); |
|
11203 this._addedHandles.remove(); |
|
11204 |
|
11205 var wrapper, |
|
11206 _destroy = function( exp ) { |
|
11207 $( exp ) |
|
11208 .removeData( "resizable" ) |
|
11209 .removeData( "ui-resizable" ) |
|
11210 .off( ".resizable" ); |
|
11211 }; |
|
11212 |
|
11213 // TODO: Unwrap at same DOM position |
|
11214 if ( this.elementIsWrapper ) { |
|
11215 _destroy( this.element ); |
|
11216 wrapper = this.element; |
|
11217 this.originalElement.css( { |
|
11218 position: wrapper.css( "position" ), |
|
11219 width: wrapper.outerWidth(), |
|
11220 height: wrapper.outerHeight(), |
|
11221 top: wrapper.css( "top" ), |
|
11222 left: wrapper.css( "left" ) |
|
11223 } ).insertAfter( wrapper ); |
|
11224 wrapper.remove(); |
|
11225 } |
|
11226 |
|
11227 this.originalElement.css( "resize", this.originalResizeStyle ); |
|
11228 _destroy( this.originalElement ); |
|
11229 |
|
11230 return this; |
|
11231 }, |
|
11232 |
|
11233 _setOption: function( key, value ) { |
|
11234 this._super( key, value ); |
|
11235 |
|
11236 switch ( key ) { |
|
11237 case "handles": |
|
11238 this._removeHandles(); |
|
11239 this._setupHandles(); |
|
11240 break; |
|
11241 case "aspectRatio": |
|
11242 this._aspectRatio = !!value; |
|
11243 break; |
|
11244 default: |
|
11245 break; |
|
11246 } |
|
11247 }, |
|
11248 |
|
11249 _setupHandles: function() { |
|
11250 var o = this.options, handle, i, n, hname, axis, that = this; |
|
11251 this.handles = o.handles || |
|
11252 ( !$( ".ui-resizable-handle", this.element ).length ? |
|
11253 "e,s,se" : { |
|
11254 n: ".ui-resizable-n", |
|
11255 e: ".ui-resizable-e", |
|
11256 s: ".ui-resizable-s", |
|
11257 w: ".ui-resizable-w", |
|
11258 se: ".ui-resizable-se", |
|
11259 sw: ".ui-resizable-sw", |
|
11260 ne: ".ui-resizable-ne", |
|
11261 nw: ".ui-resizable-nw" |
|
11262 } ); |
|
11263 |
|
11264 this._handles = $(); |
|
11265 this._addedHandles = $(); |
|
11266 if ( this.handles.constructor === String ) { |
|
11267 |
|
11268 if ( this.handles === "all" ) { |
|
11269 this.handles = "n,e,s,w,se,sw,ne,nw"; |
|
11270 } |
|
11271 |
|
11272 n = this.handles.split( "," ); |
|
11273 this.handles = {}; |
|
11274 |
|
11275 for ( i = 0; i < n.length; i++ ) { |
|
11276 |
|
11277 handle = String.prototype.trim.call( n[ i ] ); |
|
11278 hname = "ui-resizable-" + handle; |
|
11279 axis = $( "<div>" ); |
|
11280 this._addClass( axis, "ui-resizable-handle " + hname ); |
|
11281 |
|
11282 axis.css( { zIndex: o.zIndex } ); |
|
11283 |
|
11284 this.handles[ handle ] = ".ui-resizable-" + handle; |
|
11285 if ( !this.element.children( this.handles[ handle ] ).length ) { |
|
11286 this.element.append( axis ); |
|
11287 this._addedHandles = this._addedHandles.add( axis ); |
|
11288 } |
|
11289 } |
|
11290 |
|
11291 } |
|
11292 |
|
11293 this._renderAxis = function( target ) { |
|
11294 |
|
11295 var i, axis, padPos, padWrapper; |
|
11296 |
|
11297 target = target || this.element; |
|
11298 |
|
11299 for ( i in this.handles ) { |
|
11300 |
|
11301 if ( this.handles[ i ].constructor === String ) { |
|
11302 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); |
|
11303 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { |
|
11304 this.handles[ i ] = $( this.handles[ i ] ); |
|
11305 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); |
|
11306 } |
|
11307 |
|
11308 if ( this.elementIsWrapper && |
|
11309 this.originalElement[ 0 ] |
|
11310 .nodeName |
|
11311 .match( /^(textarea|input|select|button)$/i ) ) { |
|
11312 axis = $( this.handles[ i ], this.element ); |
|
11313 |
|
11314 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? |
|
11315 axis.outerHeight() : |
|
11316 axis.outerWidth(); |
|
11317 |
|
11318 padPos = [ "padding", |
|
11319 /ne|nw|n/.test( i ) ? "Top" : |
|
11320 /se|sw|s/.test( i ) ? "Bottom" : |
|
11321 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); |
|
11322 |
|
11323 target.css( padPos, padWrapper ); |
|
11324 |
|
11325 this._proportionallyResize(); |
|
11326 } |
|
11327 |
|
11328 this._handles = this._handles.add( this.handles[ i ] ); |
|
11329 } |
|
11330 }; |
|
11331 |
|
11332 // TODO: make renderAxis a prototype function |
|
11333 this._renderAxis( this.element ); |
|
11334 |
|
11335 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); |
|
11336 this._handles.disableSelection(); |
|
11337 |
|
11338 this._handles.on( "mouseover", function() { |
|
11339 if ( !that.resizing ) { |
|
11340 if ( this.className ) { |
|
11341 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); |
|
11342 } |
|
11343 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; |
|
11344 } |
|
11345 } ); |
|
11346 |
|
11347 if ( o.autoHide ) { |
|
11348 this._handles.hide(); |
|
11349 this._addClass( "ui-resizable-autohide" ); |
|
11350 } |
|
11351 }, |
|
11352 |
|
11353 _removeHandles: function() { |
|
11354 this._addedHandles.remove(); |
|
11355 }, |
|
11356 |
|
11357 _mouseCapture: function( event ) { |
|
11358 var i, handle, |
|
11359 capture = false; |
|
11360 |
|
11361 for ( i in this.handles ) { |
|
11362 handle = $( this.handles[ i ] )[ 0 ]; |
|
11363 if ( handle === event.target || $.contains( handle, event.target ) ) { |
|
11364 capture = true; |
|
11365 } |
|
11366 } |
|
11367 |
|
11368 return !this.options.disabled && capture; |
|
11369 }, |
|
11370 |
|
11371 _mouseStart: function( event ) { |
|
11372 |
|
11373 var curleft, curtop, cursor, |
|
11374 o = this.options, |
|
11375 el = this.element; |
|
11376 |
|
11377 this.resizing = true; |
|
11378 |
|
11379 this._renderProxy(); |
|
11380 |
|
11381 curleft = this._num( this.helper.css( "left" ) ); |
|
11382 curtop = this._num( this.helper.css( "top" ) ); |
|
11383 |
|
11384 if ( o.containment ) { |
|
11385 curleft += $( o.containment ).scrollLeft() || 0; |
|
11386 curtop += $( o.containment ).scrollTop() || 0; |
|
11387 } |
|
11388 |
|
11389 this.offset = this.helper.offset(); |
|
11390 this.position = { left: curleft, top: curtop }; |
|
11391 |
|
11392 this.size = this._helper ? { |
|
11393 width: this.helper.width(), |
|
11394 height: this.helper.height() |
|
11395 } : { |
|
11396 width: el.width(), |
|
11397 height: el.height() |
|
11398 }; |
|
11399 |
|
11400 this.originalSize = this._helper ? { |
|
11401 width: el.outerWidth(), |
|
11402 height: el.outerHeight() |
|
11403 } : { |
|
11404 width: el.width(), |
|
11405 height: el.height() |
|
11406 }; |
|
11407 |
|
11408 this.sizeDiff = { |
|
11409 width: el.outerWidth() - el.width(), |
|
11410 height: el.outerHeight() - el.height() |
|
11411 }; |
|
11412 |
|
11413 this.originalPosition = { left: curleft, top: curtop }; |
|
11414 this.originalMousePosition = { left: event.pageX, top: event.pageY }; |
|
11415 |
|
11416 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? |
|
11417 o.aspectRatio : |
|
11418 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); |
|
11419 |
|
11420 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); |
|
11421 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); |
|
11422 |
|
11423 this._addClass( "ui-resizable-resizing" ); |
|
11424 this._propagate( "start", event ); |
|
11425 return true; |
|
11426 }, |
|
11427 |
|
11428 _mouseDrag: function( event ) { |
|
11429 |
|
11430 var data, props, |
|
11431 smp = this.originalMousePosition, |
|
11432 a = this.axis, |
|
11433 dx = ( event.pageX - smp.left ) || 0, |
|
11434 dy = ( event.pageY - smp.top ) || 0, |
|
11435 trigger = this._change[ a ]; |
|
11436 |
|
11437 this._updatePrevProperties(); |
|
11438 |
|
11439 if ( !trigger ) { |
|
11440 return false; |
|
11441 } |
|
11442 |
|
11443 data = trigger.apply( this, [ event, dx, dy ] ); |
|
11444 |
|
11445 this._updateVirtualBoundaries( event.shiftKey ); |
|
11446 if ( this._aspectRatio || event.shiftKey ) { |
|
11447 data = this._updateRatio( data, event ); |
|
11448 } |
|
11449 |
|
11450 data = this._respectSize( data, event ); |
|
11451 |
|
11452 this._updateCache( data ); |
|
11453 |
|
11454 this._propagate( "resize", event ); |
|
11455 |
|
11456 props = this._applyChanges(); |
|
11457 |
|
11458 if ( !this._helper && this._proportionallyResizeElements.length ) { |
|
11459 this._proportionallyResize(); |
|
11460 } |
|
11461 |
|
11462 if ( !$.isEmptyObject( props ) ) { |
|
11463 this._updatePrevProperties(); |
|
11464 this._trigger( "resize", event, this.ui() ); |
|
11465 this._applyChanges(); |
|
11466 } |
|
11467 |
|
11468 return false; |
|
11469 }, |
|
11470 |
|
11471 _mouseStop: function( event ) { |
|
11472 |
|
11473 this.resizing = false; |
|
11474 var pr, ista, soffseth, soffsetw, s, left, top, |
|
11475 o = this.options, that = this; |
|
11476 |
|
11477 if ( this._helper ) { |
|
11478 |
|
11479 pr = this._proportionallyResizeElements; |
|
11480 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); |
|
11481 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; |
|
11482 soffsetw = ista ? 0 : that.sizeDiff.width; |
|
11483 |
|
11484 s = { |
|
11485 width: ( that.helper.width() - soffsetw ), |
|
11486 height: ( that.helper.height() - soffseth ) |
|
11487 }; |
|
11488 left = ( parseFloat( that.element.css( "left" ) ) + |
|
11489 ( that.position.left - that.originalPosition.left ) ) || null; |
|
11490 top = ( parseFloat( that.element.css( "top" ) ) + |
|
11491 ( that.position.top - that.originalPosition.top ) ) || null; |
|
11492 |
|
11493 if ( !o.animate ) { |
|
11494 this.element.css( $.extend( s, { top: top, left: left } ) ); |
|
11495 } |
|
11496 |
|
11497 that.helper.height( that.size.height ); |
|
11498 that.helper.width( that.size.width ); |
|
11499 |
|
11500 if ( this._helper && !o.animate ) { |
|
11501 this._proportionallyResize(); |
|
11502 } |
|
11503 } |
|
11504 |
|
11505 $( "body" ).css( "cursor", "auto" ); |
|
11506 |
|
11507 this._removeClass( "ui-resizable-resizing" ); |
|
11508 |
|
11509 this._propagate( "stop", event ); |
|
11510 |
|
11511 if ( this._helper ) { |
|
11512 this.helper.remove(); |
|
11513 } |
|
11514 |
|
11515 return false; |
|
11516 |
|
11517 }, |
|
11518 |
|
11519 _updatePrevProperties: function() { |
|
11520 this.prevPosition = { |
|
11521 top: this.position.top, |
|
11522 left: this.position.left |
|
11523 }; |
|
11524 this.prevSize = { |
|
11525 width: this.size.width, |
|
11526 height: this.size.height |
|
11527 }; |
|
11528 }, |
|
11529 |
|
11530 _applyChanges: function() { |
|
11531 var props = {}; |
|
11532 |
|
11533 if ( this.position.top !== this.prevPosition.top ) { |
|
11534 props.top = this.position.top + "px"; |
|
11535 } |
|
11536 if ( this.position.left !== this.prevPosition.left ) { |
|
11537 props.left = this.position.left + "px"; |
|
11538 } |
|
11539 if ( this.size.width !== this.prevSize.width ) { |
|
11540 props.width = this.size.width + "px"; |
|
11541 } |
|
11542 if ( this.size.height !== this.prevSize.height ) { |
|
11543 props.height = this.size.height + "px"; |
|
11544 } |
|
11545 |
|
11546 this.helper.css( props ); |
|
11547 |
|
11548 return props; |
|
11549 }, |
|
11550 |
|
11551 _updateVirtualBoundaries: function( forceAspectRatio ) { |
|
11552 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, |
|
11553 o = this.options; |
|
11554 |
|
11555 b = { |
|
11556 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, |
|
11557 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, |
|
11558 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, |
|
11559 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity |
|
11560 }; |
|
11561 |
|
11562 if ( this._aspectRatio || forceAspectRatio ) { |
|
11563 pMinWidth = b.minHeight * this.aspectRatio; |
|
11564 pMinHeight = b.minWidth / this.aspectRatio; |
|
11565 pMaxWidth = b.maxHeight * this.aspectRatio; |
|
11566 pMaxHeight = b.maxWidth / this.aspectRatio; |
|
11567 |
|
11568 if ( pMinWidth > b.minWidth ) { |
|
11569 b.minWidth = pMinWidth; |
|
11570 } |
|
11571 if ( pMinHeight > b.minHeight ) { |
|
11572 b.minHeight = pMinHeight; |
|
11573 } |
|
11574 if ( pMaxWidth < b.maxWidth ) { |
|
11575 b.maxWidth = pMaxWidth; |
|
11576 } |
|
11577 if ( pMaxHeight < b.maxHeight ) { |
|
11578 b.maxHeight = pMaxHeight; |
|
11579 } |
|
11580 } |
|
11581 this._vBoundaries = b; |
|
11582 }, |
|
11583 |
|
11584 _updateCache: function( data ) { |
|
11585 this.offset = this.helper.offset(); |
|
11586 if ( this._isNumber( data.left ) ) { |
|
11587 this.position.left = data.left; |
|
11588 } |
|
11589 if ( this._isNumber( data.top ) ) { |
|
11590 this.position.top = data.top; |
|
11591 } |
|
11592 if ( this._isNumber( data.height ) ) { |
|
11593 this.size.height = data.height; |
|
11594 } |
|
11595 if ( this._isNumber( data.width ) ) { |
|
11596 this.size.width = data.width; |
|
11597 } |
|
11598 }, |
|
11599 |
|
11600 _updateRatio: function( data ) { |
|
11601 |
|
11602 var cpos = this.position, |
|
11603 csize = this.size, |
|
11604 a = this.axis; |
|
11605 |
|
11606 if ( this._isNumber( data.height ) ) { |
|
11607 data.width = ( data.height * this.aspectRatio ); |
|
11608 } else if ( this._isNumber( data.width ) ) { |
|
11609 data.height = ( data.width / this.aspectRatio ); |
|
11610 } |
|
11611 |
|
11612 if ( a === "sw" ) { |
|
11613 data.left = cpos.left + ( csize.width - data.width ); |
|
11614 data.top = null; |
|
11615 } |
|
11616 if ( a === "nw" ) { |
|
11617 data.top = cpos.top + ( csize.height - data.height ); |
|
11618 data.left = cpos.left + ( csize.width - data.width ); |
|
11619 } |
|
11620 |
|
11621 return data; |
|
11622 }, |
|
11623 |
|
11624 _respectSize: function( data ) { |
|
11625 |
|
11626 var o = this._vBoundaries, |
|
11627 a = this.axis, |
|
11628 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), |
|
11629 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), |
|
11630 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), |
|
11631 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), |
|
11632 dw = this.originalPosition.left + this.originalSize.width, |
|
11633 dh = this.originalPosition.top + this.originalSize.height, |
|
11634 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); |
|
11635 if ( isminw ) { |
|
11636 data.width = o.minWidth; |
|
11637 } |
|
11638 if ( isminh ) { |
|
11639 data.height = o.minHeight; |
|
11640 } |
|
11641 if ( ismaxw ) { |
|
11642 data.width = o.maxWidth; |
|
11643 } |
|
11644 if ( ismaxh ) { |
|
11645 data.height = o.maxHeight; |
|
11646 } |
|
11647 |
|
11648 if ( isminw && cw ) { |
|
11649 data.left = dw - o.minWidth; |
|
11650 } |
|
11651 if ( ismaxw && cw ) { |
|
11652 data.left = dw - o.maxWidth; |
|
11653 } |
|
11654 if ( isminh && ch ) { |
|
11655 data.top = dh - o.minHeight; |
|
11656 } |
|
11657 if ( ismaxh && ch ) { |
|
11658 data.top = dh - o.maxHeight; |
|
11659 } |
|
11660 |
|
11661 // Fixing jump error on top/left - bug #2330 |
|
11662 if ( !data.width && !data.height && !data.left && data.top ) { |
|
11663 data.top = null; |
|
11664 } else if ( !data.width && !data.height && !data.top && data.left ) { |
|
11665 data.left = null; |
|
11666 } |
|
11667 |
|
11668 return data; |
|
11669 }, |
|
11670 |
|
11671 _getPaddingPlusBorderDimensions: function( element ) { |
|
11672 var i = 0, |
|
11673 widths = [], |
|
11674 borders = [ |
|
11675 element.css( "borderTopWidth" ), |
|
11676 element.css( "borderRightWidth" ), |
|
11677 element.css( "borderBottomWidth" ), |
|
11678 element.css( "borderLeftWidth" ) |
|
11679 ], |
|
11680 paddings = [ |
|
11681 element.css( "paddingTop" ), |
|
11682 element.css( "paddingRight" ), |
|
11683 element.css( "paddingBottom" ), |
|
11684 element.css( "paddingLeft" ) |
|
11685 ]; |
|
11686 |
|
11687 for ( ; i < 4; i++ ) { |
|
11688 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); |
|
11689 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); |
|
11690 } |
|
11691 |
|
11692 return { |
|
11693 height: widths[ 0 ] + widths[ 2 ], |
|
11694 width: widths[ 1 ] + widths[ 3 ] |
|
11695 }; |
|
11696 }, |
|
11697 |
|
11698 _proportionallyResize: function() { |
|
11699 |
|
11700 if ( !this._proportionallyResizeElements.length ) { |
|
11701 return; |
|
11702 } |
|
11703 |
|
11704 var prel, |
|
11705 i = 0, |
|
11706 element = this.helper || this.element; |
|
11707 |
|
11708 for ( ; i < this._proportionallyResizeElements.length; i++ ) { |
|
11709 |
|
11710 prel = this._proportionallyResizeElements[ i ]; |
|
11711 |
|
11712 // TODO: Seems like a bug to cache this.outerDimensions |
|
11713 // considering that we are in a loop. |
|
11714 if ( !this.outerDimensions ) { |
|
11715 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); |
|
11716 } |
|
11717 |
|
11718 prel.css( { |
|
11719 height: ( element.height() - this.outerDimensions.height ) || 0, |
|
11720 width: ( element.width() - this.outerDimensions.width ) || 0 |
|
11721 } ); |
|
11722 |
|
11723 } |
|
11724 |
|
11725 }, |
|
11726 |
|
11727 _renderProxy: function() { |
|
11728 |
|
11729 var el = this.element, o = this.options; |
|
11730 this.elementOffset = el.offset(); |
|
11731 |
|
11732 if ( this._helper ) { |
|
11733 |
|
11734 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); |
|
11735 |
|
11736 this._addClass( this.helper, this._helper ); |
|
11737 this.helper.css( { |
|
11738 width: this.element.outerWidth(), |
|
11739 height: this.element.outerHeight(), |
|
11740 position: "absolute", |
|
11741 left: this.elementOffset.left + "px", |
|
11742 top: this.elementOffset.top + "px", |
|
11743 zIndex: ++o.zIndex //TODO: Don't modify option |
|
11744 } ); |
|
11745 |
|
11746 this.helper |
|
11747 .appendTo( "body" ) |
|
11748 .disableSelection(); |
|
11749 |
|
11750 } else { |
|
11751 this.helper = this.element; |
|
11752 } |
|
11753 |
|
11754 }, |
|
11755 |
|
11756 _change: { |
|
11757 e: function( event, dx ) { |
|
11758 return { width: this.originalSize.width + dx }; |
|
11759 }, |
|
11760 w: function( event, dx ) { |
|
11761 var cs = this.originalSize, sp = this.originalPosition; |
|
11762 return { left: sp.left + dx, width: cs.width - dx }; |
|
11763 }, |
|
11764 n: function( event, dx, dy ) { |
|
11765 var cs = this.originalSize, sp = this.originalPosition; |
|
11766 return { top: sp.top + dy, height: cs.height - dy }; |
|
11767 }, |
|
11768 s: function( event, dx, dy ) { |
|
11769 return { height: this.originalSize.height + dy }; |
|
11770 }, |
|
11771 se: function( event, dx, dy ) { |
|
11772 return $.extend( this._change.s.apply( this, arguments ), |
|
11773 this._change.e.apply( this, [ event, dx, dy ] ) ); |
|
11774 }, |
|
11775 sw: function( event, dx, dy ) { |
|
11776 return $.extend( this._change.s.apply( this, arguments ), |
|
11777 this._change.w.apply( this, [ event, dx, dy ] ) ); |
|
11778 }, |
|
11779 ne: function( event, dx, dy ) { |
|
11780 return $.extend( this._change.n.apply( this, arguments ), |
|
11781 this._change.e.apply( this, [ event, dx, dy ] ) ); |
|
11782 }, |
|
11783 nw: function( event, dx, dy ) { |
|
11784 return $.extend( this._change.n.apply( this, arguments ), |
|
11785 this._change.w.apply( this, [ event, dx, dy ] ) ); |
|
11786 } |
|
11787 }, |
|
11788 |
|
11789 _propagate: function( n, event ) { |
|
11790 $.ui.plugin.call( this, n, [ event, this.ui() ] ); |
|
11791 if ( n !== "resize" ) { |
|
11792 this._trigger( n, event, this.ui() ); |
|
11793 } |
|
11794 }, |
|
11795 |
|
11796 plugins: {}, |
|
11797 |
|
11798 ui: function() { |
|
11799 return { |
|
11800 originalElement: this.originalElement, |
|
11801 element: this.element, |
|
11802 helper: this.helper, |
|
11803 position: this.position, |
|
11804 size: this.size, |
|
11805 originalSize: this.originalSize, |
|
11806 originalPosition: this.originalPosition |
|
11807 }; |
|
11808 } |
|
11809 |
|
11810 } ); |
|
11811 |
|
11812 /* |
|
11813 * Resizable Extensions |
|
11814 */ |
|
11815 |
|
11816 $.ui.plugin.add( "resizable", "animate", { |
|
11817 |
|
11818 stop: function( event ) { |
|
11819 var that = $( this ).resizable( "instance" ), |
|
11820 o = that.options, |
|
11821 pr = that._proportionallyResizeElements, |
|
11822 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), |
|
11823 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, |
|
11824 soffsetw = ista ? 0 : that.sizeDiff.width, |
|
11825 style = { |
|
11826 width: ( that.size.width - soffsetw ), |
|
11827 height: ( that.size.height - soffseth ) |
|
11828 }, |
|
11829 left = ( parseFloat( that.element.css( "left" ) ) + |
|
11830 ( that.position.left - that.originalPosition.left ) ) || null, |
|
11831 top = ( parseFloat( that.element.css( "top" ) ) + |
|
11832 ( that.position.top - that.originalPosition.top ) ) || null; |
|
11833 |
|
11834 that.element.animate( |
|
11835 $.extend( style, top && left ? { top: top, left: left } : {} ), { |
|
11836 duration: o.animateDuration, |
|
11837 easing: o.animateEasing, |
|
11838 step: function() { |
|
11839 |
|
11840 var data = { |
|
11841 width: parseFloat( that.element.css( "width" ) ), |
|
11842 height: parseFloat( that.element.css( "height" ) ), |
|
11843 top: parseFloat( that.element.css( "top" ) ), |
|
11844 left: parseFloat( that.element.css( "left" ) ) |
|
11845 }; |
|
11846 |
|
11847 if ( pr && pr.length ) { |
|
11848 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); |
|
11849 } |
|
11850 |
|
11851 // Propagating resize, and updating values for each animation step |
|
11852 that._updateCache( data ); |
|
11853 that._propagate( "resize", event ); |
|
11854 |
|
11855 } |
|
11856 } |
|
11857 ); |
|
11858 } |
|
11859 |
|
11860 } ); |
|
11861 |
|
11862 $.ui.plugin.add( "resizable", "containment", { |
|
11863 |
|
11864 start: function() { |
|
11865 var element, p, co, ch, cw, width, height, |
|
11866 that = $( this ).resizable( "instance" ), |
|
11867 o = that.options, |
|
11868 el = that.element, |
|
11869 oc = o.containment, |
|
11870 ce = ( oc instanceof $ ) ? |
|
11871 oc.get( 0 ) : |
|
11872 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; |
|
11873 |
|
11874 if ( !ce ) { |
|
11875 return; |
|
11876 } |
|
11877 |
|
11878 that.containerElement = $( ce ); |
|
11879 |
|
11880 if ( /document/.test( oc ) || oc === document ) { |
|
11881 that.containerOffset = { |
|
11882 left: 0, |
|
11883 top: 0 |
|
11884 }; |
|
11885 that.containerPosition = { |
|
11886 left: 0, |
|
11887 top: 0 |
|
11888 }; |
|
11889 |
|
11890 that.parentData = { |
|
11891 element: $( document ), |
|
11892 left: 0, |
|
11893 top: 0, |
|
11894 width: $( document ).width(), |
|
11895 height: $( document ).height() || document.body.parentNode.scrollHeight |
|
11896 }; |
|
11897 } else { |
|
11898 element = $( ce ); |
|
11899 p = []; |
|
11900 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { |
|
11901 p[ i ] = that._num( element.css( "padding" + name ) ); |
|
11902 } ); |
|
11903 |
|
11904 that.containerOffset = element.offset(); |
|
11905 that.containerPosition = element.position(); |
|
11906 that.containerSize = { |
|
11907 height: ( element.innerHeight() - p[ 3 ] ), |
|
11908 width: ( element.innerWidth() - p[ 1 ] ) |
|
11909 }; |
|
11910 |
|
11911 co = that.containerOffset; |
|
11912 ch = that.containerSize.height; |
|
11913 cw = that.containerSize.width; |
|
11914 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); |
|
11915 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); |
|
11916 |
|
11917 that.parentData = { |
|
11918 element: ce, |
|
11919 left: co.left, |
|
11920 top: co.top, |
|
11921 width: width, |
|
11922 height: height |
|
11923 }; |
|
11924 } |
|
11925 }, |
|
11926 |
|
11927 resize: function( event ) { |
|
11928 var woset, hoset, isParent, isOffsetRelative, |
|
11929 that = $( this ).resizable( "instance" ), |
|
11930 o = that.options, |
|
11931 co = that.containerOffset, |
|
11932 cp = that.position, |
|
11933 pRatio = that._aspectRatio || event.shiftKey, |
|
11934 cop = { |
|
11935 top: 0, |
|
11936 left: 0 |
|
11937 }, |
|
11938 ce = that.containerElement, |
|
11939 continueResize = true; |
|
11940 |
|
11941 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { |
|
11942 cop = co; |
|
11943 } |
|
11944 |
|
11945 if ( cp.left < ( that._helper ? co.left : 0 ) ) { |
|
11946 that.size.width = that.size.width + |
|
11947 ( that._helper ? |
|
11948 ( that.position.left - co.left ) : |
|
11949 ( that.position.left - cop.left ) ); |
|
11950 |
|
11951 if ( pRatio ) { |
|
11952 that.size.height = that.size.width / that.aspectRatio; |
|
11953 continueResize = false; |
|
11954 } |
|
11955 that.position.left = o.helper ? co.left : 0; |
|
11956 } |
|
11957 |
|
11958 if ( cp.top < ( that._helper ? co.top : 0 ) ) { |
|
11959 that.size.height = that.size.height + |
|
11960 ( that._helper ? |
|
11961 ( that.position.top - co.top ) : |
|
11962 that.position.top ); |
|
11963 |
|
11964 if ( pRatio ) { |
|
11965 that.size.width = that.size.height * that.aspectRatio; |
|
11966 continueResize = false; |
|
11967 } |
|
11968 that.position.top = that._helper ? co.top : 0; |
|
11969 } |
|
11970 |
|
11971 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); |
|
11972 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); |
|
11973 |
|
11974 if ( isParent && isOffsetRelative ) { |
|
11975 that.offset.left = that.parentData.left + that.position.left; |
|
11976 that.offset.top = that.parentData.top + that.position.top; |
|
11977 } else { |
|
11978 that.offset.left = that.element.offset().left; |
|
11979 that.offset.top = that.element.offset().top; |
|
11980 } |
|
11981 |
|
11982 woset = Math.abs( that.sizeDiff.width + |
|
11983 ( that._helper ? |
|
11984 that.offset.left - cop.left : |
|
11985 ( that.offset.left - co.left ) ) ); |
|
11986 |
|
11987 hoset = Math.abs( that.sizeDiff.height + |
|
11988 ( that._helper ? |
|
11989 that.offset.top - cop.top : |
|
11990 ( that.offset.top - co.top ) ) ); |
|
11991 |
|
11992 if ( woset + that.size.width >= that.parentData.width ) { |
|
11993 that.size.width = that.parentData.width - woset; |
|
11994 if ( pRatio ) { |
|
11995 that.size.height = that.size.width / that.aspectRatio; |
|
11996 continueResize = false; |
|
11997 } |
|
11998 } |
|
11999 |
|
12000 if ( hoset + that.size.height >= that.parentData.height ) { |
|
12001 that.size.height = that.parentData.height - hoset; |
|
12002 if ( pRatio ) { |
|
12003 that.size.width = that.size.height * that.aspectRatio; |
|
12004 continueResize = false; |
|
12005 } |
|
12006 } |
|
12007 |
|
12008 if ( !continueResize ) { |
|
12009 that.position.left = that.prevPosition.left; |
|
12010 that.position.top = that.prevPosition.top; |
|
12011 that.size.width = that.prevSize.width; |
|
12012 that.size.height = that.prevSize.height; |
|
12013 } |
|
12014 }, |
|
12015 |
|
12016 stop: function() { |
|
12017 var that = $( this ).resizable( "instance" ), |
|
12018 o = that.options, |
|
12019 co = that.containerOffset, |
|
12020 cop = that.containerPosition, |
|
12021 ce = that.containerElement, |
|
12022 helper = $( that.helper ), |
|
12023 ho = helper.offset(), |
|
12024 w = helper.outerWidth() - that.sizeDiff.width, |
|
12025 h = helper.outerHeight() - that.sizeDiff.height; |
|
12026 |
|
12027 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { |
|
12028 $( this ).css( { |
|
12029 left: ho.left - cop.left - co.left, |
|
12030 width: w, |
|
12031 height: h |
|
12032 } ); |
|
12033 } |
|
12034 |
|
12035 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { |
|
12036 $( this ).css( { |
|
12037 left: ho.left - cop.left - co.left, |
|
12038 width: w, |
|
12039 height: h |
|
12040 } ); |
|
12041 } |
|
12042 } |
|
12043 } ); |
|
12044 |
|
12045 $.ui.plugin.add( "resizable", "alsoResize", { |
|
12046 |
|
12047 start: function() { |
|
12048 var that = $( this ).resizable( "instance" ), |
|
12049 o = that.options; |
|
12050 |
|
12051 $( o.alsoResize ).each( function() { |
|
12052 var el = $( this ); |
|
12053 el.data( "ui-resizable-alsoresize", { |
|
12054 width: parseFloat( el.width() ), height: parseFloat( el.height() ), |
|
12055 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) |
|
12056 } ); |
|
12057 } ); |
|
12058 }, |
|
12059 |
|
12060 resize: function( event, ui ) { |
|
12061 var that = $( this ).resizable( "instance" ), |
|
12062 o = that.options, |
|
12063 os = that.originalSize, |
|
12064 op = that.originalPosition, |
|
12065 delta = { |
|
12066 height: ( that.size.height - os.height ) || 0, |
|
12067 width: ( that.size.width - os.width ) || 0, |
|
12068 top: ( that.position.top - op.top ) || 0, |
|
12069 left: ( that.position.left - op.left ) || 0 |
|
12070 }; |
|
12071 |
|
12072 $( o.alsoResize ).each( function() { |
|
12073 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, |
|
12074 css = el.parents( ui.originalElement[ 0 ] ).length ? |
|
12075 [ "width", "height" ] : |
|
12076 [ "width", "height", "top", "left" ]; |
|
12077 |
|
12078 $.each( css, function( i, prop ) { |
|
12079 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); |
|
12080 if ( sum && sum >= 0 ) { |
|
12081 style[ prop ] = sum || null; |
|
12082 } |
|
12083 } ); |
|
12084 |
|
12085 el.css( style ); |
|
12086 } ); |
|
12087 }, |
|
12088 |
|
12089 stop: function() { |
|
12090 $( this ).removeData( "ui-resizable-alsoresize" ); |
|
12091 } |
|
12092 } ); |
|
12093 |
|
12094 $.ui.plugin.add( "resizable", "ghost", { |
|
12095 |
|
12096 start: function() { |
|
12097 |
|
12098 var that = $( this ).resizable( "instance" ), cs = that.size; |
|
12099 |
|
12100 that.ghost = that.originalElement.clone(); |
|
12101 that.ghost.css( { |
|
12102 opacity: 0.25, |
|
12103 display: "block", |
|
12104 position: "relative", |
|
12105 height: cs.height, |
|
12106 width: cs.width, |
|
12107 margin: 0, |
|
12108 left: 0, |
|
12109 top: 0 |
|
12110 } ); |
|
12111 |
|
12112 that._addClass( that.ghost, "ui-resizable-ghost" ); |
|
12113 |
|
12114 // DEPRECATED |
|
12115 // TODO: remove after 1.12 |
|
12116 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { |
|
12117 |
|
12118 // Ghost option |
|
12119 that.ghost.addClass( this.options.ghost ); |
|
12120 } |
|
12121 |
|
12122 that.ghost.appendTo( that.helper ); |
|
12123 |
|
12124 }, |
|
12125 |
|
12126 resize: function() { |
|
12127 var that = $( this ).resizable( "instance" ); |
|
12128 if ( that.ghost ) { |
|
12129 that.ghost.css( { |
|
12130 position: "relative", |
|
12131 height: that.size.height, |
|
12132 width: that.size.width |
|
12133 } ); |
|
12134 } |
|
12135 }, |
|
12136 |
|
12137 stop: function() { |
|
12138 var that = $( this ).resizable( "instance" ); |
|
12139 if ( that.ghost && that.helper ) { |
|
12140 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); |
|
12141 } |
|
12142 } |
|
12143 |
|
12144 } ); |
|
12145 |
|
12146 $.ui.plugin.add( "resizable", "grid", { |
|
12147 |
|
12148 resize: function() { |
|
12149 var outerDimensions, |
|
12150 that = $( this ).resizable( "instance" ), |
|
12151 o = that.options, |
|
12152 cs = that.size, |
|
12153 os = that.originalSize, |
|
12154 op = that.originalPosition, |
|
12155 a = that.axis, |
|
12156 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, |
|
12157 gridX = ( grid[ 0 ] || 1 ), |
|
12158 gridY = ( grid[ 1 ] || 1 ), |
|
12159 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, |
|
12160 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, |
|
12161 newWidth = os.width + ox, |
|
12162 newHeight = os.height + oy, |
|
12163 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), |
|
12164 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), |
|
12165 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), |
|
12166 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); |
|
12167 |
|
12168 o.grid = grid; |
|
12169 |
|
12170 if ( isMinWidth ) { |
|
12171 newWidth += gridX; |
|
12172 } |
|
12173 if ( isMinHeight ) { |
|
12174 newHeight += gridY; |
|
12175 } |
|
12176 if ( isMaxWidth ) { |
|
12177 newWidth -= gridX; |
|
12178 } |
|
12179 if ( isMaxHeight ) { |
|
12180 newHeight -= gridY; |
|
12181 } |
|
12182 |
|
12183 if ( /^(se|s|e)$/.test( a ) ) { |
|
12184 that.size.width = newWidth; |
|
12185 that.size.height = newHeight; |
|
12186 } else if ( /^(ne)$/.test( a ) ) { |
|
12187 that.size.width = newWidth; |
|
12188 that.size.height = newHeight; |
|
12189 that.position.top = op.top - oy; |
|
12190 } else if ( /^(sw)$/.test( a ) ) { |
|
12191 that.size.width = newWidth; |
|
12192 that.size.height = newHeight; |
|
12193 that.position.left = op.left - ox; |
|
12194 } else { |
|
12195 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { |
|
12196 outerDimensions = that._getPaddingPlusBorderDimensions( this ); |
|
12197 } |
|
12198 |
|
12199 if ( newHeight - gridY > 0 ) { |
|
12200 that.size.height = newHeight; |
|
12201 that.position.top = op.top - oy; |
|
12202 } else { |
|
12203 newHeight = gridY - outerDimensions.height; |
|
12204 that.size.height = newHeight; |
|
12205 that.position.top = op.top + os.height - newHeight; |
|
12206 } |
|
12207 if ( newWidth - gridX > 0 ) { |
|
12208 that.size.width = newWidth; |
|
12209 that.position.left = op.left - ox; |
|
12210 } else { |
|
12211 newWidth = gridX - outerDimensions.width; |
|
12212 that.size.width = newWidth; |
|
12213 that.position.left = op.left + os.width - newWidth; |
|
12214 } |
|
12215 } |
|
12216 } |
|
12217 |
|
12218 } ); |
|
12219 |
|
12220 var widgetsResizable = $.ui.resizable; |
|
12221 |
|
12222 |
|
12223 /*! |
|
12224 * jQuery UI Dialog 1.13.2 |
|
12225 * http://jqueryui.com |
|
12226 * |
|
12227 * Copyright jQuery Foundation and other contributors |
|
12228 * Released under the MIT license. |
|
12229 * http://jquery.org/license |
|
12230 */ |
|
12231 |
|
12232 //>>label: Dialog |
|
12233 //>>group: Widgets |
|
12234 //>>description: Displays customizable dialog windows. |
|
12235 //>>docs: http://api.jqueryui.com/dialog/ |
|
12236 //>>demos: http://jqueryui.com/dialog/ |
|
12237 //>>css.structure: ../../themes/base/core.css |
|
12238 //>>css.structure: ../../themes/base/dialog.css |
|
12239 //>>css.theme: ../../themes/base/theme.css |
|
12240 |
|
12241 |
|
12242 $.widget( "ui.dialog", { |
|
12243 version: "1.13.2", |
|
12244 options: { |
|
12245 appendTo: "body", |
|
12246 autoOpen: true, |
|
12247 buttons: [], |
|
12248 classes: { |
|
12249 "ui-dialog": "ui-corner-all", |
|
12250 "ui-dialog-titlebar": "ui-corner-all" |
|
12251 }, |
|
12252 closeOnEscape: true, |
|
12253 closeText: "Close", |
|
12254 draggable: true, |
|
12255 hide: null, |
|
12256 height: "auto", |
|
12257 maxHeight: null, |
|
12258 maxWidth: null, |
|
12259 minHeight: 150, |
|
12260 minWidth: 150, |
|
12261 modal: false, |
|
12262 position: { |
|
12263 my: "center", |
|
12264 at: "center", |
|
12265 of: window, |
|
12266 collision: "fit", |
|
12267 |
|
12268 // Ensure the titlebar is always visible |
|
12269 using: function( pos ) { |
|
12270 var topOffset = $( this ).css( pos ).offset().top; |
|
12271 if ( topOffset < 0 ) { |
|
12272 $( this ).css( "top", pos.top - topOffset ); |
|
12273 } |
|
12274 } |
|
12275 }, |
|
12276 resizable: true, |
|
12277 show: null, |
|
12278 title: null, |
|
12279 width: 300, |
|
12280 |
|
12281 // Callbacks |
|
12282 beforeClose: null, |
|
12283 close: null, |
|
12284 drag: null, |
|
12285 dragStart: null, |
|
12286 dragStop: null, |
|
12287 focus: null, |
|
12288 open: null, |
|
12289 resize: null, |
|
12290 resizeStart: null, |
|
12291 resizeStop: null |
|
12292 }, |
|
12293 |
|
12294 sizeRelatedOptions: { |
|
12295 buttons: true, |
|
12296 height: true, |
|
12297 maxHeight: true, |
|
12298 maxWidth: true, |
|
12299 minHeight: true, |
|
12300 minWidth: true, |
|
12301 width: true |
|
12302 }, |
|
12303 |
|
12304 resizableRelatedOptions: { |
|
12305 maxHeight: true, |
|
12306 maxWidth: true, |
|
12307 minHeight: true, |
|
12308 minWidth: true |
|
12309 }, |
|
12310 |
|
12311 _create: function() { |
|
12312 this.originalCss = { |
|
12313 display: this.element[ 0 ].style.display, |
|
12314 width: this.element[ 0 ].style.width, |
|
12315 minHeight: this.element[ 0 ].style.minHeight, |
|
12316 maxHeight: this.element[ 0 ].style.maxHeight, |
|
12317 height: this.element[ 0 ].style.height |
|
12318 }; |
|
12319 this.originalPosition = { |
|
12320 parent: this.element.parent(), |
|
12321 index: this.element.parent().children().index( this.element ) |
|
12322 }; |
|
12323 this.originalTitle = this.element.attr( "title" ); |
|
12324 if ( this.options.title == null && this.originalTitle != null ) { |
|
12325 this.options.title = this.originalTitle; |
|
12326 } |
|
12327 |
|
12328 // Dialogs can't be disabled |
|
12329 if ( this.options.disabled ) { |
|
12330 this.options.disabled = false; |
|
12331 } |
|
12332 |
|
12333 this._createWrapper(); |
|
12334 |
|
12335 this.element |
|
12336 .show() |
|
12337 .removeAttr( "title" ) |
|
12338 .appendTo( this.uiDialog ); |
|
12339 |
|
12340 this._addClass( "ui-dialog-content", "ui-widget-content" ); |
|
12341 |
|
12342 this._createTitlebar(); |
|
12343 this._createButtonPane(); |
|
12344 |
|
12345 if ( this.options.draggable && $.fn.draggable ) { |
|
12346 this._makeDraggable(); |
|
12347 } |
|
12348 if ( this.options.resizable && $.fn.resizable ) { |
|
12349 this._makeResizable(); |
|
12350 } |
|
12351 |
|
12352 this._isOpen = false; |
|
12353 |
|
12354 this._trackFocus(); |
|
12355 }, |
|
12356 |
|
12357 _init: function() { |
|
12358 if ( this.options.autoOpen ) { |
|
12359 this.open(); |
|
12360 } |
|
12361 }, |
|
12362 |
|
12363 _appendTo: function() { |
|
12364 var element = this.options.appendTo; |
|
12365 if ( element && ( element.jquery || element.nodeType ) ) { |
|
12366 return $( element ); |
|
12367 } |
|
12368 return this.document.find( element || "body" ).eq( 0 ); |
|
12369 }, |
|
12370 |
|
12371 _destroy: function() { |
|
12372 var next, |
|
12373 originalPosition = this.originalPosition; |
|
12374 |
|
12375 this._untrackInstance(); |
|
12376 this._destroyOverlay(); |
|
12377 |
|
12378 this.element |
|
12379 .removeUniqueId() |
|
12380 .css( this.originalCss ) |
|
12381 |
|
12382 // Without detaching first, the following becomes really slow |
|
12383 .detach(); |
|
12384 |
|
12385 this.uiDialog.remove(); |
|
12386 |
|
12387 if ( this.originalTitle ) { |
|
12388 this.element.attr( "title", this.originalTitle ); |
|
12389 } |
|
12390 |
|
12391 next = originalPosition.parent.children().eq( originalPosition.index ); |
|
12392 |
|
12393 // Don't try to place the dialog next to itself (#8613) |
|
12394 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { |
|
12395 next.before( this.element ); |
|
12396 } else { |
|
12397 originalPosition.parent.append( this.element ); |
|
12398 } |
|
12399 }, |
|
12400 |
|
12401 widget: function() { |
|
12402 return this.uiDialog; |
|
12403 }, |
|
12404 |
|
12405 disable: $.noop, |
|
12406 enable: $.noop, |
|
12407 |
|
12408 close: function( event ) { |
|
12409 var that = this; |
|
12410 |
|
12411 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { |
|
12412 return; |
|
12413 } |
|
12414 |
|
12415 this._isOpen = false; |
|
12416 this._focusedElement = null; |
|
12417 this._destroyOverlay(); |
|
12418 this._untrackInstance(); |
|
12419 |
|
12420 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { |
|
12421 |
|
12422 // Hiding a focused element doesn't trigger blur in WebKit |
|
12423 // so in case we have nothing to focus on, explicitly blur the active element |
|
12424 // https://bugs.webkit.org/show_bug.cgi?id=47182 |
|
12425 $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); |
|
12426 } |
|
12427 |
|
12428 this._hide( this.uiDialog, this.options.hide, function() { |
|
12429 that._trigger( "close", event ); |
|
12430 } ); |
|
12431 }, |
|
12432 |
|
12433 isOpen: function() { |
|
12434 return this._isOpen; |
|
12435 }, |
|
12436 |
|
12437 moveToTop: function() { |
|
12438 this._moveToTop(); |
|
12439 }, |
|
12440 |
|
12441 _moveToTop: function( event, silent ) { |
|
12442 var moved = false, |
|
12443 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { |
|
12444 return +$( this ).css( "z-index" ); |
|
12445 } ).get(), |
|
12446 zIndexMax = Math.max.apply( null, zIndices ); |
|
12447 |
|
12448 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { |
|
12449 this.uiDialog.css( "z-index", zIndexMax + 1 ); |
|
12450 moved = true; |
|
12451 } |
|
12452 |
|
12453 if ( moved && !silent ) { |
|
12454 this._trigger( "focus", event ); |
|
12455 } |
|
12456 return moved; |
|
12457 }, |
|
12458 |
|
12459 open: function() { |
|
12460 var that = this; |
|
12461 if ( this._isOpen ) { |
|
12462 if ( this._moveToTop() ) { |
|
12463 this._focusTabbable(); |
|
12464 } |
|
12465 return; |
|
12466 } |
|
12467 |
|
12468 this._isOpen = true; |
|
12469 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); |
|
12470 |
|
12471 this._size(); |
|
12472 this._position(); |
|
12473 this._createOverlay(); |
|
12474 this._moveToTop( null, true ); |
|
12475 |
|
12476 // Ensure the overlay is moved to the top with the dialog, but only when |
|
12477 // opening. The overlay shouldn't move after the dialog is open so that |
|
12478 // modeless dialogs opened after the modal dialog stack properly. |
|
12479 if ( this.overlay ) { |
|
12480 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); |
|
12481 } |
|
12482 |
|
12483 this._show( this.uiDialog, this.options.show, function() { |
|
12484 that._focusTabbable(); |
|
12485 that._trigger( "focus" ); |
|
12486 } ); |
|
12487 |
|
12488 // Track the dialog immediately upon opening in case a focus event |
|
12489 // somehow occurs outside of the dialog before an element inside the |
|
12490 // dialog is focused (#10152) |
|
12491 this._makeFocusTarget(); |
|
12492 |
|
12493 this._trigger( "open" ); |
|
12494 }, |
|
12495 |
|
12496 _focusTabbable: function() { |
|
12497 |
|
12498 // Set focus to the first match: |
|
12499 // 1. An element that was focused previously |
|
12500 // 2. First element inside the dialog matching [autofocus] |
|
12501 // 3. Tabbable element inside the content element |
|
12502 // 4. Tabbable element inside the buttonpane |
|
12503 // 5. The close button |
|
12504 // 6. The dialog itself |
|
12505 var hasFocus = this._focusedElement; |
|
12506 if ( !hasFocus ) { |
|
12507 hasFocus = this.element.find( "[autofocus]" ); |
|
12508 } |
|
12509 if ( !hasFocus.length ) { |
|
12510 hasFocus = this.element.find( ":tabbable" ); |
|
12511 } |
|
12512 if ( !hasFocus.length ) { |
|
12513 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); |
|
12514 } |
|
12515 if ( !hasFocus.length ) { |
|
12516 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); |
|
12517 } |
|
12518 if ( !hasFocus.length ) { |
|
12519 hasFocus = this.uiDialog; |
|
12520 } |
|
12521 hasFocus.eq( 0 ).trigger( "focus" ); |
|
12522 }, |
|
12523 |
|
12524 _restoreTabbableFocus: function() { |
|
12525 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), |
|
12526 isActive = this.uiDialog[ 0 ] === activeElement || |
|
12527 $.contains( this.uiDialog[ 0 ], activeElement ); |
|
12528 if ( !isActive ) { |
|
12529 this._focusTabbable(); |
|
12530 } |
|
12531 }, |
|
12532 |
|
12533 _keepFocus: function( event ) { |
|
12534 event.preventDefault(); |
|
12535 this._restoreTabbableFocus(); |
|
12536 |
|
12537 // support: IE |
|
12538 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() |
|
12539 // so we check again later |
|
12540 this._delay( this._restoreTabbableFocus ); |
|
12541 }, |
|
12542 |
|
12543 _createWrapper: function() { |
|
12544 this.uiDialog = $( "<div>" ) |
|
12545 .hide() |
|
12546 .attr( { |
|
12547 |
|
12548 // Setting tabIndex makes the div focusable |
|
12549 tabIndex: -1, |
|
12550 role: "dialog" |
|
12551 } ) |
|
12552 .appendTo( this._appendTo() ); |
|
12553 |
|
12554 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); |
|
12555 this._on( this.uiDialog, { |
|
12556 keydown: function( event ) { |
|
12557 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && |
|
12558 event.keyCode === $.ui.keyCode.ESCAPE ) { |
|
12559 event.preventDefault(); |
|
12560 this.close( event ); |
|
12561 return; |
|
12562 } |
|
12563 |
|
12564 // Prevent tabbing out of dialogs |
|
12565 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { |
|
12566 return; |
|
12567 } |
|
12568 var tabbables = this.uiDialog.find( ":tabbable" ), |
|
12569 first = tabbables.first(), |
|
12570 last = tabbables.last(); |
|
12571 |
|
12572 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && |
|
12573 !event.shiftKey ) { |
|
12574 this._delay( function() { |
|
12575 first.trigger( "focus" ); |
|
12576 } ); |
|
12577 event.preventDefault(); |
|
12578 } else if ( ( event.target === first[ 0 ] || |
|
12579 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { |
|
12580 this._delay( function() { |
|
12581 last.trigger( "focus" ); |
|
12582 } ); |
|
12583 event.preventDefault(); |
|
12584 } |
|
12585 }, |
|
12586 mousedown: function( event ) { |
|
12587 if ( this._moveToTop( event ) ) { |
|
12588 this._focusTabbable(); |
|
12589 } |
|
12590 } |
|
12591 } ); |
|
12592 |
|
12593 // We assume that any existing aria-describedby attribute means |
|
12594 // that the dialog content is marked up properly |
|
12595 // otherwise we brute force the content as the description |
|
12596 if ( !this.element.find( "[aria-describedby]" ).length ) { |
|
12597 this.uiDialog.attr( { |
|
12598 "aria-describedby": this.element.uniqueId().attr( "id" ) |
|
12599 } ); |
|
12600 } |
|
12601 }, |
|
12602 |
|
12603 _createTitlebar: function() { |
|
12604 var uiDialogTitle; |
|
12605 |
|
12606 this.uiDialogTitlebar = $( "<div>" ); |
|
12607 this._addClass( this.uiDialogTitlebar, |
|
12608 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); |
|
12609 this._on( this.uiDialogTitlebar, { |
|
12610 mousedown: function( event ) { |
|
12611 |
|
12612 // Don't prevent click on close button (#8838) |
|
12613 // Focusing a dialog that is partially scrolled out of view |
|
12614 // causes the browser to scroll it into view, preventing the click event |
|
12615 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { |
|
12616 |
|
12617 // Dialog isn't getting focus when dragging (#8063) |
|
12618 this.uiDialog.trigger( "focus" ); |
|
12619 } |
|
12620 } |
|
12621 } ); |
|
12622 |
|
12623 // Support: IE |
|
12624 // Use type="button" to prevent enter keypresses in textboxes from closing the |
|
12625 // dialog in IE (#9312) |
|
12626 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) |
|
12627 .button( { |
|
12628 label: $( "<a>" ).text( this.options.closeText ).html(), |
|
12629 icon: "ui-icon-closethick", |
|
12630 showLabel: false |
|
12631 } ) |
|
12632 .appendTo( this.uiDialogTitlebar ); |
|
12633 |
|
12634 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); |
|
12635 this._on( this.uiDialogTitlebarClose, { |
|
12636 click: function( event ) { |
|
12637 event.preventDefault(); |
|
12638 this.close( event ); |
|
12639 } |
|
12640 } ); |
|
12641 |
|
12642 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); |
|
12643 this._addClass( uiDialogTitle, "ui-dialog-title" ); |
|
12644 this._title( uiDialogTitle ); |
|
12645 |
|
12646 this.uiDialogTitlebar.prependTo( this.uiDialog ); |
|
12647 |
|
12648 this.uiDialog.attr( { |
|
12649 "aria-labelledby": uiDialogTitle.attr( "id" ) |
|
12650 } ); |
|
12651 }, |
|
12652 |
|
12653 _title: function( title ) { |
|
12654 if ( this.options.title ) { |
|
12655 title.text( this.options.title ); |
|
12656 } else { |
|
12657 title.html( " " ); |
|
12658 } |
|
12659 }, |
|
12660 |
|
12661 _createButtonPane: function() { |
|
12662 this.uiDialogButtonPane = $( "<div>" ); |
|
12663 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", |
|
12664 "ui-widget-content ui-helper-clearfix" ); |
|
12665 |
|
12666 this.uiButtonSet = $( "<div>" ) |
|
12667 .appendTo( this.uiDialogButtonPane ); |
|
12668 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); |
|
12669 |
|
12670 this._createButtons(); |
|
12671 }, |
|
12672 |
|
12673 _createButtons: function() { |
|
12674 var that = this, |
|
12675 buttons = this.options.buttons; |
|
12676 |
|
12677 // If we already have a button pane, remove it |
|
12678 this.uiDialogButtonPane.remove(); |
|
12679 this.uiButtonSet.empty(); |
|
12680 |
|
12681 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { |
|
12682 this._removeClass( this.uiDialog, "ui-dialog-buttons" ); |
|
12683 return; |
|
12684 } |
|
12685 |
|
12686 $.each( buttons, function( name, props ) { |
|
12687 var click, buttonOptions; |
|
12688 props = typeof props === "function" ? |
|
12689 { click: props, text: name } : |
|
12690 props; |
|
12691 |
|
12692 // Default to a non-submitting button |
|
12693 props = $.extend( { type: "button" }, props ); |
|
12694 |
|
12695 // Change the context for the click callback to be the main element |
|
12696 click = props.click; |
|
12697 buttonOptions = { |
|
12698 icon: props.icon, |
|
12699 iconPosition: props.iconPosition, |
|
12700 showLabel: props.showLabel, |
|
12701 |
|
12702 // Deprecated options |
|
12703 icons: props.icons, |
|
12704 text: props.text |
|
12705 }; |
|
12706 |
|
12707 delete props.click; |
|
12708 delete props.icon; |
|
12709 delete props.iconPosition; |
|
12710 delete props.showLabel; |
|
12711 |
|
12712 // Deprecated options |
|
12713 delete props.icons; |
|
12714 if ( typeof props.text === "boolean" ) { |
|
12715 delete props.text; |
|
12716 } |
|
12717 |
|
12718 $( "<button></button>", props ) |
|
12719 .button( buttonOptions ) |
|
12720 .appendTo( that.uiButtonSet ) |
|
12721 .on( "click", function() { |
|
12722 click.apply( that.element[ 0 ], arguments ); |
|
12723 } ); |
|
12724 } ); |
|
12725 this._addClass( this.uiDialog, "ui-dialog-buttons" ); |
|
12726 this.uiDialogButtonPane.appendTo( this.uiDialog ); |
|
12727 }, |
|
12728 |
|
12729 _makeDraggable: function() { |
|
12730 var that = this, |
|
12731 options = this.options; |
|
12732 |
|
12733 function filteredUi( ui ) { |
|
12734 return { |
|
12735 position: ui.position, |
|
12736 offset: ui.offset |
|
12737 }; |
|
12738 } |
|
12739 |
|
12740 this.uiDialog.draggable( { |
|
12741 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", |
|
12742 handle: ".ui-dialog-titlebar", |
|
12743 containment: "document", |
|
12744 start: function( event, ui ) { |
|
12745 that._addClass( $( this ), "ui-dialog-dragging" ); |
|
12746 that._blockFrames(); |
|
12747 that._trigger( "dragStart", event, filteredUi( ui ) ); |
|
12748 }, |
|
12749 drag: function( event, ui ) { |
|
12750 that._trigger( "drag", event, filteredUi( ui ) ); |
|
12751 }, |
|
12752 stop: function( event, ui ) { |
|
12753 var left = ui.offset.left - that.document.scrollLeft(), |
|
12754 top = ui.offset.top - that.document.scrollTop(); |
|
12755 |
|
12756 options.position = { |
|
12757 my: "left top", |
|
12758 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + |
|
12759 "top" + ( top >= 0 ? "+" : "" ) + top, |
|
12760 of: that.window |
|
12761 }; |
|
12762 that._removeClass( $( this ), "ui-dialog-dragging" ); |
|
12763 that._unblockFrames(); |
|
12764 that._trigger( "dragStop", event, filteredUi( ui ) ); |
|
12765 } |
|
12766 } ); |
|
12767 }, |
|
12768 |
|
12769 _makeResizable: function() { |
|
12770 var that = this, |
|
12771 options = this.options, |
|
12772 handles = options.resizable, |
|
12773 |
|
12774 // .ui-resizable has position: relative defined in the stylesheet |
|
12775 // but dialogs have to use absolute or fixed positioning |
|
12776 position = this.uiDialog.css( "position" ), |
|
12777 resizeHandles = typeof handles === "string" ? |
|
12778 handles : |
|
12779 "n,e,s,w,se,sw,ne,nw"; |
|
12780 |
|
12781 function filteredUi( ui ) { |
|
12782 return { |
|
12783 originalPosition: ui.originalPosition, |
|
12784 originalSize: ui.originalSize, |
|
12785 position: ui.position, |
|
12786 size: ui.size |
|
12787 }; |
|
12788 } |
|
12789 |
|
12790 this.uiDialog.resizable( { |
|
12791 cancel: ".ui-dialog-content", |
|
12792 containment: "document", |
|
12793 alsoResize: this.element, |
|
12794 maxWidth: options.maxWidth, |
|
12795 maxHeight: options.maxHeight, |
|
12796 minWidth: options.minWidth, |
|
12797 minHeight: this._minHeight(), |
|
12798 handles: resizeHandles, |
|
12799 start: function( event, ui ) { |
|
12800 that._addClass( $( this ), "ui-dialog-resizing" ); |
|
12801 that._blockFrames(); |
|
12802 that._trigger( "resizeStart", event, filteredUi( ui ) ); |
|
12803 }, |
|
12804 resize: function( event, ui ) { |
|
12805 that._trigger( "resize", event, filteredUi( ui ) ); |
|
12806 }, |
|
12807 stop: function( event, ui ) { |
|
12808 var offset = that.uiDialog.offset(), |
|
12809 left = offset.left - that.document.scrollLeft(), |
|
12810 top = offset.top - that.document.scrollTop(); |
|
12811 |
|
12812 options.height = that.uiDialog.height(); |
|
12813 options.width = that.uiDialog.width(); |
|
12814 options.position = { |
|
12815 my: "left top", |
|
12816 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + |
|
12817 "top" + ( top >= 0 ? "+" : "" ) + top, |
|
12818 of: that.window |
|
12819 }; |
|
12820 that._removeClass( $( this ), "ui-dialog-resizing" ); |
|
12821 that._unblockFrames(); |
|
12822 that._trigger( "resizeStop", event, filteredUi( ui ) ); |
|
12823 } |
|
12824 } ) |
|
12825 .css( "position", position ); |
|
12826 }, |
|
12827 |
|
12828 _trackFocus: function() { |
|
12829 this._on( this.widget(), { |
|
12830 focusin: function( event ) { |
|
12831 this._makeFocusTarget(); |
|
12832 this._focusedElement = $( event.target ); |
|
12833 } |
|
12834 } ); |
|
12835 }, |
|
12836 |
|
12837 _makeFocusTarget: function() { |
|
12838 this._untrackInstance(); |
|
12839 this._trackingInstances().unshift( this ); |
|
12840 }, |
|
12841 |
|
12842 _untrackInstance: function() { |
|
12843 var instances = this._trackingInstances(), |
|
12844 exists = $.inArray( this, instances ); |
|
12845 if ( exists !== -1 ) { |
|
12846 instances.splice( exists, 1 ); |
|
12847 } |
|
12848 }, |
|
12849 |
|
12850 _trackingInstances: function() { |
|
12851 var instances = this.document.data( "ui-dialog-instances" ); |
|
12852 if ( !instances ) { |
|
12853 instances = []; |
|
12854 this.document.data( "ui-dialog-instances", instances ); |
|
12855 } |
|
12856 return instances; |
|
12857 }, |
|
12858 |
|
12859 _minHeight: function() { |
|
12860 var options = this.options; |
|
12861 |
|
12862 return options.height === "auto" ? |
|
12863 options.minHeight : |
|
12864 Math.min( options.minHeight, options.height ); |
|
12865 }, |
|
12866 |
|
12867 _position: function() { |
|
12868 |
|
12869 // Need to show the dialog to get the actual offset in the position plugin |
|
12870 var isVisible = this.uiDialog.is( ":visible" ); |
|
12871 if ( !isVisible ) { |
|
12872 this.uiDialog.show(); |
|
12873 } |
|
12874 this.uiDialog.position( this.options.position ); |
|
12875 if ( !isVisible ) { |
|
12876 this.uiDialog.hide(); |
|
12877 } |
|
12878 }, |
|
12879 |
|
12880 _setOptions: function( options ) { |
|
12881 var that = this, |
|
12882 resize = false, |
|
12883 resizableOptions = {}; |
|
12884 |
|
12885 $.each( options, function( key, value ) { |
|
12886 that._setOption( key, value ); |
|
12887 |
|
12888 if ( key in that.sizeRelatedOptions ) { |
|
12889 resize = true; |
|
12890 } |
|
12891 if ( key in that.resizableRelatedOptions ) { |
|
12892 resizableOptions[ key ] = value; |
|
12893 } |
|
12894 } ); |
|
12895 |
|
12896 if ( resize ) { |
|
12897 this._size(); |
|
12898 this._position(); |
|
12899 } |
|
12900 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { |
|
12901 this.uiDialog.resizable( "option", resizableOptions ); |
|
12902 } |
|
12903 }, |
|
12904 |
|
12905 _setOption: function( key, value ) { |
|
12906 var isDraggable, isResizable, |
|
12907 uiDialog = this.uiDialog; |
|
12908 |
|
12909 if ( key === "disabled" ) { |
|
12910 return; |
|
12911 } |
|
12912 |
|
12913 this._super( key, value ); |
|
12914 |
|
12915 if ( key === "appendTo" ) { |
|
12916 this.uiDialog.appendTo( this._appendTo() ); |
|
12917 } |
|
12918 |
|
12919 if ( key === "buttons" ) { |
|
12920 this._createButtons(); |
|
12921 } |
|
12922 |
|
12923 if ( key === "closeText" ) { |
|
12924 this.uiDialogTitlebarClose.button( { |
|
12925 |
|
12926 // Ensure that we always pass a string |
|
12927 label: $( "<a>" ).text( "" + this.options.closeText ).html() |
|
12928 } ); |
|
12929 } |
|
12930 |
|
12931 if ( key === "draggable" ) { |
|
12932 isDraggable = uiDialog.is( ":data(ui-draggable)" ); |
|
12933 if ( isDraggable && !value ) { |
|
12934 uiDialog.draggable( "destroy" ); |
|
12935 } |
|
12936 |
|
12937 if ( !isDraggable && value ) { |
|
12938 this._makeDraggable(); |
|
12939 } |
|
12940 } |
|
12941 |
|
12942 if ( key === "position" ) { |
|
12943 this._position(); |
|
12944 } |
|
12945 |
|
12946 if ( key === "resizable" ) { |
|
12947 |
|
12948 // currently resizable, becoming non-resizable |
|
12949 isResizable = uiDialog.is( ":data(ui-resizable)" ); |
|
12950 if ( isResizable && !value ) { |
|
12951 uiDialog.resizable( "destroy" ); |
|
12952 } |
|
12953 |
|
12954 // Currently resizable, changing handles |
|
12955 if ( isResizable && typeof value === "string" ) { |
|
12956 uiDialog.resizable( "option", "handles", value ); |
|
12957 } |
|
12958 |
|
12959 // Currently non-resizable, becoming resizable |
|
12960 if ( !isResizable && value !== false ) { |
|
12961 this._makeResizable(); |
|
12962 } |
|
12963 } |
|
12964 |
|
12965 if ( key === "title" ) { |
|
12966 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); |
|
12967 } |
|
12968 }, |
|
12969 |
|
12970 _size: function() { |
|
12971 |
|
12972 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content |
|
12973 // divs will both have width and height set, so we need to reset them |
|
12974 var nonContentHeight, minContentHeight, maxContentHeight, |
|
12975 options = this.options; |
|
12976 |
|
12977 // Reset content sizing |
|
12978 this.element.show().css( { |
|
12979 width: "auto", |
|
12980 minHeight: 0, |
|
12981 maxHeight: "none", |
|
12982 height: 0 |
|
12983 } ); |
|
12984 |
|
12985 if ( options.minWidth > options.width ) { |
|
12986 options.width = options.minWidth; |
|
12987 } |
|
12988 |
|
12989 // Reset wrapper sizing |
|
12990 // determine the height of all the non-content elements |
|
12991 nonContentHeight = this.uiDialog.css( { |
|
12992 height: "auto", |
|
12993 width: options.width |
|
12994 } ) |
|
12995 .outerHeight(); |
|
12996 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); |
|
12997 maxContentHeight = typeof options.maxHeight === "number" ? |
|
12998 Math.max( 0, options.maxHeight - nonContentHeight ) : |
|
12999 "none"; |
|
13000 |
|
13001 if ( options.height === "auto" ) { |
|
13002 this.element.css( { |
|
13003 minHeight: minContentHeight, |
|
13004 maxHeight: maxContentHeight, |
|
13005 height: "auto" |
|
13006 } ); |
|
13007 } else { |
|
13008 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); |
|
13009 } |
|
13010 |
|
13011 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { |
|
13012 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); |
|
13013 } |
|
13014 }, |
|
13015 |
|
13016 _blockFrames: function() { |
|
13017 this.iframeBlocks = this.document.find( "iframe" ).map( function() { |
|
13018 var iframe = $( this ); |
|
13019 |
|
13020 return $( "<div>" ) |
|
13021 .css( { |
|
13022 position: "absolute", |
|
13023 width: iframe.outerWidth(), |
|
13024 height: iframe.outerHeight() |
|
13025 } ) |
|
13026 .appendTo( iframe.parent() ) |
|
13027 .offset( iframe.offset() )[ 0 ]; |
|
13028 } ); |
|
13029 }, |
|
13030 |
|
13031 _unblockFrames: function() { |
|
13032 if ( this.iframeBlocks ) { |
|
13033 this.iframeBlocks.remove(); |
|
13034 delete this.iframeBlocks; |
|
13035 } |
|
13036 }, |
|
13037 |
|
13038 _allowInteraction: function( event ) { |
|
13039 if ( $( event.target ).closest( ".ui-dialog" ).length ) { |
|
13040 return true; |
|
13041 } |
|
13042 |
|
13043 // TODO: Remove hack when datepicker implements |
|
13044 // the .ui-front logic (#8989) |
|
13045 return !!$( event.target ).closest( ".ui-datepicker" ).length; |
|
13046 }, |
|
13047 |
|
13048 _createOverlay: function() { |
|
13049 if ( !this.options.modal ) { |
|
13050 return; |
|
13051 } |
|
13052 |
|
13053 var jqMinor = $.fn.jquery.substring( 0, 4 ); |
|
13054 |
|
13055 // We use a delay in case the overlay is created from an |
|
13056 // event that we're going to be cancelling (#2804) |
|
13057 var isOpening = true; |
|
13058 this._delay( function() { |
|
13059 isOpening = false; |
|
13060 } ); |
|
13061 |
|
13062 if ( !this.document.data( "ui-dialog-overlays" ) ) { |
|
13063 |
|
13064 // Prevent use of anchors and inputs |
|
13065 // This doesn't use `_on()` because it is a shared event handler |
|
13066 // across all open modal dialogs. |
|
13067 this.document.on( "focusin.ui-dialog", function( event ) { |
|
13068 if ( isOpening ) { |
|
13069 return; |
|
13070 } |
|
13071 |
|
13072 var instance = this._trackingInstances()[ 0 ]; |
|
13073 if ( !instance._allowInteraction( event ) ) { |
|
13074 event.preventDefault(); |
|
13075 instance._focusTabbable(); |
|
13076 |
|
13077 // Support: jQuery >=3.4 <3.6 only |
|
13078 // Focus re-triggering in jQuery 3.4/3.5 makes the original element |
|
13079 // have its focus event propagated last, breaking the re-targeting. |
|
13080 // Trigger focus in a delay in addition if needed to avoid the issue |
|
13081 // See https://github.com/jquery/jquery/issues/4382 |
|
13082 if ( jqMinor === "3.4." || jqMinor === "3.5." ) { |
|
13083 instance._delay( instance._restoreTabbableFocus ); |
|
13084 } |
|
13085 } |
|
13086 }.bind( this ) ); |
|
13087 } |
|
13088 |
|
13089 this.overlay = $( "<div>" ) |
|
13090 .appendTo( this._appendTo() ); |
|
13091 |
|
13092 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); |
|
13093 this._on( this.overlay, { |
|
13094 mousedown: "_keepFocus" |
|
13095 } ); |
|
13096 this.document.data( "ui-dialog-overlays", |
|
13097 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); |
|
13098 }, |
|
13099 |
|
13100 _destroyOverlay: function() { |
|
13101 if ( !this.options.modal ) { |
|
13102 return; |
|
13103 } |
|
13104 |
|
13105 if ( this.overlay ) { |
|
13106 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; |
|
13107 |
|
13108 if ( !overlays ) { |
|
13109 this.document.off( "focusin.ui-dialog" ); |
|
13110 this.document.removeData( "ui-dialog-overlays" ); |
|
13111 } else { |
|
13112 this.document.data( "ui-dialog-overlays", overlays ); |
|
13113 } |
|
13114 |
|
13115 this.overlay.remove(); |
|
13116 this.overlay = null; |
|
13117 } |
|
13118 } |
|
13119 } ); |
|
13120 |
|
13121 // DEPRECATED |
|
13122 // TODO: switch return back to widget declaration at top of file when this is removed |
|
13123 if ( $.uiBackCompat !== false ) { |
|
13124 |
|
13125 // Backcompat for dialogClass option |
|
13126 $.widget( "ui.dialog", $.ui.dialog, { |
|
13127 options: { |
|
13128 dialogClass: "" |
|
13129 }, |
|
13130 _createWrapper: function() { |
|
13131 this._super(); |
|
13132 this.uiDialog.addClass( this.options.dialogClass ); |
|
13133 }, |
|
13134 _setOption: function( key, value ) { |
|
13135 if ( key === "dialogClass" ) { |
|
13136 this.uiDialog |
|
13137 .removeClass( this.options.dialogClass ) |
|
13138 .addClass( value ); |
|
13139 } |
|
13140 this._superApply( arguments ); |
|
13141 } |
|
13142 } ); |
|
13143 } |
|
13144 |
|
13145 var widgetsDialog = $.ui.dialog; |
|
13146 |
|
13147 |
|
13148 /*! |
|
13149 * jQuery UI Droppable 1.13.2 |
|
13150 * http://jqueryui.com |
|
13151 * |
|
13152 * Copyright jQuery Foundation and other contributors |
|
13153 * Released under the MIT license. |
|
13154 * http://jquery.org/license |
|
13155 */ |
|
13156 |
|
13157 //>>label: Droppable |
|
13158 //>>group: Interactions |
|
13159 //>>description: Enables drop targets for draggable elements. |
|
13160 //>>docs: http://api.jqueryui.com/droppable/ |
|
13161 //>>demos: http://jqueryui.com/droppable/ |
|
13162 |
|
13163 |
|
13164 $.widget( "ui.droppable", { |
|
13165 version: "1.13.2", |
|
13166 widgetEventPrefix: "drop", |
|
13167 options: { |
|
13168 accept: "*", |
|
13169 addClasses: true, |
|
13170 greedy: false, |
|
13171 scope: "default", |
|
13172 tolerance: "intersect", |
|
13173 |
|
13174 // Callbacks |
|
13175 activate: null, |
|
13176 deactivate: null, |
|
13177 drop: null, |
|
13178 out: null, |
|
13179 over: null |
|
13180 }, |
|
13181 _create: function() { |
|
13182 |
|
13183 var proportions, |
|
13184 o = this.options, |
|
13185 accept = o.accept; |
|
13186 |
|
13187 this.isover = false; |
|
13188 this.isout = true; |
|
13189 |
|
13190 this.accept = typeof accept === "function" ? accept : function( d ) { |
|
13191 return d.is( accept ); |
|
13192 }; |
|
13193 |
|
13194 this.proportions = function( /* valueToWrite */ ) { |
|
13195 if ( arguments.length ) { |
|
13196 |
|
13197 // Store the droppable's proportions |
|
13198 proportions = arguments[ 0 ]; |
|
13199 } else { |
|
13200 |
|
13201 // Retrieve or derive the droppable's proportions |
|
13202 return proportions ? |
|
13203 proportions : |
|
13204 proportions = { |
|
13205 width: this.element[ 0 ].offsetWidth, |
|
13206 height: this.element[ 0 ].offsetHeight |
|
13207 }; |
|
13208 } |
|
13209 }; |
|
13210 |
|
13211 this._addToManager( o.scope ); |
|
13212 |
|
13213 if ( o.addClasses ) { |
|
13214 this._addClass( "ui-droppable" ); |
|
13215 } |
|
13216 |
|
13217 }, |
|
13218 |
|
13219 _addToManager: function( scope ) { |
|
13220 |
|
13221 // Add the reference and positions to the manager |
|
13222 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; |
|
13223 $.ui.ddmanager.droppables[ scope ].push( this ); |
|
13224 }, |
|
13225 |
|
13226 _splice: function( drop ) { |
|
13227 var i = 0; |
|
13228 for ( ; i < drop.length; i++ ) { |
|
13229 if ( drop[ i ] === this ) { |
|
13230 drop.splice( i, 1 ); |
|
13231 } |
|
13232 } |
|
13233 }, |
|
13234 |
|
13235 _destroy: function() { |
|
13236 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; |
|
13237 |
|
13238 this._splice( drop ); |
|
13239 }, |
|
13240 |
|
13241 _setOption: function( key, value ) { |
|
13242 |
|
13243 if ( key === "accept" ) { |
|
13244 this.accept = typeof value === "function" ? value : function( d ) { |
|
13245 return d.is( value ); |
|
13246 }; |
|
13247 } else if ( key === "scope" ) { |
|
13248 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; |
|
13249 |
|
13250 this._splice( drop ); |
|
13251 this._addToManager( value ); |
|
13252 } |
|
13253 |
|
13254 this._super( key, value ); |
|
13255 }, |
|
13256 |
|
13257 _activate: function( event ) { |
|
13258 var draggable = $.ui.ddmanager.current; |
|
13259 |
|
13260 this._addActiveClass(); |
|
13261 if ( draggable ) { |
|
13262 this._trigger( "activate", event, this.ui( draggable ) ); |
|
13263 } |
|
13264 }, |
|
13265 |
|
13266 _deactivate: function( event ) { |
|
13267 var draggable = $.ui.ddmanager.current; |
|
13268 |
|
13269 this._removeActiveClass(); |
|
13270 if ( draggable ) { |
|
13271 this._trigger( "deactivate", event, this.ui( draggable ) ); |
|
13272 } |
|
13273 }, |
|
13274 |
|
13275 _over: function( event ) { |
|
13276 |
|
13277 var draggable = $.ui.ddmanager.current; |
|
13278 |
|
13279 // Bail if draggable and droppable are same element |
|
13280 if ( !draggable || ( draggable.currentItem || |
|
13281 draggable.element )[ 0 ] === this.element[ 0 ] ) { |
|
13282 return; |
|
13283 } |
|
13284 |
|
13285 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || |
|
13286 draggable.element ) ) ) { |
|
13287 this._addHoverClass(); |
|
13288 this._trigger( "over", event, this.ui( draggable ) ); |
|
13289 } |
|
13290 |
|
13291 }, |
|
13292 |
|
13293 _out: function( event ) { |
|
13294 |
|
13295 var draggable = $.ui.ddmanager.current; |
|
13296 |
|
13297 // Bail if draggable and droppable are same element |
|
13298 if ( !draggable || ( draggable.currentItem || |
|
13299 draggable.element )[ 0 ] === this.element[ 0 ] ) { |
|
13300 return; |
|
13301 } |
|
13302 |
|
13303 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || |
|
13304 draggable.element ) ) ) { |
|
13305 this._removeHoverClass(); |
|
13306 this._trigger( "out", event, this.ui( draggable ) ); |
|
13307 } |
|
13308 |
|
13309 }, |
|
13310 |
|
13311 _drop: function( event, custom ) { |
|
13312 |
|
13313 var draggable = custom || $.ui.ddmanager.current, |
|
13314 childrenIntersection = false; |
|
13315 |
|
13316 // Bail if draggable and droppable are same element |
|
13317 if ( !draggable || ( draggable.currentItem || |
|
13318 draggable.element )[ 0 ] === this.element[ 0 ] ) { |
|
13319 return false; |
|
13320 } |
|
13321 |
|
13322 this.element |
|
13323 .find( ":data(ui-droppable)" ) |
|
13324 .not( ".ui-draggable-dragging" ) |
|
13325 .each( function() { |
|
13326 var inst = $( this ).droppable( "instance" ); |
|
13327 if ( |
|
13328 inst.options.greedy && |
|
13329 !inst.options.disabled && |
|
13330 inst.options.scope === draggable.options.scope && |
|
13331 inst.accept.call( |
|
13332 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) |
|
13333 ) && |
|
13334 $.ui.intersect( |
|
13335 draggable, |
|
13336 $.extend( inst, { offset: inst.element.offset() } ), |
|
13337 inst.options.tolerance, event |
|
13338 ) |
|
13339 ) { |
|
13340 childrenIntersection = true; |
|
13341 return false; |
|
13342 } |
|
13343 } ); |
|
13344 if ( childrenIntersection ) { |
|
13345 return false; |
|
13346 } |
|
13347 |
|
13348 if ( this.accept.call( this.element[ 0 ], |
|
13349 ( draggable.currentItem || draggable.element ) ) ) { |
|
13350 this._removeActiveClass(); |
|
13351 this._removeHoverClass(); |
|
13352 |
|
13353 this._trigger( "drop", event, this.ui( draggable ) ); |
|
13354 return this.element; |
|
13355 } |
|
13356 |
|
13357 return false; |
|
13358 |
|
13359 }, |
|
13360 |
|
13361 ui: function( c ) { |
|
13362 return { |
|
13363 draggable: ( c.currentItem || c.element ), |
|
13364 helper: c.helper, |
|
13365 position: c.position, |
|
13366 offset: c.positionAbs |
|
13367 }; |
|
13368 }, |
|
13369 |
|
13370 // Extension points just to make backcompat sane and avoid duplicating logic |
|
13371 // TODO: Remove in 1.14 along with call to it below |
|
13372 _addHoverClass: function() { |
|
13373 this._addClass( "ui-droppable-hover" ); |
|
13374 }, |
|
13375 |
|
13376 _removeHoverClass: function() { |
|
13377 this._removeClass( "ui-droppable-hover" ); |
|
13378 }, |
|
13379 |
|
13380 _addActiveClass: function() { |
|
13381 this._addClass( "ui-droppable-active" ); |
|
13382 }, |
|
13383 |
|
13384 _removeActiveClass: function() { |
|
13385 this._removeClass( "ui-droppable-active" ); |
|
13386 } |
|
13387 } ); |
|
13388 |
|
13389 $.ui.intersect = ( function() { |
|
13390 function isOverAxis( x, reference, size ) { |
|
13391 return ( x >= reference ) && ( x < ( reference + size ) ); |
|
13392 } |
|
13393 |
|
13394 return function( draggable, droppable, toleranceMode, event ) { |
|
13395 |
|
13396 if ( !droppable.offset ) { |
|
13397 return false; |
|
13398 } |
|
13399 |
|
13400 var x1 = ( draggable.positionAbs || |
|
13401 draggable.position.absolute ).left + draggable.margins.left, |
|
13402 y1 = ( draggable.positionAbs || |
|
13403 draggable.position.absolute ).top + draggable.margins.top, |
|
13404 x2 = x1 + draggable.helperProportions.width, |
|
13405 y2 = y1 + draggable.helperProportions.height, |
|
13406 l = droppable.offset.left, |
|
13407 t = droppable.offset.top, |
|
13408 r = l + droppable.proportions().width, |
|
13409 b = t + droppable.proportions().height; |
|
13410 |
|
13411 switch ( toleranceMode ) { |
|
13412 case "fit": |
|
13413 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); |
|
13414 case "intersect": |
|
13415 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half |
|
13416 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half |
|
13417 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half |
|
13418 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half |
|
13419 case "pointer": |
|
13420 return isOverAxis( event.pageY, t, droppable.proportions().height ) && |
|
13421 isOverAxis( event.pageX, l, droppable.proportions().width ); |
|
13422 case "touch": |
|
13423 return ( |
|
13424 ( y1 >= t && y1 <= b ) || // Top edge touching |
|
13425 ( y2 >= t && y2 <= b ) || // Bottom edge touching |
|
13426 ( y1 < t && y2 > b ) // Surrounded vertically |
|
13427 ) && ( |
|
13428 ( x1 >= l && x1 <= r ) || // Left edge touching |
|
13429 ( x2 >= l && x2 <= r ) || // Right edge touching |
|
13430 ( x1 < l && x2 > r ) // Surrounded horizontally |
|
13431 ); |
|
13432 default: |
|
13433 return false; |
|
13434 } |
|
13435 }; |
|
13436 } )(); |
|
13437 |
|
13438 /* |
|
13439 This manager tracks offsets of draggables and droppables |
|
13440 */ |
|
13441 $.ui.ddmanager = { |
|
13442 current: null, |
|
13443 droppables: { "default": [] }, |
|
13444 prepareOffsets: function( t, event ) { |
|
13445 |
|
13446 var i, j, |
|
13447 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], |
|
13448 type = event ? event.type : null, // workaround for #2317 |
|
13449 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); |
|
13450 |
|
13451 droppablesLoop: for ( i = 0; i < m.length; i++ ) { |
|
13452 |
|
13453 // No disabled and non-accepted |
|
13454 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], |
|
13455 ( t.currentItem || t.element ) ) ) ) { |
|
13456 continue; |
|
13457 } |
|
13458 |
|
13459 // Filter out elements in the current dragged item |
|
13460 for ( j = 0; j < list.length; j++ ) { |
|
13461 if ( list[ j ] === m[ i ].element[ 0 ] ) { |
|
13462 m[ i ].proportions().height = 0; |
|
13463 continue droppablesLoop; |
|
13464 } |
|
13465 } |
|
13466 |
|
13467 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; |
|
13468 if ( !m[ i ].visible ) { |
|
13469 continue; |
|
13470 } |
|
13471 |
|
13472 // Activate the droppable if used directly from draggables |
|
13473 if ( type === "mousedown" ) { |
|
13474 m[ i ]._activate.call( m[ i ], event ); |
|
13475 } |
|
13476 |
|
13477 m[ i ].offset = m[ i ].element.offset(); |
|
13478 m[ i ].proportions( { |
|
13479 width: m[ i ].element[ 0 ].offsetWidth, |
|
13480 height: m[ i ].element[ 0 ].offsetHeight |
|
13481 } ); |
|
13482 |
|
13483 } |
|
13484 |
|
13485 }, |
|
13486 drop: function( draggable, event ) { |
|
13487 |
|
13488 var dropped = false; |
|
13489 |
|
13490 // Create a copy of the droppables in case the list changes during the drop (#9116) |
|
13491 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { |
|
13492 |
|
13493 if ( !this.options ) { |
|
13494 return; |
|
13495 } |
|
13496 if ( !this.options.disabled && this.visible && |
|
13497 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { |
|
13498 dropped = this._drop.call( this, event ) || dropped; |
|
13499 } |
|
13500 |
|
13501 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], |
|
13502 ( draggable.currentItem || draggable.element ) ) ) { |
|
13503 this.isout = true; |
|
13504 this.isover = false; |
|
13505 this._deactivate.call( this, event ); |
|
13506 } |
|
13507 |
|
13508 } ); |
|
13509 return dropped; |
|
13510 |
|
13511 }, |
|
13512 dragStart: function( draggable, event ) { |
|
13513 |
|
13514 // Listen for scrolling so that if the dragging causes scrolling the position of the |
|
13515 // droppables can be recalculated (see #5003) |
|
13516 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { |
|
13517 if ( !draggable.options.refreshPositions ) { |
|
13518 $.ui.ddmanager.prepareOffsets( draggable, event ); |
|
13519 } |
|
13520 } ); |
|
13521 }, |
|
13522 drag: function( draggable, event ) { |
|
13523 |
|
13524 // If you have a highly dynamic page, you might try this option. It renders positions |
|
13525 // every time you move the mouse. |
|
13526 if ( draggable.options.refreshPositions ) { |
|
13527 $.ui.ddmanager.prepareOffsets( draggable, event ); |
|
13528 } |
|
13529 |
|
13530 // Run through all droppables and check their positions based on specific tolerance options |
|
13531 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { |
|
13532 |
|
13533 if ( this.options.disabled || this.greedyChild || !this.visible ) { |
|
13534 return; |
|
13535 } |
|
13536 |
|
13537 var parentInstance, scope, parent, |
|
13538 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), |
|
13539 c = !intersects && this.isover ? |
|
13540 "isout" : |
|
13541 ( intersects && !this.isover ? "isover" : null ); |
|
13542 if ( !c ) { |
|
13543 return; |
|
13544 } |
|
13545 |
|
13546 if ( this.options.greedy ) { |
|
13547 |
|
13548 // find droppable parents with same scope |
|
13549 scope = this.options.scope; |
|
13550 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { |
|
13551 return $( this ).droppable( "instance" ).options.scope === scope; |
|
13552 } ); |
|
13553 |
|
13554 if ( parent.length ) { |
|
13555 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); |
|
13556 parentInstance.greedyChild = ( c === "isover" ); |
|
13557 } |
|
13558 } |
|
13559 |
|
13560 // We just moved into a greedy child |
|
13561 if ( parentInstance && c === "isover" ) { |
|
13562 parentInstance.isover = false; |
|
13563 parentInstance.isout = true; |
|
13564 parentInstance._out.call( parentInstance, event ); |
|
13565 } |
|
13566 |
|
13567 this[ c ] = true; |
|
13568 this[ c === "isout" ? "isover" : "isout" ] = false; |
|
13569 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); |
|
13570 |
|
13571 // We just moved out of a greedy child |
|
13572 if ( parentInstance && c === "isout" ) { |
|
13573 parentInstance.isout = false; |
|
13574 parentInstance.isover = true; |
|
13575 parentInstance._over.call( parentInstance, event ); |
|
13576 } |
|
13577 } ); |
|
13578 |
|
13579 }, |
|
13580 dragStop: function( draggable, event ) { |
|
13581 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); |
|
13582 |
|
13583 // Call prepareOffsets one final time since IE does not fire return scroll events when |
|
13584 // overflow was caused by drag (see #5003) |
|
13585 if ( !draggable.options.refreshPositions ) { |
|
13586 $.ui.ddmanager.prepareOffsets( draggable, event ); |
|
13587 } |
|
13588 } |
|
13589 }; |
|
13590 |
|
13591 // DEPRECATED |
|
13592 // TODO: switch return back to widget declaration at top of file when this is removed |
|
13593 if ( $.uiBackCompat !== false ) { |
|
13594 |
|
13595 // Backcompat for activeClass and hoverClass options |
|
13596 $.widget( "ui.droppable", $.ui.droppable, { |
|
13597 options: { |
|
13598 hoverClass: false, |
|
13599 activeClass: false |
|
13600 }, |
|
13601 _addActiveClass: function() { |
|
13602 this._super(); |
|
13603 if ( this.options.activeClass ) { |
|
13604 this.element.addClass( this.options.activeClass ); |
|
13605 } |
|
13606 }, |
|
13607 _removeActiveClass: function() { |
|
13608 this._super(); |
|
13609 if ( this.options.activeClass ) { |
|
13610 this.element.removeClass( this.options.activeClass ); |
|
13611 } |
|
13612 }, |
|
13613 _addHoverClass: function() { |
|
13614 this._super(); |
|
13615 if ( this.options.hoverClass ) { |
|
13616 this.element.addClass( this.options.hoverClass ); |
|
13617 } |
|
13618 }, |
|
13619 _removeHoverClass: function() { |
|
13620 this._super(); |
|
13621 if ( this.options.hoverClass ) { |
|
13622 this.element.removeClass( this.options.hoverClass ); |
|
13623 } |
|
13624 } |
|
13625 } ); |
|
13626 } |
|
13627 |
|
13628 var widgetsDroppable = $.ui.droppable; |
|
13629 |
|
13630 |
|
13631 /*! |
|
13632 * jQuery UI Progressbar 1.13.2 |
|
13633 * http://jqueryui.com |
|
13634 * |
|
13635 * Copyright jQuery Foundation and other contributors |
|
13636 * Released under the MIT license. |
|
13637 * http://jquery.org/license |
|
13638 */ |
|
13639 |
|
13640 //>>label: Progressbar |
|
13641 //>>group: Widgets |
|
13642 /* eslint-disable max-len */ |
|
13643 //>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. |
|
13644 /* eslint-enable max-len */ |
|
13645 //>>docs: http://api.jqueryui.com/progressbar/ |
|
13646 //>>demos: http://jqueryui.com/progressbar/ |
|
13647 //>>css.structure: ../../themes/base/core.css |
|
13648 //>>css.structure: ../../themes/base/progressbar.css |
|
13649 //>>css.theme: ../../themes/base/theme.css |
|
13650 |
|
13651 |
|
13652 var widgetsProgressbar = $.widget( "ui.progressbar", { |
|
13653 version: "1.13.2", |
|
13654 options: { |
|
13655 classes: { |
|
13656 "ui-progressbar": "ui-corner-all", |
|
13657 "ui-progressbar-value": "ui-corner-left", |
|
13658 "ui-progressbar-complete": "ui-corner-right" |
|
13659 }, |
|
13660 max: 100, |
|
13661 value: 0, |
|
13662 |
|
13663 change: null, |
|
13664 complete: null |
|
13665 }, |
|
13666 |
|
13667 min: 0, |
|
13668 |
|
13669 _create: function() { |
|
13670 |
|
13671 // Constrain initial value |
|
13672 this.oldValue = this.options.value = this._constrainedValue(); |
|
13673 |
|
13674 this.element.attr( { |
|
13675 |
|
13676 // Only set static values; aria-valuenow and aria-valuemax are |
|
13677 // set inside _refreshValue() |
|
13678 role: "progressbar", |
|
13679 "aria-valuemin": this.min |
|
13680 } ); |
|
13681 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); |
|
13682 |
|
13683 this.valueDiv = $( "<div>" ).appendTo( this.element ); |
|
13684 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); |
|
13685 this._refreshValue(); |
|
13686 }, |
|
13687 |
|
13688 _destroy: function() { |
|
13689 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); |
|
13690 |
|
13691 this.valueDiv.remove(); |
|
13692 }, |
|
13693 |
|
13694 value: function( newValue ) { |
|
13695 if ( newValue === undefined ) { |
|
13696 return this.options.value; |
|
13697 } |
|
13698 |
|
13699 this.options.value = this._constrainedValue( newValue ); |
|
13700 this._refreshValue(); |
|
13701 }, |
|
13702 |
|
13703 _constrainedValue: function( newValue ) { |
|
13704 if ( newValue === undefined ) { |
|
13705 newValue = this.options.value; |
|
13706 } |
|
13707 |
|
13708 this.indeterminate = newValue === false; |
|
13709 |
|
13710 // Sanitize value |
|
13711 if ( typeof newValue !== "number" ) { |
|
13712 newValue = 0; |
|
13713 } |
|
13714 |
|
13715 return this.indeterminate ? false : |
|
13716 Math.min( this.options.max, Math.max( this.min, newValue ) ); |
|
13717 }, |
|
13718 |
|
13719 _setOptions: function( options ) { |
|
13720 |
|
13721 // Ensure "value" option is set after other values (like max) |
|
13722 var value = options.value; |
|
13723 delete options.value; |
|
13724 |
|
13725 this._super( options ); |
|
13726 |
|
13727 this.options.value = this._constrainedValue( value ); |
|
13728 this._refreshValue(); |
|
13729 }, |
|
13730 |
|
13731 _setOption: function( key, value ) { |
|
13732 if ( key === "max" ) { |
|
13733 |
|
13734 // Don't allow a max less than min |
|
13735 value = Math.max( this.min, value ); |
|
13736 } |
|
13737 this._super( key, value ); |
|
13738 }, |
|
13739 |
|
13740 _setOptionDisabled: function( value ) { |
|
13741 this._super( value ); |
|
13742 |
|
13743 this.element.attr( "aria-disabled", value ); |
|
13744 this._toggleClass( null, "ui-state-disabled", !!value ); |
|
13745 }, |
|
13746 |
|
13747 _percentage: function() { |
|
13748 return this.indeterminate ? |
|
13749 100 : |
|
13750 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); |
|
13751 }, |
|
13752 |
|
13753 _refreshValue: function() { |
|
13754 var value = this.options.value, |
|
13755 percentage = this._percentage(); |
|
13756 |
|
13757 this.valueDiv |
|
13758 .toggle( this.indeterminate || value > this.min ) |
|
13759 .width( percentage.toFixed( 0 ) + "%" ); |
|
13760 |
|
13761 this |
|
13762 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, |
|
13763 value === this.options.max ) |
|
13764 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); |
|
13765 |
|
13766 if ( this.indeterminate ) { |
|
13767 this.element.removeAttr( "aria-valuenow" ); |
|
13768 if ( !this.overlayDiv ) { |
|
13769 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); |
|
13770 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); |
|
13771 } |
|
13772 } else { |
|
13773 this.element.attr( { |
|
13774 "aria-valuemax": this.options.max, |
|
13775 "aria-valuenow": value |
|
13776 } ); |
|
13777 if ( this.overlayDiv ) { |
|
13778 this.overlayDiv.remove(); |
|
13779 this.overlayDiv = null; |
|
13780 } |
|
13781 } |
|
13782 |
|
13783 if ( this.oldValue !== value ) { |
|
13784 this.oldValue = value; |
|
13785 this._trigger( "change" ); |
|
13786 } |
|
13787 if ( value === this.options.max ) { |
|
13788 this._trigger( "complete" ); |
|
13789 } |
|
13790 } |
|
13791 } ); |
|
13792 |
|
13793 |
|
13794 /*! |
|
13795 * jQuery UI Selectable 1.13.2 |
|
13796 * http://jqueryui.com |
|
13797 * |
|
13798 * Copyright jQuery Foundation and other contributors |
|
13799 * Released under the MIT license. |
|
13800 * http://jquery.org/license |
|
13801 */ |
|
13802 |
|
13803 //>>label: Selectable |
|
13804 //>>group: Interactions |
|
13805 //>>description: Allows groups of elements to be selected with the mouse. |
|
13806 //>>docs: http://api.jqueryui.com/selectable/ |
|
13807 //>>demos: http://jqueryui.com/selectable/ |
|
13808 //>>css.structure: ../../themes/base/selectable.css |
|
13809 |
|
13810 |
|
13811 var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { |
|
13812 version: "1.13.2", |
|
13813 options: { |
|
13814 appendTo: "body", |
|
13815 autoRefresh: true, |
|
13816 distance: 0, |
|
13817 filter: "*", |
|
13818 tolerance: "touch", |
|
13819 |
|
13820 // Callbacks |
|
13821 selected: null, |
|
13822 selecting: null, |
|
13823 start: null, |
|
13824 stop: null, |
|
13825 unselected: null, |
|
13826 unselecting: null |
|
13827 }, |
|
13828 _create: function() { |
|
13829 var that = this; |
|
13830 |
|
13831 this._addClass( "ui-selectable" ); |
|
13832 |
|
13833 this.dragged = false; |
|
13834 |
|
13835 // Cache selectee children based on filter |
|
13836 this.refresh = function() { |
|
13837 that.elementPos = $( that.element[ 0 ] ).offset(); |
|
13838 that.selectees = $( that.options.filter, that.element[ 0 ] ); |
|
13839 that._addClass( that.selectees, "ui-selectee" ); |
|
13840 that.selectees.each( function() { |
|
13841 var $this = $( this ), |
|
13842 selecteeOffset = $this.offset(), |
|
13843 pos = { |
|
13844 left: selecteeOffset.left - that.elementPos.left, |
|
13845 top: selecteeOffset.top - that.elementPos.top |
|
13846 }; |
|
13847 $.data( this, "selectable-item", { |
|
13848 element: this, |
|
13849 $element: $this, |
|
13850 left: pos.left, |
|
13851 top: pos.top, |
|
13852 right: pos.left + $this.outerWidth(), |
|
13853 bottom: pos.top + $this.outerHeight(), |
|
13854 startselected: false, |
|
13855 selected: $this.hasClass( "ui-selected" ), |
|
13856 selecting: $this.hasClass( "ui-selecting" ), |
|
13857 unselecting: $this.hasClass( "ui-unselecting" ) |
|
13858 } ); |
|
13859 } ); |
|
13860 }; |
|
13861 this.refresh(); |
|
13862 |
|
13863 this._mouseInit(); |
|
13864 |
|
13865 this.helper = $( "<div>" ); |
|
13866 this._addClass( this.helper, "ui-selectable-helper" ); |
|
13867 }, |
|
13868 |
|
13869 _destroy: function() { |
|
13870 this.selectees.removeData( "selectable-item" ); |
|
13871 this._mouseDestroy(); |
|
13872 }, |
|
13873 |
|
13874 _mouseStart: function( event ) { |
|
13875 var that = this, |
|
13876 options = this.options; |
|
13877 |
|
13878 this.opos = [ event.pageX, event.pageY ]; |
|
13879 this.elementPos = $( this.element[ 0 ] ).offset(); |
|
13880 |
|
13881 if ( this.options.disabled ) { |
|
13882 return; |
|
13883 } |
|
13884 |
|
13885 this.selectees = $( options.filter, this.element[ 0 ] ); |
|
13886 |
|
13887 this._trigger( "start", event ); |
|
13888 |
|
13889 $( options.appendTo ).append( this.helper ); |
|
13890 |
|
13891 // position helper (lasso) |
|
13892 this.helper.css( { |
|
13893 "left": event.pageX, |
|
13894 "top": event.pageY, |
|
13895 "width": 0, |
|
13896 "height": 0 |
|
13897 } ); |
|
13898 |
|
13899 if ( options.autoRefresh ) { |
|
13900 this.refresh(); |
|
13901 } |
|
13902 |
|
13903 this.selectees.filter( ".ui-selected" ).each( function() { |
|
13904 var selectee = $.data( this, "selectable-item" ); |
|
13905 selectee.startselected = true; |
|
13906 if ( !event.metaKey && !event.ctrlKey ) { |
|
13907 that._removeClass( selectee.$element, "ui-selected" ); |
|
13908 selectee.selected = false; |
|
13909 that._addClass( selectee.$element, "ui-unselecting" ); |
|
13910 selectee.unselecting = true; |
|
13911 |
|
13912 // selectable UNSELECTING callback |
|
13913 that._trigger( "unselecting", event, { |
|
13914 unselecting: selectee.element |
|
13915 } ); |
|
13916 } |
|
13917 } ); |
|
13918 |
|
13919 $( event.target ).parents().addBack().each( function() { |
|
13920 var doSelect, |
|
13921 selectee = $.data( this, "selectable-item" ); |
|
13922 if ( selectee ) { |
|
13923 doSelect = ( !event.metaKey && !event.ctrlKey ) || |
|
13924 !selectee.$element.hasClass( "ui-selected" ); |
|
13925 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) |
|
13926 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); |
|
13927 selectee.unselecting = !doSelect; |
|
13928 selectee.selecting = doSelect; |
|
13929 selectee.selected = doSelect; |
|
13930 |
|
13931 // selectable (UN)SELECTING callback |
|
13932 if ( doSelect ) { |
|
13933 that._trigger( "selecting", event, { |
|
13934 selecting: selectee.element |
|
13935 } ); |
|
13936 } else { |
|
13937 that._trigger( "unselecting", event, { |
|
13938 unselecting: selectee.element |
|
13939 } ); |
|
13940 } |
|
13941 return false; |
|
13942 } |
|
13943 } ); |
|
13944 |
|
13945 }, |
|
13946 |
|
13947 _mouseDrag: function( event ) { |
|
13948 |
|
13949 this.dragged = true; |
|
13950 |
|
13951 if ( this.options.disabled ) { |
|
13952 return; |
|
13953 } |
|
13954 |
|
13955 var tmp, |
|
13956 that = this, |
|
13957 options = this.options, |
|
13958 x1 = this.opos[ 0 ], |
|
13959 y1 = this.opos[ 1 ], |
|
13960 x2 = event.pageX, |
|
13961 y2 = event.pageY; |
|
13962 |
|
13963 if ( x1 > x2 ) { |
|
13964 tmp = x2; x2 = x1; x1 = tmp; |
|
13965 } |
|
13966 if ( y1 > y2 ) { |
|
13967 tmp = y2; y2 = y1; y1 = tmp; |
|
13968 } |
|
13969 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); |
|
13970 |
|
13971 this.selectees.each( function() { |
|
13972 var selectee = $.data( this, "selectable-item" ), |
|
13973 hit = false, |
|
13974 offset = {}; |
|
13975 |
|
13976 //prevent helper from being selected if appendTo: selectable |
|
13977 if ( !selectee || selectee.element === that.element[ 0 ] ) { |
|
13978 return; |
|
13979 } |
|
13980 |
|
13981 offset.left = selectee.left + that.elementPos.left; |
|
13982 offset.right = selectee.right + that.elementPos.left; |
|
13983 offset.top = selectee.top + that.elementPos.top; |
|
13984 offset.bottom = selectee.bottom + that.elementPos.top; |
|
13985 |
|
13986 if ( options.tolerance === "touch" ) { |
|
13987 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || |
|
13988 offset.bottom < y1 ) ); |
|
13989 } else if ( options.tolerance === "fit" ) { |
|
13990 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && |
|
13991 offset.bottom < y2 ); |
|
13992 } |
|
13993 |
|
13994 if ( hit ) { |
|
13995 |
|
13996 // SELECT |
|
13997 if ( selectee.selected ) { |
|
13998 that._removeClass( selectee.$element, "ui-selected" ); |
|
13999 selectee.selected = false; |
|
14000 } |
|
14001 if ( selectee.unselecting ) { |
|
14002 that._removeClass( selectee.$element, "ui-unselecting" ); |
|
14003 selectee.unselecting = false; |
|
14004 } |
|
14005 if ( !selectee.selecting ) { |
|
14006 that._addClass( selectee.$element, "ui-selecting" ); |
|
14007 selectee.selecting = true; |
|
14008 |
|
14009 // selectable SELECTING callback |
|
14010 that._trigger( "selecting", event, { |
|
14011 selecting: selectee.element |
|
14012 } ); |
|
14013 } |
|
14014 } else { |
|
14015 |
|
14016 // UNSELECT |
|
14017 if ( selectee.selecting ) { |
|
14018 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { |
|
14019 that._removeClass( selectee.$element, "ui-selecting" ); |
|
14020 selectee.selecting = false; |
|
14021 that._addClass( selectee.$element, "ui-selected" ); |
|
14022 selectee.selected = true; |
|
14023 } else { |
|
14024 that._removeClass( selectee.$element, "ui-selecting" ); |
|
14025 selectee.selecting = false; |
|
14026 if ( selectee.startselected ) { |
|
14027 that._addClass( selectee.$element, "ui-unselecting" ); |
|
14028 selectee.unselecting = true; |
|
14029 } |
|
14030 |
|
14031 // selectable UNSELECTING callback |
|
14032 that._trigger( "unselecting", event, { |
|
14033 unselecting: selectee.element |
|
14034 } ); |
|
14035 } |
|
14036 } |
|
14037 if ( selectee.selected ) { |
|
14038 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { |
|
14039 that._removeClass( selectee.$element, "ui-selected" ); |
|
14040 selectee.selected = false; |
|
14041 |
|
14042 that._addClass( selectee.$element, "ui-unselecting" ); |
|
14043 selectee.unselecting = true; |
|
14044 |
|
14045 // selectable UNSELECTING callback |
|
14046 that._trigger( "unselecting", event, { |
|
14047 unselecting: selectee.element |
|
14048 } ); |
|
14049 } |
|
14050 } |
|
14051 } |
|
14052 } ); |
|
14053 |
|
14054 return false; |
|
14055 }, |
|
14056 |
|
14057 _mouseStop: function( event ) { |
|
14058 var that = this; |
|
14059 |
|
14060 this.dragged = false; |
|
14061 |
|
14062 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { |
|
14063 var selectee = $.data( this, "selectable-item" ); |
|
14064 that._removeClass( selectee.$element, "ui-unselecting" ); |
|
14065 selectee.unselecting = false; |
|
14066 selectee.startselected = false; |
|
14067 that._trigger( "unselected", event, { |
|
14068 unselected: selectee.element |
|
14069 } ); |
|
14070 } ); |
|
14071 $( ".ui-selecting", this.element[ 0 ] ).each( function() { |
|
14072 var selectee = $.data( this, "selectable-item" ); |
|
14073 that._removeClass( selectee.$element, "ui-selecting" ) |
|
14074 ._addClass( selectee.$element, "ui-selected" ); |
|
14075 selectee.selecting = false; |
|
14076 selectee.selected = true; |
|
14077 selectee.startselected = true; |
|
14078 that._trigger( "selected", event, { |
|
14079 selected: selectee.element |
|
14080 } ); |
|
14081 } ); |
|
14082 this._trigger( "stop", event ); |
|
14083 |
|
14084 this.helper.remove(); |
|
14085 |
|
14086 return false; |
|
14087 } |
|
14088 |
|
14089 } ); |
|
14090 |
|
14091 |
|
14092 /*! |
|
14093 * jQuery UI Selectmenu 1.13.2 |
|
14094 * http://jqueryui.com |
|
14095 * |
|
14096 * Copyright jQuery Foundation and other contributors |
|
14097 * Released under the MIT license. |
|
14098 * http://jquery.org/license |
|
14099 */ |
|
14100 |
|
14101 //>>label: Selectmenu |
|
14102 //>>group: Widgets |
|
14103 /* eslint-disable max-len */ |
|
14104 //>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. |
|
14105 /* eslint-enable max-len */ |
|
14106 //>>docs: http://api.jqueryui.com/selectmenu/ |
|
14107 //>>demos: http://jqueryui.com/selectmenu/ |
|
14108 //>>css.structure: ../../themes/base/core.css |
|
14109 //>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css |
|
14110 //>>css.theme: ../../themes/base/theme.css |
|
14111 |
|
14112 |
|
14113 var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { |
|
14114 version: "1.13.2", |
|
14115 defaultElement: "<select>", |
|
14116 options: { |
|
14117 appendTo: null, |
|
14118 classes: { |
|
14119 "ui-selectmenu-button-open": "ui-corner-top", |
|
14120 "ui-selectmenu-button-closed": "ui-corner-all" |
|
14121 }, |
|
14122 disabled: null, |
|
14123 icons: { |
|
14124 button: "ui-icon-triangle-1-s" |
|
14125 }, |
|
14126 position: { |
|
14127 my: "left top", |
|
14128 at: "left bottom", |
|
14129 collision: "none" |
|
14130 }, |
|
14131 width: false, |
|
14132 |
|
14133 // Callbacks |
|
14134 change: null, |
|
14135 close: null, |
|
14136 focus: null, |
|
14137 open: null, |
|
14138 select: null |
|
14139 }, |
|
14140 |
|
14141 _create: function() { |
|
14142 var selectmenuId = this.element.uniqueId().attr( "id" ); |
|
14143 this.ids = { |
|
14144 element: selectmenuId, |
|
14145 button: selectmenuId + "-button", |
|
14146 menu: selectmenuId + "-menu" |
|
14147 }; |
|
14148 |
|
14149 this._drawButton(); |
|
14150 this._drawMenu(); |
|
14151 this._bindFormResetHandler(); |
|
14152 |
|
14153 this._rendered = false; |
|
14154 this.menuItems = $(); |
|
14155 }, |
|
14156 |
|
14157 _drawButton: function() { |
|
14158 var icon, |
|
14159 that = this, |
|
14160 item = this._parseOption( |
|
14161 this.element.find( "option:selected" ), |
|
14162 this.element[ 0 ].selectedIndex |
|
14163 ); |
|
14164 |
|
14165 // Associate existing label with the new button |
|
14166 this.labels = this.element.labels().attr( "for", this.ids.button ); |
|
14167 this._on( this.labels, { |
|
14168 click: function( event ) { |
|
14169 this.button.trigger( "focus" ); |
|
14170 event.preventDefault(); |
|
14171 } |
|
14172 } ); |
|
14173 |
|
14174 // Hide original select element |
|
14175 this.element.hide(); |
|
14176 |
|
14177 // Create button |
|
14178 this.button = $( "<span>", { |
|
14179 tabindex: this.options.disabled ? -1 : 0, |
|
14180 id: this.ids.button, |
|
14181 role: "combobox", |
|
14182 "aria-expanded": "false", |
|
14183 "aria-autocomplete": "list", |
|
14184 "aria-owns": this.ids.menu, |
|
14185 "aria-haspopup": "true", |
|
14186 title: this.element.attr( "title" ) |
|
14187 } ) |
|
14188 .insertAfter( this.element ); |
|
14189 |
|
14190 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", |
|
14191 "ui-button ui-widget" ); |
|
14192 |
|
14193 icon = $( "<span>" ).appendTo( this.button ); |
|
14194 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); |
|
14195 this.buttonItem = this._renderButtonItem( item ) |
|
14196 .appendTo( this.button ); |
|
14197 |
|
14198 if ( this.options.width !== false ) { |
|
14199 this._resizeButton(); |
|
14200 } |
|
14201 |
|
14202 this._on( this.button, this._buttonEvents ); |
|
14203 this.button.one( "focusin", function() { |
|
14204 |
|
14205 // Delay rendering the menu items until the button receives focus. |
|
14206 // The menu may have already been rendered via a programmatic open. |
|
14207 if ( !that._rendered ) { |
|
14208 that._refreshMenu(); |
|
14209 } |
|
14210 } ); |
|
14211 }, |
|
14212 |
|
14213 _drawMenu: function() { |
|
14214 var that = this; |
|
14215 |
|
14216 // Create menu |
|
14217 this.menu = $( "<ul>", { |
|
14218 "aria-hidden": "true", |
|
14219 "aria-labelledby": this.ids.button, |
|
14220 id: this.ids.menu |
|
14221 } ); |
|
14222 |
|
14223 // Wrap menu |
|
14224 this.menuWrap = $( "<div>" ).append( this.menu ); |
|
14225 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); |
|
14226 this.menuWrap.appendTo( this._appendTo() ); |
|
14227 |
|
14228 // Initialize menu widget |
|
14229 this.menuInstance = this.menu |
|
14230 .menu( { |
|
14231 classes: { |
|
14232 "ui-menu": "ui-corner-bottom" |
|
14233 }, |
|
14234 role: "listbox", |
|
14235 select: function( event, ui ) { |
|
14236 event.preventDefault(); |
|
14237 |
|
14238 // Support: IE8 |
|
14239 // If the item was selected via a click, the text selection |
|
14240 // will be destroyed in IE |
|
14241 that._setSelection(); |
|
14242 |
|
14243 that._select( ui.item.data( "ui-selectmenu-item" ), event ); |
|
14244 }, |
|
14245 focus: function( event, ui ) { |
|
14246 var item = ui.item.data( "ui-selectmenu-item" ); |
|
14247 |
|
14248 // Prevent inital focus from firing and check if its a newly focused item |
|
14249 if ( that.focusIndex != null && item.index !== that.focusIndex ) { |
|
14250 that._trigger( "focus", event, { item: item } ); |
|
14251 if ( !that.isOpen ) { |
|
14252 that._select( item, event ); |
|
14253 } |
|
14254 } |
|
14255 that.focusIndex = item.index; |
|
14256 |
|
14257 that.button.attr( "aria-activedescendant", |
|
14258 that.menuItems.eq( item.index ).attr( "id" ) ); |
|
14259 } |
|
14260 } ) |
|
14261 .menu( "instance" ); |
|
14262 |
|
14263 // Don't close the menu on mouseleave |
|
14264 this.menuInstance._off( this.menu, "mouseleave" ); |
|
14265 |
|
14266 // Cancel the menu's collapseAll on document click |
|
14267 this.menuInstance._closeOnDocumentClick = function() { |
|
14268 return false; |
|
14269 }; |
|
14270 |
|
14271 // Selects often contain empty items, but never contain dividers |
|
14272 this.menuInstance._isDivider = function() { |
|
14273 return false; |
|
14274 }; |
|
14275 }, |
|
14276 |
|
14277 refresh: function() { |
|
14278 this._refreshMenu(); |
|
14279 this.buttonItem.replaceWith( |
|
14280 this.buttonItem = this._renderButtonItem( |
|
14281 |
|
14282 // Fall back to an empty object in case there are no options |
|
14283 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} |
|
14284 ) |
|
14285 ); |
|
14286 if ( this.options.width === null ) { |
|
14287 this._resizeButton(); |
|
14288 } |
|
14289 }, |
|
14290 |
|
14291 _refreshMenu: function() { |
|
14292 var item, |
|
14293 options = this.element.find( "option" ); |
|
14294 |
|
14295 this.menu.empty(); |
|
14296 |
|
14297 this._parseOptions( options ); |
|
14298 this._renderMenu( this.menu, this.items ); |
|
14299 |
|
14300 this.menuInstance.refresh(); |
|
14301 this.menuItems = this.menu.find( "li" ) |
|
14302 .not( ".ui-selectmenu-optgroup" ) |
|
14303 .find( ".ui-menu-item-wrapper" ); |
|
14304 |
|
14305 this._rendered = true; |
|
14306 |
|
14307 if ( !options.length ) { |
|
14308 return; |
|
14309 } |
|
14310 |
|
14311 item = this._getSelectedItem(); |
|
14312 |
|
14313 // Update the menu to have the correct item focused |
|
14314 this.menuInstance.focus( null, item ); |
|
14315 this._setAria( item.data( "ui-selectmenu-item" ) ); |
|
14316 |
|
14317 // Set disabled state |
|
14318 this._setOption( "disabled", this.element.prop( "disabled" ) ); |
|
14319 }, |
|
14320 |
|
14321 open: function( event ) { |
|
14322 if ( this.options.disabled ) { |
|
14323 return; |
|
14324 } |
|
14325 |
|
14326 // If this is the first time the menu is being opened, render the items |
|
14327 if ( !this._rendered ) { |
|
14328 this._refreshMenu(); |
|
14329 } else { |
|
14330 |
|
14331 // Menu clears focus on close, reset focus to selected item |
|
14332 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); |
|
14333 this.menuInstance.focus( null, this._getSelectedItem() ); |
|
14334 } |
|
14335 |
|
14336 // If there are no options, don't open the menu |
|
14337 if ( !this.menuItems.length ) { |
|
14338 return; |
|
14339 } |
|
14340 |
|
14341 this.isOpen = true; |
|
14342 this._toggleAttr(); |
|
14343 this._resizeMenu(); |
|
14344 this._position(); |
|
14345 |
|
14346 this._on( this.document, this._documentClick ); |
|
14347 |
|
14348 this._trigger( "open", event ); |
|
14349 }, |
|
14350 |
|
14351 _position: function() { |
|
14352 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); |
|
14353 }, |
|
14354 |
|
14355 close: function( event ) { |
|
14356 if ( !this.isOpen ) { |
|
14357 return; |
|
14358 } |
|
14359 |
|
14360 this.isOpen = false; |
|
14361 this._toggleAttr(); |
|
14362 |
|
14363 this.range = null; |
|
14364 this._off( this.document ); |
|
14365 |
|
14366 this._trigger( "close", event ); |
|
14367 }, |
|
14368 |
|
14369 widget: function() { |
|
14370 return this.button; |
|
14371 }, |
|
14372 |
|
14373 menuWidget: function() { |
|
14374 return this.menu; |
|
14375 }, |
|
14376 |
|
14377 _renderButtonItem: function( item ) { |
|
14378 var buttonItem = $( "<span>" ); |
|
14379 |
|
14380 this._setText( buttonItem, item.label ); |
|
14381 this._addClass( buttonItem, "ui-selectmenu-text" ); |
|
14382 |
|
14383 return buttonItem; |
|
14384 }, |
|
14385 |
|
14386 _renderMenu: function( ul, items ) { |
|
14387 var that = this, |
|
14388 currentOptgroup = ""; |
|
14389 |
|
14390 $.each( items, function( index, item ) { |
|
14391 var li; |
|
14392 |
|
14393 if ( item.optgroup !== currentOptgroup ) { |
|
14394 li = $( "<li>", { |
|
14395 text: item.optgroup |
|
14396 } ); |
|
14397 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + |
|
14398 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? |
|
14399 " ui-state-disabled" : |
|
14400 "" ) ); |
|
14401 |
|
14402 li.appendTo( ul ); |
|
14403 |
|
14404 currentOptgroup = item.optgroup; |
|
14405 } |
|
14406 |
|
14407 that._renderItemData( ul, item ); |
|
14408 } ); |
|
14409 }, |
|
14410 |
|
14411 _renderItemData: function( ul, item ) { |
|
14412 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); |
|
14413 }, |
|
14414 |
|
14415 _renderItem: function( ul, item ) { |
|
14416 var li = $( "<li>" ), |
|
14417 wrapper = $( "<div>", { |
|
14418 title: item.element.attr( "title" ) |
|
14419 } ); |
|
14420 |
|
14421 if ( item.disabled ) { |
|
14422 this._addClass( li, null, "ui-state-disabled" ); |
|
14423 } |
|
14424 this._setText( wrapper, item.label ); |
|
14425 |
|
14426 return li.append( wrapper ).appendTo( ul ); |
|
14427 }, |
|
14428 |
|
14429 _setText: function( element, value ) { |
|
14430 if ( value ) { |
|
14431 element.text( value ); |
|
14432 } else { |
|
14433 element.html( " " ); |
|
14434 } |
|
14435 }, |
|
14436 |
|
14437 _move: function( direction, event ) { |
|
14438 var item, next, |
|
14439 filter = ".ui-menu-item"; |
|
14440 |
|
14441 if ( this.isOpen ) { |
|
14442 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); |
|
14443 } else { |
|
14444 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); |
|
14445 filter += ":not(.ui-state-disabled)"; |
|
14446 } |
|
14447 |
|
14448 if ( direction === "first" || direction === "last" ) { |
|
14449 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); |
|
14450 } else { |
|
14451 next = item[ direction + "All" ]( filter ).eq( 0 ); |
|
14452 } |
|
14453 |
|
14454 if ( next.length ) { |
|
14455 this.menuInstance.focus( event, next ); |
|
14456 } |
|
14457 }, |
|
14458 |
|
14459 _getSelectedItem: function() { |
|
14460 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); |
|
14461 }, |
|
14462 |
|
14463 _toggle: function( event ) { |
|
14464 this[ this.isOpen ? "close" : "open" ]( event ); |
|
14465 }, |
|
14466 |
|
14467 _setSelection: function() { |
|
14468 var selection; |
|
14469 |
|
14470 if ( !this.range ) { |
|
14471 return; |
|
14472 } |
|
14473 |
|
14474 if ( window.getSelection ) { |
|
14475 selection = window.getSelection(); |
|
14476 selection.removeAllRanges(); |
|
14477 selection.addRange( this.range ); |
|
14478 |
|
14479 // Support: IE8 |
|
14480 } else { |
|
14481 this.range.select(); |
|
14482 } |
|
14483 |
|
14484 // Support: IE |
|
14485 // Setting the text selection kills the button focus in IE, but |
|
14486 // restoring the focus doesn't kill the selection. |
|
14487 this.button.trigger( "focus" ); |
|
14488 }, |
|
14489 |
|
14490 _documentClick: { |
|
14491 mousedown: function( event ) { |
|
14492 if ( !this.isOpen ) { |
|
14493 return; |
|
14494 } |
|
14495 |
|
14496 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + |
|
14497 $.escapeSelector( this.ids.button ) ).length ) { |
|
14498 this.close( event ); |
|
14499 } |
|
14500 } |
|
14501 }, |
|
14502 |
|
14503 _buttonEvents: { |
|
14504 |
|
14505 // Prevent text selection from being reset when interacting with the selectmenu (#10144) |
|
14506 mousedown: function() { |
|
14507 var selection; |
|
14508 |
|
14509 if ( window.getSelection ) { |
|
14510 selection = window.getSelection(); |
|
14511 if ( selection.rangeCount ) { |
|
14512 this.range = selection.getRangeAt( 0 ); |
|
14513 } |
|
14514 |
|
14515 // Support: IE8 |
|
14516 } else { |
|
14517 this.range = document.selection.createRange(); |
|
14518 } |
|
14519 }, |
|
14520 |
|
14521 click: function( event ) { |
|
14522 this._setSelection(); |
|
14523 this._toggle( event ); |
|
14524 }, |
|
14525 |
|
14526 keydown: function( event ) { |
|
14527 var preventDefault = true; |
|
14528 switch ( event.keyCode ) { |
|
14529 case $.ui.keyCode.TAB: |
|
14530 case $.ui.keyCode.ESCAPE: |
|
14531 this.close( event ); |
|
14532 preventDefault = false; |
|
14533 break; |
|
14534 case $.ui.keyCode.ENTER: |
|
14535 if ( this.isOpen ) { |
|
14536 this._selectFocusedItem( event ); |
|
14537 } |
|
14538 break; |
|
14539 case $.ui.keyCode.UP: |
|
14540 if ( event.altKey ) { |
|
14541 this._toggle( event ); |
|
14542 } else { |
|
14543 this._move( "prev", event ); |
|
14544 } |
|
14545 break; |
|
14546 case $.ui.keyCode.DOWN: |
|
14547 if ( event.altKey ) { |
|
14548 this._toggle( event ); |
|
14549 } else { |
|
14550 this._move( "next", event ); |
|
14551 } |
|
14552 break; |
|
14553 case $.ui.keyCode.SPACE: |
|
14554 if ( this.isOpen ) { |
|
14555 this._selectFocusedItem( event ); |
|
14556 } else { |
|
14557 this._toggle( event ); |
|
14558 } |
|
14559 break; |
|
14560 case $.ui.keyCode.LEFT: |
|
14561 this._move( "prev", event ); |
|
14562 break; |
|
14563 case $.ui.keyCode.RIGHT: |
|
14564 this._move( "next", event ); |
|
14565 break; |
|
14566 case $.ui.keyCode.HOME: |
|
14567 case $.ui.keyCode.PAGE_UP: |
|
14568 this._move( "first", event ); |
|
14569 break; |
|
14570 case $.ui.keyCode.END: |
|
14571 case $.ui.keyCode.PAGE_DOWN: |
|
14572 this._move( "last", event ); |
|
14573 break; |
|
14574 default: |
|
14575 this.menu.trigger( event ); |
|
14576 preventDefault = false; |
|
14577 } |
|
14578 |
|
14579 if ( preventDefault ) { |
|
14580 event.preventDefault(); |
|
14581 } |
|
14582 } |
|
14583 }, |
|
14584 |
|
14585 _selectFocusedItem: function( event ) { |
|
14586 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); |
|
14587 if ( !item.hasClass( "ui-state-disabled" ) ) { |
|
14588 this._select( item.data( "ui-selectmenu-item" ), event ); |
|
14589 } |
|
14590 }, |
|
14591 |
|
14592 _select: function( item, event ) { |
|
14593 var oldIndex = this.element[ 0 ].selectedIndex; |
|
14594 |
|
14595 // Change native select element |
|
14596 this.element[ 0 ].selectedIndex = item.index; |
|
14597 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); |
|
14598 this._setAria( item ); |
|
14599 this._trigger( "select", event, { item: item } ); |
|
14600 |
|
14601 if ( item.index !== oldIndex ) { |
|
14602 this._trigger( "change", event, { item: item } ); |
|
14603 } |
|
14604 |
|
14605 this.close( event ); |
|
14606 }, |
|
14607 |
|
14608 _setAria: function( item ) { |
|
14609 var id = this.menuItems.eq( item.index ).attr( "id" ); |
|
14610 |
|
14611 this.button.attr( { |
|
14612 "aria-labelledby": id, |
|
14613 "aria-activedescendant": id |
|
14614 } ); |
|
14615 this.menu.attr( "aria-activedescendant", id ); |
|
14616 }, |
|
14617 |
|
14618 _setOption: function( key, value ) { |
|
14619 if ( key === "icons" ) { |
|
14620 var icon = this.button.find( "span.ui-icon" ); |
|
14621 this._removeClass( icon, null, this.options.icons.button ) |
|
14622 ._addClass( icon, null, value.button ); |
|
14623 } |
|
14624 |
|
14625 this._super( key, value ); |
|
14626 |
|
14627 if ( key === "appendTo" ) { |
|
14628 this.menuWrap.appendTo( this._appendTo() ); |
|
14629 } |
|
14630 |
|
14631 if ( key === "width" ) { |
|
14632 this._resizeButton(); |
|
14633 } |
|
14634 }, |
|
14635 |
|
14636 _setOptionDisabled: function( value ) { |
|
14637 this._super( value ); |
|
14638 |
|
14639 this.menuInstance.option( "disabled", value ); |
|
14640 this.button.attr( "aria-disabled", value ); |
|
14641 this._toggleClass( this.button, null, "ui-state-disabled", value ); |
|
14642 |
|
14643 this.element.prop( "disabled", value ); |
|
14644 if ( value ) { |
|
14645 this.button.attr( "tabindex", -1 ); |
|
14646 this.close(); |
|
14647 } else { |
|
14648 this.button.attr( "tabindex", 0 ); |
|
14649 } |
|
14650 }, |
|
14651 |
|
14652 _appendTo: function() { |
|
14653 var element = this.options.appendTo; |
|
14654 |
|
14655 if ( element ) { |
|
14656 element = element.jquery || element.nodeType ? |
|
14657 $( element ) : |
|
14658 this.document.find( element ).eq( 0 ); |
|
14659 } |
|
14660 |
|
14661 if ( !element || !element[ 0 ] ) { |
|
14662 element = this.element.closest( ".ui-front, dialog" ); |
|
14663 } |
|
14664 |
|
14665 if ( !element.length ) { |
|
14666 element = this.document[ 0 ].body; |
|
14667 } |
|
14668 |
|
14669 return element; |
|
14670 }, |
|
14671 |
|
14672 _toggleAttr: function() { |
|
14673 this.button.attr( "aria-expanded", this.isOpen ); |
|
14674 |
|
14675 // We can't use two _toggleClass() calls here, because we need to make sure |
|
14676 // we always remove classes first and add them second, otherwise if both classes have the |
|
14677 // same theme class, it will be removed after we add it. |
|
14678 this._removeClass( this.button, "ui-selectmenu-button-" + |
|
14679 ( this.isOpen ? "closed" : "open" ) ) |
|
14680 ._addClass( this.button, "ui-selectmenu-button-" + |
|
14681 ( this.isOpen ? "open" : "closed" ) ) |
|
14682 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); |
|
14683 |
|
14684 this.menu.attr( "aria-hidden", !this.isOpen ); |
|
14685 }, |
|
14686 |
|
14687 _resizeButton: function() { |
|
14688 var width = this.options.width; |
|
14689 |
|
14690 // For `width: false`, just remove inline style and stop |
|
14691 if ( width === false ) { |
|
14692 this.button.css( "width", "" ); |
|
14693 return; |
|
14694 } |
|
14695 |
|
14696 // For `width: null`, match the width of the original element |
|
14697 if ( width === null ) { |
|
14698 width = this.element.show().outerWidth(); |
|
14699 this.element.hide(); |
|
14700 } |
|
14701 |
|
14702 this.button.outerWidth( width ); |
|
14703 }, |
|
14704 |
|
14705 _resizeMenu: function() { |
|
14706 this.menu.outerWidth( Math.max( |
|
14707 this.button.outerWidth(), |
|
14708 |
|
14709 // Support: IE10 |
|
14710 // IE10 wraps long text (possibly a rounding bug) |
|
14711 // so we add 1px to avoid the wrapping |
|
14712 this.menu.width( "" ).outerWidth() + 1 |
|
14713 ) ); |
|
14714 }, |
|
14715 |
|
14716 _getCreateOptions: function() { |
|
14717 var options = this._super(); |
|
14718 |
|
14719 options.disabled = this.element.prop( "disabled" ); |
|
14720 |
|
14721 return options; |
|
14722 }, |
|
14723 |
|
14724 _parseOptions: function( options ) { |
|
14725 var that = this, |
|
14726 data = []; |
|
14727 options.each( function( index, item ) { |
|
14728 if ( item.hidden ) { |
|
14729 return; |
|
14730 } |
|
14731 |
|
14732 data.push( that._parseOption( $( item ), index ) ); |
|
14733 } ); |
|
14734 this.items = data; |
|
14735 }, |
|
14736 |
|
14737 _parseOption: function( option, index ) { |
|
14738 var optgroup = option.parent( "optgroup" ); |
|
14739 |
|
14740 return { |
|
14741 element: option, |
|
14742 index: index, |
|
14743 value: option.val(), |
|
14744 label: option.text(), |
|
14745 optgroup: optgroup.attr( "label" ) || "", |
|
14746 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) |
|
14747 }; |
|
14748 }, |
|
14749 |
|
14750 _destroy: function() { |
|
14751 this._unbindFormResetHandler(); |
|
14752 this.menuWrap.remove(); |
|
14753 this.button.remove(); |
|
14754 this.element.show(); |
|
14755 this.element.removeUniqueId(); |
|
14756 this.labels.attr( "for", this.ids.element ); |
|
14757 } |
|
14758 } ] ); |
|
14759 |
|
14760 |
|
14761 /*! |
|
14762 * jQuery UI Slider 1.13.2 |
|
14763 * http://jqueryui.com |
|
14764 * |
|
14765 * Copyright jQuery Foundation and other contributors |
|
14766 * Released under the MIT license. |
|
14767 * http://jquery.org/license |
|
14768 */ |
|
14769 |
|
14770 //>>label: Slider |
|
14771 //>>group: Widgets |
|
14772 //>>description: Displays a flexible slider with ranges and accessibility via keyboard. |
|
14773 //>>docs: http://api.jqueryui.com/slider/ |
|
14774 //>>demos: http://jqueryui.com/slider/ |
|
14775 //>>css.structure: ../../themes/base/core.css |
|
14776 //>>css.structure: ../../themes/base/slider.css |
|
14777 //>>css.theme: ../../themes/base/theme.css |
|
14778 |
|
14779 |
|
14780 var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { |
|
14781 version: "1.13.2", |
|
14782 widgetEventPrefix: "slide", |
|
14783 |
|
14784 options: { |
|
14785 animate: false, |
|
14786 classes: { |
|
14787 "ui-slider": "ui-corner-all", |
|
14788 "ui-slider-handle": "ui-corner-all", |
|
14789 |
|
14790 // Note: ui-widget-header isn't the most fittingly semantic framework class for this |
|
14791 // element, but worked best visually with a variety of themes |
|
14792 "ui-slider-range": "ui-corner-all ui-widget-header" |
|
14793 }, |
|
14794 distance: 0, |
|
14795 max: 100, |
|
14796 min: 0, |
|
14797 orientation: "horizontal", |
|
14798 range: false, |
|
14799 step: 1, |
|
14800 value: 0, |
|
14801 values: null, |
|
14802 |
|
14803 // Callbacks |
|
14804 change: null, |
|
14805 slide: null, |
|
14806 start: null, |
|
14807 stop: null |
|
14808 }, |
|
14809 |
|
14810 // Number of pages in a slider |
|
14811 // (how many times can you page up/down to go through the whole range) |
|
14812 numPages: 5, |
|
14813 |
|
14814 _create: function() { |
|
14815 this._keySliding = false; |
|
14816 this._mouseSliding = false; |
|
14817 this._animateOff = true; |
|
14818 this._handleIndex = null; |
|
14819 this._detectOrientation(); |
|
14820 this._mouseInit(); |
|
14821 this._calculateNewMax(); |
|
14822 |
|
14823 this._addClass( "ui-slider ui-slider-" + this.orientation, |
|
14824 "ui-widget ui-widget-content" ); |
|
14825 |
|
14826 this._refresh(); |
|
14827 |
|
14828 this._animateOff = false; |
|
14829 }, |
|
14830 |
|
14831 _refresh: function() { |
|
14832 this._createRange(); |
|
14833 this._createHandles(); |
|
14834 this._setupEvents(); |
|
14835 this._refreshValue(); |
|
14836 }, |
|
14837 |
|
14838 _createHandles: function() { |
|
14839 var i, handleCount, |
|
14840 options = this.options, |
|
14841 existingHandles = this.element.find( ".ui-slider-handle" ), |
|
14842 handle = "<span tabindex='0'></span>", |
|
14843 handles = []; |
|
14844 |
|
14845 handleCount = ( options.values && options.values.length ) || 1; |
|
14846 |
|
14847 if ( existingHandles.length > handleCount ) { |
|
14848 existingHandles.slice( handleCount ).remove(); |
|
14849 existingHandles = existingHandles.slice( 0, handleCount ); |
|
14850 } |
|
14851 |
|
14852 for ( i = existingHandles.length; i < handleCount; i++ ) { |
|
14853 handles.push( handle ); |
|
14854 } |
|
14855 |
|
14856 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); |
|
14857 |
|
14858 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); |
|
14859 |
|
14860 this.handle = this.handles.eq( 0 ); |
|
14861 |
|
14862 this.handles.each( function( i ) { |
|
14863 $( this ) |
|
14864 .data( "ui-slider-handle-index", i ) |
|
14865 .attr( "tabIndex", 0 ); |
|
14866 } ); |
|
14867 }, |
|
14868 |
|
14869 _createRange: function() { |
|
14870 var options = this.options; |
|
14871 |
|
14872 if ( options.range ) { |
|
14873 if ( options.range === true ) { |
|
14874 if ( !options.values ) { |
|
14875 options.values = [ this._valueMin(), this._valueMin() ]; |
|
14876 } else if ( options.values.length && options.values.length !== 2 ) { |
|
14877 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; |
|
14878 } else if ( Array.isArray( options.values ) ) { |
|
14879 options.values = options.values.slice( 0 ); |
|
14880 } |
|
14881 } |
|
14882 |
|
14883 if ( !this.range || !this.range.length ) { |
|
14884 this.range = $( "<div>" ) |
|
14885 .appendTo( this.element ); |
|
14886 |
|
14887 this._addClass( this.range, "ui-slider-range" ); |
|
14888 } else { |
|
14889 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); |
|
14890 |
|
14891 // Handle range switching from true to min/max |
|
14892 this.range.css( { |
|
14893 "left": "", |
|
14894 "bottom": "" |
|
14895 } ); |
|
14896 } |
|
14897 if ( options.range === "min" || options.range === "max" ) { |
|
14898 this._addClass( this.range, "ui-slider-range-" + options.range ); |
|
14899 } |
|
14900 } else { |
|
14901 if ( this.range ) { |
|
14902 this.range.remove(); |
|
14903 } |
|
14904 this.range = null; |
|
14905 } |
|
14906 }, |
|
14907 |
|
14908 _setupEvents: function() { |
|
14909 this._off( this.handles ); |
|
14910 this._on( this.handles, this._handleEvents ); |
|
14911 this._hoverable( this.handles ); |
|
14912 this._focusable( this.handles ); |
|
14913 }, |
|
14914 |
|
14915 _destroy: function() { |
|
14916 this.handles.remove(); |
|
14917 if ( this.range ) { |
|
14918 this.range.remove(); |
|
14919 } |
|
14920 |
|
14921 this._mouseDestroy(); |
|
14922 }, |
|
14923 |
|
14924 _mouseCapture: function( event ) { |
|
14925 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, |
|
14926 that = this, |
|
14927 o = this.options; |
|
14928 |
|
14929 if ( o.disabled ) { |
|
14930 return false; |
|
14931 } |
|
14932 |
|
14933 this.elementSize = { |
|
14934 width: this.element.outerWidth(), |
|
14935 height: this.element.outerHeight() |
|
14936 }; |
|
14937 this.elementOffset = this.element.offset(); |
|
14938 |
|
14939 position = { x: event.pageX, y: event.pageY }; |
|
14940 normValue = this._normValueFromMouse( position ); |
|
14941 distance = this._valueMax() - this._valueMin() + 1; |
|
14942 this.handles.each( function( i ) { |
|
14943 var thisDistance = Math.abs( normValue - that.values( i ) ); |
|
14944 if ( ( distance > thisDistance ) || |
|
14945 ( distance === thisDistance && |
|
14946 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { |
|
14947 distance = thisDistance; |
|
14948 closestHandle = $( this ); |
|
14949 index = i; |
|
14950 } |
|
14951 } ); |
|
14952 |
|
14953 allowed = this._start( event, index ); |
|
14954 if ( allowed === false ) { |
|
14955 return false; |
|
14956 } |
|
14957 this._mouseSliding = true; |
|
14958 |
|
14959 this._handleIndex = index; |
|
14960 |
|
14961 this._addClass( closestHandle, null, "ui-state-active" ); |
|
14962 closestHandle.trigger( "focus" ); |
|
14963 |
|
14964 offset = closestHandle.offset(); |
|
14965 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); |
|
14966 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { |
|
14967 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), |
|
14968 top: event.pageY - offset.top - |
|
14969 ( closestHandle.height() / 2 ) - |
|
14970 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - |
|
14971 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + |
|
14972 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) |
|
14973 }; |
|
14974 |
|
14975 if ( !this.handles.hasClass( "ui-state-hover" ) ) { |
|
14976 this._slide( event, index, normValue ); |
|
14977 } |
|
14978 this._animateOff = true; |
|
14979 return true; |
|
14980 }, |
|
14981 |
|
14982 _mouseStart: function() { |
|
14983 return true; |
|
14984 }, |
|
14985 |
|
14986 _mouseDrag: function( event ) { |
|
14987 var position = { x: event.pageX, y: event.pageY }, |
|
14988 normValue = this._normValueFromMouse( position ); |
|
14989 |
|
14990 this._slide( event, this._handleIndex, normValue ); |
|
14991 |
|
14992 return false; |
|
14993 }, |
|
14994 |
|
14995 _mouseStop: function( event ) { |
|
14996 this._removeClass( this.handles, null, "ui-state-active" ); |
|
14997 this._mouseSliding = false; |
|
14998 |
|
14999 this._stop( event, this._handleIndex ); |
|
15000 this._change( event, this._handleIndex ); |
|
15001 |
|
15002 this._handleIndex = null; |
|
15003 this._clickOffset = null; |
|
15004 this._animateOff = false; |
|
15005 |
|
15006 return false; |
|
15007 }, |
|
15008 |
|
15009 _detectOrientation: function() { |
|
15010 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; |
|
15011 }, |
|
15012 |
|
15013 _normValueFromMouse: function( position ) { |
|
15014 var pixelTotal, |
|
15015 pixelMouse, |
|
15016 percentMouse, |
|
15017 valueTotal, |
|
15018 valueMouse; |
|
15019 |
|
15020 if ( this.orientation === "horizontal" ) { |
|
15021 pixelTotal = this.elementSize.width; |
|
15022 pixelMouse = position.x - this.elementOffset.left - |
|
15023 ( this._clickOffset ? this._clickOffset.left : 0 ); |
|
15024 } else { |
|
15025 pixelTotal = this.elementSize.height; |
|
15026 pixelMouse = position.y - this.elementOffset.top - |
|
15027 ( this._clickOffset ? this._clickOffset.top : 0 ); |
|
15028 } |
|
15029 |
|
15030 percentMouse = ( pixelMouse / pixelTotal ); |
|
15031 if ( percentMouse > 1 ) { |
|
15032 percentMouse = 1; |
|
15033 } |
|
15034 if ( percentMouse < 0 ) { |
|
15035 percentMouse = 0; |
|
15036 } |
|
15037 if ( this.orientation === "vertical" ) { |
|
15038 percentMouse = 1 - percentMouse; |
|
15039 } |
|
15040 |
|
15041 valueTotal = this._valueMax() - this._valueMin(); |
|
15042 valueMouse = this._valueMin() + percentMouse * valueTotal; |
|
15043 |
|
15044 return this._trimAlignValue( valueMouse ); |
|
15045 }, |
|
15046 |
|
15047 _uiHash: function( index, value, values ) { |
|
15048 var uiHash = { |
|
15049 handle: this.handles[ index ], |
|
15050 handleIndex: index, |
|
15051 value: value !== undefined ? value : this.value() |
|
15052 }; |
|
15053 |
|
15054 if ( this._hasMultipleValues() ) { |
|
15055 uiHash.value = value !== undefined ? value : this.values( index ); |
|
15056 uiHash.values = values || this.values(); |
|
15057 } |
|
15058 |
|
15059 return uiHash; |
|
15060 }, |
|
15061 |
|
15062 _hasMultipleValues: function() { |
|
15063 return this.options.values && this.options.values.length; |
|
15064 }, |
|
15065 |
|
15066 _start: function( event, index ) { |
|
15067 return this._trigger( "start", event, this._uiHash( index ) ); |
|
15068 }, |
|
15069 |
|
15070 _slide: function( event, index, newVal ) { |
|
15071 var allowed, otherVal, |
|
15072 currentValue = this.value(), |
|
15073 newValues = this.values(); |
|
15074 |
|
15075 if ( this._hasMultipleValues() ) { |
|
15076 otherVal = this.values( index ? 0 : 1 ); |
|
15077 currentValue = this.values( index ); |
|
15078 |
|
15079 if ( this.options.values.length === 2 && this.options.range === true ) { |
|
15080 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); |
|
15081 } |
|
15082 |
|
15083 newValues[ index ] = newVal; |
|
15084 } |
|
15085 |
|
15086 if ( newVal === currentValue ) { |
|
15087 return; |
|
15088 } |
|
15089 |
|
15090 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); |
|
15091 |
|
15092 // A slide can be canceled by returning false from the slide callback |
|
15093 if ( allowed === false ) { |
|
15094 return; |
|
15095 } |
|
15096 |
|
15097 if ( this._hasMultipleValues() ) { |
|
15098 this.values( index, newVal ); |
|
15099 } else { |
|
15100 this.value( newVal ); |
|
15101 } |
|
15102 }, |
|
15103 |
|
15104 _stop: function( event, index ) { |
|
15105 this._trigger( "stop", event, this._uiHash( index ) ); |
|
15106 }, |
|
15107 |
|
15108 _change: function( event, index ) { |
|
15109 if ( !this._keySliding && !this._mouseSliding ) { |
|
15110 |
|
15111 //store the last changed value index for reference when handles overlap |
|
15112 this._lastChangedValue = index; |
|
15113 this._trigger( "change", event, this._uiHash( index ) ); |
|
15114 } |
|
15115 }, |
|
15116 |
|
15117 value: function( newValue ) { |
|
15118 if ( arguments.length ) { |
|
15119 this.options.value = this._trimAlignValue( newValue ); |
|
15120 this._refreshValue(); |
|
15121 this._change( null, 0 ); |
|
15122 return; |
|
15123 } |
|
15124 |
|
15125 return this._value(); |
|
15126 }, |
|
15127 |
|
15128 values: function( index, newValue ) { |
|
15129 var vals, |
|
15130 newValues, |
|
15131 i; |
|
15132 |
|
15133 if ( arguments.length > 1 ) { |
|
15134 this.options.values[ index ] = this._trimAlignValue( newValue ); |
|
15135 this._refreshValue(); |
|
15136 this._change( null, index ); |
|
15137 return; |
|
15138 } |
|
15139 |
|
15140 if ( arguments.length ) { |
|
15141 if ( Array.isArray( arguments[ 0 ] ) ) { |
|
15142 vals = this.options.values; |
|
15143 newValues = arguments[ 0 ]; |
|
15144 for ( i = 0; i < vals.length; i += 1 ) { |
|
15145 vals[ i ] = this._trimAlignValue( newValues[ i ] ); |
|
15146 this._change( null, i ); |
|
15147 } |
|
15148 this._refreshValue(); |
|
15149 } else { |
|
15150 if ( this._hasMultipleValues() ) { |
|
15151 return this._values( index ); |
|
15152 } else { |
|
15153 return this.value(); |
|
15154 } |
|
15155 } |
|
15156 } else { |
|
15157 return this._values(); |
|
15158 } |
|
15159 }, |
|
15160 |
|
15161 _setOption: function( key, value ) { |
|
15162 var i, |
|
15163 valsLength = 0; |
|
15164 |
|
15165 if ( key === "range" && this.options.range === true ) { |
|
15166 if ( value === "min" ) { |
|
15167 this.options.value = this._values( 0 ); |
|
15168 this.options.values = null; |
|
15169 } else if ( value === "max" ) { |
|
15170 this.options.value = this._values( this.options.values.length - 1 ); |
|
15171 this.options.values = null; |
|
15172 } |
|
15173 } |
|
15174 |
|
15175 if ( Array.isArray( this.options.values ) ) { |
|
15176 valsLength = this.options.values.length; |
|
15177 } |
|
15178 |
|
15179 this._super( key, value ); |
|
15180 |
|
15181 switch ( key ) { |
|
15182 case "orientation": |
|
15183 this._detectOrientation(); |
|
15184 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) |
|
15185 ._addClass( "ui-slider-" + this.orientation ); |
|
15186 this._refreshValue(); |
|
15187 if ( this.options.range ) { |
|
15188 this._refreshRange( value ); |
|
15189 } |
|
15190 |
|
15191 // Reset positioning from previous orientation |
|
15192 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); |
|
15193 break; |
|
15194 case "value": |
|
15195 this._animateOff = true; |
|
15196 this._refreshValue(); |
|
15197 this._change( null, 0 ); |
|
15198 this._animateOff = false; |
|
15199 break; |
|
15200 case "values": |
|
15201 this._animateOff = true; |
|
15202 this._refreshValue(); |
|
15203 |
|
15204 // Start from the last handle to prevent unreachable handles (#9046) |
|
15205 for ( i = valsLength - 1; i >= 0; i-- ) { |
|
15206 this._change( null, i ); |
|
15207 } |
|
15208 this._animateOff = false; |
|
15209 break; |
|
15210 case "step": |
|
15211 case "min": |
|
15212 case "max": |
|
15213 this._animateOff = true; |
|
15214 this._calculateNewMax(); |
|
15215 this._refreshValue(); |
|
15216 this._animateOff = false; |
|
15217 break; |
|
15218 case "range": |
|
15219 this._animateOff = true; |
|
15220 this._refresh(); |
|
15221 this._animateOff = false; |
|
15222 break; |
|
15223 } |
|
15224 }, |
|
15225 |
|
15226 _setOptionDisabled: function( value ) { |
|
15227 this._super( value ); |
|
15228 |
|
15229 this._toggleClass( null, "ui-state-disabled", !!value ); |
|
15230 }, |
|
15231 |
|
15232 //internal value getter |
|
15233 // _value() returns value trimmed by min and max, aligned by step |
|
15234 _value: function() { |
|
15235 var val = this.options.value; |
|
15236 val = this._trimAlignValue( val ); |
|
15237 |
|
15238 return val; |
|
15239 }, |
|
15240 |
|
15241 //internal values getter |
|
15242 // _values() returns array of values trimmed by min and max, aligned by step |
|
15243 // _values( index ) returns single value trimmed by min and max, aligned by step |
|
15244 _values: function( index ) { |
|
15245 var val, |
|
15246 vals, |
|
15247 i; |
|
15248 |
|
15249 if ( arguments.length ) { |
|
15250 val = this.options.values[ index ]; |
|
15251 val = this._trimAlignValue( val ); |
|
15252 |
|
15253 return val; |
|
15254 } else if ( this._hasMultipleValues() ) { |
|
15255 |
|
15256 // .slice() creates a copy of the array |
|
15257 // this copy gets trimmed by min and max and then returned |
|
15258 vals = this.options.values.slice(); |
|
15259 for ( i = 0; i < vals.length; i += 1 ) { |
|
15260 vals[ i ] = this._trimAlignValue( vals[ i ] ); |
|
15261 } |
|
15262 |
|
15263 return vals; |
|
15264 } else { |
|
15265 return []; |
|
15266 } |
|
15267 }, |
|
15268 |
|
15269 // Returns the step-aligned value that val is closest to, between (inclusive) min and max |
|
15270 _trimAlignValue: function( val ) { |
|
15271 if ( val <= this._valueMin() ) { |
|
15272 return this._valueMin(); |
|
15273 } |
|
15274 if ( val >= this._valueMax() ) { |
|
15275 return this._valueMax(); |
|
15276 } |
|
15277 var step = ( this.options.step > 0 ) ? this.options.step : 1, |
|
15278 valModStep = ( val - this._valueMin() ) % step, |
|
15279 alignValue = val - valModStep; |
|
15280 |
|
15281 if ( Math.abs( valModStep ) * 2 >= step ) { |
|
15282 alignValue += ( valModStep > 0 ) ? step : ( -step ); |
|
15283 } |
|
15284 |
|
15285 // Since JavaScript has problems with large floats, round |
|
15286 // the final value to 5 digits after the decimal point (see #4124) |
|
15287 return parseFloat( alignValue.toFixed( 5 ) ); |
|
15288 }, |
|
15289 |
|
15290 _calculateNewMax: function() { |
|
15291 var max = this.options.max, |
|
15292 min = this._valueMin(), |
|
15293 step = this.options.step, |
|
15294 aboveMin = Math.round( ( max - min ) / step ) * step; |
|
15295 max = aboveMin + min; |
|
15296 if ( max > this.options.max ) { |
|
15297 |
|
15298 //If max is not divisible by step, rounding off may increase its value |
|
15299 max -= step; |
|
15300 } |
|
15301 this.max = parseFloat( max.toFixed( this._precision() ) ); |
|
15302 }, |
|
15303 |
|
15304 _precision: function() { |
|
15305 var precision = this._precisionOf( this.options.step ); |
|
15306 if ( this.options.min !== null ) { |
|
15307 precision = Math.max( precision, this._precisionOf( this.options.min ) ); |
|
15308 } |
|
15309 return precision; |
|
15310 }, |
|
15311 |
|
15312 _precisionOf: function( num ) { |
|
15313 var str = num.toString(), |
|
15314 decimal = str.indexOf( "." ); |
|
15315 return decimal === -1 ? 0 : str.length - decimal - 1; |
|
15316 }, |
|
15317 |
|
15318 _valueMin: function() { |
|
15319 return this.options.min; |
|
15320 }, |
|
15321 |
|
15322 _valueMax: function() { |
|
15323 return this.max; |
|
15324 }, |
|
15325 |
|
15326 _refreshRange: function( orientation ) { |
|
15327 if ( orientation === "vertical" ) { |
|
15328 this.range.css( { "width": "", "left": "" } ); |
|
15329 } |
|
15330 if ( orientation === "horizontal" ) { |
|
15331 this.range.css( { "height": "", "bottom": "" } ); |
|
15332 } |
|
15333 }, |
|
15334 |
|
15335 _refreshValue: function() { |
|
15336 var lastValPercent, valPercent, value, valueMin, valueMax, |
|
15337 oRange = this.options.range, |
|
15338 o = this.options, |
|
15339 that = this, |
|
15340 animate = ( !this._animateOff ) ? o.animate : false, |
|
15341 _set = {}; |
|
15342 |
|
15343 if ( this._hasMultipleValues() ) { |
|
15344 this.handles.each( function( i ) { |
|
15345 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - |
|
15346 that._valueMin() ) * 100; |
|
15347 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; |
|
15348 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); |
|
15349 if ( that.options.range === true ) { |
|
15350 if ( that.orientation === "horizontal" ) { |
|
15351 if ( i === 0 ) { |
|
15352 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { |
|
15353 left: valPercent + "%" |
|
15354 }, o.animate ); |
|
15355 } |
|
15356 if ( i === 1 ) { |
|
15357 that.range[ animate ? "animate" : "css" ]( { |
|
15358 width: ( valPercent - lastValPercent ) + "%" |
|
15359 }, { |
|
15360 queue: false, |
|
15361 duration: o.animate |
|
15362 } ); |
|
15363 } |
|
15364 } else { |
|
15365 if ( i === 0 ) { |
|
15366 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { |
|
15367 bottom: ( valPercent ) + "%" |
|
15368 }, o.animate ); |
|
15369 } |
|
15370 if ( i === 1 ) { |
|
15371 that.range[ animate ? "animate" : "css" ]( { |
|
15372 height: ( valPercent - lastValPercent ) + "%" |
|
15373 }, { |
|
15374 queue: false, |
|
15375 duration: o.animate |
|
15376 } ); |
|
15377 } |
|
15378 } |
|
15379 } |
|
15380 lastValPercent = valPercent; |
|
15381 } ); |
|
15382 } else { |
|
15383 value = this.value(); |
|
15384 valueMin = this._valueMin(); |
|
15385 valueMax = this._valueMax(); |
|
15386 valPercent = ( valueMax !== valueMin ) ? |
|
15387 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : |
|
15388 0; |
|
15389 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; |
|
15390 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); |
|
15391 |
|
15392 if ( oRange === "min" && this.orientation === "horizontal" ) { |
|
15393 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { |
|
15394 width: valPercent + "%" |
|
15395 }, o.animate ); |
|
15396 } |
|
15397 if ( oRange === "max" && this.orientation === "horizontal" ) { |
|
15398 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { |
|
15399 width: ( 100 - valPercent ) + "%" |
|
15400 }, o.animate ); |
|
15401 } |
|
15402 if ( oRange === "min" && this.orientation === "vertical" ) { |
|
15403 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { |
|
15404 height: valPercent + "%" |
|
15405 }, o.animate ); |
|
15406 } |
|
15407 if ( oRange === "max" && this.orientation === "vertical" ) { |
|
15408 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { |
|
15409 height: ( 100 - valPercent ) + "%" |
|
15410 }, o.animate ); |
|
15411 } |
|
15412 } |
|
15413 }, |
|
15414 |
|
15415 _handleEvents: { |
|
15416 keydown: function( event ) { |
|
15417 var allowed, curVal, newVal, step, |
|
15418 index = $( event.target ).data( "ui-slider-handle-index" ); |
|
15419 |
|
15420 switch ( event.keyCode ) { |
|
15421 case $.ui.keyCode.HOME: |
|
15422 case $.ui.keyCode.END: |
|
15423 case $.ui.keyCode.PAGE_UP: |
|
15424 case $.ui.keyCode.PAGE_DOWN: |
|
15425 case $.ui.keyCode.UP: |
|
15426 case $.ui.keyCode.RIGHT: |
|
15427 case $.ui.keyCode.DOWN: |
|
15428 case $.ui.keyCode.LEFT: |
|
15429 event.preventDefault(); |
|
15430 if ( !this._keySliding ) { |
|
15431 this._keySliding = true; |
|
15432 this._addClass( $( event.target ), null, "ui-state-active" ); |
|
15433 allowed = this._start( event, index ); |
|
15434 if ( allowed === false ) { |
|
15435 return; |
|
15436 } |
|
15437 } |
|
15438 break; |
|
15439 } |
|
15440 |
|
15441 step = this.options.step; |
|
15442 if ( this._hasMultipleValues() ) { |
|
15443 curVal = newVal = this.values( index ); |
|
15444 } else { |
|
15445 curVal = newVal = this.value(); |
|
15446 } |
|
15447 |
|
15448 switch ( event.keyCode ) { |
|
15449 case $.ui.keyCode.HOME: |
|
15450 newVal = this._valueMin(); |
|
15451 break; |
|
15452 case $.ui.keyCode.END: |
|
15453 newVal = this._valueMax(); |
|
15454 break; |
|
15455 case $.ui.keyCode.PAGE_UP: |
|
15456 newVal = this._trimAlignValue( |
|
15457 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) |
|
15458 ); |
|
15459 break; |
|
15460 case $.ui.keyCode.PAGE_DOWN: |
|
15461 newVal = this._trimAlignValue( |
|
15462 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); |
|
15463 break; |
|
15464 case $.ui.keyCode.UP: |
|
15465 case $.ui.keyCode.RIGHT: |
|
15466 if ( curVal === this._valueMax() ) { |
|
15467 return; |
|
15468 } |
|
15469 newVal = this._trimAlignValue( curVal + step ); |
|
15470 break; |
|
15471 case $.ui.keyCode.DOWN: |
|
15472 case $.ui.keyCode.LEFT: |
|
15473 if ( curVal === this._valueMin() ) { |
|
15474 return; |
|
15475 } |
|
15476 newVal = this._trimAlignValue( curVal - step ); |
|
15477 break; |
|
15478 } |
|
15479 |
|
15480 this._slide( event, index, newVal ); |
|
15481 }, |
|
15482 keyup: function( event ) { |
|
15483 var index = $( event.target ).data( "ui-slider-handle-index" ); |
|
15484 |
|
15485 if ( this._keySliding ) { |
|
15486 this._keySliding = false; |
|
15487 this._stop( event, index ); |
|
15488 this._change( event, index ); |
|
15489 this._removeClass( $( event.target ), null, "ui-state-active" ); |
|
15490 } |
|
15491 } |
|
15492 } |
|
15493 } ); |
|
15494 |
|
15495 |
|
15496 /*! |
|
15497 * jQuery UI Sortable 1.13.2 |
|
15498 * http://jqueryui.com |
|
15499 * |
|
15500 * Copyright jQuery Foundation and other contributors |
|
15501 * Released under the MIT license. |
|
15502 * http://jquery.org/license |
|
15503 */ |
|
15504 |
|
15505 //>>label: Sortable |
|
15506 //>>group: Interactions |
|
15507 //>>description: Enables items in a list to be sorted using the mouse. |
|
15508 //>>docs: http://api.jqueryui.com/sortable/ |
|
15509 //>>demos: http://jqueryui.com/sortable/ |
|
15510 //>>css.structure: ../../themes/base/sortable.css |
|
15511 |
|
15512 |
|
15513 var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { |
|
15514 version: "1.13.2", |
|
15515 widgetEventPrefix: "sort", |
|
15516 ready: false, |
|
15517 options: { |
|
15518 appendTo: "parent", |
|
15519 axis: false, |
|
15520 connectWith: false, |
|
15521 containment: false, |
|
15522 cursor: "auto", |
|
15523 cursorAt: false, |
|
15524 dropOnEmpty: true, |
|
15525 forcePlaceholderSize: false, |
|
15526 forceHelperSize: false, |
|
15527 grid: false, |
|
15528 handle: false, |
|
15529 helper: "original", |
|
15530 items: "> *", |
|
15531 opacity: false, |
|
15532 placeholder: false, |
|
15533 revert: false, |
|
15534 scroll: true, |
|
15535 scrollSensitivity: 20, |
|
15536 scrollSpeed: 20, |
|
15537 scope: "default", |
|
15538 tolerance: "intersect", |
|
15539 zIndex: 1000, |
|
15540 |
|
15541 // Callbacks |
|
15542 activate: null, |
|
15543 beforeStop: null, |
|
15544 change: null, |
|
15545 deactivate: null, |
|
15546 out: null, |
|
15547 over: null, |
|
15548 receive: null, |
|
15549 remove: null, |
|
15550 sort: null, |
|
15551 start: null, |
|
15552 stop: null, |
|
15553 update: null |
|
15554 }, |
|
15555 |
|
15556 _isOverAxis: function( x, reference, size ) { |
|
15557 return ( x >= reference ) && ( x < ( reference + size ) ); |
|
15558 }, |
|
15559 |
|
15560 _isFloating: function( item ) { |
|
15561 return ( /left|right/ ).test( item.css( "float" ) ) || |
|
15562 ( /inline|table-cell/ ).test( item.css( "display" ) ); |
|
15563 }, |
|
15564 |
|
15565 _create: function() { |
|
15566 this.containerCache = {}; |
|
15567 this._addClass( "ui-sortable" ); |
|
15568 |
|
15569 //Get the items |
|
15570 this.refresh(); |
|
15571 |
|
15572 //Let's determine the parent's offset |
|
15573 this.offset = this.element.offset(); |
|
15574 |
|
15575 //Initialize mouse events for interaction |
|
15576 this._mouseInit(); |
|
15577 |
|
15578 this._setHandleClassName(); |
|
15579 |
|
15580 //We're ready to go |
|
15581 this.ready = true; |
|
15582 |
|
15583 }, |
|
15584 |
|
15585 _setOption: function( key, value ) { |
|
15586 this._super( key, value ); |
|
15587 |
|
15588 if ( key === "handle" ) { |
|
15589 this._setHandleClassName(); |
|
15590 } |
|
15591 }, |
|
15592 |
|
15593 _setHandleClassName: function() { |
|
15594 var that = this; |
|
15595 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); |
|
15596 $.each( this.items, function() { |
|
15597 that._addClass( |
|
15598 this.instance.options.handle ? |
|
15599 this.item.find( this.instance.options.handle ) : |
|
15600 this.item, |
|
15601 "ui-sortable-handle" |
|
15602 ); |
|
15603 } ); |
|
15604 }, |
|
15605 |
|
15606 _destroy: function() { |
|
15607 this._mouseDestroy(); |
|
15608 |
|
15609 for ( var i = this.items.length - 1; i >= 0; i-- ) { |
|
15610 this.items[ i ].item.removeData( this.widgetName + "-item" ); |
|
15611 } |
|
15612 |
|
15613 return this; |
|
15614 }, |
|
15615 |
|
15616 _mouseCapture: function( event, overrideHandle ) { |
|
15617 var currentItem = null, |
|
15618 validHandle = false, |
|
15619 that = this; |
|
15620 |
|
15621 if ( this.reverting ) { |
|
15622 return false; |
|
15623 } |
|
15624 |
|
15625 if ( this.options.disabled || this.options.type === "static" ) { |
|
15626 return false; |
|
15627 } |
|
15628 |
|
15629 //We have to refresh the items data once first |
|
15630 this._refreshItems( event ); |
|
15631 |
|
15632 //Find out if the clicked node (or one of its parents) is a actual item in this.items |
|
15633 $( event.target ).parents().each( function() { |
|
15634 if ( $.data( this, that.widgetName + "-item" ) === that ) { |
|
15635 currentItem = $( this ); |
|
15636 return false; |
|
15637 } |
|
15638 } ); |
|
15639 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { |
|
15640 currentItem = $( event.target ); |
|
15641 } |
|
15642 |
|
15643 if ( !currentItem ) { |
|
15644 return false; |
|
15645 } |
|
15646 if ( this.options.handle && !overrideHandle ) { |
|
15647 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { |
|
15648 if ( this === event.target ) { |
|
15649 validHandle = true; |
|
15650 } |
|
15651 } ); |
|
15652 if ( !validHandle ) { |
|
15653 return false; |
|
15654 } |
|
15655 } |
|
15656 |
|
15657 this.currentItem = currentItem; |
|
15658 this._removeCurrentsFromItems(); |
|
15659 return true; |
|
15660 |
|
15661 }, |
|
15662 |
|
15663 _mouseStart: function( event, overrideHandle, noActivation ) { |
|
15664 |
|
15665 var i, body, |
|
15666 o = this.options; |
|
15667 |
|
15668 this.currentContainer = this; |
|
15669 |
|
15670 //We only need to call refreshPositions, because the refreshItems call has been moved to |
|
15671 // mouseCapture |
|
15672 this.refreshPositions(); |
|
15673 |
|
15674 //Prepare the dragged items parent |
|
15675 this.appendTo = $( o.appendTo !== "parent" ? |
|
15676 o.appendTo : |
|
15677 this.currentItem.parent() ); |
|
15678 |
|
15679 //Create and append the visible helper |
|
15680 this.helper = this._createHelper( event ); |
|
15681 |
|
15682 //Cache the helper size |
|
15683 this._cacheHelperProportions(); |
|
15684 |
|
15685 /* |
|
15686 * - Position generation - |
|
15687 * This block generates everything position related - it's the core of draggables. |
|
15688 */ |
|
15689 |
|
15690 //Cache the margins of the original element |
|
15691 this._cacheMargins(); |
|
15692 |
|
15693 //The element's absolute position on the page minus margins |
|
15694 this.offset = this.currentItem.offset(); |
|
15695 this.offset = { |
|
15696 top: this.offset.top - this.margins.top, |
|
15697 left: this.offset.left - this.margins.left |
|
15698 }; |
|
15699 |
|
15700 $.extend( this.offset, { |
|
15701 click: { //Where the click happened, relative to the element |
|
15702 left: event.pageX - this.offset.left, |
|
15703 top: event.pageY - this.offset.top |
|
15704 }, |
|
15705 |
|
15706 // This is a relative to absolute position minus the actual position calculation - |
|
15707 // only used for relative positioned helper |
|
15708 relative: this._getRelativeOffset() |
|
15709 } ); |
|
15710 |
|
15711 // After we get the helper offset, but before we get the parent offset we can |
|
15712 // change the helper's position to absolute |
|
15713 // TODO: Still need to figure out a way to make relative sorting possible |
|
15714 this.helper.css( "position", "absolute" ); |
|
15715 this.cssPosition = this.helper.css( "position" ); |
|
15716 |
|
15717 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied |
|
15718 if ( o.cursorAt ) { |
|
15719 this._adjustOffsetFromHelper( o.cursorAt ); |
|
15720 } |
|
15721 |
|
15722 //Cache the former DOM position |
|
15723 this.domPosition = { |
|
15724 prev: this.currentItem.prev()[ 0 ], |
|
15725 parent: this.currentItem.parent()[ 0 ] |
|
15726 }; |
|
15727 |
|
15728 // If the helper is not the original, hide the original so it's not playing any role during |
|
15729 // the drag, won't cause anything bad this way |
|
15730 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { |
|
15731 this.currentItem.hide(); |
|
15732 } |
|
15733 |
|
15734 //Create the placeholder |
|
15735 this._createPlaceholder(); |
|
15736 |
|
15737 //Get the next scrolling parent |
|
15738 this.scrollParent = this.placeholder.scrollParent(); |
|
15739 |
|
15740 $.extend( this.offset, { |
|
15741 parent: this._getParentOffset() |
|
15742 } ); |
|
15743 |
|
15744 //Set a containment if given in the options |
|
15745 if ( o.containment ) { |
|
15746 this._setContainment(); |
|
15747 } |
|
15748 |
|
15749 if ( o.cursor && o.cursor !== "auto" ) { // cursor option |
|
15750 body = this.document.find( "body" ); |
|
15751 |
|
15752 // Support: IE |
|
15753 this.storedCursor = body.css( "cursor" ); |
|
15754 body.css( "cursor", o.cursor ); |
|
15755 |
|
15756 this.storedStylesheet = |
|
15757 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); |
|
15758 } |
|
15759 |
|
15760 // We need to make sure to grab the zIndex before setting the |
|
15761 // opacity, because setting the opacity to anything lower than 1 |
|
15762 // causes the zIndex to change from "auto" to 0. |
|
15763 if ( o.zIndex ) { // zIndex option |
|
15764 if ( this.helper.css( "zIndex" ) ) { |
|
15765 this._storedZIndex = this.helper.css( "zIndex" ); |
|
15766 } |
|
15767 this.helper.css( "zIndex", o.zIndex ); |
|
15768 } |
|
15769 |
|
15770 if ( o.opacity ) { // opacity option |
|
15771 if ( this.helper.css( "opacity" ) ) { |
|
15772 this._storedOpacity = this.helper.css( "opacity" ); |
|
15773 } |
|
15774 this.helper.css( "opacity", o.opacity ); |
|
15775 } |
|
15776 |
|
15777 //Prepare scrolling |
|
15778 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && |
|
15779 this.scrollParent[ 0 ].tagName !== "HTML" ) { |
|
15780 this.overflowOffset = this.scrollParent.offset(); |
|
15781 } |
|
15782 |
|
15783 //Call callbacks |
|
15784 this._trigger( "start", event, this._uiHash() ); |
|
15785 |
|
15786 //Recache the helper size |
|
15787 if ( !this._preserveHelperProportions ) { |
|
15788 this._cacheHelperProportions(); |
|
15789 } |
|
15790 |
|
15791 //Post "activate" events to possible containers |
|
15792 if ( !noActivation ) { |
|
15793 for ( i = this.containers.length - 1; i >= 0; i-- ) { |
|
15794 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); |
|
15795 } |
|
15796 } |
|
15797 |
|
15798 //Prepare possible droppables |
|
15799 if ( $.ui.ddmanager ) { |
|
15800 $.ui.ddmanager.current = this; |
|
15801 } |
|
15802 |
|
15803 if ( $.ui.ddmanager && !o.dropBehaviour ) { |
|
15804 $.ui.ddmanager.prepareOffsets( this, event ); |
|
15805 } |
|
15806 |
|
15807 this.dragging = true; |
|
15808 |
|
15809 this._addClass( this.helper, "ui-sortable-helper" ); |
|
15810 |
|
15811 //Move the helper, if needed |
|
15812 if ( !this.helper.parent().is( this.appendTo ) ) { |
|
15813 this.helper.detach().appendTo( this.appendTo ); |
|
15814 |
|
15815 //Update position |
|
15816 this.offset.parent = this._getParentOffset(); |
|
15817 } |
|
15818 |
|
15819 //Generate the original position |
|
15820 this.position = this.originalPosition = this._generatePosition( event ); |
|
15821 this.originalPageX = event.pageX; |
|
15822 this.originalPageY = event.pageY; |
|
15823 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); |
|
15824 |
|
15825 this._mouseDrag( event ); |
|
15826 |
|
15827 return true; |
|
15828 |
|
15829 }, |
|
15830 |
|
15831 _scroll: function( event ) { |
|
15832 var o = this.options, |
|
15833 scrolled = false; |
|
15834 |
|
15835 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && |
|
15836 this.scrollParent[ 0 ].tagName !== "HTML" ) { |
|
15837 |
|
15838 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - |
|
15839 event.pageY < o.scrollSensitivity ) { |
|
15840 this.scrollParent[ 0 ].scrollTop = |
|
15841 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; |
|
15842 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { |
|
15843 this.scrollParent[ 0 ].scrollTop = |
|
15844 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; |
|
15845 } |
|
15846 |
|
15847 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - |
|
15848 event.pageX < o.scrollSensitivity ) { |
|
15849 this.scrollParent[ 0 ].scrollLeft = scrolled = |
|
15850 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; |
|
15851 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { |
|
15852 this.scrollParent[ 0 ].scrollLeft = scrolled = |
|
15853 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; |
|
15854 } |
|
15855 |
|
15856 } else { |
|
15857 |
|
15858 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { |
|
15859 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); |
|
15860 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < |
|
15861 o.scrollSensitivity ) { |
|
15862 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); |
|
15863 } |
|
15864 |
|
15865 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { |
|
15866 scrolled = this.document.scrollLeft( |
|
15867 this.document.scrollLeft() - o.scrollSpeed |
|
15868 ); |
|
15869 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < |
|
15870 o.scrollSensitivity ) { |
|
15871 scrolled = this.document.scrollLeft( |
|
15872 this.document.scrollLeft() + o.scrollSpeed |
|
15873 ); |
|
15874 } |
|
15875 |
|
15876 } |
|
15877 |
|
15878 return scrolled; |
|
15879 }, |
|
15880 |
|
15881 _mouseDrag: function( event ) { |
|
15882 var i, item, itemElement, intersection, |
|
15883 o = this.options; |
|
15884 |
|
15885 //Compute the helpers position |
|
15886 this.position = this._generatePosition( event ); |
|
15887 this.positionAbs = this._convertPositionTo( "absolute" ); |
|
15888 |
|
15889 //Set the helper position |
|
15890 if ( !this.options.axis || this.options.axis !== "y" ) { |
|
15891 this.helper[ 0 ].style.left = this.position.left + "px"; |
|
15892 } |
|
15893 if ( !this.options.axis || this.options.axis !== "x" ) { |
|
15894 this.helper[ 0 ].style.top = this.position.top + "px"; |
|
15895 } |
|
15896 |
|
15897 //Do scrolling |
|
15898 if ( o.scroll ) { |
|
15899 if ( this._scroll( event ) !== false ) { |
|
15900 |
|
15901 //Update item positions used in position checks |
|
15902 this._refreshItemPositions( true ); |
|
15903 |
|
15904 if ( $.ui.ddmanager && !o.dropBehaviour ) { |
|
15905 $.ui.ddmanager.prepareOffsets( this, event ); |
|
15906 } |
|
15907 } |
|
15908 } |
|
15909 |
|
15910 this.dragDirection = { |
|
15911 vertical: this._getDragVerticalDirection(), |
|
15912 horizontal: this._getDragHorizontalDirection() |
|
15913 }; |
|
15914 |
|
15915 //Rearrange |
|
15916 for ( i = this.items.length - 1; i >= 0; i-- ) { |
|
15917 |
|
15918 //Cache variables and intersection, continue if no intersection |
|
15919 item = this.items[ i ]; |
|
15920 itemElement = item.item[ 0 ]; |
|
15921 intersection = this._intersectsWithPointer( item ); |
|
15922 if ( !intersection ) { |
|
15923 continue; |
|
15924 } |
|
15925 |
|
15926 // Only put the placeholder inside the current Container, skip all |
|
15927 // items from other containers. This works because when moving |
|
15928 // an item from one container to another the |
|
15929 // currentContainer is switched before the placeholder is moved. |
|
15930 // |
|
15931 // Without this, moving items in "sub-sortables" can cause |
|
15932 // the placeholder to jitter between the outer and inner container. |
|
15933 if ( item.instance !== this.currentContainer ) { |
|
15934 continue; |
|
15935 } |
|
15936 |
|
15937 // Cannot intersect with itself |
|
15938 // no useless actions that have been done before |
|
15939 // no action if the item moved is the parent of the item checked |
|
15940 if ( itemElement !== this.currentItem[ 0 ] && |
|
15941 this.placeholder[ intersection === 1 ? |
|
15942 "next" : "prev" ]()[ 0 ] !== itemElement && |
|
15943 !$.contains( this.placeholder[ 0 ], itemElement ) && |
|
15944 ( this.options.type === "semi-dynamic" ? |
|
15945 !$.contains( this.element[ 0 ], itemElement ) : |
|
15946 true |
|
15947 ) |
|
15948 ) { |
|
15949 |
|
15950 this.direction = intersection === 1 ? "down" : "up"; |
|
15951 |
|
15952 if ( this.options.tolerance === "pointer" || |
|
15953 this._intersectsWithSides( item ) ) { |
|
15954 this._rearrange( event, item ); |
|
15955 } else { |
|
15956 break; |
|
15957 } |
|
15958 |
|
15959 this._trigger( "change", event, this._uiHash() ); |
|
15960 break; |
|
15961 } |
|
15962 } |
|
15963 |
|
15964 //Post events to containers |
|
15965 this._contactContainers( event ); |
|
15966 |
|
15967 //Interconnect with droppables |
|
15968 if ( $.ui.ddmanager ) { |
|
15969 $.ui.ddmanager.drag( this, event ); |
|
15970 } |
|
15971 |
|
15972 //Call callbacks |
|
15973 this._trigger( "sort", event, this._uiHash() ); |
|
15974 |
|
15975 this.lastPositionAbs = this.positionAbs; |
|
15976 return false; |
|
15977 |
|
15978 }, |
|
15979 |
|
15980 _mouseStop: function( event, noPropagation ) { |
|
15981 |
|
15982 if ( !event ) { |
|
15983 return; |
|
15984 } |
|
15985 |
|
15986 //If we are using droppables, inform the manager about the drop |
|
15987 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { |
|
15988 $.ui.ddmanager.drop( this, event ); |
|
15989 } |
|
15990 |
|
15991 if ( this.options.revert ) { |
|
15992 var that = this, |
|
15993 cur = this.placeholder.offset(), |
|
15994 axis = this.options.axis, |
|
15995 animation = {}; |
|
15996 |
|
15997 if ( !axis || axis === "x" ) { |
|
15998 animation.left = cur.left - this.offset.parent.left - this.margins.left + |
|
15999 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? |
|
16000 0 : |
|
16001 this.offsetParent[ 0 ].scrollLeft |
|
16002 ); |
|
16003 } |
|
16004 if ( !axis || axis === "y" ) { |
|
16005 animation.top = cur.top - this.offset.parent.top - this.margins.top + |
|
16006 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? |
|
16007 0 : |
|
16008 this.offsetParent[ 0 ].scrollTop |
|
16009 ); |
|
16010 } |
|
16011 this.reverting = true; |
|
16012 $( this.helper ).animate( |
|
16013 animation, |
|
16014 parseInt( this.options.revert, 10 ) || 500, |
|
16015 function() { |
|
16016 that._clear( event ); |
|
16017 } |
|
16018 ); |
|
16019 } else { |
|
16020 this._clear( event, noPropagation ); |
|
16021 } |
|
16022 |
|
16023 return false; |
|
16024 |
|
16025 }, |
|
16026 |
|
16027 cancel: function() { |
|
16028 |
|
16029 if ( this.dragging ) { |
|
16030 |
|
16031 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); |
|
16032 |
|
16033 if ( this.options.helper === "original" ) { |
|
16034 this.currentItem.css( this._storedCSS ); |
|
16035 this._removeClass( this.currentItem, "ui-sortable-helper" ); |
|
16036 } else { |
|
16037 this.currentItem.show(); |
|
16038 } |
|
16039 |
|
16040 //Post deactivating events to containers |
|
16041 for ( var i = this.containers.length - 1; i >= 0; i-- ) { |
|
16042 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); |
|
16043 if ( this.containers[ i ].containerCache.over ) { |
|
16044 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); |
|
16045 this.containers[ i ].containerCache.over = 0; |
|
16046 } |
|
16047 } |
|
16048 |
|
16049 } |
|
16050 |
|
16051 if ( this.placeholder ) { |
|
16052 |
|
16053 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, |
|
16054 // it unbinds ALL events from the original node! |
|
16055 if ( this.placeholder[ 0 ].parentNode ) { |
|
16056 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); |
|
16057 } |
|
16058 if ( this.options.helper !== "original" && this.helper && |
|
16059 this.helper[ 0 ].parentNode ) { |
|
16060 this.helper.remove(); |
|
16061 } |
|
16062 |
|
16063 $.extend( this, { |
|
16064 helper: null, |
|
16065 dragging: false, |
|
16066 reverting: false, |
|
16067 _noFinalSort: null |
|
16068 } ); |
|
16069 |
|
16070 if ( this.domPosition.prev ) { |
|
16071 $( this.domPosition.prev ).after( this.currentItem ); |
|
16072 } else { |
|
16073 $( this.domPosition.parent ).prepend( this.currentItem ); |
|
16074 } |
|
16075 } |
|
16076 |
|
16077 return this; |
|
16078 |
|
16079 }, |
|
16080 |
|
16081 serialize: function( o ) { |
|
16082 |
|
16083 var items = this._getItemsAsjQuery( o && o.connected ), |
|
16084 str = []; |
|
16085 o = o || {}; |
|
16086 |
|
16087 $( items ).each( function() { |
|
16088 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) |
|
16089 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); |
|
16090 if ( res ) { |
|
16091 str.push( |
|
16092 ( o.key || res[ 1 ] + "[]" ) + |
|
16093 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); |
|
16094 } |
|
16095 } ); |
|
16096 |
|
16097 if ( !str.length && o.key ) { |
|
16098 str.push( o.key + "=" ); |
|
16099 } |
|
16100 |
|
16101 return str.join( "&" ); |
|
16102 |
|
16103 }, |
|
16104 |
|
16105 toArray: function( o ) { |
|
16106 |
|
16107 var items = this._getItemsAsjQuery( o && o.connected ), |
|
16108 ret = []; |
|
16109 |
|
16110 o = o || {}; |
|
16111 |
|
16112 items.each( function() { |
|
16113 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); |
|
16114 } ); |
|
16115 return ret; |
|
16116 |
|
16117 }, |
|
16118 |
|
16119 /* Be careful with the following core functions */ |
|
16120 _intersectsWith: function( item ) { |
|
16121 |
|
16122 var x1 = this.positionAbs.left, |
|
16123 x2 = x1 + this.helperProportions.width, |
|
16124 y1 = this.positionAbs.top, |
|
16125 y2 = y1 + this.helperProportions.height, |
|
16126 l = item.left, |
|
16127 r = l + item.width, |
|
16128 t = item.top, |
|
16129 b = t + item.height, |
|
16130 dyClick = this.offset.click.top, |
|
16131 dxClick = this.offset.click.left, |
|
16132 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && |
|
16133 ( y1 + dyClick ) < b ), |
|
16134 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && |
|
16135 ( x1 + dxClick ) < r ), |
|
16136 isOverElement = isOverElementHeight && isOverElementWidth; |
|
16137 |
|
16138 if ( this.options.tolerance === "pointer" || |
|
16139 this.options.forcePointerForContainers || |
|
16140 ( this.options.tolerance !== "pointer" && |
|
16141 this.helperProportions[ this.floating ? "width" : "height" ] > |
|
16142 item[ this.floating ? "width" : "height" ] ) |
|
16143 ) { |
|
16144 return isOverElement; |
|
16145 } else { |
|
16146 |
|
16147 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half |
|
16148 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half |
|
16149 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half |
|
16150 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half |
|
16151 |
|
16152 } |
|
16153 }, |
|
16154 |
|
16155 _intersectsWithPointer: function( item ) { |
|
16156 var verticalDirection, horizontalDirection, |
|
16157 isOverElementHeight = ( this.options.axis === "x" ) || |
|
16158 this._isOverAxis( |
|
16159 this.positionAbs.top + this.offset.click.top, item.top, item.height ), |
|
16160 isOverElementWidth = ( this.options.axis === "y" ) || |
|
16161 this._isOverAxis( |
|
16162 this.positionAbs.left + this.offset.click.left, item.left, item.width ), |
|
16163 isOverElement = isOverElementHeight && isOverElementWidth; |
|
16164 |
|
16165 if ( !isOverElement ) { |
|
16166 return false; |
|
16167 } |
|
16168 |
|
16169 verticalDirection = this.dragDirection.vertical; |
|
16170 horizontalDirection = this.dragDirection.horizontal; |
|
16171 |
|
16172 return this.floating ? |
|
16173 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : |
|
16174 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); |
|
16175 |
|
16176 }, |
|
16177 |
|
16178 _intersectsWithSides: function( item ) { |
|
16179 |
|
16180 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + |
|
16181 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), |
|
16182 isOverRightHalf = this._isOverAxis( this.positionAbs.left + |
|
16183 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), |
|
16184 verticalDirection = this.dragDirection.vertical, |
|
16185 horizontalDirection = this.dragDirection.horizontal; |
|
16186 |
|
16187 if ( this.floating && horizontalDirection ) { |
|
16188 return ( ( horizontalDirection === "right" && isOverRightHalf ) || |
|
16189 ( horizontalDirection === "left" && !isOverRightHalf ) ); |
|
16190 } else { |
|
16191 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || |
|
16192 ( verticalDirection === "up" && !isOverBottomHalf ) ); |
|
16193 } |
|
16194 |
|
16195 }, |
|
16196 |
|
16197 _getDragVerticalDirection: function() { |
|
16198 var delta = this.positionAbs.top - this.lastPositionAbs.top; |
|
16199 return delta !== 0 && ( delta > 0 ? "down" : "up" ); |
|
16200 }, |
|
16201 |
|
16202 _getDragHorizontalDirection: function() { |
|
16203 var delta = this.positionAbs.left - this.lastPositionAbs.left; |
|
16204 return delta !== 0 && ( delta > 0 ? "right" : "left" ); |
|
16205 }, |
|
16206 |
|
16207 refresh: function( event ) { |
|
16208 this._refreshItems( event ); |
|
16209 this._setHandleClassName(); |
|
16210 this.refreshPositions(); |
|
16211 return this; |
|
16212 }, |
|
16213 |
|
16214 _connectWith: function() { |
|
16215 var options = this.options; |
|
16216 return options.connectWith.constructor === String ? |
|
16217 [ options.connectWith ] : |
|
16218 options.connectWith; |
|
16219 }, |
|
16220 |
|
16221 _getItemsAsjQuery: function( connected ) { |
|
16222 |
|
16223 var i, j, cur, inst, |
|
16224 items = [], |
|
16225 queries = [], |
|
16226 connectWith = this._connectWith(); |
|
16227 |
|
16228 if ( connectWith && connected ) { |
|
16229 for ( i = connectWith.length - 1; i >= 0; i-- ) { |
|
16230 cur = $( connectWith[ i ], this.document[ 0 ] ); |
|
16231 for ( j = cur.length - 1; j >= 0; j-- ) { |
|
16232 inst = $.data( cur[ j ], this.widgetFullName ); |
|
16233 if ( inst && inst !== this && !inst.options.disabled ) { |
|
16234 queries.push( [ typeof inst.options.items === "function" ? |
|
16235 inst.options.items.call( inst.element ) : |
|
16236 $( inst.options.items, inst.element ) |
|
16237 .not( ".ui-sortable-helper" ) |
|
16238 .not( ".ui-sortable-placeholder" ), inst ] ); |
|
16239 } |
|
16240 } |
|
16241 } |
|
16242 } |
|
16243 |
|
16244 queries.push( [ typeof this.options.items === "function" ? |
|
16245 this.options.items |
|
16246 .call( this.element, null, { options: this.options, item: this.currentItem } ) : |
|
16247 $( this.options.items, this.element ) |
|
16248 .not( ".ui-sortable-helper" ) |
|
16249 .not( ".ui-sortable-placeholder" ), this ] ); |
|
16250 |
|
16251 function addItems() { |
|
16252 items.push( this ); |
|
16253 } |
|
16254 for ( i = queries.length - 1; i >= 0; i-- ) { |
|
16255 queries[ i ][ 0 ].each( addItems ); |
|
16256 } |
|
16257 |
|
16258 return $( items ); |
|
16259 |
|
16260 }, |
|
16261 |
|
16262 _removeCurrentsFromItems: function() { |
|
16263 |
|
16264 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); |
|
16265 |
|
16266 this.items = $.grep( this.items, function( item ) { |
|
16267 for ( var j = 0; j < list.length; j++ ) { |
|
16268 if ( list[ j ] === item.item[ 0 ] ) { |
|
16269 return false; |
|
16270 } |
|
16271 } |
|
16272 return true; |
|
16273 } ); |
|
16274 |
|
16275 }, |
|
16276 |
|
16277 _refreshItems: function( event ) { |
|
16278 |
|
16279 this.items = []; |
|
16280 this.containers = [ this ]; |
|
16281 |
|
16282 var i, j, cur, inst, targetData, _queries, item, queriesLength, |
|
16283 items = this.items, |
|
16284 queries = [ [ typeof this.options.items === "function" ? |
|
16285 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : |
|
16286 $( this.options.items, this.element ), this ] ], |
|
16287 connectWith = this._connectWith(); |
|
16288 |
|
16289 //Shouldn't be run the first time through due to massive slow-down |
|
16290 if ( connectWith && this.ready ) { |
|
16291 for ( i = connectWith.length - 1; i >= 0; i-- ) { |
|
16292 cur = $( connectWith[ i ], this.document[ 0 ] ); |
|
16293 for ( j = cur.length - 1; j >= 0; j-- ) { |
|
16294 inst = $.data( cur[ j ], this.widgetFullName ); |
|
16295 if ( inst && inst !== this && !inst.options.disabled ) { |
|
16296 queries.push( [ typeof inst.options.items === "function" ? |
|
16297 inst.options.items |
|
16298 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : |
|
16299 $( inst.options.items, inst.element ), inst ] ); |
|
16300 this.containers.push( inst ); |
|
16301 } |
|
16302 } |
|
16303 } |
|
16304 } |
|
16305 |
|
16306 for ( i = queries.length - 1; i >= 0; i-- ) { |
|
16307 targetData = queries[ i ][ 1 ]; |
|
16308 _queries = queries[ i ][ 0 ]; |
|
16309 |
|
16310 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { |
|
16311 item = $( _queries[ j ] ); |
|
16312 |
|
16313 // Data for target checking (mouse manager) |
|
16314 item.data( this.widgetName + "-item", targetData ); |
|
16315 |
|
16316 items.push( { |
|
16317 item: item, |
|
16318 instance: targetData, |
|
16319 width: 0, height: 0, |
|
16320 left: 0, top: 0 |
|
16321 } ); |
|
16322 } |
|
16323 } |
|
16324 |
|
16325 }, |
|
16326 |
|
16327 _refreshItemPositions: function( fast ) { |
|
16328 var i, item, t, p; |
|
16329 |
|
16330 for ( i = this.items.length - 1; i >= 0; i-- ) { |
|
16331 item = this.items[ i ]; |
|
16332 |
|
16333 //We ignore calculating positions of all connected containers when we're not over them |
|
16334 if ( this.currentContainer && item.instance !== this.currentContainer && |
|
16335 item.item[ 0 ] !== this.currentItem[ 0 ] ) { |
|
16336 continue; |
|
16337 } |
|
16338 |
|
16339 t = this.options.toleranceElement ? |
|
16340 $( this.options.toleranceElement, item.item ) : |
|
16341 item.item; |
|
16342 |
|
16343 if ( !fast ) { |
|
16344 item.width = t.outerWidth(); |
|
16345 item.height = t.outerHeight(); |
|
16346 } |
|
16347 |
|
16348 p = t.offset(); |
|
16349 item.left = p.left; |
|
16350 item.top = p.top; |
|
16351 } |
|
16352 }, |
|
16353 |
|
16354 refreshPositions: function( fast ) { |
|
16355 |
|
16356 // Determine whether items are being displayed horizontally |
|
16357 this.floating = this.items.length ? |
|
16358 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : |
|
16359 false; |
|
16360 |
|
16361 // This has to be redone because due to the item being moved out/into the offsetParent, |
|
16362 // the offsetParent's position will change |
|
16363 if ( this.offsetParent && this.helper ) { |
|
16364 this.offset.parent = this._getParentOffset(); |
|
16365 } |
|
16366 |
|
16367 this._refreshItemPositions( fast ); |
|
16368 |
|
16369 var i, p; |
|
16370 |
|
16371 if ( this.options.custom && this.options.custom.refreshContainers ) { |
|
16372 this.options.custom.refreshContainers.call( this ); |
|
16373 } else { |
|
16374 for ( i = this.containers.length - 1; i >= 0; i-- ) { |
|
16375 p = this.containers[ i ].element.offset(); |
|
16376 this.containers[ i ].containerCache.left = p.left; |
|
16377 this.containers[ i ].containerCache.top = p.top; |
|
16378 this.containers[ i ].containerCache.width = |
|
16379 this.containers[ i ].element.outerWidth(); |
|
16380 this.containers[ i ].containerCache.height = |
|
16381 this.containers[ i ].element.outerHeight(); |
|
16382 } |
|
16383 } |
|
16384 |
|
16385 return this; |
|
16386 }, |
|
16387 |
|
16388 _createPlaceholder: function( that ) { |
|
16389 that = that || this; |
|
16390 var className, nodeName, |
|
16391 o = that.options; |
|
16392 |
|
16393 if ( !o.placeholder || o.placeholder.constructor === String ) { |
|
16394 className = o.placeholder; |
|
16395 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); |
|
16396 o.placeholder = { |
|
16397 element: function() { |
|
16398 |
|
16399 var element = $( "<" + nodeName + ">", that.document[ 0 ] ); |
|
16400 |
|
16401 that._addClass( element, "ui-sortable-placeholder", |
|
16402 className || that.currentItem[ 0 ].className ) |
|
16403 ._removeClass( element, "ui-sortable-helper" ); |
|
16404 |
|
16405 if ( nodeName === "tbody" ) { |
|
16406 that._createTrPlaceholder( |
|
16407 that.currentItem.find( "tr" ).eq( 0 ), |
|
16408 $( "<tr>", that.document[ 0 ] ).appendTo( element ) |
|
16409 ); |
|
16410 } else if ( nodeName === "tr" ) { |
|
16411 that._createTrPlaceholder( that.currentItem, element ); |
|
16412 } else if ( nodeName === "img" ) { |
|
16413 element.attr( "src", that.currentItem.attr( "src" ) ); |
|
16414 } |
|
16415 |
|
16416 if ( !className ) { |
|
16417 element.css( "visibility", "hidden" ); |
|
16418 } |
|
16419 |
|
16420 return element; |
|
16421 }, |
|
16422 update: function( container, p ) { |
|
16423 |
|
16424 // 1. If a className is set as 'placeholder option, we don't force sizes - |
|
16425 // the class is responsible for that |
|
16426 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a |
|
16427 // class name is specified |
|
16428 if ( className && !o.forcePlaceholderSize ) { |
|
16429 return; |
|
16430 } |
|
16431 |
|
16432 // If the element doesn't have a actual height or width by itself (without |
|
16433 // styles coming from a stylesheet), it receives the inline height and width |
|
16434 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height |
|
16435 // anyway since we're populating them with <td>s above, but they're unlikely to |
|
16436 // be the correct height on their own if the row heights are dynamic, so we'll |
|
16437 // always assign the height of the dragged item given forcePlaceholderSize |
|
16438 // is true. |
|
16439 if ( !p.height() || ( o.forcePlaceholderSize && |
|
16440 ( nodeName === "tbody" || nodeName === "tr" ) ) ) { |
|
16441 p.height( |
|
16442 that.currentItem.innerHeight() - |
|
16443 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - |
|
16444 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); |
|
16445 } |
|
16446 if ( !p.width() ) { |
|
16447 p.width( |
|
16448 that.currentItem.innerWidth() - |
|
16449 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - |
|
16450 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); |
|
16451 } |
|
16452 } |
|
16453 }; |
|
16454 } |
|
16455 |
|
16456 //Create the placeholder |
|
16457 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); |
|
16458 |
|
16459 //Append it after the actual current item |
|
16460 that.currentItem.after( that.placeholder ); |
|
16461 |
|
16462 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) |
|
16463 o.placeholder.update( that, that.placeholder ); |
|
16464 |
|
16465 }, |
|
16466 |
|
16467 _createTrPlaceholder: function( sourceTr, targetTr ) { |
|
16468 var that = this; |
|
16469 |
|
16470 sourceTr.children().each( function() { |
|
16471 $( "<td> </td>", that.document[ 0 ] ) |
|
16472 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) |
|
16473 .appendTo( targetTr ); |
|
16474 } ); |
|
16475 }, |
|
16476 |
|
16477 _contactContainers: function( event ) { |
|
16478 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, |
|
16479 floating, axis, |
|
16480 innermostContainer = null, |
|
16481 innermostIndex = null; |
|
16482 |
|
16483 // Get innermost container that intersects with item |
|
16484 for ( i = this.containers.length - 1; i >= 0; i-- ) { |
|
16485 |
|
16486 // Never consider a container that's located within the item itself |
|
16487 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { |
|
16488 continue; |
|
16489 } |
|
16490 |
|
16491 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { |
|
16492 |
|
16493 // If we've already found a container and it's more "inner" than this, then continue |
|
16494 if ( innermostContainer && |
|
16495 $.contains( |
|
16496 this.containers[ i ].element[ 0 ], |
|
16497 innermostContainer.element[ 0 ] ) ) { |
|
16498 continue; |
|
16499 } |
|
16500 |
|
16501 innermostContainer = this.containers[ i ]; |
|
16502 innermostIndex = i; |
|
16503 |
|
16504 } else { |
|
16505 |
|
16506 // container doesn't intersect. trigger "out" event if necessary |
|
16507 if ( this.containers[ i ].containerCache.over ) { |
|
16508 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); |
|
16509 this.containers[ i ].containerCache.over = 0; |
|
16510 } |
|
16511 } |
|
16512 |
|
16513 } |
|
16514 |
|
16515 // If no intersecting containers found, return |
|
16516 if ( !innermostContainer ) { |
|
16517 return; |
|
16518 } |
|
16519 |
|
16520 // Move the item into the container if it's not there already |
|
16521 if ( this.containers.length === 1 ) { |
|
16522 if ( !this.containers[ innermostIndex ].containerCache.over ) { |
|
16523 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); |
|
16524 this.containers[ innermostIndex ].containerCache.over = 1; |
|
16525 } |
|
16526 } else { |
|
16527 |
|
16528 // When entering a new container, we will find the item with the least distance and |
|
16529 // append our item near it |
|
16530 dist = 10000; |
|
16531 itemWithLeastDistance = null; |
|
16532 floating = innermostContainer.floating || this._isFloating( this.currentItem ); |
|
16533 posProperty = floating ? "left" : "top"; |
|
16534 sizeProperty = floating ? "width" : "height"; |
|
16535 axis = floating ? "pageX" : "pageY"; |
|
16536 |
|
16537 for ( j = this.items.length - 1; j >= 0; j-- ) { |
|
16538 if ( !$.contains( |
|
16539 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) |
|
16540 ) { |
|
16541 continue; |
|
16542 } |
|
16543 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { |
|
16544 continue; |
|
16545 } |
|
16546 |
|
16547 cur = this.items[ j ].item.offset()[ posProperty ]; |
|
16548 nearBottom = false; |
|
16549 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { |
|
16550 nearBottom = true; |
|
16551 } |
|
16552 |
|
16553 if ( Math.abs( event[ axis ] - cur ) < dist ) { |
|
16554 dist = Math.abs( event[ axis ] - cur ); |
|
16555 itemWithLeastDistance = this.items[ j ]; |
|
16556 this.direction = nearBottom ? "up" : "down"; |
|
16557 } |
|
16558 } |
|
16559 |
|
16560 //Check if dropOnEmpty is enabled |
|
16561 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { |
|
16562 return; |
|
16563 } |
|
16564 |
|
16565 if ( this.currentContainer === this.containers[ innermostIndex ] ) { |
|
16566 if ( !this.currentContainer.containerCache.over ) { |
|
16567 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); |
|
16568 this.currentContainer.containerCache.over = 1; |
|
16569 } |
|
16570 return; |
|
16571 } |
|
16572 |
|
16573 if ( itemWithLeastDistance ) { |
|
16574 this._rearrange( event, itemWithLeastDistance, null, true ); |
|
16575 } else { |
|
16576 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); |
|
16577 } |
|
16578 this._trigger( "change", event, this._uiHash() ); |
|
16579 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); |
|
16580 this.currentContainer = this.containers[ innermostIndex ]; |
|
16581 |
|
16582 //Update the placeholder |
|
16583 this.options.placeholder.update( this.currentContainer, this.placeholder ); |
|
16584 |
|
16585 //Update scrollParent |
|
16586 this.scrollParent = this.placeholder.scrollParent(); |
|
16587 |
|
16588 //Update overflowOffset |
|
16589 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && |
|
16590 this.scrollParent[ 0 ].tagName !== "HTML" ) { |
|
16591 this.overflowOffset = this.scrollParent.offset(); |
|
16592 } |
|
16593 |
|
16594 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); |
|
16595 this.containers[ innermostIndex ].containerCache.over = 1; |
|
16596 } |
|
16597 |
|
16598 }, |
|
16599 |
|
16600 _createHelper: function( event ) { |
|
16601 |
|
16602 var o = this.options, |
|
16603 helper = typeof o.helper === "function" ? |
|
16604 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : |
|
16605 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); |
|
16606 |
|
16607 //Add the helper to the DOM if that didn't happen already |
|
16608 if ( !helper.parents( "body" ).length ) { |
|
16609 this.appendTo[ 0 ].appendChild( helper[ 0 ] ); |
|
16610 } |
|
16611 |
|
16612 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { |
|
16613 this._storedCSS = { |
|
16614 width: this.currentItem[ 0 ].style.width, |
|
16615 height: this.currentItem[ 0 ].style.height, |
|
16616 position: this.currentItem.css( "position" ), |
|
16617 top: this.currentItem.css( "top" ), |
|
16618 left: this.currentItem.css( "left" ) |
|
16619 }; |
|
16620 } |
|
16621 |
|
16622 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { |
|
16623 helper.width( this.currentItem.width() ); |
|
16624 } |
|
16625 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { |
|
16626 helper.height( this.currentItem.height() ); |
|
16627 } |
|
16628 |
|
16629 return helper; |
|
16630 |
|
16631 }, |
|
16632 |
|
16633 _adjustOffsetFromHelper: function( obj ) { |
|
16634 if ( typeof obj === "string" ) { |
|
16635 obj = obj.split( " " ); |
|
16636 } |
|
16637 if ( Array.isArray( obj ) ) { |
|
16638 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; |
|
16639 } |
|
16640 if ( "left" in obj ) { |
|
16641 this.offset.click.left = obj.left + this.margins.left; |
|
16642 } |
|
16643 if ( "right" in obj ) { |
|
16644 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; |
|
16645 } |
|
16646 if ( "top" in obj ) { |
|
16647 this.offset.click.top = obj.top + this.margins.top; |
|
16648 } |
|
16649 if ( "bottom" in obj ) { |
|
16650 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; |
|
16651 } |
|
16652 }, |
|
16653 |
|
16654 _getParentOffset: function() { |
|
16655 |
|
16656 //Get the offsetParent and cache its position |
|
16657 this.offsetParent = this.helper.offsetParent(); |
|
16658 var po = this.offsetParent.offset(); |
|
16659 |
|
16660 // This is a special case where we need to modify a offset calculated on start, since the |
|
16661 // following happened: |
|
16662 // 1. The position of the helper is absolute, so it's position is calculated based on the |
|
16663 // next positioned parent |
|
16664 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't |
|
16665 // the document, which means that the scroll is included in the initial calculation of the |
|
16666 // offset of the parent, and never recalculated upon drag |
|
16667 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && |
|
16668 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { |
|
16669 po.left += this.scrollParent.scrollLeft(); |
|
16670 po.top += this.scrollParent.scrollTop(); |
|
16671 } |
|
16672 |
|
16673 // This needs to be actually done for all browsers, since pageX/pageY includes this |
|
16674 // information with an ugly IE fix |
|
16675 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || |
|
16676 ( this.offsetParent[ 0 ].tagName && |
|
16677 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { |
|
16678 po = { top: 0, left: 0 }; |
|
16679 } |
|
16680 |
|
16681 return { |
|
16682 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), |
|
16683 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) |
|
16684 }; |
|
16685 |
|
16686 }, |
|
16687 |
|
16688 _getRelativeOffset: function() { |
|
16689 |
|
16690 if ( this.cssPosition === "relative" ) { |
|
16691 var p = this.currentItem.position(); |
|
16692 return { |
|
16693 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + |
|
16694 this.scrollParent.scrollTop(), |
|
16695 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + |
|
16696 this.scrollParent.scrollLeft() |
|
16697 }; |
|
16698 } else { |
|
16699 return { top: 0, left: 0 }; |
|
16700 } |
|
16701 |
|
16702 }, |
|
16703 |
|
16704 _cacheMargins: function() { |
|
16705 this.margins = { |
|
16706 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), |
|
16707 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) |
|
16708 }; |
|
16709 }, |
|
16710 |
|
16711 _cacheHelperProportions: function() { |
|
16712 this.helperProportions = { |
|
16713 width: this.helper.outerWidth(), |
|
16714 height: this.helper.outerHeight() |
|
16715 }; |
|
16716 }, |
|
16717 |
|
16718 _setContainment: function() { |
|
16719 |
|
16720 var ce, co, over, |
|
16721 o = this.options; |
|
16722 if ( o.containment === "parent" ) { |
|
16723 o.containment = this.helper[ 0 ].parentNode; |
|
16724 } |
|
16725 if ( o.containment === "document" || o.containment === "window" ) { |
|
16726 this.containment = [ |
|
16727 0 - this.offset.relative.left - this.offset.parent.left, |
|
16728 0 - this.offset.relative.top - this.offset.parent.top, |
|
16729 o.containment === "document" ? |
|
16730 this.document.width() : |
|
16731 this.window.width() - this.helperProportions.width - this.margins.left, |
|
16732 ( o.containment === "document" ? |
|
16733 ( this.document.height() || document.body.parentNode.scrollHeight ) : |
|
16734 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight |
|
16735 ) - this.helperProportions.height - this.margins.top |
|
16736 ]; |
|
16737 } |
|
16738 |
|
16739 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { |
|
16740 ce = $( o.containment )[ 0 ]; |
|
16741 co = $( o.containment ).offset(); |
|
16742 over = ( $( ce ).css( "overflow" ) !== "hidden" ); |
|
16743 |
|
16744 this.containment = [ |
|
16745 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + |
|
16746 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, |
|
16747 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + |
|
16748 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, |
|
16749 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - |
|
16750 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - |
|
16751 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - |
|
16752 this.helperProportions.width - this.margins.left, |
|
16753 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - |
|
16754 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - |
|
16755 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - |
|
16756 this.helperProportions.height - this.margins.top |
|
16757 ]; |
|
16758 } |
|
16759 |
|
16760 }, |
|
16761 |
|
16762 _convertPositionTo: function( d, pos ) { |
|
16763 |
|
16764 if ( !pos ) { |
|
16765 pos = this.position; |
|
16766 } |
|
16767 var mod = d === "absolute" ? 1 : -1, |
|
16768 scroll = this.cssPosition === "absolute" && |
|
16769 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && |
|
16770 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? |
|
16771 this.offsetParent : |
|
16772 this.scrollParent, |
|
16773 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); |
|
16774 |
|
16775 return { |
|
16776 top: ( |
|
16777 |
|
16778 // The absolute mouse position |
|
16779 pos.top + |
|
16780 |
|
16781 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
16782 this.offset.relative.top * mod + |
|
16783 |
|
16784 // The offsetParent's offset without borders (offset + border) |
|
16785 this.offset.parent.top * mod - |
|
16786 ( ( this.cssPosition === "fixed" ? |
|
16787 -this.scrollParent.scrollTop() : |
|
16788 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) |
|
16789 ), |
|
16790 left: ( |
|
16791 |
|
16792 // The absolute mouse position |
|
16793 pos.left + |
|
16794 |
|
16795 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
16796 this.offset.relative.left * mod + |
|
16797 |
|
16798 // The offsetParent's offset without borders (offset + border) |
|
16799 this.offset.parent.left * mod - |
|
16800 ( ( this.cssPosition === "fixed" ? |
|
16801 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : |
|
16802 scroll.scrollLeft() ) * mod ) |
|
16803 ) |
|
16804 }; |
|
16805 |
|
16806 }, |
|
16807 |
|
16808 _generatePosition: function( event ) { |
|
16809 |
|
16810 var top, left, |
|
16811 o = this.options, |
|
16812 pageX = event.pageX, |
|
16813 pageY = event.pageY, |
|
16814 scroll = this.cssPosition === "absolute" && |
|
16815 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && |
|
16816 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? |
|
16817 this.offsetParent : |
|
16818 this.scrollParent, |
|
16819 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); |
|
16820 |
|
16821 // This is another very weird special case that only happens for relative elements: |
|
16822 // 1. If the css position is relative |
|
16823 // 2. and the scroll parent is the document or similar to the offset parent |
|
16824 // we have to refresh the relative offset during the scroll so there are no jumps |
|
16825 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && |
|
16826 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { |
|
16827 this.offset.relative = this._getRelativeOffset(); |
|
16828 } |
|
16829 |
|
16830 /* |
|
16831 * - Position constraining - |
|
16832 * Constrain the position to a mix of grid, containment. |
|
16833 */ |
|
16834 |
|
16835 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options |
|
16836 |
|
16837 if ( this.containment ) { |
|
16838 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { |
|
16839 pageX = this.containment[ 0 ] + this.offset.click.left; |
|
16840 } |
|
16841 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { |
|
16842 pageY = this.containment[ 1 ] + this.offset.click.top; |
|
16843 } |
|
16844 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { |
|
16845 pageX = this.containment[ 2 ] + this.offset.click.left; |
|
16846 } |
|
16847 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { |
|
16848 pageY = this.containment[ 3 ] + this.offset.click.top; |
|
16849 } |
|
16850 } |
|
16851 |
|
16852 if ( o.grid ) { |
|
16853 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / |
|
16854 o.grid[ 1 ] ) * o.grid[ 1 ]; |
|
16855 pageY = this.containment ? |
|
16856 ( ( top - this.offset.click.top >= this.containment[ 1 ] && |
|
16857 top - this.offset.click.top <= this.containment[ 3 ] ) ? |
|
16858 top : |
|
16859 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? |
|
16860 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : |
|
16861 top; |
|
16862 |
|
16863 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / |
|
16864 o.grid[ 0 ] ) * o.grid[ 0 ]; |
|
16865 pageX = this.containment ? |
|
16866 ( ( left - this.offset.click.left >= this.containment[ 0 ] && |
|
16867 left - this.offset.click.left <= this.containment[ 2 ] ) ? |
|
16868 left : |
|
16869 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? |
|
16870 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : |
|
16871 left; |
|
16872 } |
|
16873 |
|
16874 } |
|
16875 |
|
16876 return { |
|
16877 top: ( |
|
16878 |
|
16879 // The absolute mouse position |
|
16880 pageY - |
|
16881 |
|
16882 // Click offset (relative to the element) |
|
16883 this.offset.click.top - |
|
16884 |
|
16885 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
16886 this.offset.relative.top - |
|
16887 |
|
16888 // The offsetParent's offset without borders (offset + border) |
|
16889 this.offset.parent.top + |
|
16890 ( ( this.cssPosition === "fixed" ? |
|
16891 -this.scrollParent.scrollTop() : |
|
16892 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) |
|
16893 ), |
|
16894 left: ( |
|
16895 |
|
16896 // The absolute mouse position |
|
16897 pageX - |
|
16898 |
|
16899 // Click offset (relative to the element) |
|
16900 this.offset.click.left - |
|
16901 |
|
16902 // Only for relative positioned nodes: Relative offset from element to offset parent |
|
16903 this.offset.relative.left - |
|
16904 |
|
16905 // The offsetParent's offset without borders (offset + border) |
|
16906 this.offset.parent.left + |
|
16907 ( ( this.cssPosition === "fixed" ? |
|
16908 -this.scrollParent.scrollLeft() : |
|
16909 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) |
|
16910 ) |
|
16911 }; |
|
16912 |
|
16913 }, |
|
16914 |
|
16915 _rearrange: function( event, i, a, hardRefresh ) { |
|
16916 |
|
16917 if ( a ) { |
|
16918 a[ 0 ].appendChild( this.placeholder[ 0 ] ); |
|
16919 } else { |
|
16920 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], |
|
16921 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); |
|
16922 } |
|
16923 |
|
16924 //Various things done here to improve the performance: |
|
16925 // 1. we create a setTimeout, that calls refreshPositions |
|
16926 // 2. on the instance, we have a counter variable, that get's higher after every append |
|
16927 // 3. on the local scope, we copy the counter variable, and check in the timeout, |
|
16928 // if it's still the same |
|
16929 // 4. this lets only the last addition to the timeout stack through |
|
16930 this.counter = this.counter ? ++this.counter : 1; |
|
16931 var counter = this.counter; |
|
16932 |
|
16933 this._delay( function() { |
|
16934 if ( counter === this.counter ) { |
|
16935 |
|
16936 //Precompute after each DOM insertion, NOT on mousemove |
|
16937 this.refreshPositions( !hardRefresh ); |
|
16938 } |
|
16939 } ); |
|
16940 |
|
16941 }, |
|
16942 |
|
16943 _clear: function( event, noPropagation ) { |
|
16944 |
|
16945 this.reverting = false; |
|
16946 |
|
16947 // We delay all events that have to be triggered to after the point where the placeholder |
|
16948 // has been removed and everything else normalized again |
|
16949 var i, |
|
16950 delayedTriggers = []; |
|
16951 |
|
16952 // We first have to update the dom position of the actual currentItem |
|
16953 // Note: don't do it if the current item is already removed (by a user), or it gets |
|
16954 // reappended (see #4088) |
|
16955 if ( !this._noFinalSort && this.currentItem.parent().length ) { |
|
16956 this.placeholder.before( this.currentItem ); |
|
16957 } |
|
16958 this._noFinalSort = null; |
|
16959 |
|
16960 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { |
|
16961 for ( i in this._storedCSS ) { |
|
16962 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { |
|
16963 this._storedCSS[ i ] = ""; |
|
16964 } |
|
16965 } |
|
16966 this.currentItem.css( this._storedCSS ); |
|
16967 this._removeClass( this.currentItem, "ui-sortable-helper" ); |
|
16968 } else { |
|
16969 this.currentItem.show(); |
|
16970 } |
|
16971 |
|
16972 if ( this.fromOutside && !noPropagation ) { |
|
16973 delayedTriggers.push( function( event ) { |
|
16974 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); |
|
16975 } ); |
|
16976 } |
|
16977 if ( ( this.fromOutside || |
|
16978 this.domPosition.prev !== |
|
16979 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || |
|
16980 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { |
|
16981 |
|
16982 // Trigger update callback if the DOM position has changed |
|
16983 delayedTriggers.push( function( event ) { |
|
16984 this._trigger( "update", event, this._uiHash() ); |
|
16985 } ); |
|
16986 } |
|
16987 |
|
16988 // Check if the items Container has Changed and trigger appropriate |
|
16989 // events. |
|
16990 if ( this !== this.currentContainer ) { |
|
16991 if ( !noPropagation ) { |
|
16992 delayedTriggers.push( function( event ) { |
|
16993 this._trigger( "remove", event, this._uiHash() ); |
|
16994 } ); |
|
16995 delayedTriggers.push( ( function( c ) { |
|
16996 return function( event ) { |
|
16997 c._trigger( "receive", event, this._uiHash( this ) ); |
|
16998 }; |
|
16999 } ).call( this, this.currentContainer ) ); |
|
17000 delayedTriggers.push( ( function( c ) { |
|
17001 return function( event ) { |
|
17002 c._trigger( "update", event, this._uiHash( this ) ); |
|
17003 }; |
|
17004 } ).call( this, this.currentContainer ) ); |
|
17005 } |
|
17006 } |
|
17007 |
|
17008 //Post events to containers |
|
17009 function delayEvent( type, instance, container ) { |
|
17010 return function( event ) { |
|
17011 container._trigger( type, event, instance._uiHash( instance ) ); |
|
17012 }; |
|
17013 } |
|
17014 for ( i = this.containers.length - 1; i >= 0; i-- ) { |
|
17015 if ( !noPropagation ) { |
|
17016 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); |
|
17017 } |
|
17018 if ( this.containers[ i ].containerCache.over ) { |
|
17019 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); |
|
17020 this.containers[ i ].containerCache.over = 0; |
|
17021 } |
|
17022 } |
|
17023 |
|
17024 //Do what was originally in plugins |
|
17025 if ( this.storedCursor ) { |
|
17026 this.document.find( "body" ).css( "cursor", this.storedCursor ); |
|
17027 this.storedStylesheet.remove(); |
|
17028 } |
|
17029 if ( this._storedOpacity ) { |
|
17030 this.helper.css( "opacity", this._storedOpacity ); |
|
17031 } |
|
17032 if ( this._storedZIndex ) { |
|
17033 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); |
|
17034 } |
|
17035 |
|
17036 this.dragging = false; |
|
17037 |
|
17038 if ( !noPropagation ) { |
|
17039 this._trigger( "beforeStop", event, this._uiHash() ); |
|
17040 } |
|
17041 |
|
17042 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, |
|
17043 // it unbinds ALL events from the original node! |
|
17044 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); |
|
17045 |
|
17046 if ( !this.cancelHelperRemoval ) { |
|
17047 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { |
|
17048 this.helper.remove(); |
|
17049 } |
|
17050 this.helper = null; |
|
17051 } |
|
17052 |
|
17053 if ( !noPropagation ) { |
|
17054 for ( i = 0; i < delayedTriggers.length; i++ ) { |
|
17055 |
|
17056 // Trigger all delayed events |
|
17057 delayedTriggers[ i ].call( this, event ); |
|
17058 } |
|
17059 this._trigger( "stop", event, this._uiHash() ); |
|
17060 } |
|
17061 |
|
17062 this.fromOutside = false; |
|
17063 return !this.cancelHelperRemoval; |
|
17064 |
|
17065 }, |
|
17066 |
|
17067 _trigger: function() { |
|
17068 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { |
|
17069 this.cancel(); |
|
17070 } |
|
17071 }, |
|
17072 |
|
17073 _uiHash: function( _inst ) { |
|
17074 var inst = _inst || this; |
|
17075 return { |
|
17076 helper: inst.helper, |
|
17077 placeholder: inst.placeholder || $( [] ), |
|
17078 position: inst.position, |
|
17079 originalPosition: inst.originalPosition, |
|
17080 offset: inst.positionAbs, |
|
17081 item: inst.currentItem, |
|
17082 sender: _inst ? _inst.element : null |
|
17083 }; |
|
17084 } |
|
17085 |
|
17086 } ); |
|
17087 |
|
17088 |
|
17089 /*! |
|
17090 * jQuery UI Spinner 1.13.2 |
|
17091 * http://jqueryui.com |
|
17092 * |
|
17093 * Copyright jQuery Foundation and other contributors |
|
17094 * Released under the MIT license. |
|
17095 * http://jquery.org/license |
|
17096 */ |
|
17097 |
|
17098 //>>label: Spinner |
|
17099 //>>group: Widgets |
|
17100 //>>description: Displays buttons to easily input numbers via the keyboard or mouse. |
|
17101 //>>docs: http://api.jqueryui.com/spinner/ |
|
17102 //>>demos: http://jqueryui.com/spinner/ |
|
17103 //>>css.structure: ../../themes/base/core.css |
|
17104 //>>css.structure: ../../themes/base/spinner.css |
|
17105 //>>css.theme: ../../themes/base/theme.css |
|
17106 |
|
17107 |
|
17108 function spinnerModifier( fn ) { |
|
17109 return function() { |
|
17110 var previous = this.element.val(); |
|
17111 fn.apply( this, arguments ); |
|
17112 this._refresh(); |
|
17113 if ( previous !== this.element.val() ) { |
|
17114 this._trigger( "change" ); |
|
17115 } |
|
17116 }; |
|
17117 } |
|
17118 |
|
17119 $.widget( "ui.spinner", { |
|
17120 version: "1.13.2", |
|
17121 defaultElement: "<input>", |
|
17122 widgetEventPrefix: "spin", |
|
17123 options: { |
|
17124 classes: { |
|
17125 "ui-spinner": "ui-corner-all", |
|
17126 "ui-spinner-down": "ui-corner-br", |
|
17127 "ui-spinner-up": "ui-corner-tr" |
|
17128 }, |
|
17129 culture: null, |
|
17130 icons: { |
|
17131 down: "ui-icon-triangle-1-s", |
|
17132 up: "ui-icon-triangle-1-n" |
|
17133 }, |
|
17134 incremental: true, |
|
17135 max: null, |
|
17136 min: null, |
|
17137 numberFormat: null, |
|
17138 page: 10, |
|
17139 step: 1, |
|
17140 |
|
17141 change: null, |
|
17142 spin: null, |
|
17143 start: null, |
|
17144 stop: null |
|
17145 }, |
|
17146 |
|
17147 _create: function() { |
|
17148 |
|
17149 // handle string values that need to be parsed |
|
17150 this._setOption( "max", this.options.max ); |
|
17151 this._setOption( "min", this.options.min ); |
|
17152 this._setOption( "step", this.options.step ); |
|
17153 |
|
17154 // Only format if there is a value, prevents the field from being marked |
|
17155 // as invalid in Firefox, see #9573. |
|
17156 if ( this.value() !== "" ) { |
|
17157 |
|
17158 // Format the value, but don't constrain. |
|
17159 this._value( this.element.val(), true ); |
|
17160 } |
|
17161 |
|
17162 this._draw(); |
|
17163 this._on( this._events ); |
|
17164 this._refresh(); |
|
17165 |
|
17166 // Turning off autocomplete prevents the browser from remembering the |
|
17167 // value when navigating through history, so we re-enable autocomplete |
|
17168 // if the page is unloaded before the widget is destroyed. #7790 |
|
17169 this._on( this.window, { |
|
17170 beforeunload: function() { |
|
17171 this.element.removeAttr( "autocomplete" ); |
|
17172 } |
|
17173 } ); |
|
17174 }, |
|
17175 |
|
17176 _getCreateOptions: function() { |
|
17177 var options = this._super(); |
|
17178 var element = this.element; |
|
17179 |
|
17180 $.each( [ "min", "max", "step" ], function( i, option ) { |
|
17181 var value = element.attr( option ); |
|
17182 if ( value != null && value.length ) { |
|
17183 options[ option ] = value; |
|
17184 } |
|
17185 } ); |
|
17186 |
|
17187 return options; |
|
17188 }, |
|
17189 |
|
17190 _events: { |
|
17191 keydown: function( event ) { |
|
17192 if ( this._start( event ) && this._keydown( event ) ) { |
|
17193 event.preventDefault(); |
|
17194 } |
|
17195 }, |
|
17196 keyup: "_stop", |
|
17197 focus: function() { |
|
17198 this.previous = this.element.val(); |
|
17199 }, |
|
17200 blur: function( event ) { |
|
17201 if ( this.cancelBlur ) { |
|
17202 delete this.cancelBlur; |
|
17203 return; |
|
17204 } |
|
17205 |
|
17206 this._stop(); |
|
17207 this._refresh(); |
|
17208 if ( this.previous !== this.element.val() ) { |
|
17209 this._trigger( "change", event ); |
|
17210 } |
|
17211 }, |
|
17212 mousewheel: function( event, delta ) { |
|
17213 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); |
|
17214 var isActive = this.element[ 0 ] === activeElement; |
|
17215 |
|
17216 if ( !isActive || !delta ) { |
|
17217 return; |
|
17218 } |
|
17219 |
|
17220 if ( !this.spinning && !this._start( event ) ) { |
|
17221 return false; |
|
17222 } |
|
17223 |
|
17224 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); |
|
17225 clearTimeout( this.mousewheelTimer ); |
|
17226 this.mousewheelTimer = this._delay( function() { |
|
17227 if ( this.spinning ) { |
|
17228 this._stop( event ); |
|
17229 } |
|
17230 }, 100 ); |
|
17231 event.preventDefault(); |
|
17232 }, |
|
17233 "mousedown .ui-spinner-button": function( event ) { |
|
17234 var previous; |
|
17235 |
|
17236 // We never want the buttons to have focus; whenever the user is |
|
17237 // interacting with the spinner, the focus should be on the input. |
|
17238 // If the input is focused then this.previous is properly set from |
|
17239 // when the input first received focus. If the input is not focused |
|
17240 // then we need to set this.previous based on the value before spinning. |
|
17241 previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? |
|
17242 this.previous : this.element.val(); |
|
17243 function checkFocus() { |
|
17244 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); |
|
17245 if ( !isActive ) { |
|
17246 this.element.trigger( "focus" ); |
|
17247 this.previous = previous; |
|
17248 |
|
17249 // support: IE |
|
17250 // IE sets focus asynchronously, so we need to check if focus |
|
17251 // moved off of the input because the user clicked on the button. |
|
17252 this._delay( function() { |
|
17253 this.previous = previous; |
|
17254 } ); |
|
17255 } |
|
17256 } |
|
17257 |
|
17258 // Ensure focus is on (or stays on) the text field |
|
17259 event.preventDefault(); |
|
17260 checkFocus.call( this ); |
|
17261 |
|
17262 // Support: IE |
|
17263 // IE doesn't prevent moving focus even with event.preventDefault() |
|
17264 // so we set a flag to know when we should ignore the blur event |
|
17265 // and check (again) if focus moved off of the input. |
|
17266 this.cancelBlur = true; |
|
17267 this._delay( function() { |
|
17268 delete this.cancelBlur; |
|
17269 checkFocus.call( this ); |
|
17270 } ); |
|
17271 |
|
17272 if ( this._start( event ) === false ) { |
|
17273 return; |
|
17274 } |
|
17275 |
|
17276 this._repeat( null, $( event.currentTarget ) |
|
17277 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); |
|
17278 }, |
|
17279 "mouseup .ui-spinner-button": "_stop", |
|
17280 "mouseenter .ui-spinner-button": function( event ) { |
|
17281 |
|
17282 // button will add ui-state-active if mouse was down while mouseleave and kept down |
|
17283 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { |
|
17284 return; |
|
17285 } |
|
17286 |
|
17287 if ( this._start( event ) === false ) { |
|
17288 return false; |
|
17289 } |
|
17290 this._repeat( null, $( event.currentTarget ) |
|
17291 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); |
|
17292 }, |
|
17293 |
|
17294 // TODO: do we really want to consider this a stop? |
|
17295 // shouldn't we just stop the repeater and wait until mouseup before |
|
17296 // we trigger the stop event? |
|
17297 "mouseleave .ui-spinner-button": "_stop" |
|
17298 }, |
|
17299 |
|
17300 // Support mobile enhanced option and make backcompat more sane |
|
17301 _enhance: function() { |
|
17302 this.uiSpinner = this.element |
|
17303 .attr( "autocomplete", "off" ) |
|
17304 .wrap( "<span>" ) |
|
17305 .parent() |
|
17306 |
|
17307 // Add buttons |
|
17308 .append( |
|
17309 "<a></a><a></a>" |
|
17310 ); |
|
17311 }, |
|
17312 |
|
17313 _draw: function() { |
|
17314 this._enhance(); |
|
17315 |
|
17316 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); |
|
17317 this._addClass( "ui-spinner-input" ); |
|
17318 |
|
17319 this.element.attr( "role", "spinbutton" ); |
|
17320 |
|
17321 // Button bindings |
|
17322 this.buttons = this.uiSpinner.children( "a" ) |
|
17323 .attr( "tabIndex", -1 ) |
|
17324 .attr( "aria-hidden", true ) |
|
17325 .button( { |
|
17326 classes: { |
|
17327 "ui-button": "" |
|
17328 } |
|
17329 } ); |
|
17330 |
|
17331 // TODO: Right now button does not support classes this is already updated in button PR |
|
17332 this._removeClass( this.buttons, "ui-corner-all" ); |
|
17333 |
|
17334 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); |
|
17335 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); |
|
17336 this.buttons.first().button( { |
|
17337 "icon": this.options.icons.up, |
|
17338 "showLabel": false |
|
17339 } ); |
|
17340 this.buttons.last().button( { |
|
17341 "icon": this.options.icons.down, |
|
17342 "showLabel": false |
|
17343 } ); |
|
17344 |
|
17345 // IE 6 doesn't understand height: 50% for the buttons |
|
17346 // unless the wrapper has an explicit height |
|
17347 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && |
|
17348 this.uiSpinner.height() > 0 ) { |
|
17349 this.uiSpinner.height( this.uiSpinner.height() ); |
|
17350 } |
|
17351 }, |
|
17352 |
|
17353 _keydown: function( event ) { |
|
17354 var options = this.options, |
|
17355 keyCode = $.ui.keyCode; |
|
17356 |
|
17357 switch ( event.keyCode ) { |
|
17358 case keyCode.UP: |
|
17359 this._repeat( null, 1, event ); |
|
17360 return true; |
|
17361 case keyCode.DOWN: |
|
17362 this._repeat( null, -1, event ); |
|
17363 return true; |
|
17364 case keyCode.PAGE_UP: |
|
17365 this._repeat( null, options.page, event ); |
|
17366 return true; |
|
17367 case keyCode.PAGE_DOWN: |
|
17368 this._repeat( null, -options.page, event ); |
|
17369 return true; |
|
17370 } |
|
17371 |
|
17372 return false; |
|
17373 }, |
|
17374 |
|
17375 _start: function( event ) { |
|
17376 if ( !this.spinning && this._trigger( "start", event ) === false ) { |
|
17377 return false; |
|
17378 } |
|
17379 |
|
17380 if ( !this.counter ) { |
|
17381 this.counter = 1; |
|
17382 } |
|
17383 this.spinning = true; |
|
17384 return true; |
|
17385 }, |
|
17386 |
|
17387 _repeat: function( i, steps, event ) { |
|
17388 i = i || 500; |
|
17389 |
|
17390 clearTimeout( this.timer ); |
|
17391 this.timer = this._delay( function() { |
|
17392 this._repeat( 40, steps, event ); |
|
17393 }, i ); |
|
17394 |
|
17395 this._spin( steps * this.options.step, event ); |
|
17396 }, |
|
17397 |
|
17398 _spin: function( step, event ) { |
|
17399 var value = this.value() || 0; |
|
17400 |
|
17401 if ( !this.counter ) { |
|
17402 this.counter = 1; |
|
17403 } |
|
17404 |
|
17405 value = this._adjustValue( value + step * this._increment( this.counter ) ); |
|
17406 |
|
17407 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { |
|
17408 this._value( value ); |
|
17409 this.counter++; |
|
17410 } |
|
17411 }, |
|
17412 |
|
17413 _increment: function( i ) { |
|
17414 var incremental = this.options.incremental; |
|
17415 |
|
17416 if ( incremental ) { |
|
17417 return typeof incremental === "function" ? |
|
17418 incremental( i ) : |
|
17419 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); |
|
17420 } |
|
17421 |
|
17422 return 1; |
|
17423 }, |
|
17424 |
|
17425 _precision: function() { |
|
17426 var precision = this._precisionOf( this.options.step ); |
|
17427 if ( this.options.min !== null ) { |
|
17428 precision = Math.max( precision, this._precisionOf( this.options.min ) ); |
|
17429 } |
|
17430 return precision; |
|
17431 }, |
|
17432 |
|
17433 _precisionOf: function( num ) { |
|
17434 var str = num.toString(), |
|
17435 decimal = str.indexOf( "." ); |
|
17436 return decimal === -1 ? 0 : str.length - decimal - 1; |
|
17437 }, |
|
17438 |
|
17439 _adjustValue: function( value ) { |
|
17440 var base, aboveMin, |
|
17441 options = this.options; |
|
17442 |
|
17443 // Make sure we're at a valid step |
|
17444 // - find out where we are relative to the base (min or 0) |
|
17445 base = options.min !== null ? options.min : 0; |
|
17446 aboveMin = value - base; |
|
17447 |
|
17448 // - round to the nearest step |
|
17449 aboveMin = Math.round( aboveMin / options.step ) * options.step; |
|
17450 |
|
17451 // - rounding is based on 0, so adjust back to our base |
|
17452 value = base + aboveMin; |
|
17453 |
|
17454 // Fix precision from bad JS floating point math |
|
17455 value = parseFloat( value.toFixed( this._precision() ) ); |
|
17456 |
|
17457 // Clamp the value |
|
17458 if ( options.max !== null && value > options.max ) { |
|
17459 return options.max; |
|
17460 } |
|
17461 if ( options.min !== null && value < options.min ) { |
|
17462 return options.min; |
|
17463 } |
|
17464 |
|
17465 return value; |
|
17466 }, |
|
17467 |
|
17468 _stop: function( event ) { |
|
17469 if ( !this.spinning ) { |
|
17470 return; |
|
17471 } |
|
17472 |
|
17473 clearTimeout( this.timer ); |
|
17474 clearTimeout( this.mousewheelTimer ); |
|
17475 this.counter = 0; |
|
17476 this.spinning = false; |
|
17477 this._trigger( "stop", event ); |
|
17478 }, |
|
17479 |
|
17480 _setOption: function( key, value ) { |
|
17481 var prevValue, first, last; |
|
17482 |
|
17483 if ( key === "culture" || key === "numberFormat" ) { |
|
17484 prevValue = this._parse( this.element.val() ); |
|
17485 this.options[ key ] = value; |
|
17486 this.element.val( this._format( prevValue ) ); |
|
17487 return; |
|
17488 } |
|
17489 |
|
17490 if ( key === "max" || key === "min" || key === "step" ) { |
|
17491 if ( typeof value === "string" ) { |
|
17492 value = this._parse( value ); |
|
17493 } |
|
17494 } |
|
17495 if ( key === "icons" ) { |
|
17496 first = this.buttons.first().find( ".ui-icon" ); |
|
17497 this._removeClass( first, null, this.options.icons.up ); |
|
17498 this._addClass( first, null, value.up ); |
|
17499 last = this.buttons.last().find( ".ui-icon" ); |
|
17500 this._removeClass( last, null, this.options.icons.down ); |
|
17501 this._addClass( last, null, value.down ); |
|
17502 } |
|
17503 |
|
17504 this._super( key, value ); |
|
17505 }, |
|
17506 |
|
17507 _setOptionDisabled: function( value ) { |
|
17508 this._super( value ); |
|
17509 |
|
17510 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); |
|
17511 this.element.prop( "disabled", !!value ); |
|
17512 this.buttons.button( value ? "disable" : "enable" ); |
|
17513 }, |
|
17514 |
|
17515 _setOptions: spinnerModifier( function( options ) { |
|
17516 this._super( options ); |
|
17517 } ), |
|
17518 |
|
17519 _parse: function( val ) { |
|
17520 if ( typeof val === "string" && val !== "" ) { |
|
17521 val = window.Globalize && this.options.numberFormat ? |
|
17522 Globalize.parseFloat( val, 10, this.options.culture ) : +val; |
|
17523 } |
|
17524 return val === "" || isNaN( val ) ? null : val; |
|
17525 }, |
|
17526 |
|
17527 _format: function( value ) { |
|
17528 if ( value === "" ) { |
|
17529 return ""; |
|
17530 } |
|
17531 return window.Globalize && this.options.numberFormat ? |
|
17532 Globalize.format( value, this.options.numberFormat, this.options.culture ) : |
|
17533 value; |
|
17534 }, |
|
17535 |
|
17536 _refresh: function() { |
|
17537 this.element.attr( { |
|
17538 "aria-valuemin": this.options.min, |
|
17539 "aria-valuemax": this.options.max, |
|
17540 |
|
17541 // TODO: what should we do with values that can't be parsed? |
|
17542 "aria-valuenow": this._parse( this.element.val() ) |
|
17543 } ); |
|
17544 }, |
|
17545 |
|
17546 isValid: function() { |
|
17547 var value = this.value(); |
|
17548 |
|
17549 // Null is invalid |
|
17550 if ( value === null ) { |
|
17551 return false; |
|
17552 } |
|
17553 |
|
17554 // If value gets adjusted, it's invalid |
|
17555 return value === this._adjustValue( value ); |
|
17556 }, |
|
17557 |
|
17558 // Update the value without triggering change |
|
17559 _value: function( value, allowAny ) { |
|
17560 var parsed; |
|
17561 if ( value !== "" ) { |
|
17562 parsed = this._parse( value ); |
|
17563 if ( parsed !== null ) { |
|
17564 if ( !allowAny ) { |
|
17565 parsed = this._adjustValue( parsed ); |
|
17566 } |
|
17567 value = this._format( parsed ); |
|
17568 } |
|
17569 } |
|
17570 this.element.val( value ); |
|
17571 this._refresh(); |
|
17572 }, |
|
17573 |
|
17574 _destroy: function() { |
|
17575 this.element |
|
17576 .prop( "disabled", false ) |
|
17577 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); |
|
17578 |
|
17579 this.uiSpinner.replaceWith( this.element ); |
|
17580 }, |
|
17581 |
|
17582 stepUp: spinnerModifier( function( steps ) { |
|
17583 this._stepUp( steps ); |
|
17584 } ), |
|
17585 _stepUp: function( steps ) { |
|
17586 if ( this._start() ) { |
|
17587 this._spin( ( steps || 1 ) * this.options.step ); |
|
17588 this._stop(); |
|
17589 } |
|
17590 }, |
|
17591 |
|
17592 stepDown: spinnerModifier( function( steps ) { |
|
17593 this._stepDown( steps ); |
|
17594 } ), |
|
17595 _stepDown: function( steps ) { |
|
17596 if ( this._start() ) { |
|
17597 this._spin( ( steps || 1 ) * -this.options.step ); |
|
17598 this._stop(); |
|
17599 } |
|
17600 }, |
|
17601 |
|
17602 pageUp: spinnerModifier( function( pages ) { |
|
17603 this._stepUp( ( pages || 1 ) * this.options.page ); |
|
17604 } ), |
|
17605 |
|
17606 pageDown: spinnerModifier( function( pages ) { |
|
17607 this._stepDown( ( pages || 1 ) * this.options.page ); |
|
17608 } ), |
|
17609 |
|
17610 value: function( newVal ) { |
|
17611 if ( !arguments.length ) { |
|
17612 return this._parse( this.element.val() ); |
|
17613 } |
|
17614 spinnerModifier( this._value ).call( this, newVal ); |
|
17615 }, |
|
17616 |
|
17617 widget: function() { |
|
17618 return this.uiSpinner; |
|
17619 } |
|
17620 } ); |
|
17621 |
|
17622 // DEPRECATED |
|
17623 // TODO: switch return back to widget declaration at top of file when this is removed |
|
17624 if ( $.uiBackCompat !== false ) { |
|
17625 |
|
17626 // Backcompat for spinner html extension points |
|
17627 $.widget( "ui.spinner", $.ui.spinner, { |
|
17628 _enhance: function() { |
|
17629 this.uiSpinner = this.element |
|
17630 .attr( "autocomplete", "off" ) |
|
17631 .wrap( this._uiSpinnerHtml() ) |
|
17632 .parent() |
|
17633 |
|
17634 // Add buttons |
|
17635 .append( this._buttonHtml() ); |
|
17636 }, |
|
17637 _uiSpinnerHtml: function() { |
|
17638 return "<span>"; |
|
17639 }, |
|
17640 |
|
17641 _buttonHtml: function() { |
|
17642 return "<a></a><a></a>"; |
|
17643 } |
|
17644 } ); |
|
17645 } |
|
17646 |
|
17647 var widgetsSpinner = $.ui.spinner; |
|
17648 |
|
17649 |
|
17650 /*! |
|
17651 * jQuery UI Tabs 1.13.2 |
|
17652 * http://jqueryui.com |
|
17653 * |
|
17654 * Copyright jQuery Foundation and other contributors |
|
17655 * Released under the MIT license. |
|
17656 * http://jquery.org/license |
|
17657 */ |
|
17658 |
|
17659 //>>label: Tabs |
|
17660 //>>group: Widgets |
|
17661 //>>description: Transforms a set of container elements into a tab structure. |
|
17662 //>>docs: http://api.jqueryui.com/tabs/ |
|
17663 //>>demos: http://jqueryui.com/tabs/ |
|
17664 //>>css.structure: ../../themes/base/core.css |
|
17665 //>>css.structure: ../../themes/base/tabs.css |
|
17666 //>>css.theme: ../../themes/base/theme.css |
|
17667 |
|
17668 |
|
17669 $.widget( "ui.tabs", { |
|
17670 version: "1.13.2", |
|
17671 delay: 300, |
|
17672 options: { |
|
17673 active: null, |
|
17674 classes: { |
|
17675 "ui-tabs": "ui-corner-all", |
|
17676 "ui-tabs-nav": "ui-corner-all", |
|
17677 "ui-tabs-panel": "ui-corner-bottom", |
|
17678 "ui-tabs-tab": "ui-corner-top" |
|
17679 }, |
|
17680 collapsible: false, |
|
17681 event: "click", |
|
17682 heightStyle: "content", |
|
17683 hide: null, |
|
17684 show: null, |
|
17685 |
|
17686 // Callbacks |
|
17687 activate: null, |
|
17688 beforeActivate: null, |
|
17689 beforeLoad: null, |
|
17690 load: null |
|
17691 }, |
|
17692 |
|
17693 _isLocal: ( function() { |
|
17694 var rhash = /#.*$/; |
|
17695 |
|
17696 return function( anchor ) { |
|
17697 var anchorUrl, locationUrl; |
|
17698 |
|
17699 anchorUrl = anchor.href.replace( rhash, "" ); |
|
17700 locationUrl = location.href.replace( rhash, "" ); |
|
17701 |
|
17702 // Decoding may throw an error if the URL isn't UTF-8 (#9518) |
|
17703 try { |
|
17704 anchorUrl = decodeURIComponent( anchorUrl ); |
|
17705 } catch ( error ) {} |
|
17706 try { |
|
17707 locationUrl = decodeURIComponent( locationUrl ); |
|
17708 } catch ( error ) {} |
|
17709 |
|
17710 return anchor.hash.length > 1 && anchorUrl === locationUrl; |
|
17711 }; |
|
17712 } )(), |
|
17713 |
|
17714 _create: function() { |
|
17715 var that = this, |
|
17716 options = this.options; |
|
17717 |
|
17718 this.running = false; |
|
17719 |
|
17720 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); |
|
17721 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); |
|
17722 |
|
17723 this._processTabs(); |
|
17724 options.active = this._initialActive(); |
|
17725 |
|
17726 // Take disabling tabs via class attribute from HTML |
|
17727 // into account and update option properly. |
|
17728 if ( Array.isArray( options.disabled ) ) { |
|
17729 options.disabled = $.uniqueSort( options.disabled.concat( |
|
17730 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { |
|
17731 return that.tabs.index( li ); |
|
17732 } ) |
|
17733 ) ).sort(); |
|
17734 } |
|
17735 |
|
17736 // Check for length avoids error when initializing empty list |
|
17737 if ( this.options.active !== false && this.anchors.length ) { |
|
17738 this.active = this._findActive( options.active ); |
|
17739 } else { |
|
17740 this.active = $(); |
|
17741 } |
|
17742 |
|
17743 this._refresh(); |
|
17744 |
|
17745 if ( this.active.length ) { |
|
17746 this.load( options.active ); |
|
17747 } |
|
17748 }, |
|
17749 |
|
17750 _initialActive: function() { |
|
17751 var active = this.options.active, |
|
17752 collapsible = this.options.collapsible, |
|
17753 locationHash = location.hash.substring( 1 ); |
|
17754 |
|
17755 if ( active === null ) { |
|
17756 |
|
17757 // check the fragment identifier in the URL |
|
17758 if ( locationHash ) { |
|
17759 this.tabs.each( function( i, tab ) { |
|
17760 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { |
|
17761 active = i; |
|
17762 return false; |
|
17763 } |
|
17764 } ); |
|
17765 } |
|
17766 |
|
17767 // Check for a tab marked active via a class |
|
17768 if ( active === null ) { |
|
17769 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); |
|
17770 } |
|
17771 |
|
17772 // No active tab, set to false |
|
17773 if ( active === null || active === -1 ) { |
|
17774 active = this.tabs.length ? 0 : false; |
|
17775 } |
|
17776 } |
|
17777 |
|
17778 // Handle numbers: negative, out of range |
|
17779 if ( active !== false ) { |
|
17780 active = this.tabs.index( this.tabs.eq( active ) ); |
|
17781 if ( active === -1 ) { |
|
17782 active = collapsible ? false : 0; |
|
17783 } |
|
17784 } |
|
17785 |
|
17786 // Don't allow collapsible: false and active: false |
|
17787 if ( !collapsible && active === false && this.anchors.length ) { |
|
17788 active = 0; |
|
17789 } |
|
17790 |
|
17791 return active; |
|
17792 }, |
|
17793 |
|
17794 _getCreateEventData: function() { |
|
17795 return { |
|
17796 tab: this.active, |
|
17797 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) |
|
17798 }; |
|
17799 }, |
|
17800 |
|
17801 _tabKeydown: function( event ) { |
|
17802 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), |
|
17803 selectedIndex = this.tabs.index( focusedTab ), |
|
17804 goingForward = true; |
|
17805 |
|
17806 if ( this._handlePageNav( event ) ) { |
|
17807 return; |
|
17808 } |
|
17809 |
|
17810 switch ( event.keyCode ) { |
|
17811 case $.ui.keyCode.RIGHT: |
|
17812 case $.ui.keyCode.DOWN: |
|
17813 selectedIndex++; |
|
17814 break; |
|
17815 case $.ui.keyCode.UP: |
|
17816 case $.ui.keyCode.LEFT: |
|
17817 goingForward = false; |
|
17818 selectedIndex--; |
|
17819 break; |
|
17820 case $.ui.keyCode.END: |
|
17821 selectedIndex = this.anchors.length - 1; |
|
17822 break; |
|
17823 case $.ui.keyCode.HOME: |
|
17824 selectedIndex = 0; |
|
17825 break; |
|
17826 case $.ui.keyCode.SPACE: |
|
17827 |
|
17828 // Activate only, no collapsing |
|
17829 event.preventDefault(); |
|
17830 clearTimeout( this.activating ); |
|
17831 this._activate( selectedIndex ); |
|
17832 return; |
|
17833 case $.ui.keyCode.ENTER: |
|
17834 |
|
17835 // Toggle (cancel delayed activation, allow collapsing) |
|
17836 event.preventDefault(); |
|
17837 clearTimeout( this.activating ); |
|
17838 |
|
17839 // Determine if we should collapse or activate |
|
17840 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); |
|
17841 return; |
|
17842 default: |
|
17843 return; |
|
17844 } |
|
17845 |
|
17846 // Focus the appropriate tab, based on which key was pressed |
|
17847 event.preventDefault(); |
|
17848 clearTimeout( this.activating ); |
|
17849 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); |
|
17850 |
|
17851 // Navigating with control/command key will prevent automatic activation |
|
17852 if ( !event.ctrlKey && !event.metaKey ) { |
|
17853 |
|
17854 // Update aria-selected immediately so that AT think the tab is already selected. |
|
17855 // Otherwise AT may confuse the user by stating that they need to activate the tab, |
|
17856 // but the tab will already be activated by the time the announcement finishes. |
|
17857 focusedTab.attr( "aria-selected", "false" ); |
|
17858 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); |
|
17859 |
|
17860 this.activating = this._delay( function() { |
|
17861 this.option( "active", selectedIndex ); |
|
17862 }, this.delay ); |
|
17863 } |
|
17864 }, |
|
17865 |
|
17866 _panelKeydown: function( event ) { |
|
17867 if ( this._handlePageNav( event ) ) { |
|
17868 return; |
|
17869 } |
|
17870 |
|
17871 // Ctrl+up moves focus to the current tab |
|
17872 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { |
|
17873 event.preventDefault(); |
|
17874 this.active.trigger( "focus" ); |
|
17875 } |
|
17876 }, |
|
17877 |
|
17878 // Alt+page up/down moves focus to the previous/next tab (and activates) |
|
17879 _handlePageNav: function( event ) { |
|
17880 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { |
|
17881 this._activate( this._focusNextTab( this.options.active - 1, false ) ); |
|
17882 return true; |
|
17883 } |
|
17884 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { |
|
17885 this._activate( this._focusNextTab( this.options.active + 1, true ) ); |
|
17886 return true; |
|
17887 } |
|
17888 }, |
|
17889 |
|
17890 _findNextTab: function( index, goingForward ) { |
|
17891 var lastTabIndex = this.tabs.length - 1; |
|
17892 |
|
17893 function constrain() { |
|
17894 if ( index > lastTabIndex ) { |
|
17895 index = 0; |
|
17896 } |
|
17897 if ( index < 0 ) { |
|
17898 index = lastTabIndex; |
|
17899 } |
|
17900 return index; |
|
17901 } |
|
17902 |
|
17903 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { |
|
17904 index = goingForward ? index + 1 : index - 1; |
|
17905 } |
|
17906 |
|
17907 return index; |
|
17908 }, |
|
17909 |
|
17910 _focusNextTab: function( index, goingForward ) { |
|
17911 index = this._findNextTab( index, goingForward ); |
|
17912 this.tabs.eq( index ).trigger( "focus" ); |
|
17913 return index; |
|
17914 }, |
|
17915 |
|
17916 _setOption: function( key, value ) { |
|
17917 if ( key === "active" ) { |
|
17918 |
|
17919 // _activate() will handle invalid values and update this.options |
|
17920 this._activate( value ); |
|
17921 return; |
|
17922 } |
|
17923 |
|
17924 this._super( key, value ); |
|
17925 |
|
17926 if ( key === "collapsible" ) { |
|
17927 this._toggleClass( "ui-tabs-collapsible", null, value ); |
|
17928 |
|
17929 // Setting collapsible: false while collapsed; open first panel |
|
17930 if ( !value && this.options.active === false ) { |
|
17931 this._activate( 0 ); |
|
17932 } |
|
17933 } |
|
17934 |
|
17935 if ( key === "event" ) { |
|
17936 this._setupEvents( value ); |
|
17937 } |
|
17938 |
|
17939 if ( key === "heightStyle" ) { |
|
17940 this._setupHeightStyle( value ); |
|
17941 } |
|
17942 }, |
|
17943 |
|
17944 _sanitizeSelector: function( hash ) { |
|
17945 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; |
|
17946 }, |
|
17947 |
|
17948 refresh: function() { |
|
17949 var options = this.options, |
|
17950 lis = this.tablist.children( ":has(a[href])" ); |
|
17951 |
|
17952 // Get disabled tabs from class attribute from HTML |
|
17953 // this will get converted to a boolean if needed in _refresh() |
|
17954 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { |
|
17955 return lis.index( tab ); |
|
17956 } ); |
|
17957 |
|
17958 this._processTabs(); |
|
17959 |
|
17960 // Was collapsed or no tabs |
|
17961 if ( options.active === false || !this.anchors.length ) { |
|
17962 options.active = false; |
|
17963 this.active = $(); |
|
17964 |
|
17965 // was active, but active tab is gone |
|
17966 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { |
|
17967 |
|
17968 // all remaining tabs are disabled |
|
17969 if ( this.tabs.length === options.disabled.length ) { |
|
17970 options.active = false; |
|
17971 this.active = $(); |
|
17972 |
|
17973 // activate previous tab |
|
17974 } else { |
|
17975 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); |
|
17976 } |
|
17977 |
|
17978 // was active, active tab still exists |
|
17979 } else { |
|
17980 |
|
17981 // make sure active index is correct |
|
17982 options.active = this.tabs.index( this.active ); |
|
17983 } |
|
17984 |
|
17985 this._refresh(); |
|
17986 }, |
|
17987 |
|
17988 _refresh: function() { |
|
17989 this._setOptionDisabled( this.options.disabled ); |
|
17990 this._setupEvents( this.options.event ); |
|
17991 this._setupHeightStyle( this.options.heightStyle ); |
|
17992 |
|
17993 this.tabs.not( this.active ).attr( { |
|
17994 "aria-selected": "false", |
|
17995 "aria-expanded": "false", |
|
17996 tabIndex: -1 |
|
17997 } ); |
|
17998 this.panels.not( this._getPanelForTab( this.active ) ) |
|
17999 .hide() |
|
18000 .attr( { |
|
18001 "aria-hidden": "true" |
|
18002 } ); |
|
18003 |
|
18004 // Make sure one tab is in the tab order |
|
18005 if ( !this.active.length ) { |
|
18006 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); |
|
18007 } else { |
|
18008 this.active |
|
18009 .attr( { |
|
18010 "aria-selected": "true", |
|
18011 "aria-expanded": "true", |
|
18012 tabIndex: 0 |
|
18013 } ); |
|
18014 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); |
|
18015 this._getPanelForTab( this.active ) |
|
18016 .show() |
|
18017 .attr( { |
|
18018 "aria-hidden": "false" |
|
18019 } ); |
|
18020 } |
|
18021 }, |
|
18022 |
|
18023 _processTabs: function() { |
|
18024 var that = this, |
|
18025 prevTabs = this.tabs, |
|
18026 prevAnchors = this.anchors, |
|
18027 prevPanels = this.panels; |
|
18028 |
|
18029 this.tablist = this._getList().attr( "role", "tablist" ); |
|
18030 this._addClass( this.tablist, "ui-tabs-nav", |
|
18031 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); |
|
18032 |
|
18033 // Prevent users from focusing disabled tabs via click |
|
18034 this.tablist |
|
18035 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { |
|
18036 if ( $( this ).is( ".ui-state-disabled" ) ) { |
|
18037 event.preventDefault(); |
|
18038 } |
|
18039 } ) |
|
18040 |
|
18041 // Support: IE <9 |
|
18042 // Preventing the default action in mousedown doesn't prevent IE |
|
18043 // from focusing the element, so if the anchor gets focused, blur. |
|
18044 // We don't have to worry about focusing the previously focused |
|
18045 // element since clicking on a non-focusable element should focus |
|
18046 // the body anyway. |
|
18047 .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { |
|
18048 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { |
|
18049 this.blur(); |
|
18050 } |
|
18051 } ); |
|
18052 |
|
18053 this.tabs = this.tablist.find( "> li:has(a[href])" ) |
|
18054 .attr( { |
|
18055 role: "tab", |
|
18056 tabIndex: -1 |
|
18057 } ); |
|
18058 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); |
|
18059 |
|
18060 this.anchors = this.tabs.map( function() { |
|
18061 return $( "a", this )[ 0 ]; |
|
18062 } ) |
|
18063 .attr( { |
|
18064 tabIndex: -1 |
|
18065 } ); |
|
18066 this._addClass( this.anchors, "ui-tabs-anchor" ); |
|
18067 |
|
18068 this.panels = $(); |
|
18069 |
|
18070 this.anchors.each( function( i, anchor ) { |
|
18071 var selector, panel, panelId, |
|
18072 anchorId = $( anchor ).uniqueId().attr( "id" ), |
|
18073 tab = $( anchor ).closest( "li" ), |
|
18074 originalAriaControls = tab.attr( "aria-controls" ); |
|
18075 |
|
18076 // Inline tab |
|
18077 if ( that._isLocal( anchor ) ) { |
|
18078 selector = anchor.hash; |
|
18079 panelId = selector.substring( 1 ); |
|
18080 panel = that.element.find( that._sanitizeSelector( selector ) ); |
|
18081 |
|
18082 // remote tab |
|
18083 } else { |
|
18084 |
|
18085 // If the tab doesn't already have aria-controls, |
|
18086 // generate an id by using a throw-away element |
|
18087 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; |
|
18088 selector = "#" + panelId; |
|
18089 panel = that.element.find( selector ); |
|
18090 if ( !panel.length ) { |
|
18091 panel = that._createPanel( panelId ); |
|
18092 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); |
|
18093 } |
|
18094 panel.attr( "aria-live", "polite" ); |
|
18095 } |
|
18096 |
|
18097 if ( panel.length ) { |
|
18098 that.panels = that.panels.add( panel ); |
|
18099 } |
|
18100 if ( originalAriaControls ) { |
|
18101 tab.data( "ui-tabs-aria-controls", originalAriaControls ); |
|
18102 } |
|
18103 tab.attr( { |
|
18104 "aria-controls": panelId, |
|
18105 "aria-labelledby": anchorId |
|
18106 } ); |
|
18107 panel.attr( "aria-labelledby", anchorId ); |
|
18108 } ); |
|
18109 |
|
18110 this.panels.attr( "role", "tabpanel" ); |
|
18111 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); |
|
18112 |
|
18113 // Avoid memory leaks (#10056) |
|
18114 if ( prevTabs ) { |
|
18115 this._off( prevTabs.not( this.tabs ) ); |
|
18116 this._off( prevAnchors.not( this.anchors ) ); |
|
18117 this._off( prevPanels.not( this.panels ) ); |
|
18118 } |
|
18119 }, |
|
18120 |
|
18121 // Allow overriding how to find the list for rare usage scenarios (#7715) |
|
18122 _getList: function() { |
|
18123 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); |
|
18124 }, |
|
18125 |
|
18126 _createPanel: function( id ) { |
|
18127 return $( "<div>" ) |
|
18128 .attr( "id", id ) |
|
18129 .data( "ui-tabs-destroy", true ); |
|
18130 }, |
|
18131 |
|
18132 _setOptionDisabled: function( disabled ) { |
|
18133 var currentItem, li, i; |
|
18134 |
|
18135 if ( Array.isArray( disabled ) ) { |
|
18136 if ( !disabled.length ) { |
|
18137 disabled = false; |
|
18138 } else if ( disabled.length === this.anchors.length ) { |
|
18139 disabled = true; |
|
18140 } |
|
18141 } |
|
18142 |
|
18143 // Disable tabs |
|
18144 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { |
|
18145 currentItem = $( li ); |
|
18146 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { |
|
18147 currentItem.attr( "aria-disabled", "true" ); |
|
18148 this._addClass( currentItem, null, "ui-state-disabled" ); |
|
18149 } else { |
|
18150 currentItem.removeAttr( "aria-disabled" ); |
|
18151 this._removeClass( currentItem, null, "ui-state-disabled" ); |
|
18152 } |
|
18153 } |
|
18154 |
|
18155 this.options.disabled = disabled; |
|
18156 |
|
18157 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, |
|
18158 disabled === true ); |
|
18159 }, |
|
18160 |
|
18161 _setupEvents: function( event ) { |
|
18162 var events = {}; |
|
18163 if ( event ) { |
|
18164 $.each( event.split( " " ), function( index, eventName ) { |
|
18165 events[ eventName ] = "_eventHandler"; |
|
18166 } ); |
|
18167 } |
|
18168 |
|
18169 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); |
|
18170 |
|
18171 // Always prevent the default action, even when disabled |
|
18172 this._on( true, this.anchors, { |
|
18173 click: function( event ) { |
|
18174 event.preventDefault(); |
|
18175 } |
|
18176 } ); |
|
18177 this._on( this.anchors, events ); |
|
18178 this._on( this.tabs, { keydown: "_tabKeydown" } ); |
|
18179 this._on( this.panels, { keydown: "_panelKeydown" } ); |
|
18180 |
|
18181 this._focusable( this.tabs ); |
|
18182 this._hoverable( this.tabs ); |
|
18183 }, |
|
18184 |
|
18185 _setupHeightStyle: function( heightStyle ) { |
|
18186 var maxHeight, |
|
18187 parent = this.element.parent(); |
|
18188 |
|
18189 if ( heightStyle === "fill" ) { |
|
18190 maxHeight = parent.height(); |
|
18191 maxHeight -= this.element.outerHeight() - this.element.height(); |
|
18192 |
|
18193 this.element.siblings( ":visible" ).each( function() { |
|
18194 var elem = $( this ), |
|
18195 position = elem.css( "position" ); |
|
18196 |
|
18197 if ( position === "absolute" || position === "fixed" ) { |
|
18198 return; |
|
18199 } |
|
18200 maxHeight -= elem.outerHeight( true ); |
|
18201 } ); |
|
18202 |
|
18203 this.element.children().not( this.panels ).each( function() { |
|
18204 maxHeight -= $( this ).outerHeight( true ); |
|
18205 } ); |
|
18206 |
|
18207 this.panels.each( function() { |
|
18208 $( this ).height( Math.max( 0, maxHeight - |
|
18209 $( this ).innerHeight() + $( this ).height() ) ); |
|
18210 } ) |
|
18211 .css( "overflow", "auto" ); |
|
18212 } else if ( heightStyle === "auto" ) { |
|
18213 maxHeight = 0; |
|
18214 this.panels.each( function() { |
|
18215 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); |
|
18216 } ).height( maxHeight ); |
|
18217 } |
|
18218 }, |
|
18219 |
|
18220 _eventHandler: function( event ) { |
|
18221 var options = this.options, |
|
18222 active = this.active, |
|
18223 anchor = $( event.currentTarget ), |
|
18224 tab = anchor.closest( "li" ), |
|
18225 clickedIsActive = tab[ 0 ] === active[ 0 ], |
|
18226 collapsing = clickedIsActive && options.collapsible, |
|
18227 toShow = collapsing ? $() : this._getPanelForTab( tab ), |
|
18228 toHide = !active.length ? $() : this._getPanelForTab( active ), |
|
18229 eventData = { |
|
18230 oldTab: active, |
|
18231 oldPanel: toHide, |
|
18232 newTab: collapsing ? $() : tab, |
|
18233 newPanel: toShow |
|
18234 }; |
|
18235 |
|
18236 event.preventDefault(); |
|
18237 |
|
18238 if ( tab.hasClass( "ui-state-disabled" ) || |
|
18239 |
|
18240 // tab is already loading |
|
18241 tab.hasClass( "ui-tabs-loading" ) || |
|
18242 |
|
18243 // can't switch durning an animation |
|
18244 this.running || |
|
18245 |
|
18246 // click on active header, but not collapsible |
|
18247 ( clickedIsActive && !options.collapsible ) || |
|
18248 |
|
18249 // allow canceling activation |
|
18250 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { |
|
18251 return; |
|
18252 } |
|
18253 |
|
18254 options.active = collapsing ? false : this.tabs.index( tab ); |
|
18255 |
|
18256 this.active = clickedIsActive ? $() : tab; |
|
18257 if ( this.xhr ) { |
|
18258 this.xhr.abort(); |
|
18259 } |
|
18260 |
|
18261 if ( !toHide.length && !toShow.length ) { |
|
18262 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); |
|
18263 } |
|
18264 |
|
18265 if ( toShow.length ) { |
|
18266 this.load( this.tabs.index( tab ), event ); |
|
18267 } |
|
18268 this._toggle( event, eventData ); |
|
18269 }, |
|
18270 |
|
18271 // Handles show/hide for selecting tabs |
|
18272 _toggle: function( event, eventData ) { |
|
18273 var that = this, |
|
18274 toShow = eventData.newPanel, |
|
18275 toHide = eventData.oldPanel; |
|
18276 |
|
18277 this.running = true; |
|
18278 |
|
18279 function complete() { |
|
18280 that.running = false; |
|
18281 that._trigger( "activate", event, eventData ); |
|
18282 } |
|
18283 |
|
18284 function show() { |
|
18285 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); |
|
18286 |
|
18287 if ( toShow.length && that.options.show ) { |
|
18288 that._show( toShow, that.options.show, complete ); |
|
18289 } else { |
|
18290 toShow.show(); |
|
18291 complete(); |
|
18292 } |
|
18293 } |
|
18294 |
|
18295 // Start out by hiding, then showing, then completing |
|
18296 if ( toHide.length && this.options.hide ) { |
|
18297 this._hide( toHide, this.options.hide, function() { |
|
18298 that._removeClass( eventData.oldTab.closest( "li" ), |
|
18299 "ui-tabs-active", "ui-state-active" ); |
|
18300 show(); |
|
18301 } ); |
|
18302 } else { |
|
18303 this._removeClass( eventData.oldTab.closest( "li" ), |
|
18304 "ui-tabs-active", "ui-state-active" ); |
|
18305 toHide.hide(); |
|
18306 show(); |
|
18307 } |
|
18308 |
|
18309 toHide.attr( "aria-hidden", "true" ); |
|
18310 eventData.oldTab.attr( { |
|
18311 "aria-selected": "false", |
|
18312 "aria-expanded": "false" |
|
18313 } ); |
|
18314 |
|
18315 // If we're switching tabs, remove the old tab from the tab order. |
|
18316 // If we're opening from collapsed state, remove the previous tab from the tab order. |
|
18317 // If we're collapsing, then keep the collapsing tab in the tab order. |
|
18318 if ( toShow.length && toHide.length ) { |
|
18319 eventData.oldTab.attr( "tabIndex", -1 ); |
|
18320 } else if ( toShow.length ) { |
|
18321 this.tabs.filter( function() { |
|
18322 return $( this ).attr( "tabIndex" ) === 0; |
|
18323 } ) |
|
18324 .attr( "tabIndex", -1 ); |
|
18325 } |
|
18326 |
|
18327 toShow.attr( "aria-hidden", "false" ); |
|
18328 eventData.newTab.attr( { |
|
18329 "aria-selected": "true", |
|
18330 "aria-expanded": "true", |
|
18331 tabIndex: 0 |
|
18332 } ); |
|
18333 }, |
|
18334 |
|
18335 _activate: function( index ) { |
|
18336 var anchor, |
|
18337 active = this._findActive( index ); |
|
18338 |
|
18339 // Trying to activate the already active panel |
|
18340 if ( active[ 0 ] === this.active[ 0 ] ) { |
|
18341 return; |
|
18342 } |
|
18343 |
|
18344 // Trying to collapse, simulate a click on the current active header |
|
18345 if ( !active.length ) { |
|
18346 active = this.active; |
|
18347 } |
|
18348 |
|
18349 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; |
|
18350 this._eventHandler( { |
|
18351 target: anchor, |
|
18352 currentTarget: anchor, |
|
18353 preventDefault: $.noop |
|
18354 } ); |
|
18355 }, |
|
18356 |
|
18357 _findActive: function( index ) { |
|
18358 return index === false ? $() : this.tabs.eq( index ); |
|
18359 }, |
|
18360 |
|
18361 _getIndex: function( index ) { |
|
18362 |
|
18363 // meta-function to give users option to provide a href string instead of a numerical index. |
|
18364 if ( typeof index === "string" ) { |
|
18365 index = this.anchors.index( this.anchors.filter( "[href$='" + |
|
18366 $.escapeSelector( index ) + "']" ) ); |
|
18367 } |
|
18368 |
|
18369 return index; |
|
18370 }, |
|
18371 |
|
18372 _destroy: function() { |
|
18373 if ( this.xhr ) { |
|
18374 this.xhr.abort(); |
|
18375 } |
|
18376 |
|
18377 this.tablist |
|
18378 .removeAttr( "role" ) |
|
18379 .off( this.eventNamespace ); |
|
18380 |
|
18381 this.anchors |
|
18382 .removeAttr( "role tabIndex" ) |
|
18383 .removeUniqueId(); |
|
18384 |
|
18385 this.tabs.add( this.panels ).each( function() { |
|
18386 if ( $.data( this, "ui-tabs-destroy" ) ) { |
|
18387 $( this ).remove(); |
|
18388 } else { |
|
18389 $( this ).removeAttr( "role tabIndex " + |
|
18390 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); |
|
18391 } |
|
18392 } ); |
|
18393 |
|
18394 this.tabs.each( function() { |
|
18395 var li = $( this ), |
|
18396 prev = li.data( "ui-tabs-aria-controls" ); |
|
18397 if ( prev ) { |
|
18398 li |
|
18399 .attr( "aria-controls", prev ) |
|
18400 .removeData( "ui-tabs-aria-controls" ); |
|
18401 } else { |
|
18402 li.removeAttr( "aria-controls" ); |
|
18403 } |
|
18404 } ); |
|
18405 |
|
18406 this.panels.show(); |
|
18407 |
|
18408 if ( this.options.heightStyle !== "content" ) { |
|
18409 this.panels.css( "height", "" ); |
|
18410 } |
|
18411 }, |
|
18412 |
|
18413 enable: function( index ) { |
|
18414 var disabled = this.options.disabled; |
|
18415 if ( disabled === false ) { |
|
18416 return; |
|
18417 } |
|
18418 |
|
18419 if ( index === undefined ) { |
|
18420 disabled = false; |
|
18421 } else { |
|
18422 index = this._getIndex( index ); |
|
18423 if ( Array.isArray( disabled ) ) { |
|
18424 disabled = $.map( disabled, function( num ) { |
|
18425 return num !== index ? num : null; |
|
18426 } ); |
|
18427 } else { |
|
18428 disabled = $.map( this.tabs, function( li, num ) { |
|
18429 return num !== index ? num : null; |
|
18430 } ); |
|
18431 } |
|
18432 } |
|
18433 this._setOptionDisabled( disabled ); |
|
18434 }, |
|
18435 |
|
18436 disable: function( index ) { |
|
18437 var disabled = this.options.disabled; |
|
18438 if ( disabled === true ) { |
|
18439 return; |
|
18440 } |
|
18441 |
|
18442 if ( index === undefined ) { |
|
18443 disabled = true; |
|
18444 } else { |
|
18445 index = this._getIndex( index ); |
|
18446 if ( $.inArray( index, disabled ) !== -1 ) { |
|
18447 return; |
|
18448 } |
|
18449 if ( Array.isArray( disabled ) ) { |
|
18450 disabled = $.merge( [ index ], disabled ).sort(); |
|
18451 } else { |
|
18452 disabled = [ index ]; |
|
18453 } |
|
18454 } |
|
18455 this._setOptionDisabled( disabled ); |
|
18456 }, |
|
18457 |
|
18458 load: function( index, event ) { |
|
18459 index = this._getIndex( index ); |
|
18460 var that = this, |
|
18461 tab = this.tabs.eq( index ), |
|
18462 anchor = tab.find( ".ui-tabs-anchor" ), |
|
18463 panel = this._getPanelForTab( tab ), |
|
18464 eventData = { |
|
18465 tab: tab, |
|
18466 panel: panel |
|
18467 }, |
|
18468 complete = function( jqXHR, status ) { |
|
18469 if ( status === "abort" ) { |
|
18470 that.panels.stop( false, true ); |
|
18471 } |
|
18472 |
|
18473 that._removeClass( tab, "ui-tabs-loading" ); |
|
18474 panel.removeAttr( "aria-busy" ); |
|
18475 |
|
18476 if ( jqXHR === that.xhr ) { |
|
18477 delete that.xhr; |
|
18478 } |
|
18479 }; |
|
18480 |
|
18481 // Not remote |
|
18482 if ( this._isLocal( anchor[ 0 ] ) ) { |
|
18483 return; |
|
18484 } |
|
18485 |
|
18486 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); |
|
18487 |
|
18488 // Support: jQuery <1.8 |
|
18489 // jQuery <1.8 returns false if the request is canceled in beforeSend, |
|
18490 // but as of 1.8, $.ajax() always returns a jqXHR object. |
|
18491 if ( this.xhr && this.xhr.statusText !== "canceled" ) { |
|
18492 this._addClass( tab, "ui-tabs-loading" ); |
|
18493 panel.attr( "aria-busy", "true" ); |
|
18494 |
|
18495 this.xhr |
|
18496 .done( function( response, status, jqXHR ) { |
|
18497 |
|
18498 // support: jQuery <1.8 |
|
18499 // http://bugs.jquery.com/ticket/11778 |
|
18500 setTimeout( function() { |
|
18501 panel.html( response ); |
|
18502 that._trigger( "load", event, eventData ); |
|
18503 |
|
18504 complete( jqXHR, status ); |
|
18505 }, 1 ); |
|
18506 } ) |
|
18507 .fail( function( jqXHR, status ) { |
|
18508 |
|
18509 // support: jQuery <1.8 |
|
18510 // http://bugs.jquery.com/ticket/11778 |
|
18511 setTimeout( function() { |
|
18512 complete( jqXHR, status ); |
|
18513 }, 1 ); |
|
18514 } ); |
|
18515 } |
|
18516 }, |
|
18517 |
|
18518 _ajaxSettings: function( anchor, event, eventData ) { |
|
18519 var that = this; |
|
18520 return { |
|
18521 |
|
18522 // Support: IE <11 only |
|
18523 // Strip any hash that exists to prevent errors with the Ajax request |
|
18524 url: anchor.attr( "href" ).replace( /#.*$/, "" ), |
|
18525 beforeSend: function( jqXHR, settings ) { |
|
18526 return that._trigger( "beforeLoad", event, |
|
18527 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); |
|
18528 } |
|
18529 }; |
|
18530 }, |
|
18531 |
|
18532 _getPanelForTab: function( tab ) { |
|
18533 var id = $( tab ).attr( "aria-controls" ); |
|
18534 return this.element.find( this._sanitizeSelector( "#" + id ) ); |
|
18535 } |
|
18536 } ); |
|
18537 |
|
18538 // DEPRECATED |
|
18539 // TODO: Switch return back to widget declaration at top of file when this is removed |
|
18540 if ( $.uiBackCompat !== false ) { |
|
18541 |
|
18542 // Backcompat for ui-tab class (now ui-tabs-tab) |
|
18543 $.widget( "ui.tabs", $.ui.tabs, { |
|
18544 _processTabs: function() { |
|
18545 this._superApply( arguments ); |
|
18546 this._addClass( this.tabs, "ui-tab" ); |
|
18547 } |
|
18548 } ); |
|
18549 } |
|
18550 |
|
18551 var widgetsTabs = $.ui.tabs; |
|
18552 |
|
18553 |
|
18554 /*! |
|
18555 * jQuery UI Tooltip 1.13.2 |
|
18556 * http://jqueryui.com |
|
18557 * |
|
18558 * Copyright jQuery Foundation and other contributors |
|
18559 * Released under the MIT license. |
|
18560 * http://jquery.org/license |
|
18561 */ |
|
18562 |
|
18563 //>>label: Tooltip |
|
18564 //>>group: Widgets |
|
18565 //>>description: Shows additional information for any element on hover or focus. |
|
18566 //>>docs: http://api.jqueryui.com/tooltip/ |
|
18567 //>>demos: http://jqueryui.com/tooltip/ |
|
18568 //>>css.structure: ../../themes/base/core.css |
|
18569 //>>css.structure: ../../themes/base/tooltip.css |
|
18570 //>>css.theme: ../../themes/base/theme.css |
|
18571 |
|
18572 |
|
18573 $.widget( "ui.tooltip", { |
|
18574 version: "1.13.2", |
|
18575 options: { |
|
18576 classes: { |
|
18577 "ui-tooltip": "ui-corner-all ui-widget-shadow" |
|
18578 }, |
|
18579 content: function() { |
|
18580 var title = $( this ).attr( "title" ); |
|
18581 |
|
18582 // Escape title, since we're going from an attribute to raw HTML |
|
18583 return $( "<a>" ).text( title ).html(); |
|
18584 }, |
|
18585 hide: true, |
|
18586 |
|
18587 // Disabled elements have inconsistent behavior across browsers (#8661) |
|
18588 items: "[title]:not([disabled])", |
|
18589 position: { |
|
18590 my: "left top+15", |
|
18591 at: "left bottom", |
|
18592 collision: "flipfit flip" |
|
18593 }, |
|
18594 show: true, |
|
18595 track: false, |
|
18596 |
|
18597 // Callbacks |
|
18598 close: null, |
|
18599 open: null |
|
18600 }, |
|
18601 |
|
18602 _addDescribedBy: function( elem, id ) { |
|
18603 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); |
|
18604 describedby.push( id ); |
|
18605 elem |
|
18606 .data( "ui-tooltip-id", id ) |
|
18607 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); |
|
18608 }, |
|
18609 |
|
18610 _removeDescribedBy: function( elem ) { |
|
18611 var id = elem.data( "ui-tooltip-id" ), |
|
18612 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), |
|
18613 index = $.inArray( id, describedby ); |
|
18614 |
|
18615 if ( index !== -1 ) { |
|
18616 describedby.splice( index, 1 ); |
|
18617 } |
|
18618 |
|
18619 elem.removeData( "ui-tooltip-id" ); |
|
18620 describedby = String.prototype.trim.call( describedby.join( " " ) ); |
|
18621 if ( describedby ) { |
|
18622 elem.attr( "aria-describedby", describedby ); |
|
18623 } else { |
|
18624 elem.removeAttr( "aria-describedby" ); |
|
18625 } |
|
18626 }, |
|
18627 |
|
18628 _create: function() { |
|
18629 this._on( { |
|
18630 mouseover: "open", |
|
18631 focusin: "open" |
|
18632 } ); |
|
18633 |
|
18634 // IDs of generated tooltips, needed for destroy |
|
18635 this.tooltips = {}; |
|
18636 |
|
18637 // IDs of parent tooltips where we removed the title attribute |
|
18638 this.parents = {}; |
|
18639 |
|
18640 // Append the aria-live region so tooltips announce correctly |
|
18641 this.liveRegion = $( "<div>" ) |
|
18642 .attr( { |
|
18643 role: "log", |
|
18644 "aria-live": "assertive", |
|
18645 "aria-relevant": "additions" |
|
18646 } ) |
|
18647 .appendTo( this.document[ 0 ].body ); |
|
18648 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); |
|
18649 |
|
18650 this.disabledTitles = $( [] ); |
|
18651 }, |
|
18652 |
|
18653 _setOption: function( key, value ) { |
|
18654 var that = this; |
|
18655 |
|
18656 this._super( key, value ); |
|
18657 |
|
18658 if ( key === "content" ) { |
|
18659 $.each( this.tooltips, function( id, tooltipData ) { |
|
18660 that._updateContent( tooltipData.element ); |
|
18661 } ); |
|
18662 } |
|
18663 }, |
|
18664 |
|
18665 _setOptionDisabled: function( value ) { |
|
18666 this[ value ? "_disable" : "_enable" ](); |
|
18667 }, |
|
18668 |
|
18669 _disable: function() { |
|
18670 var that = this; |
|
18671 |
|
18672 // Close open tooltips |
|
18673 $.each( this.tooltips, function( id, tooltipData ) { |
|
18674 var event = $.Event( "blur" ); |
|
18675 event.target = event.currentTarget = tooltipData.element[ 0 ]; |
|
18676 that.close( event, true ); |
|
18677 } ); |
|
18678 |
|
18679 // Remove title attributes to prevent native tooltips |
|
18680 this.disabledTitles = this.disabledTitles.add( |
|
18681 this.element.find( this.options.items ).addBack() |
|
18682 .filter( function() { |
|
18683 var element = $( this ); |
|
18684 if ( element.is( "[title]" ) ) { |
|
18685 return element |
|
18686 .data( "ui-tooltip-title", element.attr( "title" ) ) |
|
18687 .removeAttr( "title" ); |
|
18688 } |
|
18689 } ) |
|
18690 ); |
|
18691 }, |
|
18692 |
|
18693 _enable: function() { |
|
18694 |
|
18695 // restore title attributes |
|
18696 this.disabledTitles.each( function() { |
|
18697 var element = $( this ); |
|
18698 if ( element.data( "ui-tooltip-title" ) ) { |
|
18699 element.attr( "title", element.data( "ui-tooltip-title" ) ); |
|
18700 } |
|
18701 } ); |
|
18702 this.disabledTitles = $( [] ); |
|
18703 }, |
|
18704 |
|
18705 open: function( event ) { |
|
18706 var that = this, |
|
18707 target = $( event ? event.target : this.element ) |
|
18708 |
|
18709 // we need closest here due to mouseover bubbling, |
|
18710 // but always pointing at the same event target |
|
18711 .closest( this.options.items ); |
|
18712 |
|
18713 // No element to show a tooltip for or the tooltip is already open |
|
18714 if ( !target.length || target.data( "ui-tooltip-id" ) ) { |
|
18715 return; |
|
18716 } |
|
18717 |
|
18718 if ( target.attr( "title" ) ) { |
|
18719 target.data( "ui-tooltip-title", target.attr( "title" ) ); |
|
18720 } |
|
18721 |
|
18722 target.data( "ui-tooltip-open", true ); |
|
18723 |
|
18724 // Kill parent tooltips, custom or native, for hover |
|
18725 if ( event && event.type === "mouseover" ) { |
|
18726 target.parents().each( function() { |
|
18727 var parent = $( this ), |
|
18728 blurEvent; |
|
18729 if ( parent.data( "ui-tooltip-open" ) ) { |
|
18730 blurEvent = $.Event( "blur" ); |
|
18731 blurEvent.target = blurEvent.currentTarget = this; |
|
18732 that.close( blurEvent, true ); |
|
18733 } |
|
18734 if ( parent.attr( "title" ) ) { |
|
18735 parent.uniqueId(); |
|
18736 that.parents[ this.id ] = { |
|
18737 element: this, |
|
18738 title: parent.attr( "title" ) |
|
18739 }; |
|
18740 parent.attr( "title", "" ); |
|
18741 } |
|
18742 } ); |
|
18743 } |
|
18744 |
|
18745 this._registerCloseHandlers( event, target ); |
|
18746 this._updateContent( target, event ); |
|
18747 }, |
|
18748 |
|
18749 _updateContent: function( target, event ) { |
|
18750 var content, |
|
18751 contentOption = this.options.content, |
|
18752 that = this, |
|
18753 eventType = event ? event.type : null; |
|
18754 |
|
18755 if ( typeof contentOption === "string" || contentOption.nodeType || |
|
18756 contentOption.jquery ) { |
|
18757 return this._open( event, target, contentOption ); |
|
18758 } |
|
18759 |
|
18760 content = contentOption.call( target[ 0 ], function( response ) { |
|
18761 |
|
18762 // IE may instantly serve a cached response for ajax requests |
|
18763 // delay this call to _open so the other call to _open runs first |
|
18764 that._delay( function() { |
|
18765 |
|
18766 // Ignore async response if tooltip was closed already |
|
18767 if ( !target.data( "ui-tooltip-open" ) ) { |
|
18768 return; |
|
18769 } |
|
18770 |
|
18771 // JQuery creates a special event for focusin when it doesn't |
|
18772 // exist natively. To improve performance, the native event |
|
18773 // object is reused and the type is changed. Therefore, we can't |
|
18774 // rely on the type being correct after the event finished |
|
18775 // bubbling, so we set it back to the previous value. (#8740) |
|
18776 if ( event ) { |
|
18777 event.type = eventType; |
|
18778 } |
|
18779 this._open( event, target, response ); |
|
18780 } ); |
|
18781 } ); |
|
18782 if ( content ) { |
|
18783 this._open( event, target, content ); |
|
18784 } |
|
18785 }, |
|
18786 |
|
18787 _open: function( event, target, content ) { |
|
18788 var tooltipData, tooltip, delayedShow, a11yContent, |
|
18789 positionOption = $.extend( {}, this.options.position ); |
|
18790 |
|
18791 if ( !content ) { |
|
18792 return; |
|
18793 } |
|
18794 |
|
18795 // Content can be updated multiple times. If the tooltip already |
|
18796 // exists, then just update the content and bail. |
|
18797 tooltipData = this._find( target ); |
|
18798 if ( tooltipData ) { |
|
18799 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); |
|
18800 return; |
|
18801 } |
|
18802 |
|
18803 // If we have a title, clear it to prevent the native tooltip |
|
18804 // we have to check first to avoid defining a title if none exists |
|
18805 // (we don't want to cause an element to start matching [title]) |
|
18806 // |
|
18807 // We use removeAttr only for key events, to allow IE to export the correct |
|
18808 // accessible attributes. For mouse events, set to empty string to avoid |
|
18809 // native tooltip showing up (happens only when removing inside mouseover). |
|
18810 if ( target.is( "[title]" ) ) { |
|
18811 if ( event && event.type === "mouseover" ) { |
|
18812 target.attr( "title", "" ); |
|
18813 } else { |
|
18814 target.removeAttr( "title" ); |
|
18815 } |
|
18816 } |
|
18817 |
|
18818 tooltipData = this._tooltip( target ); |
|
18819 tooltip = tooltipData.tooltip; |
|
18820 this._addDescribedBy( target, tooltip.attr( "id" ) ); |
|
18821 tooltip.find( ".ui-tooltip-content" ).html( content ); |
|
18822 |
|
18823 // Support: Voiceover on OS X, JAWS on IE <= 9 |
|
18824 // JAWS announces deletions even when aria-relevant="additions" |
|
18825 // Voiceover will sometimes re-read the entire log region's contents from the beginning |
|
18826 this.liveRegion.children().hide(); |
|
18827 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); |
|
18828 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); |
|
18829 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); |
|
18830 a11yContent.appendTo( this.liveRegion ); |
|
18831 |
|
18832 function position( event ) { |
|
18833 positionOption.of = event; |
|
18834 if ( tooltip.is( ":hidden" ) ) { |
|
18835 return; |
|
18836 } |
|
18837 tooltip.position( positionOption ); |
|
18838 } |
|
18839 if ( this.options.track && event && /^mouse/.test( event.type ) ) { |
|
18840 this._on( this.document, { |
|
18841 mousemove: position |
|
18842 } ); |
|
18843 |
|
18844 // trigger once to override element-relative positioning |
|
18845 position( event ); |
|
18846 } else { |
|
18847 tooltip.position( $.extend( { |
|
18848 of: target |
|
18849 }, this.options.position ) ); |
|
18850 } |
|
18851 |
|
18852 tooltip.hide(); |
|
18853 |
|
18854 this._show( tooltip, this.options.show ); |
|
18855 |
|
18856 // Handle tracking tooltips that are shown with a delay (#8644). As soon |
|
18857 // as the tooltip is visible, position the tooltip using the most recent |
|
18858 // event. |
|
18859 // Adds the check to add the timers only when both delay and track options are set (#14682) |
|
18860 if ( this.options.track && this.options.show && this.options.show.delay ) { |
|
18861 delayedShow = this.delayedShow = setInterval( function() { |
|
18862 if ( tooltip.is( ":visible" ) ) { |
|
18863 position( positionOption.of ); |
|
18864 clearInterval( delayedShow ); |
|
18865 } |
|
18866 }, 13 ); |
|
18867 } |
|
18868 |
|
18869 this._trigger( "open", event, { tooltip: tooltip } ); |
|
18870 }, |
|
18871 |
|
18872 _registerCloseHandlers: function( event, target ) { |
|
18873 var events = { |
|
18874 keyup: function( event ) { |
|
18875 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { |
|
18876 var fakeEvent = $.Event( event ); |
|
18877 fakeEvent.currentTarget = target[ 0 ]; |
|
18878 this.close( fakeEvent, true ); |
|
18879 } |
|
18880 } |
|
18881 }; |
|
18882 |
|
18883 // Only bind remove handler for delegated targets. Non-delegated |
|
18884 // tooltips will handle this in destroy. |
|
18885 if ( target[ 0 ] !== this.element[ 0 ] ) { |
|
18886 events.remove = function() { |
|
18887 var targetElement = this._find( target ); |
|
18888 if ( targetElement ) { |
|
18889 this._removeTooltip( targetElement.tooltip ); |
|
18890 } |
|
18891 }; |
|
18892 } |
|
18893 |
|
18894 if ( !event || event.type === "mouseover" ) { |
|
18895 events.mouseleave = "close"; |
|
18896 } |
|
18897 if ( !event || event.type === "focusin" ) { |
|
18898 events.focusout = "close"; |
|
18899 } |
|
18900 this._on( true, target, events ); |
|
18901 }, |
|
18902 |
|
18903 close: function( event ) { |
|
18904 var tooltip, |
|
18905 that = this, |
|
18906 target = $( event ? event.currentTarget : this.element ), |
|
18907 tooltipData = this._find( target ); |
|
18908 |
|
18909 // The tooltip may already be closed |
|
18910 if ( !tooltipData ) { |
|
18911 |
|
18912 // We set ui-tooltip-open immediately upon open (in open()), but only set the |
|
18913 // additional data once there's actually content to show (in _open()). So even if the |
|
18914 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in |
|
18915 // the period between open() and _open(). |
|
18916 target.removeData( "ui-tooltip-open" ); |
|
18917 return; |
|
18918 } |
|
18919 |
|
18920 tooltip = tooltipData.tooltip; |
|
18921 |
|
18922 // Disabling closes the tooltip, so we need to track when we're closing |
|
18923 // to avoid an infinite loop in case the tooltip becomes disabled on close |
|
18924 if ( tooltipData.closing ) { |
|
18925 return; |
|
18926 } |
|
18927 |
|
18928 // Clear the interval for delayed tracking tooltips |
|
18929 clearInterval( this.delayedShow ); |
|
18930 |
|
18931 // Only set title if we had one before (see comment in _open()) |
|
18932 // If the title attribute has changed since open(), don't restore |
|
18933 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { |
|
18934 target.attr( "title", target.data( "ui-tooltip-title" ) ); |
|
18935 } |
|
18936 |
|
18937 this._removeDescribedBy( target ); |
|
18938 |
|
18939 tooltipData.hiding = true; |
|
18940 tooltip.stop( true ); |
|
18941 this._hide( tooltip, this.options.hide, function() { |
|
18942 that._removeTooltip( $( this ) ); |
|
18943 } ); |
|
18944 |
|
18945 target.removeData( "ui-tooltip-open" ); |
|
18946 this._off( target, "mouseleave focusout keyup" ); |
|
18947 |
|
18948 // Remove 'remove' binding only on delegated targets |
|
18949 if ( target[ 0 ] !== this.element[ 0 ] ) { |
|
18950 this._off( target, "remove" ); |
|
18951 } |
|
18952 this._off( this.document, "mousemove" ); |
|
18953 |
|
18954 if ( event && event.type === "mouseleave" ) { |
|
18955 $.each( this.parents, function( id, parent ) { |
|
18956 $( parent.element ).attr( "title", parent.title ); |
|
18957 delete that.parents[ id ]; |
|
18958 } ); |
|
18959 } |
|
18960 |
|
18961 tooltipData.closing = true; |
|
18962 this._trigger( "close", event, { tooltip: tooltip } ); |
|
18963 if ( !tooltipData.hiding ) { |
|
18964 tooltipData.closing = false; |
|
18965 } |
|
18966 }, |
|
18967 |
|
18968 _tooltip: function( element ) { |
|
18969 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), |
|
18970 content = $( "<div>" ).appendTo( tooltip ), |
|
18971 id = tooltip.uniqueId().attr( "id" ); |
|
18972 |
|
18973 this._addClass( content, "ui-tooltip-content" ); |
|
18974 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); |
|
18975 |
|
18976 tooltip.appendTo( this._appendTo( element ) ); |
|
18977 |
|
18978 return this.tooltips[ id ] = { |
|
18979 element: element, |
|
18980 tooltip: tooltip |
|
18981 }; |
|
18982 }, |
|
18983 |
|
18984 _find: function( target ) { |
|
18985 var id = target.data( "ui-tooltip-id" ); |
|
18986 return id ? this.tooltips[ id ] : null; |
|
18987 }, |
|
18988 |
|
18989 _removeTooltip: function( tooltip ) { |
|
18990 |
|
18991 // Clear the interval for delayed tracking tooltips |
|
18992 clearInterval( this.delayedShow ); |
|
18993 |
|
18994 tooltip.remove(); |
|
18995 delete this.tooltips[ tooltip.attr( "id" ) ]; |
|
18996 }, |
|
18997 |
|
18998 _appendTo: function( target ) { |
|
18999 var element = target.closest( ".ui-front, dialog" ); |
|
19000 |
|
19001 if ( !element.length ) { |
|
19002 element = this.document[ 0 ].body; |
|
19003 } |
|
19004 |
|
19005 return element; |
|
19006 }, |
|
19007 |
|
19008 _destroy: function() { |
|
19009 var that = this; |
|
19010 |
|
19011 // Close open tooltips |
|
19012 $.each( this.tooltips, function( id, tooltipData ) { |
|
19013 |
|
19014 // Delegate to close method to handle common cleanup |
|
19015 var event = $.Event( "blur" ), |
|
19016 element = tooltipData.element; |
|
19017 event.target = event.currentTarget = element[ 0 ]; |
|
19018 that.close( event, true ); |
|
19019 |
|
19020 // Remove immediately; destroying an open tooltip doesn't use the |
|
19021 // hide animation |
|
19022 $( "#" + id ).remove(); |
|
19023 |
|
19024 // Restore the title |
|
19025 if ( element.data( "ui-tooltip-title" ) ) { |
|
19026 |
|
19027 // If the title attribute has changed since open(), don't restore |
|
19028 if ( !element.attr( "title" ) ) { |
|
19029 element.attr( "title", element.data( "ui-tooltip-title" ) ); |
|
19030 } |
|
19031 element.removeData( "ui-tooltip-title" ); |
|
19032 } |
|
19033 } ); |
|
19034 this.liveRegion.remove(); |
|
19035 } |
|
19036 } ); |
|
19037 |
|
19038 // DEPRECATED |
|
19039 // TODO: Switch return back to widget declaration at top of file when this is removed |
|
19040 if ( $.uiBackCompat !== false ) { |
|
19041 |
|
19042 // Backcompat for tooltipClass option |
|
19043 $.widget( "ui.tooltip", $.ui.tooltip, { |
|
19044 options: { |
|
19045 tooltipClass: null |
|
19046 }, |
|
19047 _tooltip: function() { |
|
19048 var tooltipData = this._superApply( arguments ); |
|
19049 if ( this.options.tooltipClass ) { |
|
19050 tooltipData.tooltip.addClass( this.options.tooltipClass ); |
|
19051 } |
|
19052 return tooltipData; |
|
19053 } |
|
19054 } ); |
|
19055 } |
|
19056 |
|
19057 var widgetsTooltip = $.ui.tooltip; |
|
19058 |
|
19059 |
|
19060 |
|
19061 |
|
19062 } ); |