1/*! jQuery UI - v1.14.2-pre - 2025-06-06 2* https://jqueryui.com 3* Includes: widget.js, mouse.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, effect.js, data.js, disable-selection.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, focusable.js, form-reset-mixin.js, datepicker-af.js, datepicker-ar-DZ.js, datepicker-ar.js, datepicker-az.js, datepicker-be.js, datepicker-bg.js, datepicker-bs.js, datepicker-ca.js, datepicker-cs.js, datepicker-cy-GB.js, datepicker-da.js, datepicker-de-AT.js, datepicker-de.js, datepicker-el.js, datepicker-en-AU.js, datepicker-en-GB.js, datepicker-en-NZ.js, datepicker-eo.js, datepicker-es.js, datepicker-et.js, datepicker-eu.js, datepicker-fa.js, datepicker-fi.js, datepicker-fo.js, datepicker-fr-CA.js, datepicker-fr-CH.js, datepicker-fr.js, datepicker-gl.js, datepicker-he.js, datepicker-hi.js, datepicker-hr.js, datepicker-hu.js, datepicker-hy.js, datepicker-id.js, datepicker-is.js, datepicker-it-CH.js, datepicker-it.js, datepicker-ja.js, datepicker-ka.js, datepicker-kk.js, datepicker-km.js, datepicker-ko.js, datepicker-ky.js, datepicker-lb.js, datepicker-lt.js, datepicker-lv.js, datepicker-mk.js, datepicker-ml.js, datepicker-ms.js, datepicker-nb.js, datepicker-nl-BE.js, datepicker-nl.js, datepicker-nn.js, datepicker-no.js, datepicker-pl.js, datepicker-pt-BR.js, datepicker-pt.js, datepicker-rm.js, datepicker-ro.js, datepicker-ru.js, datepicker-sk.js, datepicker-sl.js, datepicker-sq.js, datepicker-sr-SR.js, datepicker-sr.js, datepicker-sv.js, datepicker-ta.js, datepicker-th.js, datepicker-tj.js, datepicker-tr.js, datepicker-uk.js, datepicker-vi.js, datepicker-zh-CN.js, datepicker-zh-HK.js, datepicker-zh-TW.js, jquery-patch.js, jquery-var-for-color.js, keycode.js, labels.js, plugin.js, position.js, scroll-parent.js, tabbable.js, unique-id.js, jquery.color.js, version.js, accordion.js, autocomplete.js, button.js, checkboxradio.js, controlgroup.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js 4* Copyright OpenJS Foundation and other contributors; Licensed */ 5( function( factory ) { 6 "use strict"; 7 8 if ( typeof define === "function" && define.amd ) { 9 10 // AMD. Register as an anonymous module. 11 define( 'ui/version.js',[ "jquery" ], factory ); 12 } else { 13 14 // Browser globals 15 factory( jQuery ); 16 } 17} )( function( $ ) { 18"use strict"; 19 20$.ui = $.ui || {}; 21 22return $.ui.version = "@VERSION"; 23 24} ); 25 26/*! 27 * jQuery UI :data @VERSION 28 * https://jqueryui.com 29 * 30 * Copyright OpenJS Foundation and other contributors 31 * Released under the MIT license. 32 * https://jquery.org/license 33 */ 34 35//>>label: :data Selector 36//>>group: Core 37//>>description: Selects elements which have data stored under the specified key. 38//>>docs: https://api.jqueryui.com/data-selector/ 39 40( function( factory ) { 41 "use strict"; 42 43 if ( typeof define === "function" && define.amd ) { 44 45 // AMD. Register as an anonymous module. 46 define( 'ui/data',[ "jquery", "./version" ], factory ); 47 } else { 48 49 // Browser globals 50 factory( jQuery ); 51 } 52} )( function( $ ) { 53"use strict"; 54 55return $.extend( $.expr.pseudos, { 56 data: $.expr.createPseudo( function( dataName ) { 57 return function( elem ) { 58 return !!$.data( elem, dataName ); 59 }; 60 } ) 61} ); 62} ); 63 64/*! 65 * jQuery UI Disable Selection @VERSION 66 * https://jqueryui.com 67 * 68 * Copyright OpenJS Foundation and other contributors 69 * Released under the MIT license. 70 * https://jquery.org/license 71 */ 72 73//>>label: disableSelection 74//>>group: Core 75//>>description: Disable selection of text content within the set of matched elements. 76//>>docs: https://api.jqueryui.com/disableSelection/ 77 78// This file is deprecated 79( function( factory ) { 80 "use strict"; 81 82 if ( typeof define === "function" && define.amd ) { 83 84 // AMD. Register as an anonymous module. 85 define( 'ui/disable-selection',[ "jquery", "./version" ], factory ); 86 } else { 87 88 // Browser globals 89 factory( jQuery ); 90 } 91} )( function( $ ) { 92"use strict"; 93 94return $.fn.extend( { 95 disableSelection: ( function() { 96 var eventType = "onselectstart" in document.createElement( "div" ) ? 97 "selectstart" : 98 "mousedown"; 99 100 return function() { 101 return this.on( eventType + ".ui-disableSelection", function( event ) { 102 event.preventDefault(); 103 } ); 104 }; 105 } )(), 106 107 enableSelection: function() { 108 return this.off( ".ui-disableSelection" ); 109 } 110} ); 111 112} ); 113 114( function( factory ) { 115 "use strict"; 116 117 if ( typeof define === "function" && define.amd ) { 118 119 // AMD. Register as an anonymous module. 120 define( 'ui/jquery-var-for-color.js',[ "jquery", "./version" ], factory ); 121 } else { 122 123 // Browser globals 124 factory( jQuery ); 125 } 126} )( function( $ ) { 127 "use strict"; 128 129// Create a local jQuery because jQuery Color relies on it and the 130// global may not exist with AMD and a custom build (#10199). 131// This module is a noop if used as a regular AMD module. 132// eslint-disable-next-line no-unused-vars 133var jQuery = $; 134 135} ); 136 137/*! 138 * jQuery Color Animations v3.0.0 139 * https://github.com/jquery/jquery-color 140 * 141 * Copyright OpenJS Foundation and other contributors 142 * Released under the MIT license. 143 * https://jquery.org/license 144 * 145 * Date: Wed May 15 16:49:44 2024 +0200 146 */ 147 148( function( root, factory ) { 149 "use strict"; 150 151 if ( typeof define === "function" && define.amd ) { 152 153 // AMD. Register as an anonymous module. 154 define( 'ui/vendor/jquery-color/jquery.color.js',[ "jquery" ], factory ); 155 } else if ( typeof exports === "object" ) { 156 module.exports = factory( require( "jquery" ) ); 157 } else { 158 factory( root.jQuery ); 159 } 160} )( this, function( jQuery, undefined ) { 161 "use strict";
vendor: 15,687 bytes, lines 161-826
161 162 163 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 164 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 165 166 class2type = {}, 167 toString = class2type.toString, 168 169 // plusequals test for += 100 -= 100 170 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 171 172 // a set of RE's that can match strings and generate color tuples. 173 stringParsers = [ { 174 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 175 parse: function( execResult ) { 176 return [ 177 execResult[ 1 ], 178 execResult[ 2 ], 179 execResult[ 3 ], 180 execResult[ 4 ] 181 ]; 182 } 183 }, { 184 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 185 parse: function( execResult ) { 186 return [ 187 execResult[ 1 ] * 2.55, 188 execResult[ 2 ] * 2.55, 189 execResult[ 3 ] * 2.55, 190 execResult[ 4 ] 191 ]; 192 } 193 }, { 194 195 // this regex ignores A-F because it's compared against an already lowercased string 196 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, 197 parse: function( execResult ) { 198 return [ 199 parseInt( execResult[ 1 ], 16 ), 200 parseInt( execResult[ 2 ], 16 ), 201 parseInt( execResult[ 3 ], 16 ), 202 execResult[ 4 ] ? 203 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : 204 1 205 ]; 206 } 207 }, { 208 209 // this regex ignores A-F because it's compared against an already lowercased string 210 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, 211 parse: function( execResult ) { 212 return [ 213 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 214 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 215 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), 216 execResult[ 4 ] ? 217 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) 218 .toFixed( 2 ) : 219 1 220 ]; 221 } 222 }, { 223 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 224 space: "hsla", 225 parse: function( execResult ) { 226 return [ 227 execResult[ 1 ], 228 execResult[ 2 ] / 100, 229 execResult[ 3 ] / 100, 230 execResult[ 4 ] 231 ]; 232 } 233 } ], 234 235 // jQuery.Color( ) 236 color = jQuery.Color = function( color, green, blue, alpha ) { 237 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 238 }, 239 spaces = { 240 rgba: { 241 props: { 242 red: { 243 idx: 0, 244 type: "byte" 245 }, 246 green: { 247 idx: 1, 248 type: "byte" 249 }, 250 blue: { 251 idx: 2, 252 type: "byte" 253 } 254 } 255 }, 256 257 hsla: { 258 props: { 259 hue: { 260 idx: 0, 261 type: "degrees" 262 }, 263 saturation: { 264 idx: 1, 265 type: "percent" 266 }, 267 lightness: { 268 idx: 2, 269 type: "percent" 270 } 271 } 272 } 273 }, 274 propTypes = { 275 "byte": { 276 floor: true, 277 max: 255 278 }, 279 "percent": { 280 max: 1 281 }, 282 "degrees": { 283 mod: 360, 284 floor: true 285 } 286 }, 287 288 // colors = jQuery.Color.names 289 colors, 290 291 // local aliases of functions called often 292 each = jQuery.each; 293 294// define cache name and alpha properties 295// for rgba and hsla spaces 296each( spaces, function( spaceName, space ) { 297 space.cache = "_" + spaceName; 298 space.props.alpha = { 299 idx: 3, 300 type: "percent", 301 def: 1 302 }; 303} ); 304 305// Populate the class2type map 306jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 307 function( _i, name ) { 308 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 309 } ); 310 311function getType( obj ) { 312 if ( obj == null ) { 313 return obj + ""; 314 } 315 316 return typeof obj === "object" ? 317 class2type[ toString.call( obj ) ] || "object" : 318 typeof obj; 319} 320 321function clamp( value, prop, allowEmpty ) { 322 var type = propTypes[ prop.type ] || {}; 323 324 if ( value == null ) { 325 return ( allowEmpty || !prop.def ) ? null : prop.def; 326 } 327 328 // ~~ is an short way of doing floor for positive numbers 329 value = type.floor ? ~~value : parseFloat( value ); 330 331 if ( type.mod ) { 332 333 // we add mod before modding to make sure that negatives values 334 // get converted properly: -10 -> 350 335 return ( value + type.mod ) % type.mod; 336 } 337 338 // for now all property types without mod have min and max 339 return Math.min( type.max, Math.max( 0, value ) ); 340} 341 342function stringParse( string ) { 343 var inst = color(), 344 rgba = inst._rgba = []; 345 346 string = string.toLowerCase(); 347 348 each( stringParsers, function( _i, parser ) { 349 var parsed, 350 match = parser.re.exec( string ), 351 values = match && parser.parse( match ), 352 spaceName = parser.space || "rgba"; 353 354 if ( values ) { 355 parsed = inst[ spaceName ]( values ); 356 357 // if this was an rgba parse the assignment might happen twice 358 // oh well.... 359 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 360 rgba = inst._rgba = parsed._rgba; 361 362 // exit each( stringParsers ) here because we matched 363 return false; 364 } 365 } ); 366 367 // Found a stringParser that handled it 368 if ( rgba.length ) { 369 370 // if this came from a parsed string, force "transparent" when alpha is 0 371 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 372 if ( rgba.join() === "0,0,0,0" ) { 373 jQuery.extend( rgba, colors.transparent ); 374 } 375 return inst; 376 } 377 378 // named colors 379 return colors[ string ]; 380} 381 382color.fn = jQuery.extend( color.prototype, { 383 parse: function( red, green, blue, alpha ) { 384 if ( red === undefined ) { 385 this._rgba = [ null, null, null, null ]; 386 return this; 387 } 388 if ( red.jquery || red.nodeType ) { 389 red = jQuery( red ).css( green ); 390 green = undefined; 391 } 392 393 var inst = this, 394 type = getType( red ), 395 rgba = this._rgba = []; 396 397 // more than 1 argument specified - assume ( red, green, blue, alpha ) 398 if ( green !== undefined ) { 399 red = [ red, green, blue, alpha ]; 400 type = "array"; 401 } 402 403 if ( type === "string" ) { 404 return this.parse( stringParse( red ) || colors._default ); 405 } 406 407 if ( type === "array" ) { 408 each( spaces.rgba.props, function( _key, prop ) { 409 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 410 } ); 411 return this; 412 } 413 414 if ( type === "object" ) { 415 if ( red instanceof color ) { 416 each( spaces, function( _spaceName, space ) { 417 if ( red[ space.cache ] ) { 418 inst[ space.cache ] = red[ space.cache ].slice(); 419 } 420 } ); 421 } else { 422 each( spaces, function( _spaceName, space ) { 423 var cache = space.cache; 424 each( space.props, function( key, prop ) { 425 426 // if the cache doesn't exist, and we know how to convert 427 if ( !inst[ cache ] && space.to ) { 428 429 // if the value was null, we don't need to copy it 430 // if the key was alpha, we don't need to copy it either 431 if ( key === "alpha" || red[ key ] == null ) { 432 return; 433 } 434 inst[ cache ] = space.to( inst._rgba ); 435 } 436 437 // this is the only case where we allow nulls for ALL properties. 438 // call clamp with alwaysAllowEmpty 439 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 440 } ); 441 442 // everything defined but alpha? 443 if ( inst[ cache ] && jQuery.inArray( 444 null, 445 inst[ cache ].slice( 0, 3 ) 446 ) < 0 ) { 447 448 // use the default of 1 449 if ( inst[ cache ][ 3 ] == null ) { 450 inst[ cache ][ 3 ] = 1; 451 } 452 453 if ( space.from ) { 454 inst._rgba = space.from( inst[ cache ] ); 455 } 456 } 457 } ); 458 } 459 return this; 460 } 461 }, 462 is: function( compare ) { 463 var is = color( compare ), 464 same = true, 465 inst = this; 466 467 each( spaces, function( _, space ) { 468 var localCache, 469 isCache = is[ space.cache ]; 470 if ( isCache ) { 471 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 472 each( space.props, function( _, prop ) { 473 if ( isCache[ prop.idx ] != null ) { 474 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 475 return same; 476 } 477 } ); 478 } 479 return same; 480 } ); 481 return same; 482 }, 483 _space: function() { 484 var used = [], 485 inst = this; 486 each( spaces, function( spaceName, space ) { 487 if ( inst[ space.cache ] ) { 488 used.push( spaceName ); 489 } 490 } ); 491 return used.pop(); 492 }, 493 transition: function( other, distance ) { 494 var end = color( other ), 495 spaceName = end._space(), 496 space = spaces[ spaceName ], 497 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 498 start = startColor[ space.cache ] || space.to( startColor._rgba ), 499 result = start.slice(); 500 501 end = end[ space.cache ]; 502 each( space.props, function( _key, prop ) { 503 var index = prop.idx, 504 startValue = start[ index ], 505 endValue = end[ index ], 506 type = propTypes[ prop.type ] || {}; 507 508 // if null, don't override start value 509 if ( endValue === null ) { 510 return; 511 } 512 513 // if null - use end 514 if ( startValue === null ) { 515 result[ index ] = endValue; 516 } else { 517 if ( type.mod ) { 518 if ( endValue - startValue > type.mod / 2 ) { 519 startValue += type.mod; 520 } else if ( startValue - endValue > type.mod / 2 ) { 521 startValue -= type.mod; 522 } 523 } 524 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 525 } 526 } ); 527 return this[ spaceName ]( result ); 528 }, 529 blend: function( opaque ) { 530 531 // if we are already opaque - return ourself 532 if ( this._rgba[ 3 ] === 1 ) { 533 return this; 534 } 535 536 var rgb = this._rgba.slice(), 537 a = rgb.pop(), 538 blend = color( opaque )._rgba; 539 540 return color( jQuery.map( rgb, function( v, i ) { 541 return ( 1 - a ) * blend[ i ] + a * v; 542 } ) ); 543 }, 544 toRgbaString: function() { 545 var prefix = "rgba(", 546 rgba = jQuery.map( this._rgba, function( v, i ) { 547 if ( v != null ) { 548 return v; 549 } 550 return i > 2 ? 1 : 0; 551 } ); 552 553 if ( rgba[ 3 ] === 1 ) { 554 rgba.pop(); 555 prefix = "rgb("; 556 } 557 558 return prefix + rgba.join( ", " ) + ")"; 559 }, 560 toHslaString: function() { 561 var prefix = "hsla(", 562 hsla = jQuery.map( this.hsla(), function( v, i ) { 563 if ( v == null ) { 564 v = i > 2 ? 1 : 0; 565 } 566 567 // catch 1 and 2 568 if ( i && i < 3 ) { 569 v = Math.round( v * 100 ) + "%"; 570 } 571 return v; 572 } ); 573 574 if ( hsla[ 3 ] === 1 ) { 575 hsla.pop(); 576 prefix = "hsl("; 577 } 578 return prefix + hsla.join( ", " ) + ")"; 579 }, 580 toHexString: function( includeAlpha ) { 581 var rgba = this._rgba.slice(), 582 alpha = rgba.pop(); 583 584 if ( includeAlpha ) { 585 rgba.push( ~~( alpha * 255 ) ); 586 } 587 588 return "#" + jQuery.map( rgba, function( v ) { 589 590 // default to 0 when nulls exist 591 return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 ); 592 } ).join( "" ); 593 }, 594 toString: function() { 595 return this.toRgbaString(); 596 } 597} ); 598color.fn.parse.prototype = color.fn; 599 600// hsla conversions adapted from: 601// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 602 603function hue2rgb( p, q, h ) { 604 h = ( h + 1 ) % 1; 605 if ( h * 6 < 1 ) { 606 return p + ( q - p ) * h * 6; 607 } 608 if ( h * 2 < 1 ) { 609 return q; 610 } 611 if ( h * 3 < 2 ) { 612 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 613 } 614 return p; 615} 616 617spaces.hsla.to = function( rgba ) { 618 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 619 return [ null, null, null, rgba[ 3 ] ]; 620 } 621 var r = rgba[ 0 ] / 255, 622 g = rgba[ 1 ] / 255, 623 b = rgba[ 2 ] / 255, 624 a = rgba[ 3 ], 625 max = Math.max( r, g, b ), 626 min = Math.min( r, g, b ), 627 diff = max - min, 628 add = max + min, 629 l = add * 0.5, 630 h, s; 631 632 if ( min === max ) { 633 h = 0; 634 } else if ( r === max ) { 635 h = ( 60 * ( g - b ) / diff ) + 360; 636 } else if ( g === max ) { 637 h = ( 60 * ( b - r ) / diff ) + 120; 638 } else { 639 h = ( 60 * ( r - g ) / diff ) + 240; 640 } 641 642 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 643 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 644 if ( diff === 0 ) { 645 s = 0; 646 } else if ( l <= 0.5 ) { 647 s = diff / add; 648 } else { 649 s = diff / ( 2 - add ); 650 } 651 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 652}; 653 654spaces.hsla.from = function( hsla ) { 655 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 656 return [ null, null, null, hsla[ 3 ] ]; 657 } 658 var h = hsla[ 0 ] / 360, 659 s = hsla[ 1 ], 660 l = hsla[ 2 ], 661 a = hsla[ 3 ], 662 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 663 p = 2 * l - q; 664 665 return [ 666 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 667 Math.round( hue2rgb( p, q, h ) * 255 ), 668 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 669 a 670 ]; 671}; 672 673 674each( spaces, function( spaceName, space ) { 675 var props = space.props, 676 cache = space.cache, 677 to = space.to, 678 from = space.from; 679 680 // makes rgba() and hsla() 681 color.fn[ spaceName ] = function( value ) { 682 683 // generate a cache for this space if it doesn't exist 684 if ( to && !this[ cache ] ) { 685 this[ cache ] = to( this._rgba ); 686 } 687 if ( value === undefined ) { 688 return this[ cache ].slice(); 689 } 690 691 var ret, 692 type = getType( value ), 693 arr = ( type === "array" || type === "object" ) ? value : arguments, 694 local = this[ cache ].slice(); 695 696 each( props, function( key, prop ) { 697 var val = arr[ type === "object" ? key : prop.idx ]; 698 if ( val == null ) { 699 val = local[ prop.idx ]; 700 } 701 local[ prop.idx ] = clamp( val, prop ); 702 } ); 703 704 if ( from ) { 705 ret = color( from( local ) ); 706 ret[ cache ] = local; 707 return ret; 708 } else { 709 return color( local ); 710 } 711 }; 712 713 // makes red() green() blue() alpha() hue() saturation() lightness() 714 each( props, function( key, prop ) { 715 716 // alpha is included in more than one space 717 if ( color.fn[ key ] ) { 718 return; 719 } 720 color.fn[ key ] = function( value ) { 721 var local, cur, match, fn, 722 vtype = getType( value ); 723 724 if ( key === "alpha" ) { 725 fn = this._hsla ? "hsla" : "rgba"; 726 } else { 727 fn = spaceName; 728 } 729 local = this[ fn ](); 730 cur = local[ prop.idx ]; 731 732 if ( vtype === "undefined" ) { 733 return cur; 734 } 735 736 if ( vtype === "function" ) { 737 value = value.call( this, cur ); 738 vtype = getType( value ); 739 } 740 if ( value == null && prop.empty ) { 741 return this; 742 } 743 if ( vtype === "string" ) { 744 match = rplusequals.exec( value ); 745 if ( match ) { 746 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 747 } 748 } 749 local[ prop.idx ] = value; 750 return this[ fn ]( local ); 751 }; 752 } ); 753} ); 754 755// add cssHook and .fx.step function for each named hook. 756// accept a space separated string of properties 757color.hook = function( hook ) { 758 var hooks = hook.split( " " ); 759 each( hooks, function( _i, hook ) { 760 jQuery.cssHooks[ hook ] = { 761 set: function( elem, value ) { 762 var parsed; 763 764 if ( value !== "transparent" && 765 ( getType( value ) !== "string" || 766 ( parsed = stringParse( value ) ) ) ) { 767 value = color( parsed || value ); 768 value = value.toRgbaString(); 769 } 770 elem.style[ hook ] = value; 771 } 772 }; 773 jQuery.fx.step[ hook ] = function( fx ) { 774 if ( !fx.colorInit ) { 775 fx.start = color( fx.elem, hook ); 776 fx.end = color( fx.end ); 777 fx.colorInit = true; 778 } 779 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 780 }; 781 } ); 782 783}; 784 785color.hook( stepHooks ); 786 787jQuery.cssHooks.borderColor = { 788 expand: function( value ) { 789 var expanded = {}; 790 791 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { 792 expanded[ "border" + part + "Color" ] = value; 793 } ); 794 return expanded; 795 } 796}; 797 798// Basic color names only. 799// Usage of any of the other color names requires adding yourself or including 800// jquery.color.svg-names.js. 801colors = jQuery.Color.names = { 802 803 // 4.1. Basic color keywords 804 aqua: "#00ffff", 805 black: "#000000", 806 blue: "#0000ff", 807 fuchsia: "#ff00ff", 808 gray: "#808080", 809 green: "#008000", 810 lime: "#00ff00", 811 maroon: "#800000", 812 navy: "#000080", 813 olive: "#808000", 814 purple: "#800080", 815 red: "#ff0000", 816 silver: "#c0c0c0", 817 teal: "#008080", 818 white: "#ffffff", 819 yellow: "#ffff00", 820 821 // 4.2.3. "transparent" color keyword 822 transparent: [ null, null, null, 0 ], 823 824 _default: "#ffffff" 825}; 826
827} ); 828 829/*! 830 * jQuery UI Effects @VERSION 831 * https://jqueryui.com 832 * 833 * Copyright OpenJS Foundation and other contributors 834 * Released under the MIT license. 835 * https://jquery.org/license 836 */ 837 838//>>label: Effects Core 839//>>group: Effects 840//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 841//>>docs: https://api.jqueryui.com/category/effects-core/ 842//>>demos: https://jqueryui.com/effect/ 843 844( function( factory ) { 845 "use strict"; 846 847 if ( typeof define === "function" && define.amd ) { 848 849 // AMD. Register as an anonymous module. 850 define( 'ui/effect',[ 851 "jquery", 852 "./jquery-var-for-color", 853 "./vendor/jquery-color/jquery.color", 854 "./version" 855 ], factory ); 856 } else { 857 858 // Browser globals 859 factory( jQuery ); 860 } 861} )( function( $ ) { 862"use strict";
vendor: 8,969 bytes, lines 862-1210
862 863 864var dataSpace = "ui-effects-", 865 dataSpaceStyle = "ui-effects-style", 866 dataSpaceAnimated = "ui-effects-animated"; 867 868$.effects = { 869 effect: {} 870}; 871 872/******************************************************************************/ 873/****************************** CLASS ANIMATIONS ******************************/ 874/******************************************************************************/ 875( function() { 876 877var classAnimationActions = [ "add", "remove", "toggle" ], 878 shorthandStyles = { 879 border: 1, 880 borderBottom: 1, 881 borderColor: 1, 882 borderLeft: 1, 883 borderRight: 1, 884 borderTop: 1, 885 borderWidth: 1, 886 margin: 1, 887 padding: 1 888 }; 889 890$.each( 891 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 892 function( _, prop ) { 893 $.fx.step[ prop ] = function( fx ) { 894 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 895 jQuery.style( fx.elem, prop, fx.end ); 896 fx.setAttr = true; 897 } 898 }; 899 } 900); 901 902function camelCase( string ) { 903 return string.replace( /-([\da-z])/gi, function( all, letter ) { 904 return letter.toUpperCase(); 905 } ); 906} 907 908function getElementStyles( elem ) { 909 var key, len, 910 style = elem.ownerDocument.defaultView.getComputedStyle( elem ), 911 styles = {}; 912 913 len = style.length; 914 while ( len-- ) { 915 key = style[ len ]; 916 if ( typeof style[ key ] === "string" ) { 917 styles[ camelCase( key ) ] = style[ key ]; 918 } 919 } 920 921 return styles; 922} 923 924function styleDifference( oldStyle, newStyle ) { 925 var diff = {}, 926 name, value; 927 928 for ( name in newStyle ) { 929 value = newStyle[ name ]; 930 if ( oldStyle[ name ] !== value ) { 931 if ( !shorthandStyles[ name ] ) { 932 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 933 diff[ name ] = value; 934 } 935 } 936 } 937 } 938 939 return diff; 940} 941 942$.effects.animateClass = function( value, duration, easing, callback ) { 943 var o = $.speed( duration, easing, callback ); 944 945 return this.queue( function() { 946 var animated = $( this ), 947 baseClass = animated.attr( "class" ) || "", 948 applyClassChange, 949 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 950 951 // Map the animated objects to store the original styles. 952 allAnimations = allAnimations.map( function() { 953 var el = $( this ); 954 return { 955 el: el, 956 start: getElementStyles( this ) 957 }; 958 } ); 959 960 // Apply class change 961 applyClassChange = function() { 962 $.each( classAnimationActions, function( i, action ) { 963 if ( value[ action ] ) { 964 animated[ action + "Class" ]( value[ action ] ); 965 } 966 } ); 967 }; 968 applyClassChange(); 969 970 // Map all animated objects again - calculate new styles and diff 971 allAnimations = allAnimations.map( function() { 972 this.end = getElementStyles( this.el[ 0 ] ); 973 this.diff = styleDifference( this.start, this.end ); 974 return this; 975 } ); 976 977 // Apply original class 978 animated.attr( "class", baseClass ); 979 980 // Map all animated objects again - this time collecting a promise 981 allAnimations = allAnimations.map( function() { 982 var styleInfo = this, 983 dfd = $.Deferred(), 984 opts = $.extend( {}, o, { 985 queue: false, 986 complete: function() { 987 dfd.resolve( styleInfo ); 988 } 989 } ); 990 991 this.el.animate( this.diff, opts ); 992 return dfd.promise(); 993 } ); 994 995 // Once all animations have completed: 996 $.when.apply( $, allAnimations.get() ).done( function() { 997 998 // Set the final class 999 applyClassChange(); 1000 1001 // For each animated element, 1002 // clear all css properties that were animated 1003 $.each( arguments, function() { 1004 var el = this.el; 1005 $.each( this.diff, function( key ) { 1006 el.css( key, "" ); 1007 } ); 1008 } ); 1009 1010 // This is guarnteed to be there if you use jQuery.speed() 1011 // it also handles dequeuing the next anim... 1012 o.complete.call( animated[ 0 ] ); 1013 } ); 1014 } ); 1015}; 1016 1017$.fn.extend( { 1018 addClass: ( function( orig ) { 1019 return function( classNames, speed, easing, callback ) { 1020 return speed ? 1021 $.effects.animateClass.call( this, 1022 { add: classNames }, speed, easing, callback ) : 1023 orig.apply( this, arguments ); 1024 }; 1025 } )( $.fn.addClass ), 1026 1027 removeClass: ( function( orig ) { 1028 return function( classNames, speed, easing, callback ) { 1029 return arguments.length > 1 ? 1030 $.effects.animateClass.call( this, 1031 { remove: classNames }, speed, easing, callback ) : 1032 orig.apply( this, arguments ); 1033 }; 1034 } )( $.fn.removeClass ), 1035 1036 toggleClass: ( function( orig ) { 1037 return function( classNames, force, speed, easing, callback ) { 1038 if ( typeof force === "boolean" || force === undefined ) { 1039 if ( !speed ) { 1040 1041 // Without speed parameter 1042 return orig.apply( this, arguments ); 1043 } else { 1044 return $.effects.animateClass.call( this, 1045 ( force ? { add: classNames } : { remove: classNames } ), 1046 speed, easing, callback ); 1047 } 1048 } else { 1049 1050 // Without force parameter 1051 return $.effects.animateClass.call( this, 1052 { toggle: classNames }, force, speed, easing ); 1053 } 1054 }; 1055 } )( $.fn.toggleClass ), 1056 1057 switchClass: function( remove, add, speed, easing, callback ) { 1058 return $.effects.animateClass.call( this, { 1059 add: add, 1060 remove: remove 1061 }, speed, easing, callback ); 1062 } 1063} ); 1064 1065} )(); 1066 1067/******************************************************************************/ 1068/*********************************** EFFECTS **********************************/ 1069/******************************************************************************/ 1070 1071( function() { 1072 1073if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { 1074 $.expr.pseudos.animated = ( function( orig ) { 1075 return function( elem ) { 1076 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 1077 }; 1078 } )( $.expr.pseudos.animated ); 1079} 1080 1081if ( $.uiBackCompat === true ) { 1082 $.extend( $.effects, { 1083 1084 // Saves a set of properties in a data storage 1085 save: function( element, set ) { 1086 var i = 0, length = set.length; 1087 for ( ; i < length; i++ ) { 1088 if ( set[ i ] !== null ) { 1089 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 1090 } 1091 } 1092 }, 1093 1094 // Restores a set of previously saved properties from a data storage 1095 restore: function( element, set ) { 1096 var val, i = 0, length = set.length; 1097 for ( ; i < length; i++ ) { 1098 if ( set[ i ] !== null ) { 1099 val = element.data( dataSpace + set[ i ] ); 1100 element.css( set[ i ], val ); 1101 } 1102 } 1103 }, 1104 1105 setMode: function( el, mode ) { 1106 if ( mode === "toggle" ) { 1107 mode = el.is( ":hidden" ) ? "show" : "hide"; 1108 } 1109 return mode; 1110 }, 1111 1112 // Wraps the element around a wrapper that copies position properties 1113 createWrapper: function( element ) { 1114 1115 // If the element is already wrapped, return it 1116 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 1117 return element.parent(); 1118 } 1119 1120 // Wrap the element 1121 var props = { 1122 width: element.outerWidth( true ), 1123 height: element.outerHeight( true ), 1124 "float": element.css( "float" ) 1125 }, 1126 wrapper = $( "<div></div>" ) 1127 .addClass( "ui-effects-wrapper" ) 1128 .css( { 1129 fontSize: "100%", 1130 background: "transparent", 1131 border: "none", 1132 margin: 0, 1133 padding: 0 1134 } ), 1135 1136 // Store the size in case width/height are defined in % - Fixes #5245 1137 size = { 1138 width: element.width(), 1139 height: element.height() 1140 }, 1141 active = document.activeElement; 1142 1143 // Support: Firefox 1144 // Firefox incorrectly exposes anonymous content 1145 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 1146 try { 1147 // eslint-disable-next-line no-unused-expressions 1148 active.id; 1149 } catch ( _e ) { 1150 active = document.body; 1151 } 1152 1153 element.wrap( wrapper ); 1154 1155 // Fixes #7595 - Elements lose focus when wrapped. 1156 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 1157 $( active ).trigger( "focus" ); 1158 } 1159 1160 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 1161 // lose the reference to the wrapped element 1162 wrapper = element.parent(); 1163 1164 // Transfer positioning properties to the wrapper 1165 if ( element.css( "position" ) === "static" ) { 1166 wrapper.css( { position: "relative" } ); 1167 element.css( { position: "relative" } ); 1168 } else { 1169 $.extend( props, { 1170 position: element.css( "position" ), 1171 zIndex: element.css( "z-index" ) 1172 } ); 1173 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 1174 props[ pos ] = element.css( pos ); 1175 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 1176 props[ pos ] = "auto"; 1177 } 1178 } ); 1179 element.css( { 1180 position: "relative", 1181 top: 0, 1182 left: 0, 1183 right: "auto", 1184 bottom: "auto" 1185 } ); 1186 } 1187 element.css( size ); 1188 1189 return wrapper.css( props ).show(); 1190 }, 1191 1192 removeWrapper: function( element ) { 1193 var active = document.activeElement; 1194 1195 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 1196 element.parent().replaceWith( element ); 1197 1198 // Fixes #7595 - Elements lose focus when wrapped. 1199 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 1200 $( active ).trigger( "focus" ); 1201 } 1202 } 1203 1204 return element; 1205 } 1206 } ); 1207} 1208 1209$.extend( $.effects, { 1210 version: "
1210@VERSION
vendor: 14,277 bytes, lines 1210-1773
1210", 1211 1212 define: function( name, mode, effect ) { 1213 if ( !effect ) { 1214 effect = mode; 1215 mode = "effect"; 1216 } 1217 1218 $.effects.effect[ name ] = effect; 1219 $.effects.effect[ name ].mode = mode; 1220 1221 return effect; 1222 }, 1223 1224 scaledDimensions: function( element, percent, direction ) { 1225 if ( percent === 0 ) { 1226 return { 1227 height: 0, 1228 width: 0, 1229 outerHeight: 0, 1230 outerWidth: 0 1231 }; 1232 } 1233 1234 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 1235 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 1236 1237 return { 1238 height: element.height() * y, 1239 width: element.width() * x, 1240 outerHeight: element.outerHeight() * y, 1241 outerWidth: element.outerWidth() * x 1242 }; 1243 1244 }, 1245 1246 clipToBox: function( animation ) { 1247 return { 1248 width: animation.clip.right - animation.clip.left, 1249 height: animation.clip.bottom - animation.clip.top, 1250 left: animation.clip.left, 1251 top: animation.clip.top 1252 }; 1253 }, 1254 1255 // Injects recently queued functions to be first in line (after "inprogress") 1256 unshift: function( element, queueLength, count ) { 1257 var queue = element.queue(); 1258 1259 if ( queueLength > 1 ) { 1260 queue.splice.apply( queue, 1261 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 1262 } 1263 element.dequeue(); 1264 }, 1265 1266 saveStyle: function( element ) { 1267 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 1268 }, 1269 1270 restoreStyle: function( element ) { 1271 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 1272 element.removeData( dataSpaceStyle ); 1273 }, 1274 1275 mode: function( element, mode ) { 1276 var hidden = element.is( ":hidden" ); 1277 1278 if ( mode === "toggle" ) { 1279 mode = hidden ? "show" : "hide"; 1280 } 1281 if ( hidden ? mode === "hide" : mode === "show" ) { 1282 mode = "none"; 1283 } 1284 return mode; 1285 }, 1286 1287 // Translates a [top,left] array into a baseline value 1288 getBaseline: function( origin, original ) { 1289 var y, x; 1290 1291 switch ( origin[ 0 ] ) { 1292 case "top": 1293 y = 0; 1294 break; 1295 case "middle": 1296 y = 0.5; 1297 break; 1298 case "bottom": 1299 y = 1; 1300 break; 1301 default: 1302 y = origin[ 0 ] / original.height; 1303 } 1304 1305 switch ( origin[ 1 ] ) { 1306 case "left": 1307 x = 0; 1308 break; 1309 case "center": 1310 x = 0.5; 1311 break; 1312 case "right": 1313 x = 1; 1314 break; 1315 default: 1316 x = origin[ 1 ] / original.width; 1317 } 1318 1319 return { 1320 x: x, 1321 y: y 1322 }; 1323 }, 1324 1325 // Creates a placeholder element so that the original element can be made absolute 1326 createPlaceholder: function( element ) { 1327 var placeholder, 1328 cssPosition = element.css( "position" ), 1329 position = element.position(); 1330 1331 // Lock in margins first to account for form elements, which 1332 // will change margin if you explicitly set height 1333 // see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 1334 // Support: Safari 1335 element.css( { 1336 marginTop: element.css( "marginTop" ), 1337 marginBottom: element.css( "marginBottom" ), 1338 marginLeft: element.css( "marginLeft" ), 1339 marginRight: element.css( "marginRight" ) 1340 } ) 1341 .outerWidth( element.outerWidth() ) 1342 .outerHeight( element.outerHeight() ); 1343 1344 if ( /^(static|relative)/.test( cssPosition ) ) { 1345 cssPosition = "absolute"; 1346 1347 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 1348 1349 // Convert inline to inline block to account for inline elements 1350 // that turn to inline block based on content (like img) 1351 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 1352 "inline-block" : 1353 "block", 1354 visibility: "hidden", 1355 1356 // Margins need to be set to account for margin collapse 1357 marginTop: element.css( "marginTop" ), 1358 marginBottom: element.css( "marginBottom" ), 1359 marginLeft: element.css( "marginLeft" ), 1360 marginRight: element.css( "marginRight" ), 1361 "float": element.css( "float" ) 1362 } ) 1363 .outerWidth( element.outerWidth() ) 1364 .outerHeight( element.outerHeight() ) 1365 .addClass( "ui-effects-placeholder" ); 1366 1367 element.data( dataSpace + "placeholder", placeholder ); 1368 } 1369 1370 element.css( { 1371 position: cssPosition, 1372 left: position.left, 1373 top: position.top 1374 } ); 1375 1376 return placeholder; 1377 }, 1378 1379 removePlaceholder: function( element ) { 1380 var dataKey = dataSpace + "placeholder", 1381 placeholder = element.data( dataKey ); 1382 1383 if ( placeholder ) { 1384 placeholder.remove(); 1385 element.removeData( dataKey ); 1386 } 1387 }, 1388 1389 // Removes a placeholder if it exists and restores 1390 // properties that were modified during placeholder creation 1391 cleanUp: function( element ) { 1392 $.effects.restoreStyle( element ); 1393 $.effects.removePlaceholder( element ); 1394 }, 1395 1396 setTransition: function( element, list, factor, value ) { 1397 value = value || {}; 1398 $.each( list, function( i, x ) { 1399 var unit = element.cssUnit( x ); 1400 if ( unit[ 0 ] > 0 ) { 1401 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 1402 } 1403 } ); 1404 return value; 1405 } 1406} ); 1407 1408// Return an effect options object for the given parameters: 1409function _normalizeArguments( effect, options, speed, callback ) { 1410 1411 // Allow passing all options as the first parameter 1412 if ( $.isPlainObject( effect ) ) { 1413 options = effect; 1414 effect = effect.effect; 1415 } 1416 1417 // Convert to an object 1418 effect = { effect: effect }; 1419 1420 // Catch (effect, null, ...) 1421 if ( options == null ) { 1422 options = {}; 1423 } 1424 1425 // Catch (effect, callback) 1426 if ( typeof options === "function" ) { 1427 callback = options; 1428 speed = null; 1429 options = {}; 1430 } 1431 1432 // Catch (effect, speed, ?) 1433 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 1434 callback = speed; 1435 speed = options; 1436 options = {}; 1437 } 1438 1439 // Catch (effect, options, callback) 1440 if ( typeof speed === "function" ) { 1441 callback = speed; 1442 speed = null; 1443 } 1444 1445 // Add options to effect 1446 if ( options ) { 1447 $.extend( effect, options ); 1448 } 1449 1450 speed = speed || options.duration; 1451 effect.duration = $.fx.off ? 0 : 1452 typeof speed === "number" ? speed : 1453 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 1454 $.fx.speeds._default; 1455 1456 effect.complete = callback || options.complete; 1457 1458 return effect; 1459} 1460 1461function standardAnimationOption( option ) { 1462 1463 // Valid standard speeds (nothing, number, named speed) 1464 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 1465 return true; 1466 } 1467 1468 // Invalid strings - treat as "normal" speed 1469 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 1470 return true; 1471 } 1472 1473 // Complete callback 1474 if ( typeof option === "function" ) { 1475 return true; 1476 } 1477 1478 // Options hash (but not naming an effect) 1479 if ( typeof option === "object" && !option.effect ) { 1480 return true; 1481 } 1482 1483 // Didn't match any standard API 1484 return false; 1485} 1486 1487$.fn.extend( { 1488 effect: function( /* effect, options, speed, callback */ ) { 1489 var args = _normalizeArguments.apply( this, arguments ), 1490 effectMethod = $.effects.effect[ args.effect ], 1491 defaultMode = effectMethod.mode, 1492 queue = args.queue, 1493 queueName = queue || "fx", 1494 complete = args.complete, 1495 mode = args.mode, 1496 modes = [], 1497 prefilter = function( next ) { 1498 var el = $( this ), 1499 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 1500 1501 // Sentinel for duck-punching the :animated pseudo-selector 1502 el.data( dataSpaceAnimated, true ); 1503 1504 // Save effect mode for later use, 1505 // we can't just call $.effects.mode again later, 1506 // as the .show() below destroys the initial state 1507 modes.push( normalizedMode ); 1508 1509 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 1510 if ( defaultMode && ( normalizedMode === "show" || 1511 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 1512 el.show(); 1513 } 1514 1515 if ( !defaultMode || normalizedMode !== "none" ) { 1516 $.effects.saveStyle( el ); 1517 } 1518 1519 if ( typeof next === "function" ) { 1520 next(); 1521 } 1522 }; 1523 1524 if ( $.fx.off || !effectMethod ) { 1525 1526 // Delegate to the original method (e.g., .show()) if possible 1527 if ( mode ) { 1528 return this[ mode ]( args.duration, complete ); 1529 } else { 1530 return this.each( function() { 1531 if ( complete ) { 1532 complete.call( this ); 1533 } 1534 } ); 1535 } 1536 } 1537 1538 function run( next ) { 1539 var elem = $( this ); 1540 1541 function cleanup() { 1542 elem.removeData( dataSpaceAnimated ); 1543 1544 $.effects.cleanUp( elem ); 1545 1546 if ( args.mode === "hide" ) { 1547 elem.hide(); 1548 } 1549 1550 done(); 1551 } 1552 1553 function done() { 1554 if ( typeof complete === "function" ) { 1555 complete.call( elem[ 0 ] ); 1556 } 1557 1558 if ( typeof next === "function" ) { 1559 next(); 1560 } 1561 } 1562 1563 // Override mode option on a per element basis, 1564 // as toggle can be either show or hide depending on element state 1565 args.mode = modes.shift(); 1566 1567 if ( $.uiBackCompat === true && !defaultMode ) { 1568 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 1569 1570 // Call the core method to track "olddisplay" properly 1571 elem[ mode ](); 1572 done(); 1573 } else { 1574 effectMethod.call( elem[ 0 ], args, done ); 1575 } 1576 } else { 1577 if ( args.mode === "none" ) { 1578 1579 // Call the core method to track "olddisplay" properly 1580 elem[ mode ](); 1581 done(); 1582 } else { 1583 effectMethod.call( elem[ 0 ], args, cleanup ); 1584 } 1585 } 1586 } 1587 1588 // Run prefilter on all elements first to ensure that 1589 // any showing or hiding happens before placeholder creation, 1590 // which ensures that any layout changes are correctly captured. 1591 return queue === false ? 1592 this.each( prefilter ).each( run ) : 1593 this.queue( queueName, prefilter ).queue( queueName, run ); 1594 }, 1595 1596 show: ( function( orig ) { 1597 return function( option ) { 1598 if ( standardAnimationOption( option ) ) { 1599 return orig.apply( this, arguments ); 1600 } else { 1601 var args = _normalizeArguments.apply( this, arguments ); 1602 args.mode = "show"; 1603 return this.effect.call( this, args ); 1604 } 1605 }; 1606 } )( $.fn.show ), 1607 1608 hide: ( function( orig ) { 1609 return function( option ) { 1610 if ( standardAnimationOption( option ) ) { 1611 return orig.apply( this, arguments ); 1612 } else { 1613 var args = _normalizeArguments.apply( this, arguments ); 1614 args.mode = "hide"; 1615 return this.effect.call( this, args ); 1616 } 1617 }; 1618 } )( $.fn.hide ), 1619 1620 toggle: ( function( orig ) { 1621 return function( option ) { 1622 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 1623 return orig.apply( this, arguments ); 1624 } else { 1625 var args = _normalizeArguments.apply( this, arguments ); 1626 args.mode = "toggle"; 1627 return this.effect.call( this, args ); 1628 } 1629 }; 1630 } )( $.fn.toggle ), 1631 1632 cssUnit: function( key ) { 1633 var style = this.css( key ), 1634 val = []; 1635 1636 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 1637 if ( style.indexOf( unit ) > 0 ) { 1638 val = [ parseFloat( style ), unit ]; 1639 } 1640 } ); 1641 return val; 1642 }, 1643 1644 cssClip: function( clipObj ) { 1645 if ( clipObj ) { 1646 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 1647 clipObj.bottom + "px " + clipObj.left + "px)" ); 1648 } 1649 return parseClip( this.css( "clip" ), this ); 1650 }, 1651 1652 transfer: function( options, done ) { 1653 var element = $( this ), 1654 target = $( options.to ), 1655 targetFixed = target.css( "position" ) === "fixed", 1656 body = $( "body" ), 1657 fixTop = targetFixed ? body.scrollTop() : 0, 1658 fixLeft = targetFixed ? body.scrollLeft() : 0, 1659 endPosition = target.offset(), 1660 animation = { 1661 top: endPosition.top - fixTop, 1662 left: endPosition.left - fixLeft, 1663 height: target.innerHeight(), 1664 width: target.innerWidth() 1665 }, 1666 startPosition = element.offset(), 1667 transfer = $( "<div class='ui-effects-transfer'></div>" ); 1668 1669 transfer 1670 .appendTo( "body" ) 1671 .addClass( options.className ) 1672 .css( { 1673 top: startPosition.top - fixTop, 1674 left: startPosition.left - fixLeft, 1675 height: element.innerHeight(), 1676 width: element.innerWidth(), 1677 position: targetFixed ? "fixed" : "absolute" 1678 } ) 1679 .animate( animation, options.duration, options.easing, function() { 1680 transfer.remove(); 1681 if ( typeof done === "function" ) { 1682 done(); 1683 } 1684 } ); 1685 } 1686} ); 1687 1688function parseClip( str, element ) { 1689 var outerWidth = element.outerWidth(), 1690 outerHeight = element.outerHeight(), 1691 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)\)$/, 1692 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 1693 1694 return { 1695 top: parseFloat( values[ 1 ] ) || 0, 1696 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 1697 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 1698 left: parseFloat( values[ 4 ] ) || 0 1699 }; 1700} 1701 1702$.fx.step.clip = function( fx ) { 1703 if ( !fx.clipInit ) { 1704 fx.start = $( fx.elem ).cssClip(); 1705 if ( typeof fx.end === "string" ) { 1706 fx.end = parseClip( fx.end, fx.elem ); 1707 } 1708 fx.clipInit = true; 1709 } 1710 1711 $( fx.elem ).cssClip( { 1712 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 1713 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 1714 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 1715 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 1716 } ); 1717}; 1718 1719} )(); 1720 1721/******************************************************************************/ 1722/*********************************** EASING ***********************************/ 1723/******************************************************************************/ 1724 1725( function() { 1726 1727// Based on easing equations from Robert Penner (http://robertpenner.com/easing) 1728 1729var baseEasings = {}; 1730 1731$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 1732 baseEasings[ name ] = function( p ) { 1733 return Math.pow( p, i + 2 ); 1734 }; 1735} ); 1736 1737$.extend( baseEasings, { 1738 Sine: function( p ) { 1739 return 1 - Math.cos( p * Math.PI / 2 ); 1740 }, 1741 Circ: function( p ) { 1742 return 1 - Math.sqrt( 1 - p * p ); 1743 }, 1744 Elastic: function( p ) { 1745 return p === 0 || p === 1 ? p : 1746 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 1747 }, 1748 Back: function( p ) { 1749 return p * p * ( 3 * p - 2 ); 1750 }, 1751 Bounce: function( p ) { 1752 var pow2, 1753 bounce = 4; 1754 1755 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 1756 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 1757 } 1758} ); 1759 1760$.each( baseEasings, function( name, easeIn ) { 1761 $.easing[ "easeIn" + name ] = easeIn; 1762 $.easing[ "easeOut" + name ] = function( p ) { 1763 return 1 - easeIn( 1 - p ); 1764 }; 1765 $.easing[ "easeInOut" + name ] = function( p ) { 1766 return p < 0.5 ? 1767 easeIn( p * 2 ) / 2 : 1768 1 - easeIn( p * -2 + 2 ) / 2; 1769 }; 1770} ); 1771 1772} )(); 1773
vendor: 54,257 bytes, lines 1774-3929
1774return $.effects; 1775 1776} ); 1777 1778/*! 1779 * jQuery UI Effects Blind @VERSION 1780 * https://jqueryui.com 1781 * 1782 * Copyright OpenJS Foundation and other contributors 1783 * Released under the MIT license. 1784 * https://jquery.org/license 1785 */ 1786 1787//>>label: Blind Effect 1788//>>group: Effects 1789//>>description: Blinds the element. 1790//>>docs: https://api.jqueryui.com/blind-effect/ 1791//>>demos: https://jqueryui.com/effect/ 1792 1793( function( factory ) { 1794 "use strict"; 1795 1796 if ( typeof define === "function" && define.amd ) { 1797 1798 // AMD. Register as an anonymous module. 1799 define( 'ui/effects/effect-blind.js',[ 1800 "jquery", 1801 "../version", 1802 "../effect" 1803 ], factory ); 1804 } else { 1805 1806 // Browser globals 1807 factory( jQuery ); 1808 } 1809} )( function( $ ) { 1810"use strict"; 1811 1812return $.effects.define( "blind", "hide", function( options, done ) { 1813 var map = { 1814 up: [ "bottom", "top" ], 1815 vertical: [ "bottom", "top" ], 1816 down: [ "top", "bottom" ], 1817 left: [ "right", "left" ], 1818 horizontal: [ "right", "left" ], 1819 right: [ "left", "right" ] 1820 }, 1821 element = $( this ), 1822 direction = options.direction || "up", 1823 start = element.cssClip(), 1824 animate = { clip: $.extend( {}, start ) }, 1825 placeholder = $.effects.createPlaceholder( element ); 1826 1827 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 1828 1829 if ( options.mode === "show" ) { 1830 element.cssClip( animate.clip ); 1831 if ( placeholder ) { 1832 placeholder.css( $.effects.clipToBox( animate ) ); 1833 } 1834 1835 animate.clip = start; 1836 } 1837 1838 if ( placeholder ) { 1839 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 1840 } 1841 1842 element.animate( animate, { 1843 queue: false, 1844 duration: options.duration, 1845 easing: options.easing, 1846 complete: done 1847 } ); 1848} ); 1849 1850} ); 1851 1852/*! 1853 * jQuery UI Effects Bounce @VERSION 1854 * https://jqueryui.com 1855 * 1856 * Copyright OpenJS Foundation and other contributors 1857 * Released under the MIT license. 1858 * https://jquery.org/license 1859 */ 1860 1861//>>label: Bounce Effect 1862//>>group: Effects 1863//>>description: Bounces an element horizontally or vertically n times. 1864//>>docs: https://api.jqueryui.com/bounce-effect/ 1865//>>demos: https://jqueryui.com/effect/ 1866 1867( function( factory ) { 1868 "use strict"; 1869 1870 if ( typeof define === "function" && define.amd ) { 1871 1872 // AMD. Register as an anonymous module. 1873 define( 'ui/effects/effect-bounce.js',[ 1874 "jquery", 1875 "../version", 1876 "../effect" 1877 ], factory ); 1878 } else { 1879 1880 // Browser globals 1881 factory( jQuery ); 1882 } 1883} )( function( $ ) { 1884"use strict"; 1885 1886return $.effects.define( "bounce", function( options, done ) { 1887 var upAnim, downAnim, refValue, 1888 element = $( this ), 1889 1890 // Defaults: 1891 mode = options.mode, 1892 hide = mode === "hide", 1893 show = mode === "show", 1894 direction = options.direction || "up", 1895 distance = options.distance, 1896 times = options.times || 5, 1897 1898 // Number of internal animations 1899 anims = times * 2 + ( show || hide ? 1 : 0 ), 1900 speed = options.duration / anims, 1901 easing = options.easing, 1902 1903 // Utility: 1904 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 1905 motion = ( direction === "up" || direction === "left" ), 1906 i = 0, 1907 1908 queuelen = element.queue().length; 1909 1910 $.effects.createPlaceholder( element ); 1911 1912 refValue = element.css( ref ); 1913 1914 // Default distance for the BIGGEST bounce is the outer Distance / 3 1915 if ( !distance ) { 1916 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 1917 } 1918 1919 if ( show ) { 1920 downAnim = { opacity: 1 }; 1921 downAnim[ ref ] = refValue; 1922 1923 // If we are showing, force opacity 0 and set the initial position 1924 // then do the "first" animation 1925 element 1926 .css( "opacity", 0 ) 1927 .css( ref, motion ? -distance * 2 : distance * 2 ) 1928 .animate( downAnim, speed, easing ); 1929 } 1930 1931 // Start at the smallest distance if we are hiding 1932 if ( hide ) { 1933 distance = distance / Math.pow( 2, times - 1 ); 1934 } 1935 1936 downAnim = {}; 1937 downAnim[ ref ] = refValue; 1938 1939 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 1940 for ( ; i < times; i++ ) { 1941 upAnim = {}; 1942 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 1943 1944 element 1945 .animate( upAnim, speed, easing ) 1946 .animate( downAnim, speed, easing ); 1947 1948 distance = hide ? distance * 2 : distance / 2; 1949 } 1950 1951 // Last Bounce when Hiding 1952 if ( hide ) { 1953 upAnim = { opacity: 0 }; 1954 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 1955 1956 element.animate( upAnim, speed, easing ); 1957 } 1958 1959 element.queue( done ); 1960 1961 $.effects.unshift( element, queuelen, anims + 1 ); 1962} ); 1963 1964} ); 1965 1966/*! 1967 * jQuery UI Effects Clip @VERSION 1968 * https://jqueryui.com 1969 * 1970 * Copyright OpenJS Foundation and other contributors 1971 * Released under the MIT license. 1972 * https://jquery.org/license 1973 */ 1974 1975//>>label: Clip Effect 1976//>>group: Effects 1977//>>description: Clips the element on and off like an old TV. 1978//>>docs: https://api.jqueryui.com/clip-effect/ 1979//>>demos: https://jqueryui.com/effect/ 1980 1981( function( factory ) { 1982 "use strict"; 1983 1984 if ( typeof define === "function" && define.amd ) { 1985 1986 // AMD. Register as an anonymous module. 1987 define( 'ui/effects/effect-clip.js',[ 1988 "jquery", 1989 "../version", 1990 "../effect" 1991 ], factory ); 1992 } else { 1993 1994 // Browser globals 1995 factory( jQuery ); 1996 } 1997} )( function( $ ) { 1998"use strict"; 1999 2000return $.effects.define( "clip", "hide", function( options, done ) { 2001 var start, 2002 animate = {}, 2003 element = $( this ), 2004 direction = options.direction || "vertical", 2005 both = direction === "both", 2006 horizontal = both || direction === "horizontal", 2007 vertical = both || direction === "vertical"; 2008 2009 start = element.cssClip(); 2010 animate.clip = { 2011 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 2012 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 2013 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 2014 left: horizontal ? ( start.right - start.left ) / 2 : start.left 2015 }; 2016 2017 $.effects.createPlaceholder( element ); 2018 2019 if ( options.mode === "show" ) { 2020 element.cssClip( animate.clip ); 2021 animate.clip = start; 2022 } 2023 2024 element.animate( animate, { 2025 queue: false, 2026 duration: options.duration, 2027 easing: options.easing, 2028 complete: done 2029 } ); 2030 2031} ); 2032 2033} ); 2034 2035/*! 2036 * jQuery UI Effects Drop @VERSION 2037 * https://jqueryui.com 2038 * 2039 * Copyright OpenJS Foundation and other contributors 2040 * Released under the MIT license. 2041 * https://jquery.org/license 2042 */ 2043 2044//>>label: Drop Effect 2045//>>group: Effects 2046//>>description: Moves an element in one direction and hides it at the same time. 2047//>>docs: https://api.jqueryui.com/drop-effect/ 2048//>>demos: https://jqueryui.com/effect/ 2049 2050( function( factory ) { 2051 "use strict"; 2052 2053 if ( typeof define === "function" && define.amd ) { 2054 2055 // AMD. Register as an anonymous module. 2056 define( 'ui/effects/effect-drop.js',[ 2057 "jquery", 2058 "../version", 2059 "../effect" 2060 ], factory ); 2061 } else { 2062 2063 // Browser globals 2064 factory( jQuery ); 2065 } 2066} )( function( $ ) { 2067"use strict"; 2068 2069return $.effects.define( "drop", "hide", function( options, done ) { 2070 2071 var distance, 2072 element = $( this ), 2073 mode = options.mode, 2074 show = mode === "show", 2075 direction = options.direction || "left", 2076 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 2077 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 2078 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 2079 animation = { 2080 opacity: 0 2081 }; 2082 2083 $.effects.createPlaceholder( element ); 2084 2085 distance = options.distance || 2086 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 2087 2088 animation[ ref ] = motion + distance; 2089 2090 if ( show ) { 2091 element.css( animation ); 2092 2093 animation[ ref ] = oppositeMotion + distance; 2094 animation.opacity = 1; 2095 } 2096 2097 // Animate 2098 element.animate( animation, { 2099 queue: false, 2100 duration: options.duration, 2101 easing: options.easing, 2102 complete: done 2103 } ); 2104} ); 2105 2106} ); 2107 2108/*! 2109 * jQuery UI Effects Explode @VERSION 2110 * https://jqueryui.com 2111 * 2112 * Copyright OpenJS Foundation and other contributors 2113 * Released under the MIT license. 2114 * https://jquery.org/license 2115 */ 2116 2117//>>label: Explode Effect 2118//>>group: Effects 2119//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 2120//>>docs: https://api.jqueryui.com/explode-effect/ 2121//>>demos: https://jqueryui.com/effect/ 2122 2123( function( factory ) { 2124 "use strict"; 2125 2126 if ( typeof define === "function" && define.amd ) { 2127 2128 // AMD. Register as an anonymous module. 2129 define( 'ui/effects/effect-explode.js',[ 2130 "jquery", 2131 "../version", 2132 "../effect" 2133 ], factory ); 2134 } else { 2135 2136 // Browser globals 2137 factory( jQuery ); 2138 } 2139} )( function( $ ) { 2140"use strict"; 2141 2142return $.effects.define( "explode", "hide", function( options, done ) { 2143 2144 var i, j, left, top, mx, my, 2145 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 2146 cells = rows, 2147 element = $( this ), 2148 mode = options.mode, 2149 show = mode === "show", 2150 2151 // Show and then visibility:hidden the element before calculating offset 2152 offset = element.show().css( "visibility", "hidden" ).offset(), 2153 2154 // Width and height of a piece 2155 width = Math.ceil( element.outerWidth() / cells ), 2156 height = Math.ceil( element.outerHeight() / rows ), 2157 pieces = []; 2158 2159 // Children animate complete: 2160 function childComplete() { 2161 pieces.push( this ); 2162 if ( pieces.length === rows * cells ) { 2163 animComplete(); 2164 } 2165 } 2166 2167 // Clone the element for each row and cell. 2168 for ( i = 0; i < rows; i++ ) { // ===> 2169 top = offset.top + i * height; 2170 my = i - ( rows - 1 ) / 2; 2171 2172 for ( j = 0; j < cells; j++ ) { // ||| 2173 left = offset.left + j * width; 2174 mx = j - ( cells - 1 ) / 2; 2175 2176 // Create a clone of the now hidden main element that will be absolute positioned 2177 // within a wrapper div off the -left and -top equal to size of our pieces 2178 element 2179 .clone() 2180 .appendTo( "body" ) 2181 .wrap( "<div></div>" ) 2182 .css( { 2183 position: "absolute", 2184 visibility: "visible", 2185 left: -j * width, 2186 top: -i * height 2187 } ) 2188 2189 // Select the wrapper - make it overflow: hidden and absolute positioned based on 2190 // where the original was located +left and +top equal to the size of pieces 2191 .parent() 2192 .addClass( "ui-effects-explode" ) 2193 .css( { 2194 position: "absolute", 2195 overflow: "hidden", 2196 width: width, 2197 height: height, 2198 left: left + ( show ? mx * width : 0 ), 2199 top: top + ( show ? my * height : 0 ), 2200 opacity: show ? 0 : 1 2201 } ) 2202 .animate( { 2203 left: left + ( show ? 0 : mx * width ), 2204 top: top + ( show ? 0 : my * height ), 2205 opacity: show ? 1 : 0 2206 }, options.duration || 500, options.easing, childComplete ); 2207 } 2208 } 2209 2210 function animComplete() { 2211 element.css( { 2212 visibility: "visible" 2213 } ); 2214 $( pieces ).remove(); 2215 done(); 2216 } 2217} ); 2218 2219} ); 2220 2221/*! 2222 * jQuery UI Effects Fade @VERSION 2223 * https://jqueryui.com 2224 * 2225 * Copyright OpenJS Foundation and other contributors 2226 * Released under the MIT license. 2227 * https://jquery.org/license 2228 */ 2229 2230//>>label: Fade Effect 2231//>>group: Effects 2232//>>description: Fades the element. 2233//>>docs: https://api.jqueryui.com/fade-effect/ 2234//>>demos: https://jqueryui.com/effect/ 2235 2236( function( factory ) { 2237 "use strict"; 2238 2239 if ( typeof define === "function" && define.amd ) { 2240 2241 // AMD. Register as an anonymous module. 2242 define( 'ui/effects/effect-fade.js',[ 2243 "jquery", 2244 "../version", 2245 "../effect" 2246 ], factory ); 2247 } else { 2248 2249 // Browser globals 2250 factory( jQuery ); 2251 } 2252} )( function( $ ) { 2253"use strict"; 2254 2255return $.effects.define( "fade", "toggle", function( options, done ) { 2256 var show = options.mode === "show"; 2257 2258 $( this ) 2259 .css( "opacity", show ? 0 : 1 ) 2260 .animate( { 2261 opacity: show ? 1 : 0 2262 }, { 2263 queue: false, 2264 duration: options.duration, 2265 easing: options.easing, 2266 complete: done 2267 } ); 2268} ); 2269 2270} ); 2271 2272/*! 2273 * jQuery UI Effects Fold @VERSION 2274 * https://jqueryui.com 2275 * 2276 * Copyright OpenJS Foundation and other contributors 2277 * Released under the MIT license. 2278 * https://jquery.org/license 2279 */ 2280 2281//>>label: Fold Effect 2282//>>group: Effects 2283//>>description: Folds an element first horizontally and then vertically. 2284//>>docs: https://api.jqueryui.com/fold-effect/ 2285//>>demos: https://jqueryui.com/effect/ 2286 2287( function( factory ) { 2288 "use strict"; 2289 2290 if ( typeof define === "function" && define.amd ) { 2291 2292 // AMD. Register as an anonymous module. 2293 define( 'ui/effects/effect-fold.js',[ 2294 "jquery", 2295 "../version", 2296 "../effect" 2297 ], factory ); 2298 } else { 2299 2300 // Browser globals 2301 factory( jQuery ); 2302 } 2303} )( function( $ ) { 2304"use strict"; 2305 2306return $.effects.define( "fold", "hide", function( options, done ) { 2307 2308 // Create element 2309 var element = $( this ), 2310 mode = options.mode, 2311 show = mode === "show", 2312 hide = mode === "hide", 2313 size = options.size || 15, 2314 percent = /([0-9]+)%/.exec( size ), 2315 horizFirst = !!options.horizFirst, 2316 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 2317 duration = options.duration / 2, 2318 2319 placeholder = $.effects.createPlaceholder( element ), 2320 2321 start = element.cssClip(), 2322 animation1 = { clip: $.extend( {}, start ) }, 2323 animation2 = { clip: $.extend( {}, start ) }, 2324 2325 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 2326 2327 queuelen = element.queue().length; 2328 2329 if ( percent ) { 2330 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 2331 } 2332 animation1.clip[ ref[ 0 ] ] = size; 2333 animation2.clip[ ref[ 0 ] ] = size; 2334 animation2.clip[ ref[ 1 ] ] = 0; 2335 2336 if ( show ) { 2337 element.cssClip( animation2.clip ); 2338 if ( placeholder ) { 2339 placeholder.css( $.effects.clipToBox( animation2 ) ); 2340 } 2341 2342 animation2.clip = start; 2343 } 2344 2345 // Animate 2346 element 2347 .queue( function( next ) { 2348 if ( placeholder ) { 2349 placeholder 2350 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 2351 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 2352 } 2353 2354 next(); 2355 } ) 2356 .animate( animation1, duration, options.easing ) 2357 .animate( animation2, duration, options.easing ) 2358 .queue( done ); 2359 2360 $.effects.unshift( element, queuelen, 4 ); 2361} ); 2362 2363} ); 2364 2365/*! 2366 * jQuery UI Effects Highlight @VERSION 2367 * https://jqueryui.com 2368 * 2369 * Copyright OpenJS Foundation and other contributors 2370 * Released under the MIT license. 2371 * https://jquery.org/license 2372 */ 2373 2374//>>label: Highlight Effect 2375//>>group: Effects 2376//>>description: Highlights the background of an element in a defined color for a custom duration. 2377//>>docs: https://api.jqueryui.com/highlight-effect/ 2378//>>demos: https://jqueryui.com/effect/ 2379 2380( function( factory ) { 2381 "use strict"; 2382 2383 if ( typeof define === "function" && define.amd ) { 2384 2385 // AMD. Register as an anonymous module. 2386 define( 'ui/effects/effect-highlight.js',[ 2387 "jquery", 2388 "../version", 2389 "../effect" 2390 ], factory ); 2391 } else { 2392 2393 // Browser globals 2394 factory( jQuery ); 2395 } 2396} )( function( $ ) { 2397"use strict"; 2398 2399return $.effects.define( "highlight", "show", function( options, done ) { 2400 var element = $( this ), 2401 animation = { 2402 backgroundColor: element.css( "backgroundColor" ) 2403 }; 2404 2405 if ( options.mode === "hide" ) { 2406 animation.opacity = 0; 2407 } 2408 2409 $.effects.saveStyle( element ); 2410 2411 element 2412 .css( { 2413 backgroundImage: "none", 2414 backgroundColor: options.color || "#ffff99" 2415 } ) 2416 .animate( animation, { 2417 queue: false, 2418 duration: options.duration, 2419 easing: options.easing, 2420 complete: done 2421 } ); 2422} ); 2423 2424} ); 2425 2426/*! 2427 * jQuery UI Effects Size @VERSION 2428 * https://jqueryui.com 2429 * 2430 * Copyright OpenJS Foundation and other contributors 2431 * Released under the MIT license. 2432 * https://jquery.org/license 2433 */ 2434 2435//>>label: Size Effect 2436//>>group: Effects 2437//>>description: Resize an element to a specified width and height. 2438//>>docs: https://api.jqueryui.com/size-effect/ 2439//>>demos: https://jqueryui.com/effect/ 2440 2441( function( factory ) { 2442 "use strict"; 2443 2444 if ( typeof define === "function" && define.amd ) { 2445 2446 // AMD. Register as an anonymous module. 2447 define( 'ui/effects/effect-size.js',[ 2448 "jquery", 2449 "../version", 2450 "../effect" 2451 ], factory ); 2452 } else { 2453 2454 // Browser globals 2455 factory( jQuery ); 2456 } 2457} )( function( $ ) { 2458"use strict"; 2459 2460return $.effects.define( "size", function( options, done ) { 2461 2462 // Create element 2463 var baseline, factor, temp, 2464 element = $( this ), 2465 2466 // Copy for children 2467 cProps = [ "fontSize" ], 2468 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 2469 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 2470 2471 // Set options 2472 mode = options.mode, 2473 restore = mode !== "effect", 2474 scale = options.scale || "both", 2475 origin = options.origin || [ "middle", "center" ], 2476 position = element.css( "position" ), 2477 pos = element.position(), 2478 original = $.effects.scaledDimensions( element ), 2479 from = options.from || original, 2480 to = options.to || $.effects.scaledDimensions( element, 0 ); 2481 2482 $.effects.createPlaceholder( element ); 2483 2484 if ( mode === "show" ) { 2485 temp = from; 2486 from = to; 2487 to = temp; 2488 } 2489 2490 // Set scaling factor 2491 factor = { 2492 from: { 2493 y: from.height / original.height, 2494 x: from.width / original.width 2495 }, 2496 to: { 2497 y: to.height / original.height, 2498 x: to.width / original.width 2499 } 2500 }; 2501 2502 // Scale the css box 2503 if ( scale === "box" || scale === "both" ) { 2504 2505 // Vertical props scaling 2506 if ( factor.from.y !== factor.to.y ) { 2507 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 2508 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 2509 } 2510 2511 // Horizontal props scaling 2512 if ( factor.from.x !== factor.to.x ) { 2513 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 2514 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 2515 } 2516 } 2517 2518 // Scale the content 2519 if ( scale === "content" || scale === "both" ) { 2520 2521 // Vertical props scaling 2522 if ( factor.from.y !== factor.to.y ) { 2523 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 2524 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 2525 } 2526 } 2527 2528 // Adjust the position properties based on the provided origin points 2529 if ( origin ) { 2530 baseline = $.effects.getBaseline( origin, original ); 2531 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 2532 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 2533 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 2534 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 2535 } 2536 delete from.outerHeight; 2537 delete from.outerWidth; 2538 element.css( from ); 2539 2540 // Animate the children if desired 2541 if ( scale === "content" || scale === "both" ) { 2542 2543 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 2544 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 2545 2546 // Only animate children with width attributes specified 2547 // TODO: is this right? should we include anything with css width specified as well 2548 element.find( "*[width]" ).each( function() { 2549 var child = $( this ), 2550 childOriginal = $.effects.scaledDimensions( child ), 2551 childFrom = { 2552 height: childOriginal.height * factor.from.y, 2553 width: childOriginal.width * factor.from.x, 2554 outerHeight: childOriginal.outerHeight * factor.from.y, 2555 outerWidth: childOriginal.outerWidth * factor.from.x 2556 }, 2557 childTo = { 2558 height: childOriginal.height * factor.to.y, 2559 width: childOriginal.width * factor.to.x, 2560 outerHeight: childOriginal.height * factor.to.y, 2561 outerWidth: childOriginal.width * factor.to.x 2562 }; 2563 2564 // Vertical props scaling 2565 if ( factor.from.y !== factor.to.y ) { 2566 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 2567 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 2568 } 2569 2570 // Horizontal props scaling 2571 if ( factor.from.x !== factor.to.x ) { 2572 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 2573 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 2574 } 2575 2576 if ( restore ) { 2577 $.effects.saveStyle( child ); 2578 } 2579 2580 // Animate children 2581 child.css( childFrom ); 2582 child.animate( childTo, options.duration, options.easing, function() { 2583 2584 // Restore children 2585 if ( restore ) { 2586 $.effects.restoreStyle( child ); 2587 } 2588 } ); 2589 } ); 2590 } 2591 2592 // Animate 2593 element.animate( to, { 2594 queue: false, 2595 duration: options.duration, 2596 easing: options.easing, 2597 complete: function() { 2598 2599 var offset = element.offset(); 2600 2601 if ( to.opacity === 0 ) { 2602 element.css( "opacity", from.opacity ); 2603 } 2604 2605 if ( !restore ) { 2606 element 2607 .css( "position", position === "static" ? "relative" : position ) 2608 .offset( offset ); 2609 2610 // Need to save style here so that automatic style restoration 2611 // doesn't restore to the original styles from before the animation. 2612 $.effects.saveStyle( element ); 2613 } 2614 2615 done(); 2616 } 2617 } ); 2618 2619} ); 2620 2621} ); 2622 2623/*! 2624 * jQuery UI Effects Scale @VERSION 2625 * https://jqueryui.com 2626 * 2627 * Copyright OpenJS Foundation and other contributors 2628 * Released under the MIT license. 2629 * https://jquery.org/license 2630 */ 2631 2632//>>label: Scale Effect 2633//>>group: Effects 2634//>>description: Grows or shrinks an element and its content. 2635//>>docs: https://api.jqueryui.com/scale-effect/ 2636//>>demos: https://jqueryui.com/effect/ 2637 2638( function( factory ) { 2639 "use strict"; 2640 2641 if ( typeof define === "function" && define.amd ) { 2642 2643 // AMD. Register as an anonymous module. 2644 define( 'ui/effects/effect-scale.js',[ 2645 "jquery", 2646 "../version", 2647 "../effect", 2648 "./effect-size" 2649 ], factory ); 2650 } else { 2651 2652 // Browser globals 2653 factory( jQuery ); 2654 } 2655} )( function( $ ) { 2656"use strict"; 2657 2658return $.effects.define( "scale", function( options, done ) { 2659 2660 // Create element 2661 var el = $( this ), 2662 mode = options.mode, 2663 percent = parseInt( options.percent, 10 ) || 2664 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 2665 2666 newOptions = $.extend( true, { 2667 from: $.effects.scaledDimensions( el ), 2668 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 2669 origin: options.origin || [ "middle", "center" ] 2670 }, options ); 2671 2672 // Fade option to support puff 2673 if ( options.fade ) { 2674 newOptions.from.opacity = 1; 2675 newOptions.to.opacity = 0; 2676 } 2677 2678 $.effects.effect.size.call( this, newOptions, done ); 2679} ); 2680 2681} ); 2682 2683/*! 2684 * jQuery UI Effects Puff @VERSION 2685 * https://jqueryui.com 2686 * 2687 * Copyright OpenJS Foundation and other contributors 2688 * Released under the MIT license. 2689 * https://jquery.org/license 2690 */ 2691 2692//>>label: Puff Effect 2693//>>group: Effects 2694//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 2695//>>docs: https://api.jqueryui.com/puff-effect/ 2696//>>demos: https://jqueryui.com/effect/ 2697 2698( function( factory ) { 2699 "use strict"; 2700 2701 if ( typeof define === "function" && define.amd ) { 2702 2703 // AMD. Register as an anonymous module. 2704 define( 'ui/effects/effect-puff.js',[ 2705 "jquery", 2706 "../version", 2707 "../effect", 2708 "./effect-scale" 2709 ], factory ); 2710 } else { 2711 2712 // Browser globals 2713 factory( jQuery ); 2714 } 2715} )( function( $ ) { 2716"use strict"; 2717 2718return $.effects.define( "puff", "hide", function( options, done ) { 2719 var newOptions = $.extend( true, {}, options, { 2720 fade: true, 2721 percent: parseInt( options.percent, 10 ) || 150 2722 } ); 2723 2724 $.effects.effect.scale.call( this, newOptions, done ); 2725} ); 2726 2727} ); 2728 2729/*! 2730 * jQuery UI Effects Pulsate @VERSION 2731 * https://jqueryui.com 2732 * 2733 * Copyright OpenJS Foundation and other contributors 2734 * Released under the MIT license. 2735 * https://jquery.org/license 2736 */ 2737 2738//>>label: Pulsate Effect 2739//>>group: Effects 2740//>>description: Pulsates an element n times by changing the opacity to zero and back. 2741//>>docs: https://api.jqueryui.com/pulsate-effect/ 2742//>>demos: https://jqueryui.com/effect/ 2743 2744( function( factory ) { 2745 "use strict"; 2746 2747 if ( typeof define === "function" && define.amd ) { 2748 2749 // AMD. Register as an anonymous module. 2750 define( 'ui/effects/effect-pulsate.js',[ 2751 "jquery", 2752 "../version", 2753 "../effect" 2754 ], factory ); 2755 } else { 2756 2757 // Browser globals 2758 factory( jQuery ); 2759 } 2760} )( function( $ ) { 2761"use strict"; 2762 2763return $.effects.define( "pulsate", "show", function( options, done ) { 2764 var element = $( this ), 2765 mode = options.mode, 2766 show = mode === "show", 2767 hide = mode === "hide", 2768 showhide = show || hide, 2769 2770 // Showing or hiding leaves off the "last" animation 2771 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 2772 duration = options.duration / anims, 2773 animateTo = 0, 2774 i = 1, 2775 queuelen = element.queue().length; 2776 2777 if ( show || !element.is( ":visible" ) ) { 2778 element.css( "opacity", 0 ).show(); 2779 animateTo = 1; 2780 } 2781 2782 // Anims - 1 opacity "toggles" 2783 for ( ; i < anims; i++ ) { 2784 element.animate( { opacity: animateTo }, duration, options.easing ); 2785 animateTo = 1 - animateTo; 2786 } 2787 2788 element.animate( { opacity: animateTo }, duration, options.easing ); 2789 2790 element.queue( done ); 2791 2792 $.effects.unshift( element, queuelen, anims + 1 ); 2793} ); 2794 2795} ); 2796 2797/*! 2798 * jQuery UI Effects Shake @VERSION 2799 * https://jqueryui.com 2800 * 2801 * Copyright OpenJS Foundation and other contributors 2802 * Released under the MIT license. 2803 * https://jquery.org/license 2804 */ 2805 2806//>>label: Shake Effect 2807//>>group: Effects 2808//>>description: Shakes an element horizontally or vertically n times. 2809//>>docs: https://api.jqueryui.com/shake-effect/ 2810//>>demos: https://jqueryui.com/effect/ 2811 2812( function( factory ) { 2813 "use strict"; 2814 2815 if ( typeof define === "function" && define.amd ) { 2816 2817 // AMD. Register as an anonymous module. 2818 define( 'ui/effects/effect-shake.js',[ 2819 "jquery", 2820 "../version", 2821 "../effect" 2822 ], factory ); 2823 } else { 2824 2825 // Browser globals 2826 factory( jQuery ); 2827 } 2828} )( function( $ ) { 2829"use strict"; 2830 2831return $.effects.define( "shake", function( options, done ) { 2832 2833 var i = 1, 2834 element = $( this ), 2835 direction = options.direction || "left", 2836 distance = options.distance || 20, 2837 times = options.times || 3, 2838 anims = times * 2 + 1, 2839 speed = Math.round( options.duration / anims ), 2840 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 2841 positiveMotion = ( direction === "up" || direction === "left" ), 2842 animation = {}, 2843 animation1 = {}, 2844 animation2 = {}, 2845 2846 queuelen = element.queue().length; 2847 2848 $.effects.createPlaceholder( element ); 2849 2850 // Animation 2851 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 2852 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 2853 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 2854 2855 // Animate 2856 element.animate( animation, speed, options.easing ); 2857 2858 // Shakes 2859 for ( ; i < times; i++ ) { 2860 element 2861 .animate( animation1, speed, options.easing ) 2862 .animate( animation2, speed, options.easing ); 2863 } 2864 2865 element 2866 .animate( animation1, speed, options.easing ) 2867 .animate( animation, speed / 2, options.easing ) 2868 .queue( done ); 2869 2870 $.effects.unshift( element, queuelen, anims + 1 ); 2871} ); 2872 2873} ); 2874 2875/*! 2876 * jQuery UI Effects Slide @VERSION 2877 * https://jqueryui.com 2878 * 2879 * Copyright OpenJS Foundation and other contributors 2880 * Released under the MIT license. 2881 * https://jquery.org/license 2882 */ 2883 2884//>>label: Slide Effect 2885//>>group: Effects 2886//>>description: Slides an element in and out of the viewport. 2887//>>docs: https://api.jqueryui.com/slide-effect/ 2888//>>demos: https://jqueryui.com/effect/ 2889 2890( function( factory ) { 2891 "use strict"; 2892 2893 if ( typeof define === "function" && define.amd ) { 2894 2895 // AMD. Register as an anonymous module. 2896 define( 'ui/effects/effect-slide.js',[ 2897 "jquery", 2898 "../version", 2899 "../effect" 2900 ], factory ); 2901 } else { 2902 2903 // Browser globals 2904 factory( jQuery ); 2905 } 2906} )( function( $ ) { 2907"use strict"; 2908 2909return $.effects.define( "slide", "show", function( options, done ) { 2910 var startClip, startRef, 2911 element = $( this ), 2912 map = { 2913 up: [ "bottom", "top" ], 2914 down: [ "top", "bottom" ], 2915 left: [ "right", "left" ], 2916 right: [ "left", "right" ] 2917 }, 2918 mode = options.mode, 2919 direction = options.direction || "left", 2920 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 2921 positiveMotion = ( direction === "up" || direction === "left" ), 2922 distance = options.distance || 2923 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 2924 animation = {}; 2925 2926 $.effects.createPlaceholder( element ); 2927 2928 startClip = element.cssClip(); 2929 startRef = element.position()[ ref ]; 2930 2931 // Define hide animation 2932 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 2933 animation.clip = element.cssClip(); 2934 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 2935 2936 // Reverse the animation if we're showing 2937 if ( mode === "show" ) { 2938 element.cssClip( animation.clip ); 2939 element.css( ref, animation[ ref ] ); 2940 animation.clip = startClip; 2941 animation[ ref ] = startRef; 2942 } 2943 2944 // Actually animate 2945 element.animate( animation, { 2946 queue: false, 2947 duration: options.duration, 2948 easing: options.easing, 2949 complete: done 2950 } ); 2951} ); 2952 2953} ); 2954 2955/*! 2956 * jQuery UI Effects Transfer @VERSION 2957 * https://jqueryui.com 2958 * 2959 * Copyright OpenJS Foundation and other contributors 2960 * Released under the MIT license. 2961 * https://jquery.org/license 2962 */ 2963 2964//>>label: Transfer Effect 2965//>>group: Effects 2966//>>description: Displays a transfer effect from one element to another. 2967//>>docs: https://api.jqueryui.com/transfer-effect/ 2968//>>demos: https://jqueryui.com/effect/ 2969 2970( function( factory ) { 2971 "use strict"; 2972 2973 if ( typeof define === "function" && define.amd ) { 2974 2975 // AMD. Register as an anonymous module. 2976 define( 'ui/effects/effect-transfer.js',[ 2977 "jquery", 2978 "../version", 2979 "../effect" 2980 ], factory ); 2981 } else { 2982 2983 // Browser globals 2984 factory( jQuery ); 2985 } 2986} )( function( $ ) { 2987"use strict"; 2988 2989var effect; 2990if ( $.uiBackCompat === true ) { 2991 effect = $.effects.define( "transfer", function( options, done ) { 2992 $( this ).transfer( options, done ); 2993 } ); 2994} 2995return effect; 2996 2997} ); 2998 2999/*! 3000 * jQuery UI Focusable @VERSION 3001 * https://jqueryui.com 3002 * 3003 * Copyright OpenJS Foundation and other contributors 3004 * Released under the MIT license. 3005 * https://jquery.org/license 3006 */ 3007 3008//>>label: :focusable Selector 3009//>>group: Core 3010//>>description: Selects elements which can be focused. 3011//>>docs: https://api.jqueryui.com/focusable-selector/ 3012 3013( function( factory ) { 3014 "use strict"; 3015 3016 if ( typeof define === "function" && define.amd ) { 3017 3018 // AMD. Register as an anonymous module. 3019 define( 'ui/focusable',[ "jquery", "./version" ], factory ); 3020 } else { 3021 3022 // Browser globals 3023 factory( jQuery ); 3024 } 3025} )( function( $ ) { 3026"use strict"; 3027 3028// Selectors 3029$.ui.focusable = function( element, hasTabindex ) { 3030 var map, mapName, img, focusableIfVisible, fieldset, 3031 nodeName = element.nodeName.toLowerCase(); 3032 3033 if ( "area" === nodeName ) { 3034 map = element.parentNode; 3035 mapName = map.name; 3036 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 3037 return false; 3038 } 3039 img = $( "img[usemap='#" + mapName + "']" ); 3040 return img.length > 0 && img.is( ":visible" ); 3041 } 3042 3043 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 3044 focusableIfVisible = !element.disabled; 3045 3046 if ( focusableIfVisible ) { 3047 3048 // Form controls within a disabled fieldset are disabled. 3049 // However, controls within the fieldset's legend do not get disabled. 3050 // Since controls generally aren't placed inside legends, we skip 3051 // this portion of the check. 3052 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 3053 if ( fieldset ) { 3054 focusableIfVisible = !fieldset.disabled; 3055 } 3056 } 3057 } else if ( "a" === nodeName ) { 3058 focusableIfVisible = element.href || hasTabindex; 3059 } else { 3060 focusableIfVisible = hasTabindex; 3061 } 3062 3063 return focusableIfVisible && $( element ).is( ":visible" ) && 3064 $( element ).css( "visibility" ) === "visible"; 3065}; 3066 3067$.extend( $.expr.pseudos, { 3068 focusable: function( element ) { 3069 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 3070 } 3071} ); 3072 3073return $.ui.focusable; 3074 3075} ); 3076 3077/*! 3078 * jQuery UI Form Reset Mixin @VERSION 3079 * https://jqueryui.com 3080 * 3081 * Copyright OpenJS Foundation and other contributors 3082 * Released under the MIT license. 3083 * https://jquery.org/license 3084 */ 3085 3086//>>label: Form Reset Mixin 3087//>>group: Core 3088//>>description: Refresh input widgets when their form is reset 3089//>>docs: https://api.jqueryui.com/form-reset-mixin/ 3090 3091( function( factory ) { 3092 "use strict"; 3093 3094 if ( typeof define === "function" && define.amd ) { 3095 3096 // AMD. Register as an anonymous module. 3097 define( 'ui/form-reset-mixin',[ 3098 "jquery", 3099 "./version" 3100 ], factory ); 3101 } else { 3102 3103 // Browser globals 3104 factory( jQuery ); 3105 } 3106} )( function( $ ) { 3107"use strict"; 3108 3109return $.ui.formResetMixin = { 3110 _formResetHandler: function() { 3111 var form = $( this ); 3112 3113 // Wait for the form reset to actually happen before refreshing 3114 setTimeout( function() { 3115 var instances = form.data( "ui-form-reset-instances" ); 3116 $.each( instances, function() { 3117 this.refresh(); 3118 } ); 3119 } ); 3120 }, 3121 3122 _bindFormResetHandler: function() { 3123 this.form = $( this.element.prop( "form" ) ); 3124 if ( !this.form.length ) { 3125 return; 3126 } 3127 3128 var instances = this.form.data( "ui-form-reset-instances" ) || []; 3129 if ( !instances.length ) { 3130 3131 // We don't use _on() here because we use a single event handler per form 3132 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 3133 } 3134 instances.push( this ); 3135 this.form.data( "ui-form-reset-instances", instances ); 3136 }, 3137 3138 _unbindFormResetHandler: function() { 3139 if ( !this.form.length ) { 3140 return; 3141 } 3142 3143 var instances = this.form.data( "ui-form-reset-instances" ); 3144 instances.splice( $.inArray( this, instances ), 1 ); 3145 if ( instances.length ) { 3146 this.form.data( "ui-form-reset-instances", instances ); 3147 } else { 3148 this.form 3149 .removeData( "ui-form-reset-instances" ) 3150 .off( "reset.ui-form-reset" ); 3151 } 3152 } 3153}; 3154 3155} ); 3156 3157/*! 3158 * jQuery UI Legacy jQuery Core patches @VERSION 3159 * https://jqueryui.com 3160 * 3161 * Copyright OpenJS Foundation and other contributors 3162 * Released under the MIT license. 3163 * https://jquery.org/license 3164 * 3165 */ 3166 3167//>>label: Legacy jQuery Core patches 3168//>>group: Core 3169//>>description: Backport `.even()`, `.odd()` and `$.escapeSelector` to older jQuery Core versions (deprecated) 3170 3171( function( factory ) { 3172"use strict"; 3173 3174 if ( typeof define === "function" && define.amd ) { 3175 3176 // AMD. Register as an anonymous module. 3177 define( 'ui/jquery-patch.js',[ "jquery", "./version" ], factory ); 3178 } else { 3179 3180 // Browser globals 3181 factory( jQuery ); 3182 } 3183} )( function( $ ) { 3184"use strict"; 3185 3186// Support: jQuery 2.2.x or older. 3187// This method has been defined in jQuery 3.0.0. 3188// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js 3189if ( !$.escapeSelector ) { 3190 $.escapeSelector = function( id ) { 3191 return CSS.escape( id + "" ); 3192 }; 3193} 3194 3195// Support: jQuery 3.4.x or older 3196// These methods have been defined in jQuery 3.5.0. 3197if ( !$.fn.even || !$.fn.odd ) { 3198 $.fn.extend( { 3199 even: function() { 3200 return this.filter( function( i ) { 3201 return i % 2 === 0; 3202 } ); 3203 }, 3204 odd: function() { 3205 return this.filter( function( i ) { 3206 return i % 2 === 1; 3207 } ); 3208 } 3209 } ); 3210} 3211 3212} ); 3213 3214/*! 3215 * jQuery UI Keycode @VERSION 3216 * https://jqueryui.com 3217 * 3218 * Copyright OpenJS Foundation and other contributors 3219 * Released under the MIT license. 3220 * https://jquery.org/license 3221 */ 3222 3223//>>label: Keycode 3224//>>group: Core 3225//>>description: Provide keycodes as keynames 3226//>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/ 3227 3228( function( factory ) { 3229 "use strict"; 3230 3231 if ( typeof define === "function" && define.amd ) { 3232 3233 // AMD. Register as an anonymous module. 3234 define( 'ui/keycode',[ "jquery", "./version" ], factory ); 3235 } else { 3236 3237 // Browser globals 3238 factory( jQuery ); 3239 } 3240} )( function( $ ) { 3241"use strict"; 3242 3243return $.ui.keyCode = { 3244 BACKSPACE: 8, 3245 COMMA: 188, 3246 DELETE: 46, 3247 DOWN: 40, 3248 END: 35, 3249 ENTER: 13, 3250 ESCAPE: 27, 3251 HOME: 36, 3252 LEFT: 37, 3253 PAGE_DOWN: 34, 3254 PAGE_UP: 33, 3255 PERIOD: 190, 3256 RIGHT: 39, 3257 SPACE: 32, 3258 TAB: 9, 3259 UP: 38 3260}; 3261 3262} ); 3263 3264/*! 3265 * jQuery UI Labels @VERSION 3266 * https://jqueryui.com 3267 * 3268 * Copyright OpenJS Foundation and other contributors 3269 * Released under the MIT license. 3270 * https://jquery.org/license 3271 */ 3272 3273//>>label: labels 3274//>>group: Core 3275//>>description: Find all the labels associated with a given input 3276//>>docs: https://api.jqueryui.com/labels/ 3277 3278( function( factory ) { 3279 "use strict"; 3280 3281 if ( typeof define === "function" && define.amd ) { 3282 3283 // AMD. Register as an anonymous module. 3284 define( 'ui/labels',[ "jquery", "./version" ], factory ); 3285 } else { 3286 3287 // Browser globals 3288 factory( jQuery ); 3289 } 3290} )( function( $ ) { 3291"use strict"; 3292 3293return $.fn.labels = function() { 3294 var ancestor, selector, id, labels, ancestors; 3295 3296 if ( !this.length ) { 3297 return this.pushStack( [] ); 3298 } 3299 3300 // Check control.labels first 3301 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 3302 return this.pushStack( this[ 0 ].labels ); 3303 } 3304 3305 // If `control.labels` is empty - e.g. inside of document fragments - find 3306 // the labels manually 3307 labels = this.eq( 0 ).parents( "label" ); 3308 3309 // Look for the label based on the id 3310 id = this.attr( "id" ); 3311 if ( id ) { 3312 3313 // We don't search against the document in case the element 3314 // is disconnected from the DOM 3315 ancestor = this.eq( 0 ).parents().last(); 3316 3317 // Get a full set of top level ancestors 3318 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 3319 3320 // Create a selector for the label based on the id 3321 selector = "label[for='" + CSS.escape( id ) + "']"; 3322 3323 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 3324 3325 } 3326 3327 // Return whatever we have found for labels 3328 return this.pushStack( labels ); 3329}; 3330 3331} ); 3332 3333( function( factory ) { 3334 "use strict"; 3335 3336 if ( typeof define === "function" && define.amd ) { 3337 3338 // AMD. Register as an anonymous module. 3339 define( 'ui/plugin',[ "jquery", "./version" ], factory ); 3340 } else { 3341 3342 // Browser globals 3343 factory( jQuery ); 3344 } 3345} )( function( $ ) { 3346"use strict"; 3347 3348// $.ui.plugin is deprecated. Use $.widget() extensions instead. 3349return $.ui.plugin = { 3350 add: function( module, option, set ) { 3351 var i, 3352 proto = $.ui[ module ].prototype; 3353 for ( i in set ) { 3354 proto.plugins[ i ] = proto.plugins[ i ] || []; 3355 proto.plugins[ i ].push( [ option, set[ i ] ] ); 3356 } 3357 }, 3358 call: function( instance, name, args, allowDisconnected ) { 3359 var i, 3360 set = instance.plugins[ name ]; 3361 3362 if ( !set ) { 3363 return; 3364 } 3365 3366 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 3367 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 3368 return; 3369 } 3370 3371 for ( i = 0; i < set.length; i++ ) { 3372 if ( instance.options[ set[ i ][ 0 ] ] ) { 3373 set[ i ][ 1 ].apply( instance.element, args ); 3374 } 3375 } 3376 } 3377}; 3378 3379} ); 3380 3381/*! 3382 * jQuery UI Position @VERSION 3383 * https://jqueryui.com 3384 * 3385 * Copyright OpenJS Foundation and other contributors 3386 * Released under the MIT license. 3387 * https://jquery.org/license 3388 * 3389 * https://api.jqueryui.com/position/ 3390 */ 3391 3392//>>label: Position 3393//>>group: Core 3394//>>description: Positions elements relative to other elements. 3395//>>docs: https://api.jqueryui.com/position/ 3396//>>demos: https://jqueryui.com/position/ 3397 3398( function( factory ) { 3399 "use strict"; 3400 3401 if ( typeof define === "function" && define.amd ) { 3402 3403 // AMD. Register as an anonymous module. 3404 define( 'ui/position',[ "jquery", "./version" ], factory ); 3405 } else { 3406 3407 // Browser globals 3408 factory( jQuery ); 3409 } 3410} )( function( $ ) { 3411"use strict"; 3412 3413( function() { 3414var cachedScrollbarWidth, 3415 max = Math.max, 3416 abs = Math.abs, 3417 rhorizontal = /left|center|right/, 3418 rvertical = /top|center|bottom/, 3419 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 3420 rposition = /^\w+/, 3421 rpercent = /%$/, 3422 _position = $.fn.position; 3423 3424function getOffsets( offsets, width, height ) { 3425 return [ 3426 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 3427 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 3428 ]; 3429} 3430 3431function parseCss( element, property ) { 3432 return parseInt( $.css( element, property ), 10 ) || 0; 3433} 3434 3435function isWindow( obj ) { 3436 return obj != null && obj === obj.window; 3437} 3438 3439function getDimensions( elem ) { 3440 var raw = elem[ 0 ]; 3441 if ( raw.nodeType === 9 ) { 3442 return { 3443 width: elem.width(), 3444 height: elem.height(), 3445 offset: { top: 0, left: 0 } 3446 }; 3447 } 3448 if ( isWindow( raw ) ) { 3449 return { 3450 width: elem.width(), 3451 height: elem.height(), 3452 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 3453 }; 3454 } 3455 if ( raw.preventDefault ) { 3456 return { 3457 width: 0, 3458 height: 0, 3459 offset: { top: raw.pageY, left: raw.pageX } 3460 }; 3461 } 3462 return { 3463 width: elem.outerWidth(), 3464 height: elem.outerHeight(), 3465 offset: elem.offset() 3466 }; 3467} 3468 3469$.position = { 3470 scrollbarWidth: function() { 3471 if ( cachedScrollbarWidth !== undefined ) { 3472 return cachedScrollbarWidth; 3473 } 3474 var w1, w2, 3475 div = $( "<div style=" + 3476 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + 3477 "<div style='height:300px;width:auto;'></div></div>" ), 3478 innerDiv = div.children()[ 0 ]; 3479 3480 $( "body" ).append( div ); 3481 w1 = innerDiv.offsetWidth; 3482 div.css( "overflow", "scroll" ); 3483 3484 w2 = innerDiv.offsetWidth; 3485 3486 if ( w1 === w2 ) { 3487 w2 = div[ 0 ].clientWidth; 3488 } 3489 3490 div.remove(); 3491 3492 return ( cachedScrollbarWidth = w1 - w2 ); 3493 }, 3494 getScrollInfo: function( within ) { 3495 var overflowX = within.isWindow || within.isDocument ? "" : 3496 within.element.css( "overflow-x" ), 3497 overflowY = within.isWindow || within.isDocument ? "" : 3498 within.element.css( "overflow-y" ), 3499 hasOverflowX = overflowX === "scroll" || 3500 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 3501 hasOverflowY = overflowY === "scroll" || 3502 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 3503 return { 3504 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 3505 height: hasOverflowX ? $.position.scrollbarWidth() : 0 3506 }; 3507 }, 3508 getWithinInfo: function( element ) { 3509 var withinElement = $( element || window ), 3510 isElemWindow = isWindow( withinElement[ 0 ] ), 3511 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 3512 hasOffset = !isElemWindow && !isDocument; 3513 return { 3514 element: withinElement, 3515 isWindow: isElemWindow, 3516 isDocument: isDocument, 3517 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 3518 scrollLeft: withinElement.scrollLeft(), 3519 scrollTop: withinElement.scrollTop(), 3520 width: withinElement.outerWidth(), 3521 height: withinElement.outerHeight() 3522 }; 3523 } 3524}; 3525 3526$.fn.position = function( options ) { 3527 if ( !options || !options.of ) { 3528 return _position.apply( this, arguments ); 3529 } 3530 3531 // Make a copy, we don't want to modify arguments 3532 options = $.extend( {}, options ); 3533 3534 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 3535 3536 // Make sure string options are treated as CSS selectors 3537 target = typeof options.of === "string" ? 3538 $( document ).find( options.of ) : 3539 $( options.of ), 3540 3541 within = $.position.getWithinInfo( options.within ), 3542 scrollInfo = $.position.getScrollInfo( within ), 3543 collision = ( options.collision || "flip" ).split( " " ), 3544 offsets = {}; 3545 3546 dimensions = getDimensions( target ); 3547 if ( target[ 0 ].preventDefault ) { 3548 3549 // Force left top to allow flipping 3550 options.at = "left top"; 3551 } 3552 targetWidth = dimensions.width; 3553 targetHeight = dimensions.height; 3554 targetOffset = dimensions.offset; 3555 3556 // Clone to reuse original targetOffset later 3557 basePosition = $.extend( {}, targetOffset ); 3558 3559 // Force my and at to have valid horizontal and vertical positions 3560 // if a value is missing or invalid, it will be converted to center 3561 $.each( [ "my", "at" ], function() { 3562 var pos = ( options[ this ] || "" ).split( " " ), 3563 horizontalOffset, 3564 verticalOffset; 3565 3566 if ( pos.length === 1 ) { 3567 pos = rhorizontal.test( pos[ 0 ] ) ? 3568 pos.concat( [ "center" ] ) : 3569 rvertical.test( pos[ 0 ] ) ? 3570 [ "center" ].concat( pos ) : 3571 [ "center", "center" ]; 3572 } 3573 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 3574 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 3575 3576 // Calculate offsets 3577 horizontalOffset = roffset.exec( pos[ 0 ] ); 3578 verticalOffset = roffset.exec( pos[ 1 ] ); 3579 offsets[ this ] = [ 3580 horizontalOffset ? horizontalOffset[ 0 ] : 0, 3581 verticalOffset ? verticalOffset[ 0 ] : 0 3582 ]; 3583 3584 // Reduce to just the positions without the offsets 3585 options[ this ] = [ 3586 rposition.exec( pos[ 0 ] )[ 0 ], 3587 rposition.exec( pos[ 1 ] )[ 0 ] 3588 ]; 3589 } ); 3590 3591 // Normalize collision option 3592 if ( collision.length === 1 ) { 3593 collision[ 1 ] = collision[ 0 ]; 3594 } 3595 3596 if ( options.at[ 0 ] === "right" ) { 3597 basePosition.left += targetWidth; 3598 } else if ( options.at[ 0 ] === "center" ) { 3599 basePosition.left += targetWidth / 2; 3600 } 3601 3602 if ( options.at[ 1 ] === "bottom" ) { 3603 basePosition.top += targetHeight; 3604 } else if ( options.at[ 1 ] === "center" ) { 3605 basePosition.top += targetHeight / 2; 3606 } 3607 3608 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 3609 basePosition.left += atOffset[ 0 ]; 3610 basePosition.top += atOffset[ 1 ]; 3611 3612 return this.each( function() { 3613 var collisionPosition, using, 3614 elem = $( this ), 3615 elemWidth = elem.outerWidth(), 3616 elemHeight = elem.outerHeight(), 3617 marginLeft = parseCss( this, "marginLeft" ), 3618 marginTop = parseCss( this, "marginTop" ), 3619 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 3620 scrollInfo.width, 3621 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 3622 scrollInfo.height, 3623 position = $.extend( {}, basePosition ), 3624 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 3625 3626 if ( options.my[ 0 ] === "right" ) { 3627 position.left -= elemWidth; 3628 } else if ( options.my[ 0 ] === "center" ) { 3629 position.left -= elemWidth / 2; 3630 } 3631 3632 if ( options.my[ 1 ] === "bottom" ) { 3633 position.top -= elemHeight; 3634 } else if ( options.my[ 1 ] === "center" ) { 3635 position.top -= elemHeight / 2; 3636 } 3637 3638 position.left += myOffset[ 0 ]; 3639 position.top += myOffset[ 1 ]; 3640 3641 collisionPosition = { 3642 marginLeft: marginLeft, 3643 marginTop: marginTop 3644 }; 3645 3646 $.each( [ "left", "top" ], function( i, dir ) { 3647 if ( $.ui.position[ collision[ i ] ] ) { 3648 $.ui.position[ collision[ i ] ][ dir ]( position, { 3649 targetWidth: targetWidth, 3650 targetHeight: targetHeight, 3651 elemWidth: elemWidth, 3652 elemHeight: elemHeight, 3653 collisionPosition: collisionPosition, 3654 collisionWidth: collisionWidth, 3655 collisionHeight: collisionHeight, 3656 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 3657 my: options.my, 3658 at: options.at, 3659 within: within, 3660 elem: elem 3661 } ); 3662 } 3663 } ); 3664 3665 if ( options.using ) { 3666 3667 // Adds feedback as second argument to using callback, if present 3668 using = function( props ) { 3669 var left = targetOffset.left - position.left, 3670 right = left + targetWidth - elemWidth, 3671 top = targetOffset.top - position.top, 3672 bottom = top + targetHeight - elemHeight, 3673 feedback = { 3674 target: { 3675 element: target, 3676 left: targetOffset.left, 3677 top: targetOffset.top, 3678 width: targetWidth, 3679 height: targetHeight 3680 }, 3681 element: { 3682 element: elem, 3683 left: position.left, 3684 top: position.top, 3685 width: elemWidth, 3686 height: elemHeight 3687 }, 3688 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 3689 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 3690 }; 3691 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 3692 feedback.horizontal = "center"; 3693 } 3694 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 3695 feedback.vertical = "middle"; 3696 } 3697 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 3698 feedback.important = "horizontal"; 3699 } else { 3700 feedback.important = "vertical"; 3701 } 3702 options.using.call( this, props, feedback ); 3703 }; 3704 } 3705 3706 elem.offset( $.extend( position, { using: using } ) ); 3707 } ); 3708}; 3709 3710$.ui.position = { 3711 fit: { 3712 left: function( position, data ) { 3713 var within = data.within, 3714 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 3715 outerWidth = within.width, 3716 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 3717 overLeft = withinOffset - collisionPosLeft, 3718 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 3719 newOverRight; 3720 3721 // Element is wider than within 3722 if ( data.collisionWidth > outerWidth ) { 3723 3724 // Element is initially over the left side of within 3725 if ( overLeft > 0 && overRight <= 0 ) { 3726 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 3727 withinOffset; 3728 position.left += overLeft - newOverRight; 3729 3730 // Element is initially over right side of within 3731 } else if ( overRight > 0 && overLeft <= 0 ) { 3732 position.left = withinOffset; 3733 3734 // Element is initially over both left and right sides of within 3735 } else { 3736 if ( overLeft > overRight ) { 3737 position.left = withinOffset + outerWidth - data.collisionWidth; 3738 } else { 3739 position.left = withinOffset; 3740 } 3741 } 3742 3743 // Too far left -> align with left edge 3744 } else if ( overLeft > 0 ) { 3745 position.left += overLeft; 3746 3747 // Too far right -> align with right edge 3748 } else if ( overRight > 0 ) { 3749 position.left -= overRight; 3750 3751 // Adjust based on position and margin 3752 } else { 3753 position.left = max( position.left - collisionPosLeft, position.left ); 3754 } 3755 }, 3756 top: function( position, data ) { 3757 var within = data.within, 3758 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 3759 outerHeight = data.within.height, 3760 collisionPosTop = position.top - data.collisionPosition.marginTop, 3761 overTop = withinOffset - collisionPosTop, 3762 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 3763 newOverBottom; 3764 3765 // Element is taller than within 3766 if ( data.collisionHeight > outerHeight ) { 3767 3768 // Element is initially over the top of within 3769 if ( overTop > 0 && overBottom <= 0 ) { 3770 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 3771 withinOffset; 3772 position.top += overTop - newOverBottom; 3773 3774 // Element is initially over bottom of within 3775 } else if ( overBottom > 0 && overTop <= 0 ) { 3776 position.top = withinOffset; 3777 3778 // Element is initially over both top and bottom of within 3779 } else { 3780 if ( overTop > overBottom ) { 3781 position.top = withinOffset + outerHeight - data.collisionHeight; 3782 } else { 3783 position.top = withinOffset; 3784 } 3785 } 3786 3787 // Too far up -> align with top 3788 } else if ( overTop > 0 ) { 3789 position.top += overTop; 3790 3791 // Too far down -> align with bottom edge 3792 } else if ( overBottom > 0 ) { 3793 position.top -= overBottom; 3794 3795 // Adjust based on position and margin 3796 } else { 3797 position.top = max( position.top - collisionPosTop, position.top ); 3798 } 3799 } 3800 }, 3801 flip: { 3802 left: function( position, data ) { 3803 var within = data.within, 3804 withinOffset = within.offset.left + within.scrollLeft, 3805 outerWidth = within.width, 3806 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 3807 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 3808 overLeft = collisionPosLeft - offsetLeft, 3809 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 3810 myOffset = data.my[ 0 ] === "left" ? 3811 -data.elemWidth : 3812 data.my[ 0 ] === "right" ? 3813 data.elemWidth : 3814 0, 3815 atOffset = data.at[ 0 ] === "left" ? 3816 data.targetWidth : 3817 data.at[ 0 ] === "right" ? 3818 -data.targetWidth : 3819 0, 3820 offset = -2 * data.offset[ 0 ], 3821 newOverRight, 3822 newOverLeft; 3823 3824 if ( overLeft < 0 ) { 3825 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 3826 outerWidth - withinOffset; 3827 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 3828 position.left += myOffset + atOffset + offset; 3829 } 3830 } else if ( overRight > 0 ) { 3831 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 3832 atOffset + offset - offsetLeft; 3833 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 3834 position.left += myOffset + atOffset + offset; 3835 } 3836 } 3837 }, 3838 top: function( position, data ) { 3839 var within = data.within, 3840 withinOffset = within.offset.top + within.scrollTop, 3841 outerHeight = within.height, 3842 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 3843 collisionPosTop = position.top - data.collisionPosition.marginTop, 3844 overTop = collisionPosTop - offsetTop, 3845 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 3846 top = data.my[ 1 ] === "top", 3847 myOffset = top ? 3848 -data.elemHeight : 3849 data.my[ 1 ] === "bottom" ? 3850 data.elemHeight : 3851 0, 3852 atOffset = data.at[ 1 ] === "top" ? 3853 data.targetHeight : 3854 data.at[ 1 ] === "bottom" ? 3855 -data.targetHeight : 3856 0, 3857 offset = -2 * data.offset[ 1 ], 3858 newOverTop, 3859 newOverBottom; 3860 if ( overTop < 0 ) { 3861 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 3862 outerHeight - withinOffset; 3863 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 3864 position.top += myOffset + atOffset + offset; 3865 } 3866 } else if ( overBottom > 0 ) { 3867 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 3868 offset - offsetTop; 3869 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 3870 position.top += myOffset + atOffset + offset; 3871 } 3872 } 3873 } 3874 }, 3875 flipfit: { 3876 left: function() { 3877 $.ui.position.flip.left.apply( this, arguments ); 3878 $.ui.position.fit.left.apply( this, arguments ); 3879 }, 3880 top: function() { 3881 $.ui.position.flip.top.apply( this, arguments ); 3882 $.ui.position.fit.top.apply( this, arguments ); 3883 } 3884 } 3885}; 3886 3887} )(); 3888 3889return $.ui.position; 3890 3891} ); 3892 3893/*! 3894 * jQuery UI Scroll Parent @VERSION 3895 * https://jqueryui.com 3896 * 3897 * Copyright OpenJS Foundation and other contributors 3898 * Released under the MIT license. 3899 * https://jquery.org/license 3900 */ 3901 3902//>>label: scrollParent 3903//>>group: Core 3904//>>description: Get the closest ancestor element that is scrollable. 3905//>>docs: https://api.jqueryui.com/scrollParent/ 3906 3907( function( factory ) { 3908 "use strict"; 3909 3910 if ( typeof define === "function" && define.amd ) { 3911 3912 // AMD. Register as an anonymous module. 3913 define( 'ui/scroll-parent',[ "jquery", "./version" ], factory ); 3914 } else { 3915 3916 // Browser globals 3917 factory( jQuery ); 3918 } 3919} )( function( $ ) { 3920"use strict"; 3921 3922return $.fn.scrollParent = function( includeHidden ) { 3923 var position = this.css( "position" ), 3924 excludeStaticParent = position === "absolute", 3925 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 3926 scrollParent = this.parents().filter( function() { 3927 var parent = $( this ); 3928 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 3929 return false;
3930 } 3931 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 3932 parent.css( "overflow-x" ) ); 3933 } ).eq( 0 ); 3934 3935 return position === "fixed" || !scrollParent.length ? 3936 $( this[ 0 ].ownerDocument || document ) : 3937 scrollParent; 3938}; 3939 3940} ); 3941 3942/*! 3943 * jQuery UI Tabbable @VERSION 3944 * https://jqueryui.com 3945 * 3946 * Copyright OpenJS Foundation and other contributors 3947 * Released under the MIT license. 3948 * https://jquery.org/license 3949 */ 3950 3951//>>label: :tabbable Selector 3952//>>group: Core 3953//>>description: Selects elements which can be tabbed to. 3954//>>docs: https://api.jqueryui.com/tabbable-selector/ 3955 3956( function( factory ) { 3957 "use strict"; 3958 3959 if ( typeof define === "function" && define.amd ) { 3960 3961 // AMD. Register as an anonymous module. 3962 define( 'ui/tabbable',[ "jquery", "./version", "./focusable" ], factory ); 3963 } else { 3964 3965 // Browser globals 3966 factory( jQuery ); 3967 } 3968} )( function( $ ) { 3969"use strict"; 3970 3971return $.extend( $.expr.pseudos, { 3972 tabbable: function( element ) { 3973 var tabIndex = $.attr( element, "tabindex" ), 3974 hasTabindex = tabIndex != null; 3975 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 3976 } 3977} ); 3978 3979} ); 3980 3981/*! 3982 * jQuery UI Unique ID @VERSION 3983 * https://jqueryui.com 3984 * 3985 * Copyright OpenJS Foundation and other contributors 3986 * Released under the MIT license. 3987 * https://jquery.org/license 3988 */ 3989 3990//>>label: uniqueId 3991//>>group: Core 3992//>>description: Functions to generate and remove uniqueId's 3993//>>docs: https://api.jqueryui.com/uniqueId/ 3994 3995( function( factory ) { 3996 "use strict"; 3997 3998 if ( typeof define === "function" && define.amd ) { 3999 4000 // AMD. Register as an anonymous module. 4001 define( 'ui/unique-id',[ "jquery", "./version" ], factory ); 4002 } else { 4003 4004 // Browser globals 4005 factory( jQuery ); 4006 } 4007} )( function( $ ) { 4008"use strict"; 4009 4010return $.fn.extend( { 4011 uniqueId: ( function() { 4012 var uuid = 0; 4013 4014 return function() { 4015 return this.each( function() { 4016 if ( !this.id ) { 4017 this.id = "ui-id-" + ( ++uuid ); 4018 } 4019 } ); 4020 }; 4021 } )(), 4022 4023 removeUniqueId: function() { 4024 return this.each( function() { 4025 if ( /^ui-id-\d+$/.test( this.id ) ) { 4026 $( this ).removeAttr( "id" ); 4027 } 4028 } ); 4029 } 4030} ); 4031 4032} ); 4033 4034/*! 4035 * jQuery UI Widget @VERSION 4036 * https://jqueryui.com 4037 * 4038 * Copyright OpenJS Foundation and other contributors 4039 * Released under the MIT license. 4040 * https://jquery.org/license 4041 */ 4042 4043//>>label: Widget 4044//>>group: Core 4045//>>description: Provides a factory for creating stateful widgets with a common API. 4046//>>docs: https://api.jqueryui.com/jQuery.widget/ 4047//>>demos: https://jqueryui.com/widget/ 4048 4049( function( factory ) { 4050 "use strict"; 4051 4052 if ( typeof define === "function" && define.amd ) { 4053 4054 // AMD. Register as an anonymous module. 4055 define( 'ui/widget',[ "jquery", "./version" ], factory ); 4056 } else { 4057 4058 // Browser globals 4059 factory( jQuery ); 4060 } 4061} )( function( $ ) { 4062"use strict";
vendor: 19,709 bytes, lines 4062-4789
4062 4063 4064var widgetUuid = 0; 4065var widgetHasOwnProperty = Array.prototype.hasOwnProperty; 4066var widgetSlice = Array.prototype.slice; 4067 4068$.cleanData = ( function( orig ) { 4069 return function( elems ) { 4070 var events, elem, i; 4071 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 4072 4073 // Only trigger remove when necessary to save time 4074 events = $._data( elem, "events" ); 4075 if ( events && events.remove ) { 4076 $( elem ).triggerHandler( "remove" ); 4077 } 4078 } 4079 orig( elems ); 4080 }; 4081} )( $.cleanData ); 4082 4083$.widget = function( name, base, prototype ) { 4084 var existingConstructor, constructor, basePrototype; 4085 4086 // ProxiedPrototype allows the provided prototype to remain unmodified 4087 // so that it can be used as a mixin for multiple widgets (#8876) 4088 var proxiedPrototype = {}; 4089 4090 var namespace = name.split( "." )[ 0 ]; 4091 name = name.split( "." )[ 1 ]; 4092 if ( name === "__proto__" || name === "constructor" ) { 4093 return $.error( "Invalid widget name: " + name ); 4094 } 4095 var fullName = namespace + "-" + name; 4096 4097 if ( !prototype ) { 4098 prototype = base; 4099 base = $.Widget; 4100 } 4101 4102 if ( Array.isArray( prototype ) ) { 4103 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 4104 } 4105 4106 // Create selector for plugin 4107 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { 4108 return !!$.data( elem, fullName ); 4109 }; 4110 4111 $[ namespace ] = $[ namespace ] || {}; 4112 existingConstructor = $[ namespace ][ name ]; 4113 constructor = $[ namespace ][ name ] = function( options, element ) { 4114 4115 // Allow instantiation without "new" keyword 4116 if ( !this || !this._createWidget ) { 4117 return new constructor( options, element ); 4118 } 4119 4120 // Allow instantiation without initializing for simple inheritance 4121 // must use "new" keyword (the code above always passes args) 4122 if ( arguments.length ) { 4123 this._createWidget( options, element ); 4124 } 4125 }; 4126 4127 // Extend with the existing constructor to carry over any static properties 4128 $.extend( constructor, existingConstructor, { 4129 version: prototype.version, 4130 4131 // Copy the object used to create the prototype in case we need to 4132 // redefine the widget later 4133 _proto: $.extend( {}, prototype ), 4134 4135 // Track widgets that inherit from this widget in case this widget is 4136 // redefined after a widget inherits from it 4137 _childConstructors: [] 4138 } ); 4139 4140 basePrototype = new base(); 4141 4142 // We need to make the options hash a property directly on the new instance 4143 // otherwise we'll modify the options hash on the prototype that we're 4144 // inheriting from 4145 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 4146 $.each( prototype, function( prop, value ) { 4147 if ( typeof value !== "function" ) { 4148 proxiedPrototype[ prop ] = value; 4149 return; 4150 } 4151 proxiedPrototype[ prop ] = ( function() { 4152 function _super() { 4153 return base.prototype[ prop ].apply( this, arguments ); 4154 } 4155 4156 function _superApply( args ) { 4157 return base.prototype[ prop ].apply( this, args ); 4158 } 4159 4160 return function() { 4161 var __super = this._super; 4162 var __superApply = this._superApply; 4163 var returnValue; 4164 4165 this._super = _super; 4166 this._superApply = _superApply; 4167 4168 returnValue = value.apply( this, arguments ); 4169 4170 this._super = __super; 4171 this._superApply = __superApply; 4172 4173 return returnValue; 4174 }; 4175 } )(); 4176 } ); 4177 constructor.prototype = $.widget.extend( basePrototype, { 4178 4179 // TODO: remove support for widgetEventPrefix 4180 // always use the name + a colon as the prefix, e.g., draggable:start 4181 // don't prefix for widgets that aren't DOM-based 4182 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 4183 }, proxiedPrototype, { 4184 constructor: constructor, 4185 namespace: namespace, 4186 widgetName: name, 4187 widgetFullName: fullName 4188 } ); 4189 4190 // If this widget is being redefined then we need to find all widgets that 4191 // are inheriting from it and redefine all of them so that they inherit from 4192 // the new version of this widget. We're essentially trying to replace one 4193 // level in the prototype chain. 4194 if ( existingConstructor ) { 4195 $.each( existingConstructor._childConstructors, function( i, child ) { 4196 var childPrototype = child.prototype; 4197 4198 // Redefine the child widget using the same prototype that was 4199 // originally used, but inherit from the new version of the base 4200 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 4201 child._proto ); 4202 } ); 4203 4204 // Remove the list of existing child constructors from the old constructor 4205 // so the old child constructors can be garbage collected 4206 delete existingConstructor._childConstructors; 4207 } else { 4208 base._childConstructors.push( constructor ); 4209 } 4210 4211 $.widget.bridge( name, constructor ); 4212 4213 return constructor; 4214}; 4215 4216$.widget.extend = function( target ) { 4217 var input = widgetSlice.call( arguments, 1 ); 4218 var inputIndex = 0; 4219 var inputLength = input.length; 4220 var key; 4221 var value; 4222 4223 for ( ; inputIndex < inputLength; inputIndex++ ) { 4224 for ( key in input[ inputIndex ] ) { 4225 value = input[ inputIndex ][ key ]; 4226 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { 4227 4228 // Clone objects 4229 if ( $.isPlainObject( value ) ) { 4230 target[ key ] = $.isPlainObject( target[ key ] ) ? 4231 $.widget.extend( {}, target[ key ], value ) : 4232 4233 // Don't extend strings, arrays, etc. with objects 4234 $.widget.extend( {}, value ); 4235 4236 // Copy everything else by reference 4237 } else { 4238 target[ key ] = value; 4239 } 4240 } 4241 } 4242 } 4243 return target; 4244}; 4245 4246$.widget.bridge = function( name, object ) { 4247 var fullName = object.prototype.widgetFullName || name; 4248 $.fn[ name ] = function( options ) { 4249 var isMethodCall = typeof options === "string"; 4250 var args = widgetSlice.call( arguments, 1 ); 4251 var returnValue = this; 4252 4253 if ( isMethodCall ) { 4254 4255 // If this is an empty collection, we need to have the instance method 4256 // return undefined instead of the jQuery instance 4257 if ( !this.length && options === "instance" ) { 4258 returnValue = undefined; 4259 } else { 4260 this.each( function() { 4261 var methodValue; 4262 var instance = $.data( this, fullName ); 4263 4264 if ( options === "instance" ) { 4265 returnValue = instance; 4266 return false; 4267 } 4268 4269 if ( !instance ) { 4270 return $.error( "cannot call methods on " + name + 4271 " prior to initialization; " + 4272 "attempted to call method '" + options + "'" ); 4273 } 4274 4275 if ( typeof instance[ options ] !== "function" || 4276 options.charAt( 0 ) === "_" ) { 4277 return $.error( "no such method '" + options + "' for " + name + 4278 " widget instance" ); 4279 } 4280 4281 methodValue = instance[ options ].apply( instance, args ); 4282 4283 if ( methodValue !== instance && methodValue !== undefined ) { 4284 returnValue = methodValue && methodValue.jquery ? 4285 returnValue.pushStack( methodValue.get() ) : 4286 methodValue; 4287 return false; 4288 } 4289 } ); 4290 } 4291 } else { 4292 4293 // Allow multiple hashes to be passed on init 4294 if ( args.length ) { 4295 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 4296 } 4297 4298 this.each( function() { 4299 var instance = $.data( this, fullName ); 4300 if ( instance ) { 4301 instance.option( options || {} ); 4302 if ( instance._init ) { 4303 instance._init(); 4304 } 4305 } else { 4306 $.data( this, fullName, new object( options, this ) ); 4307 } 4308 } ); 4309 } 4310 4311 return returnValue; 4312 }; 4313}; 4314 4315$.Widget = function( /* options, element */ ) {}; 4316$.Widget._childConstructors = []; 4317 4318$.Widget.prototype = { 4319 widgetName: "widget", 4320 widgetEventPrefix: "", 4321 defaultElement: "<div>", 4322 4323 options: { 4324 classes: {}, 4325 disabled: false, 4326 4327 // Callbacks 4328 create: null 4329 }, 4330 4331 _createWidget: function( options, element ) { 4332 element = $( element || this.defaultElement || this )[ 0 ]; 4333 this.element = $( element ); 4334 this.uuid = widgetUuid++; 4335 this.eventNamespace = "." + this.widgetName + this.uuid; 4336 4337 this.bindings = $(); 4338 this.hoverable = $(); 4339 this.focusable = $(); 4340 this.classesElementLookup = {}; 4341 4342 if ( element !== this ) { 4343 $.data( element, this.widgetFullName, this ); 4344 this._on( true, this.element, { 4345 remove: function( event ) { 4346 if ( event.target === element ) { 4347 this.destroy(); 4348 } 4349 } 4350 } ); 4351 this.document = $( element.style ? 4352 4353 // Element within the document 4354 element.ownerDocument : 4355 4356 // Element is window or document 4357 element.document || element ); 4358 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 4359 } 4360 4361 this.options = $.widget.extend( {}, 4362 this.options, 4363 this._getCreateOptions(), 4364 options ); 4365 4366 this._create(); 4367 4368 if ( this.options.disabled ) { 4369 this._setOptionDisabled( this.options.disabled ); 4370 } 4371 4372 this._trigger( "create", null, this._getCreateEventData() ); 4373 this._init(); 4374 }, 4375 4376 _getCreateOptions: function() { 4377 return {}; 4378 }, 4379 4380 _getCreateEventData: $.noop, 4381 4382 _create: $.noop, 4383 4384 _init: $.noop, 4385 4386 destroy: function() { 4387 var that = this; 4388 4389 this._destroy(); 4390 $.each( this.classesElementLookup, function( key, value ) { 4391 that._removeClass( value, key ); 4392 } ); 4393 4394 // We can probably remove the unbind calls in 2.0 4395 // all event bindings should go through this._on() 4396 this.element 4397 .off( this.eventNamespace ) 4398 .removeData( this.widgetFullName ); 4399 this.widget() 4400 .off( this.eventNamespace ) 4401 .removeAttr( "aria-disabled" ); 4402 4403 // Clean up events and states 4404 this.bindings.off( this.eventNamespace ); 4405 }, 4406 4407 _destroy: $.noop, 4408 4409 widget: function() { 4410 return this.element; 4411 }, 4412 4413 option: function( key, value ) { 4414 var options = key; 4415 var parts; 4416 var curOption; 4417 var i; 4418 4419 if ( arguments.length === 0 ) { 4420 4421 // Don't return a reference to the internal hash 4422 return $.widget.extend( {}, this.options ); 4423 } 4424 4425 if ( typeof key === "string" ) { 4426 4427 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 4428 options = {}; 4429 parts = key.split( "." ); 4430 key = parts.shift(); 4431 if ( parts.length ) { 4432 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 4433 for ( i = 0; i < parts.length - 1; i++ ) { 4434 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 4435 curOption = curOption[ parts[ i ] ]; 4436 } 4437 key = parts.pop(); 4438 if ( arguments.length === 1 ) { 4439 return curOption[ key ] === undefined ? null : curOption[ key ]; 4440 } 4441 curOption[ key ] = value; 4442 } else { 4443 if ( arguments.length === 1 ) { 4444 return this.options[ key ] === undefined ? null : this.options[ key ]; 4445 } 4446 options[ key ] = value; 4447 } 4448 } 4449 4450 this._setOptions( options ); 4451 4452 return this; 4453 }, 4454 4455 _setOptions: function( options ) { 4456 var key; 4457 4458 for ( key in options ) { 4459 this._setOption( key, options[ key ] ); 4460 } 4461 4462 return this; 4463 }, 4464 4465 _setOption: function( key, value ) { 4466 if ( key === "classes" ) { 4467 this._setOptionClasses( value ); 4468 } 4469 4470 this.options[ key ] = value; 4471 4472 if ( key === "disabled" ) { 4473 this._setOptionDisabled( value ); 4474 } 4475 4476 return this; 4477 }, 4478 4479 _setOptionClasses: function( value ) { 4480 var classKey, elements, currentElements; 4481 4482 for ( classKey in value ) { 4483 currentElements = this.classesElementLookup[ classKey ]; 4484 if ( value[ classKey ] === this.options.classes[ classKey ] || 4485 !currentElements || 4486 !currentElements.length ) { 4487 continue; 4488 } 4489 4490 // We are doing this to create a new jQuery object because the _removeClass() call 4491 // on the next line is going to destroy the reference to the current elements being 4492 // tracked. We need to save a copy of this collection so that we can add the new classes 4493 // below. 4494 elements = $( currentElements.get() ); 4495 this._removeClass( currentElements, classKey ); 4496 4497 // We don't use _addClass() here, because that uses this.options.classes 4498 // for generating the string of classes. We want to use the value passed in from 4499 // _setOption(), this is the new value of the classes option which was passed to 4500 // _setOption(). We pass this value directly to _classes(). 4501 elements.addClass( this._classes( { 4502 element: elements, 4503 keys: classKey, 4504 classes: value, 4505 add: true 4506 } ) ); 4507 } 4508 }, 4509 4510 _setOptionDisabled: function( value ) { 4511 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 4512 4513 // If the widget is becoming disabled, then nothing is interactive 4514 if ( value ) { 4515 this._removeClass( this.hoverable, null, "ui-state-hover" ); 4516 this._removeClass( this.focusable, null, "ui-state-focus" ); 4517 } 4518 }, 4519 4520 enable: function() { 4521 return this._setOptions( { disabled: false } ); 4522 }, 4523 4524 disable: function() { 4525 return this._setOptions( { disabled: true } ); 4526 }, 4527 4528 _classes: function( options ) { 4529 var full = []; 4530 var that = this; 4531 4532 options = $.extend( { 4533 element: this.element, 4534 classes: this.options.classes || {} 4535 }, options ); 4536 4537 function bindRemoveEvent() { 4538 var nodesToBind = []; 4539 4540 options.element.each( function( _, element ) { 4541 var isTracked = $.map( that.classesElementLookup, function( elements ) { 4542 return elements; 4543 } ) 4544 .some( function( elements ) { 4545 return elements.is( element ); 4546 } ); 4547 4548 if ( !isTracked ) { 4549 nodesToBind.push( element ); 4550 } 4551 } ); 4552 4553 that._on( $( nodesToBind ), { 4554 remove: "_untrackClassesElement" 4555 } ); 4556 } 4557 4558 function processClassString( classes, checkOption ) { 4559 var current, i; 4560 for ( i = 0; i < classes.length; i++ ) { 4561 current = that.classesElementLookup[ classes[ i ] ] || $(); 4562 if ( options.add ) { 4563 bindRemoveEvent(); 4564 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); 4565 } else { 4566 current = $( current.not( options.element ).get() ); 4567 } 4568 that.classesElementLookup[ classes[ i ] ] = current; 4569 full.push( classes[ i ] ); 4570 if ( checkOption && options.classes[ classes[ i ] ] ) { 4571 full.push( options.classes[ classes[ i ] ] ); 4572 } 4573 } 4574 } 4575 4576 if ( options.keys ) { 4577 processClassString( options.keys.match( /\S+/g ) || [], true ); 4578 } 4579 if ( options.extra ) { 4580 processClassString( options.extra.match( /\S+/g ) || [] ); 4581 } 4582 4583 return full.join( " " ); 4584 }, 4585 4586 _untrackClassesElement: function( event ) { 4587 var that = this; 4588 $.each( that.classesElementLookup, function( key, value ) { 4589 if ( $.inArray( event.target, value ) !== -1 ) { 4590 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 4591 } 4592 } ); 4593 4594 this._off( $( event.target ) ); 4595 }, 4596 4597 _removeClass: function( element, keys, extra ) { 4598 return this._toggleClass( element, keys, extra, false ); 4599 }, 4600 4601 _addClass: function( element, keys, extra ) { 4602 return this._toggleClass( element, keys, extra, true ); 4603 }, 4604 4605 _toggleClass: function( element, keys, extra, add ) { 4606 add = ( typeof add === "boolean" ) ? add : extra; 4607 var shift = ( typeof element === "string" || element === null ), 4608 options = { 4609 extra: shift ? keys : extra, 4610 keys: shift ? element : keys, 4611 element: shift ? this.element : element, 4612 add: add 4613 }; 4614 options.element.toggleClass( this._classes( options ), add ); 4615 return this; 4616 }, 4617 4618 _on: function( suppressDisabledCheck, element, handlers ) { 4619 var delegateElement; 4620 var instance = this; 4621 4622 // No suppressDisabledCheck flag, shuffle arguments 4623 if ( typeof suppressDisabledCheck !== "boolean" ) { 4624 handlers = element; 4625 element = suppressDisabledCheck; 4626 suppressDisabledCheck = false; 4627 } 4628 4629 // No element argument, shuffle and use this.element 4630 if ( !handlers ) { 4631 handlers = element; 4632 element = this.element; 4633 delegateElement = this.widget(); 4634 } else { 4635 element = delegateElement = $( element ); 4636 this.bindings = this.bindings.add( element ); 4637 } 4638 4639 $.each( handlers, function( event, handler ) { 4640 function handlerProxy() { 4641 4642 // Allow widgets to customize the disabled handling 4643 // - disabled as an array instead of boolean 4644 // - disabled class as method for disabling individual parts 4645 if ( !suppressDisabledCheck && 4646 ( instance.options.disabled === true || 4647 $( this ).hasClass( "ui-state-disabled" ) ) ) { 4648 return; 4649 } 4650 return ( typeof handler === "string" ? instance[ handler ] : handler ) 4651 .apply( instance, arguments ); 4652 } 4653 4654 // Copy the guid so direct unbinding works 4655 if ( typeof handler !== "string" ) { 4656 handlerProxy.guid = handler.guid = 4657 handler.guid || handlerProxy.guid || $.guid++; 4658 } 4659 4660 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 4661 var eventName = match[ 1 ] + instance.eventNamespace; 4662 var selector = match[ 2 ]; 4663 4664 if ( selector ) { 4665 delegateElement.on( eventName, selector, handlerProxy ); 4666 } else { 4667 element.on( eventName, handlerProxy ); 4668 } 4669 } ); 4670 }, 4671 4672 _off: function( element, eventName ) { 4673 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 4674 this.eventNamespace; 4675 element.off( eventName ); 4676 4677 // Clear the stack to avoid memory leaks (#10056) 4678 this.bindings = $( this.bindings.not( element ).get() ); 4679 this.focusable = $( this.focusable.not( element ).get() ); 4680 this.hoverable = $( this.hoverable.not( element ).get() ); 4681 }, 4682 4683 _delay: function( handler, delay ) { 4684 function handlerProxy() { 4685 return ( typeof handler === "string" ? instance[ handler ] : handler ) 4686 .apply( instance, arguments ); 4687 } 4688 var instance = this; 4689 return setTimeout( handlerProxy, delay || 0 ); 4690 }, 4691 4692 _hoverable: function( element ) { 4693 this.hoverable = this.hoverable.add( element ); 4694 this._on( element, { 4695 mouseenter: function( event ) { 4696 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 4697 }, 4698 mouseleave: function( event ) { 4699 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 4700 } 4701 } ); 4702 }, 4703 4704 _focusable: function( element ) { 4705 this.focusable = this.focusable.add( element ); 4706 this._on( element, { 4707 focusin: function( event ) { 4708 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 4709 }, 4710 focusout: function( event ) { 4711 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 4712 } 4713 } ); 4714 }, 4715 4716 _trigger: function( type, event, data ) { 4717 var prop, orig; 4718 var callback = this.options[ type ]; 4719 4720 data = data || {}; 4721 event = $.Event( event ); 4722 event.type = ( type === this.widgetEventPrefix ? 4723 type : 4724 this.widgetEventPrefix + type ).toLowerCase(); 4725 4726 // The original event may come from any element 4727 // so we need to reset the target on the new event 4728 event.target = this.element[ 0 ]; 4729 4730 // Copy original event properties over to the new event 4731 orig = event.originalEvent; 4732 if ( orig ) { 4733 for ( prop in orig ) { 4734 if ( !( prop in event ) ) { 4735 event[ prop ] = orig[ prop ]; 4736 } 4737 } 4738 } 4739 4740 this.element.trigger( event, data ); 4741 return !( typeof callback === "function" && 4742 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 4743 event.isDefaultPrevented() ); 4744 } 4745}; 4746 4747$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 4748 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 4749 if ( typeof options === "string" ) { 4750 options = { effect: options }; 4751 } 4752 4753 var hasOptions; 4754 var effectName = !options ? 4755 method : 4756 options === true || typeof options === "number" ? 4757 defaultEffect : 4758 options.effect || defaultEffect; 4759 4760 options = options || {}; 4761 if ( typeof options === "number" ) { 4762 options = { duration: options }; 4763 } else if ( options === true ) { 4764 options = {}; 4765 } 4766 4767 hasOptions = !$.isEmptyObject( options ); 4768 options.complete = callback; 4769 4770 if ( options.delay ) { 4771 element.delay( options.delay ); 4772 } 4773 4774 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 4775 element[ method ]( options ); 4776 } else if ( effectName !== method && element[ effectName ] ) { 4777 element[ effectName ]( options.duration, options.easing, callback ); 4778 } else { 4779 element.queue( function( next ) { 4780 $( this )[ method ](); 4781 if ( callback ) { 4782 callback.call( element[ 0 ] ); 4783 } 4784 next(); 4785 } ); 4786 } 4787 }; 4788} ); 4789
vendor: 16,808 bytes, lines 4790-5456
4790return $.widget; 4791 4792} ); 4793 4794/*! 4795 * jQuery UI Accordion @VERSION 4796 * https://jqueryui.com 4797 * 4798 * Copyright OpenJS Foundation and other contributors 4799 * Released under the MIT license. 4800 * https://jquery.org/license 4801 */ 4802 4803//>>label: Accordion 4804//>>group: Widgets 4805//>>description: Displays collapsible content panels for presenting information in a limited amount of space. 4806//>>docs: https://api.jqueryui.com/accordion/ 4807//>>demos: https://jqueryui.com/accordion/ 4808//>>css.structure: ../../themes/base/core.css 4809//>>css.structure: ../../themes/base/accordion.css 4810//>>css.theme: ../../themes/base/theme.css 4811 4812( function( factory ) { 4813 "use strict"; 4814 4815 if ( typeof define === "function" && define.amd ) { 4816 4817 // AMD. Register as an anonymous module. 4818 define( 'ui/widgets/accordion.js',[ 4819 "jquery", 4820 "../version", 4821 "../keycode", 4822 "../unique-id", 4823 "../widget" 4824 ], factory ); 4825 } else { 4826 4827 // Browser globals 4828 factory( jQuery ); 4829 } 4830} )( function( $ ) { 4831"use strict"; 4832 4833return $.widget( "ui.accordion", { 4834 version: "@VERSION", 4835 options: { 4836 active: 0, 4837 animate: {}, 4838 classes: { 4839 "ui-accordion-header": "ui-corner-top", 4840 "ui-accordion-header-collapsed": "ui-corner-all", 4841 "ui-accordion-content": "ui-corner-bottom" 4842 }, 4843 collapsible: false, 4844 event: "click", 4845 header: function( elem ) { 4846 return elem 4847 .find( "> li > :first-child" ) 4848 .add( 4849 elem.find( "> :not(li)" ) 4850 4851 // Support: jQuery <3.5 only 4852 // We could use `.even()` but that's unavailable in older jQuery. 4853 .filter( function( i ) { 4854 return i % 2 === 0; 4855 } ) 4856 ); 4857 }, 4858 heightStyle: "auto", 4859 icons: { 4860 activeHeader: "ui-icon-triangle-1-s", 4861 header: "ui-icon-triangle-1-e" 4862 }, 4863 4864 // Callbacks 4865 activate: null, 4866 beforeActivate: null 4867 }, 4868 4869 hideProps: { 4870 borderTopWidth: "hide", 4871 borderBottomWidth: "hide", 4872 paddingTop: "hide", 4873 paddingBottom: "hide", 4874 height: "hide" 4875 }, 4876 4877 showProps: { 4878 borderTopWidth: "show", 4879 borderBottomWidth: "show", 4880 paddingTop: "show", 4881 paddingBottom: "show", 4882 height: "show" 4883 }, 4884 4885 _create: function() { 4886 var options = this.options; 4887 4888 this.prevShow = this.prevHide = $(); 4889 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 4890 this.element.attr( "role", "tablist" ); 4891 4892 // Don't allow collapsible: false and active: false / null 4893 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 4894 options.active = 0; 4895 } 4896 4897 this._processPanels(); 4898 4899 // handle negative values 4900 if ( options.active < 0 ) { 4901 options.active += this.headers.length; 4902 } 4903 this._refresh(); 4904 }, 4905 4906 _getCreateEventData: function() { 4907 return { 4908 header: this.active, 4909 panel: !this.active.length ? $() : this.active.next() 4910 }; 4911 }, 4912 4913 _createIcons: function() { 4914 var icon, children, 4915 icons = this.options.icons; 4916 4917 if ( icons ) { 4918 icon = $( "<span>" ); 4919 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); 4920 icon.prependTo( this.headers ); 4921 children = this.active.children( ".ui-accordion-header-icon" ); 4922 this._removeClass( children, icons.header ) 4923 ._addClass( children, null, icons.activeHeader ) 4924 ._addClass( this.headers, "ui-accordion-icons" ); 4925 } 4926 }, 4927 4928 _destroyIcons: function() { 4929 this._removeClass( this.headers, "ui-accordion-icons" ); 4930 this.headers.children( ".ui-accordion-header-icon" ).remove(); 4931 }, 4932 4933 _destroy: function() { 4934 var contents; 4935 4936 // Clean up main element 4937 this.element.removeAttr( "role" ); 4938 4939 // Clean up headers 4940 this.headers 4941 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 4942 .removeUniqueId(); 4943 4944 this._destroyIcons(); 4945 4946 // Clean up content panels 4947 contents = this.headers.next() 4948 .css( "display", "" ) 4949 .removeAttr( "role aria-hidden aria-labelledby" ) 4950 .removeUniqueId(); 4951 4952 if ( this.options.heightStyle !== "content" ) { 4953 contents.css( "height", "" ); 4954 } 4955 }, 4956 4957 _setOption: function( key, value ) { 4958 if ( key === "active" ) { 4959 4960 // _activate() will handle invalid values and update this.options 4961 this._activate( value ); 4962 return; 4963 } 4964 4965 if ( key === "event" ) { 4966 if ( this.options.event ) { 4967 this._off( this.headers, this.options.event ); 4968 } 4969 this._setupEvents( value ); 4970 } 4971 4972 this._super( key, value ); 4973 4974 // Setting collapsible: false while collapsed; open first panel 4975 if ( key === "collapsible" && !value && this.options.active === false ) { 4976 this._activate( 0 ); 4977 } 4978 4979 if ( key === "icons" ) { 4980 this._destroyIcons(); 4981 if ( value ) { 4982 this._createIcons(); 4983 } 4984 } 4985 }, 4986 4987 _setOptionDisabled: function( value ) { 4988 this._super( value ); 4989 4990 this.element.attr( "aria-disabled", value ); 4991 this._toggleClass( null, "ui-state-disabled", !!value ); 4992 }, 4993 4994 _keydown: function( event ) { 4995 if ( event.altKey || event.ctrlKey ) { 4996 return; 4997 } 4998 4999 var keyCode = $.ui.keyCode, 5000 length = this.headers.length, 5001 currentIndex = this.headers.index( event.target ), 5002 toFocus = false; 5003 5004 switch ( event.keyCode ) { 5005 case keyCode.RIGHT: 5006 case keyCode.DOWN: 5007 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 5008 break; 5009 case keyCode.LEFT: 5010 case keyCode.UP: 5011 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 5012 break; 5013 case keyCode.SPACE: 5014 case keyCode.ENTER: 5015 this._eventHandler( event ); 5016 break; 5017 case keyCode.HOME: 5018 toFocus = this.headers[ 0 ]; 5019 break; 5020 case keyCode.END: 5021 toFocus = this.headers[ length - 1 ]; 5022 break; 5023 } 5024 5025 if ( toFocus ) { 5026 $( event.target ).attr( "tabIndex", -1 ); 5027 $( toFocus ).attr( "tabIndex", 0 ); 5028 $( toFocus ).trigger( "focus" ); 5029 event.preventDefault(); 5030 } 5031 }, 5032 5033 _panelKeyDown: function( event ) { 5034 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 5035 $( event.currentTarget ).prev().trigger( "focus" ); 5036 } 5037 }, 5038 5039 refresh: function() { 5040 var options = this.options; 5041 this._processPanels(); 5042 5043 // Was collapsed or no panel 5044 if ( ( options.active === false && options.collapsible === true ) || 5045 !this.headers.length ) { 5046 options.active = false; 5047 this.active = $(); 5048 5049 // active false only when collapsible is true 5050 } else if ( options.active === false ) { 5051 this._activate( 0 ); 5052 5053 // was active, but active panel is gone 5054 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 5055 5056 // all remaining panel are disabled 5057 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 5058 options.active = false; 5059 this.active = $(); 5060 5061 // activate previous panel 5062 } else { 5063 this._activate( Math.max( 0, options.active - 1 ) ); 5064 } 5065 5066 // was active, active panel still exists 5067 } else { 5068 5069 // make sure active index is correct 5070 options.active = this.headers.index( this.active ); 5071 } 5072 5073 this._destroyIcons(); 5074 5075 this._refresh(); 5076 }, 5077 5078 _processPanels: function() { 5079 var prevHeaders = this.headers, 5080 prevPanels = this.panels; 5081 5082 if ( typeof this.options.header === "function" ) { 5083 this.headers = this.options.header( this.element ); 5084 } else { 5085 this.headers = this.element.find( this.options.header ); 5086 } 5087 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 5088 "ui-state-default" ); 5089 5090 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 5091 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 5092 5093 // Avoid memory leaks (#10056) 5094 if ( prevPanels ) { 5095 this._off( prevHeaders.not( this.headers ) ); 5096 this._off( prevPanels.not( this.panels ) ); 5097 } 5098 }, 5099 5100 _refresh: function() { 5101 var maxHeight, 5102 options = this.options, 5103 heightStyle = options.heightStyle, 5104 parent = this.element.parent(); 5105 5106 this.active = this._findActive( options.active ); 5107 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 5108 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 5109 this._addClass( this.active.next(), "ui-accordion-content-active" ); 5110 this.active.next().show(); 5111 5112 this.headers 5113 .attr( "role", "tab" ) 5114 .each( function() { 5115 var header = $( this ), 5116 headerId = header.uniqueId().attr( "id" ), 5117 panel = header.next(), 5118 panelId = panel.uniqueId().attr( "id" ); 5119 header.attr( "aria-controls", panelId ); 5120 panel.attr( "aria-labelledby", headerId ); 5121 } ) 5122 .next() 5123 .attr( "role", "tabpanel" ); 5124 5125 this.headers 5126 .not( this.active ) 5127 .attr( { 5128 "aria-selected": "false", 5129 "aria-expanded": "false", 5130 tabIndex: -1 5131 } ) 5132 .next() 5133 .attr( { 5134 "aria-hidden": "true" 5135 } ) 5136 .hide(); 5137 5138 // Make sure at least one header is in the tab order 5139 if ( !this.active.length ) { 5140 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 5141 } else { 5142 this.active.attr( { 5143 "aria-selected": "true", 5144 "aria-expanded": "true", 5145 tabIndex: 0 5146 } ) 5147 .next() 5148 .attr( { 5149 "aria-hidden": "false" 5150 } ); 5151 } 5152 5153 this._createIcons(); 5154 5155 this._setupEvents( options.event ); 5156 5157 if ( heightStyle === "fill" ) { 5158 maxHeight = parent.height(); 5159 this.element.siblings( ":visible" ).each( function() { 5160 var elem = $( this ), 5161 position = elem.css( "position" ); 5162 5163 if ( position === "absolute" || position === "fixed" ) { 5164 return; 5165 } 5166 maxHeight -= elem.outerHeight( true ); 5167 } ); 5168 5169 this.headers.each( function() { 5170 maxHeight -= $( this ).outerHeight( true ); 5171 } ); 5172 5173 this.headers.next() 5174 .each( function() { 5175 $( this ).height( Math.max( 0, maxHeight - 5176 $( this ).innerHeight() + $( this ).height() ) ); 5177 } ) 5178 .css( "overflow", "auto" ); 5179 } else if ( heightStyle === "auto" ) { 5180 maxHeight = 0; 5181 this.headers.next() 5182 .each( function() { 5183 var isVisible = $( this ).is( ":visible" ); 5184 if ( !isVisible ) { 5185 $( this ).show(); 5186 } 5187 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 5188 if ( !isVisible ) { 5189 $( this ).hide(); 5190 } 5191 } ) 5192 .height( maxHeight ); 5193 } 5194 }, 5195 5196 _activate: function( index ) { 5197 var active = this._findActive( index )[ 0 ]; 5198 5199 // Trying to activate the already active panel 5200 if ( active === this.active[ 0 ] ) { 5201 return; 5202 } 5203 5204 // Trying to collapse, simulate a click on the currently active header 5205 active = active || this.active[ 0 ]; 5206 5207 this._eventHandler( { 5208 target: active, 5209 currentTarget: active, 5210 preventDefault: $.noop 5211 } ); 5212 }, 5213 5214 _findActive: function( selector ) { 5215 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 5216 }, 5217 5218 _setupEvents: function( event ) { 5219 var events = { 5220 keydown: "_keydown" 5221 }; 5222 if ( event ) { 5223 $.each( event.split( " " ), function( index, eventName ) { 5224 events[ eventName ] = "_eventHandler"; 5225 } ); 5226 } 5227 5228 this._off( this.headers.add( this.headers.next() ) ); 5229 this._on( this.headers, events ); 5230 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 5231 this._hoverable( this.headers ); 5232 this._focusable( this.headers ); 5233 }, 5234 5235 _eventHandler: function( event ) { 5236 var activeChildren, clickedChildren, 5237 options = this.options, 5238 active = this.active, 5239 clicked = $( event.currentTarget ), 5240 clickedIsActive = clicked[ 0 ] === active[ 0 ], 5241 collapsing = clickedIsActive && options.collapsible, 5242 toShow = collapsing ? $() : clicked.next(), 5243 toHide = active.next(), 5244 eventData = { 5245 oldHeader: active, 5246 oldPanel: toHide, 5247 newHeader: collapsing ? $() : clicked, 5248 newPanel: toShow 5249 }; 5250 5251 event.preventDefault(); 5252 5253 if ( 5254 5255 // click on active header, but not collapsible 5256 ( clickedIsActive && !options.collapsible ) || 5257 5258 // allow canceling activation 5259 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 5260 return; 5261 } 5262 5263 options.active = collapsing ? false : this.headers.index( clicked ); 5264 5265 // When the call to ._toggle() comes after the class changes 5266 // it causes a very odd bug in IE 8 (see #6720) 5267 this.active = clickedIsActive ? $() : clicked; 5268 this._toggle( eventData ); 5269 5270 // Switch classes 5271 // corner classes on the previously active header stay after the animation 5272 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 5273 if ( options.icons ) { 5274 activeChildren = active.children( ".ui-accordion-header-icon" ); 5275 this._removeClass( activeChildren, null, options.icons.activeHeader ) 5276 ._addClass( activeChildren, null, options.icons.header ); 5277 } 5278 5279 if ( !clickedIsActive ) { 5280 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 5281 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 5282 if ( options.icons ) { 5283 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 5284 this._removeClass( clickedChildren, null, options.icons.header ) 5285 ._addClass( clickedChildren, null, options.icons.activeHeader ); 5286 } 5287 5288 this._addClass( clicked.next(), "ui-accordion-content-active" ); 5289 } 5290 }, 5291 5292 _toggle: function( data ) { 5293 var toShow = data.newPanel, 5294 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 5295 5296 // Handle activating a panel during the animation for another activation 5297 this.prevShow.add( this.prevHide ).stop( true, true ); 5298 this.prevShow = toShow; 5299 this.prevHide = toHide; 5300 5301 if ( this.options.animate ) { 5302 this._animate( toShow, toHide, data ); 5303 } else { 5304 toHide.hide(); 5305 toShow.show(); 5306 this._toggleComplete( data ); 5307 } 5308 5309 toHide.attr( { 5310 "aria-hidden": "true" 5311 } ); 5312 toHide.prev().attr( { 5313 "aria-selected": "false", 5314 "aria-expanded": "false" 5315 } ); 5316 5317 // if we're switching panels, remove the old header from the tab order 5318 // if we're opening from collapsed state, remove the previous header from the tab order 5319 // if we're collapsing, then keep the collapsing header in the tab order 5320 if ( toShow.length && toHide.length ) { 5321 toHide.prev().attr( { 5322 "tabIndex": -1, 5323 "aria-expanded": "false" 5324 } ); 5325 } else if ( toShow.length ) { 5326 this.headers.filter( function() { 5327 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 5328 } ) 5329 .attr( "tabIndex", -1 ); 5330 } 5331 5332 toShow 5333 .attr( "aria-hidden", "false" ) 5334 .prev() 5335 .attr( { 5336 "aria-selected": "true", 5337 "aria-expanded": "true", 5338 tabIndex: 0 5339 } ); 5340 }, 5341 5342 _animate: function( toShow, toHide, data ) { 5343 var total, easing, duration, 5344 that = this, 5345 adjust = 0, 5346 boxSizing = toShow.css( "box-sizing" ), 5347 down = toShow.length && 5348 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 5349 animate = this.options.animate || {}, 5350 options = down && animate.down || animate, 5351 complete = function() { 5352 that._toggleComplete( data ); 5353 }; 5354 5355 if ( typeof options === "number" ) { 5356 duration = options; 5357 } 5358 if ( typeof options === "string" ) { 5359 easing = options; 5360 } 5361 5362 // fall back from options to animation in case of partial down settings 5363 easing = easing || options.easing || animate.easing; 5364 duration = duration || options.duration || animate.duration; 5365 5366 if ( !toHide.length ) { 5367 return toShow.animate( this.showProps, duration, easing, complete ); 5368 } 5369 if ( !toShow.length ) { 5370 return toHide.animate( this.hideProps, duration, easing, complete ); 5371 } 5372 5373 total = toShow.show().outerHeight(); 5374 toHide.animate( this.hideProps, { 5375 duration: duration, 5376 easing: easing, 5377 step: function( now, fx ) { 5378 fx.now = Math.round( now ); 5379 } 5380 } ); 5381 toShow 5382 .hide() 5383 .animate( this.showProps, { 5384 duration: duration, 5385 easing: easing, 5386 complete: complete, 5387 step: function( now, fx ) { 5388 fx.now = Math.round( now ); 5389 if ( fx.prop !== "height" ) { 5390 if ( boxSizing === "content-box" ) { 5391 adjust += fx.now; 5392 } 5393 } else if ( that.options.heightStyle !== "content" ) { 5394 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 5395 adjust = 0; 5396 } 5397 } 5398 } ); 5399 }, 5400 5401 _toggleComplete: function( data ) { 5402 var toHide = data.oldPanel, 5403 prev = toHide.prev(); 5404 5405 this._removeClass( toHide, "ui-accordion-content-active" ); 5406 this._removeClass( prev, "ui-accordion-header-active" ) 5407 ._addClass( prev, "ui-accordion-header-collapsed" ); 5408 5409 this._trigger( "activate", null, data ); 5410 } 5411} ); 5412 5413} ); 5414 5415/*! 5416 * jQuery UI Menu @VERSION 5417 * https://jqueryui.com 5418 * 5419 * Copyright OpenJS Foundation and other contributors 5420 * Released under the MIT license. 5421 * https://jquery.org/license 5422 */ 5423 5424//>>label: Menu 5425//>>group: Widgets 5426//>>description: Creates nestable menus. 5427//>>docs: https://api.jqueryui.com/menu/ 5428//>>demos: https://jqueryui.com/menu/ 5429//>>css.structure: ../../themes/base/core.css 5430//>>css.structure: ../../themes/base/menu.css 5431//>>css.theme: ../../themes/base/theme.css 5432 5433( function( factory ) { 5434 "use strict"; 5435 5436 if ( typeof define === "function" && define.amd ) { 5437 5438 // AMD. Register as an anonymous module. 5439 define( 'ui/widgets/menu.js',[ 5440 "jquery", 5441 "../keycode", 5442 "../position", 5443 "../unique-id", 5444 "../version", 5445 "../widget" 5446 ], factory ); 5447 } else { 5448 5449 // Browser globals 5450 factory( jQuery ); 5451 } 5452} )( function( $ ) { 5453"use strict"; 5454 5455return $.widget( "ui.menu", { 5456 version: "@VERSION
vendor: 5,700 bytes, lines 5456-5675
5456", 5457 defaultElement: "<ul>", 5458 delay: 300, 5459 options: { 5460 icons: { 5461 submenu: "ui-icon-caret-1-e" 5462 }, 5463 items: "> *", 5464 menus: "ul", 5465 position: { 5466 my: "left top", 5467 at: "right top" 5468 }, 5469 role: "menu", 5470 5471 // Callbacks 5472 blur: null, 5473 focus: null, 5474 select: null 5475 }, 5476 5477 _create: function() { 5478 this.activeMenu = this.element; 5479 5480 // Flag used to prevent firing of the click handler 5481 // as the event bubbles up through nested menus 5482 this.mouseHandled = false; 5483 this.lastMousePosition = { x: null, y: null }; 5484 this.element 5485 .uniqueId() 5486 .attr( { 5487 role: this.options.role, 5488 tabIndex: 0 5489 } ); 5490 5491 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 5492 this._on( { 5493 5494 // Prevent focus from sticking to links inside menu after clicking 5495 // them (focus should always stay on UL during navigation). 5496 "mousedown .ui-menu-item": function( event ) { 5497 event.preventDefault(); 5498 5499 this._activateItem( event ); 5500 }, 5501 "click .ui-menu-item": function( event ) { 5502 var target = $( event.target ); 5503 var active = $( this.document[ 0 ].activeElement ); 5504 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 5505 this.select( event ); 5506 5507 // Only set the mouseHandled flag if the event will bubble, see #9469. 5508 if ( !event.isPropagationStopped() ) { 5509 this.mouseHandled = true; 5510 } 5511 5512 // Open submenu on click 5513 if ( target.has( ".ui-menu" ).length ) { 5514 this.expand( event ); 5515 } else if ( !this.element.is( ":focus" ) && 5516 active.closest( ".ui-menu" ).length ) { 5517 5518 // Redirect focus to the menu 5519 this.element.trigger( "focus", [ true ] ); 5520 5521 // If the active item is on the top level, let it stay active. 5522 // Otherwise, blur the active item since it is no longer visible. 5523 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 5524 clearTimeout( this.timer ); 5525 } 5526 } 5527 } 5528 }, 5529 "mouseenter .ui-menu-item": "_activateItem", 5530 "mousemove .ui-menu-item": "_activateItem", 5531 mouseleave: "collapseAll", 5532 "mouseleave .ui-menu": "collapseAll", 5533 focus: function( event, keepActiveItem ) { 5534 5535 // If there's already an active item, keep it active 5536 // If not, activate the first item 5537 var item = this.active || this._menuItems().first(); 5538 5539 if ( !keepActiveItem ) { 5540 this.focus( event, item ); 5541 } 5542 }, 5543 blur: function( event ) { 5544 this._delay( function() { 5545 var notContained = !$.contains( 5546 this.element[ 0 ], 5547 this.document[ 0 ].activeElement 5548 ); 5549 if ( notContained ) { 5550 this.collapseAll( event ); 5551 } 5552 } ); 5553 }, 5554 keydown: "_keydown" 5555 } ); 5556 5557 this.refresh(); 5558 5559 // Clicks outside of a menu collapse any open menus 5560 this._on( this.document, { 5561 click: function( event ) { 5562 if ( this._closeOnDocumentClick( event ) ) { 5563 this.collapseAll( event, true ); 5564 } 5565 5566 // Reset the mouseHandled flag 5567 this.mouseHandled = false; 5568 } 5569 } ); 5570 }, 5571 5572 _activateItem: function( event ) { 5573 5574 // Ignore mouse events while typeahead is active, see #10458. 5575 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 5576 // is over an item in the menu 5577 if ( this.previousFilter ) { 5578 return; 5579 } 5580 5581 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) 5582 if ( event.clientX === this.lastMousePosition.x && 5583 event.clientY === this.lastMousePosition.y ) { 5584 return; 5585 } 5586 5587 this.lastMousePosition = { 5588 x: event.clientX, 5589 y: event.clientY 5590 }; 5591 5592 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 5593 target = $( event.currentTarget ); 5594 5595 // Ignore bubbled events on parent items, see #11641 5596 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 5597 return; 5598 } 5599 5600 // If the item is already active, there's nothing to do 5601 if ( target.is( ".ui-state-active" ) ) { 5602 return; 5603 } 5604 5605 // Remove ui-state-active class from siblings of the newly focused menu item 5606 // to avoid a jump caused by adjacent elements both having a class with a border 5607 this._removeClass( target.siblings().children( ".ui-state-active" ), 5608 null, "ui-state-active" ); 5609 this.focus( event, target ); 5610 }, 5611 5612 _destroy: function() { 5613 var items = this.element.find( ".ui-menu-item" ) 5614 .removeAttr( "role aria-disabled" ), 5615 submenus = items.children( ".ui-menu-item-wrapper" ) 5616 .removeUniqueId() 5617 .removeAttr( "tabIndex role aria-haspopup" ); 5618 5619 // Destroy (sub)menus 5620 this.element 5621 .removeAttr( "aria-activedescendant" ) 5622 .find( ".ui-menu" ).addBack() 5623 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 5624 "tabIndex" ) 5625 .removeUniqueId() 5626 .show(); 5627 5628 submenus.children().each( function() { 5629 var elem = $( this ); 5630 if ( elem.data( "ui-menu-submenu-caret" ) ) { 5631 elem.remove(); 5632 } 5633 } ); 5634 }, 5635 5636 _keydown: function( event ) { 5637 var match, prev, character, skip, 5638 preventDefault = true; 5639 5640 switch ( event.keyCode ) { 5641 case $.ui.keyCode.PAGE_UP: 5642 this.previousPage( event ); 5643 break; 5644 case $.ui.keyCode.PAGE_DOWN: 5645 this.nextPage( event ); 5646 break; 5647 case $.ui.keyCode.HOME: 5648 this._move( "first", "first", event ); 5649 break; 5650 case $.ui.keyCode.END: 5651 this._move( "last", "last", event ); 5652 break; 5653 case $.ui.keyCode.UP: 5654 this.previous( event ); 5655 break; 5656 case $.ui.keyCode.DOWN: 5657 this.next( event ); 5658 break; 5659 case $.ui.keyCode.LEFT: 5660 this.collapse( event ); 5661 break; 5662 case $.ui.keyCode.RIGHT: 5663 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 5664 this.expand( event ); 5665 } 5666 break; 5667 case $.ui.keyCode.ENTER: 5668 case $.ui.keyCode.SPACE: 5669 this._activate( event ); 5670 break; 5671 case $.ui.keyCode.ESCAPE: 5672 this.collapse( event ); 5673 break; 5674 default: 5675 preventDefault = false;
vendor: 2,378 bytes, lines 5676-5761
5676 prev = this.previousFilter || ""; 5677 skip = false; 5678 5679 // Support number pad values 5680 character = event.keyCode >= 96 && event.keyCode <= 105 ? 5681 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 5682 5683 clearTimeout( this.filterTimer ); 5684 5685 if ( character === prev ) { 5686 skip = true; 5687 } else { 5688 character = prev + character; 5689 } 5690 5691 match = this._filterMenuItems( character ); 5692 match = skip && match.index( this.active.next() ) !== -1 ? 5693 this.active.nextAll( ".ui-menu-item" ) : 5694 match; 5695 5696 // If no matches on the current filter, reset to the last character pressed 5697 // to move down the menu to the first item that starts with that character 5698 if ( !match.length ) { 5699 character = String.fromCharCode( event.keyCode ); 5700 match = this._filterMenuItems( character ); 5701 } 5702 5703 if ( match.length ) { 5704 this.focus( event, match ); 5705 this.previousFilter = character; 5706 this.filterTimer = this._delay( function() { 5707 delete this.previousFilter; 5708 }, 1000 ); 5709 } else { 5710 delete this.previousFilter; 5711 } 5712 } 5713 5714 if ( preventDefault ) { 5715 event.preventDefault(); 5716 } 5717 }, 5718 5719 _activate: function( event ) { 5720 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 5721 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 5722 this.expand( event ); 5723 } else { 5724 this.select( event ); 5725 } 5726 } 5727 }, 5728 5729 refresh: function() { 5730 var menus, items, newSubmenus, newItems, newWrappers, 5731 that = this, 5732 icon = this.options.icons.submenu, 5733 submenus = this.element.find( this.options.menus ); 5734 5735 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 5736 5737 // Initialize nested menus 5738 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 5739 .hide() 5740 .attr( { 5741 role: this.options.role, 5742 "aria-hidden": "true", 5743 "aria-expanded": "false" 5744 } ) 5745 .each( function() { 5746 var menu = $( this ), 5747 item = menu.prev(), 5748 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 5749 5750 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 5751 item 5752 .attr( "aria-haspopup", "true" ) 5753 .prepend( submenuCaret ); 5754 menu.attr( "aria-labelledby", item.attr( "id" ) ); 5755 } ); 5756 5757 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 5758 5759 menus = submenus.add( this.element ); 5760 items = menus.find( this.options.items ); 5761
vendor: 4,552 bytes, lines 5762-5924
5762 // Initialize menu-items containing spaces and/or dashes only as dividers 5763 items.not( ".ui-menu-item" ).each( function() { 5764 var item = $( this ); 5765 if ( that._isDivider( item ) ) { 5766 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 5767 } 5768 } ); 5769 5770 // Don't refresh list items that are already adapted 5771 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 5772 newWrappers = newItems.children() 5773 .not( ".ui-menu" ) 5774 .uniqueId() 5775 .attr( { 5776 tabIndex: -1, 5777 role: this._itemRole() 5778 } ); 5779 this._addClass( newItems, "ui-menu-item" ) 5780 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 5781 5782 // Add aria-disabled attribute to any disabled menu item 5783 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 5784 5785 // If the active item has been removed, blur the menu 5786 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 5787 this.blur(); 5788 } 5789 }, 5790 5791 _itemRole: function() { 5792 return { 5793 menu: "menuitem", 5794 listbox: "option" 5795 }[ this.options.role ]; 5796 }, 5797 5798 _setOption: function( key, value ) { 5799 if ( key === "icons" ) { 5800 var icons = this.element.find( ".ui-menu-icon" ); 5801 this._removeClass( icons, null, this.options.icons.submenu ) 5802 ._addClass( icons, null, value.submenu ); 5803 } 5804 this._super( key, value ); 5805 }, 5806 5807 _setOptionDisabled: function( value ) { 5808 this._super( value ); 5809 5810 this.element.attr( "aria-disabled", String( value ) ); 5811 this._toggleClass( null, "ui-state-disabled", !!value ); 5812 }, 5813 5814 focus: function( event, item ) { 5815 var nested, focused, activeParent; 5816 this.blur( event, event && event.type === "focus" ); 5817 5818 this._scrollIntoView( item ); 5819 5820 this.active = item.first(); 5821 5822 focused = this.active.children( ".ui-menu-item-wrapper" ); 5823 this._addClass( focused, null, "ui-state-active" ); 5824 5825 // Only update aria-activedescendant if there's a role 5826 // otherwise we assume focus is managed elsewhere 5827 if ( this.options.role ) { 5828 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 5829 } 5830 5831 // Highlight active parent menu item, if any 5832 activeParent = this.active 5833 .parent() 5834 .closest( ".ui-menu-item" ) 5835 .children( ".ui-menu-item-wrapper" ); 5836 this._addClass( activeParent, null, "ui-state-active" ); 5837 5838 if ( event && event.type === "keydown" ) { 5839 this._close(); 5840 } else { 5841 this.timer = this._delay( function() { 5842 this._close(); 5843 }, this.delay ); 5844 } 5845 5846 nested = item.children( ".ui-menu" ); 5847 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 5848 this._startOpening( nested ); 5849 } 5850 this.activeMenu = item.parent(); 5851 5852 this._trigger( "focus", event, { item: item } ); 5853 }, 5854 5855 _scrollIntoView: function( item ) { 5856 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 5857 if ( this._hasScroll() ) { 5858 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 5859 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 5860 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 5861 scroll = this.activeMenu.scrollTop(); 5862 elementHeight = this.activeMenu.height(); 5863 itemHeight = item.outerHeight(); 5864 5865 if ( offset < 0 ) { 5866 this.activeMenu.scrollTop( scroll + offset ); 5867 } else if ( offset + itemHeight > elementHeight ) { 5868 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 5869 } 5870 } 5871 }, 5872 5873 blur: function( event, fromFocus ) { 5874 if ( !fromFocus ) { 5875 clearTimeout( this.timer ); 5876 } 5877 5878 if ( !this.active ) { 5879 return; 5880 } 5881 5882 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 5883 null, "ui-state-active" ); 5884 5885 this._trigger( "blur", event, { item: this.active } ); 5886 this.active = null; 5887 }, 5888 5889 _startOpening: function( submenu ) { 5890 clearTimeout( this.timer ); 5891 5892 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 5893 // shift in the submenu position when mousing over the caret icon 5894 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 5895 return; 5896 } 5897 5898 this.timer = this._delay( function() { 5899 this._close(); 5900 this._open( submenu ); 5901 }, this.delay ); 5902 }, 5903 5904 _open: function( submenu ) { 5905 var position = $.extend( { 5906 of: this.active 5907 }, this.options.position ); 5908 5909 clearTimeout( this.timer ); 5910 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 5911 .hide() 5912 .attr( "aria-hidden", "true" ); 5913 5914 submenu 5915 .show() 5916 .removeAttr( "aria-hidden" ) 5917 .attr( "aria-expanded", "true" ) 5918 .position( position ); 5919 }, 5920 5921 collapseAll: function( event, all ) { 5922 clearTimeout( this.timer ); 5923 this.timer = this._delay( function() { 5924
vendor: 5,398 bytes, lines 5925-6125
5925 // If we were passed an event, look for the submenu that contains the event 5926 var currentMenu = all ? this.element : 5927 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 5928 5929 // If we found no valid submenu ancestor, use the main menu to close all 5930 // sub menus anyway 5931 if ( !currentMenu.length ) { 5932 currentMenu = this.element; 5933 } 5934 5935 this._close( currentMenu ); 5936 5937 this.blur( event ); 5938 5939 // Work around active item staying active after menu is blurred 5940 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 5941 5942 this.activeMenu = currentMenu; 5943 }, all ? 0 : this.delay ); 5944 }, 5945 5946 // With no arguments, closes the currently active menu - if nothing is active 5947 // it closes all menus. If passed an argument, it will search for menus BELOW 5948 _close: function( startMenu ) { 5949 if ( !startMenu ) { 5950 startMenu = this.active ? this.active.parent() : this.element; 5951 } 5952 5953 startMenu.find( ".ui-menu" ) 5954 .hide() 5955 .attr( "aria-hidden", "true" ) 5956 .attr( "aria-expanded", "false" ); 5957 }, 5958 5959 _closeOnDocumentClick: function( event ) { 5960 return !$( event.target ).closest( ".ui-menu" ).length; 5961 }, 5962 5963 _isDivider: function( item ) { 5964 5965 // Match hyphen, em dash, en dash 5966 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 5967 }, 5968 5969 collapse: function( event ) { 5970 var newItem = this.active && 5971 this.active.parent().closest( ".ui-menu-item", this.element ); 5972 if ( newItem && newItem.length ) { 5973 this._close(); 5974 this.focus( event, newItem ); 5975 } 5976 }, 5977 5978 expand: function( event ) { 5979 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); 5980 5981 if ( newItem && newItem.length ) { 5982 this._open( newItem.parent() ); 5983 5984 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 5985 this._delay( function() { 5986 this.focus( event, newItem ); 5987 } ); 5988 } 5989 }, 5990 5991 next: function( event ) { 5992 this._move( "next", "first", event ); 5993 }, 5994 5995 previous: function( event ) { 5996 this._move( "prev", "last", event ); 5997 }, 5998 5999 isFirstItem: function() { 6000 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 6001 }, 6002 6003 isLastItem: function() { 6004 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 6005 }, 6006 6007 _menuItems: function( menu ) { 6008 return ( menu || this.element ) 6009 .find( this.options.items ) 6010 .filter( ".ui-menu-item" ); 6011 }, 6012 6013 _move: function( direction, filter, event ) { 6014 var next; 6015 if ( this.active ) { 6016 if ( direction === "first" || direction === "last" ) { 6017 next = this.active 6018 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 6019 .last(); 6020 } else { 6021 next = this.active 6022 [ direction + "All" ]( ".ui-menu-item" ) 6023 .first(); 6024 } 6025 } 6026 if ( !next || !next.length || !this.active ) { 6027 next = this._menuItems( this.activeMenu )[ filter ](); 6028 } 6029 6030 this.focus( event, next ); 6031 }, 6032 6033 nextPage: function( event ) { 6034 var item, base, height; 6035 6036 if ( !this.active ) { 6037 this.next( event ); 6038 return; 6039 } 6040 if ( this.isLastItem() ) { 6041 return; 6042 } 6043 if ( this._hasScroll() ) { 6044 base = this.active.offset().top; 6045 height = this.element.innerHeight(); 6046 6047 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 6048 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 6049 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 6050 } 6051 6052 this.active.nextAll( ".ui-menu-item" ).each( function() { 6053 item = $( this ); 6054 return item.offset().top - base - height < 0; 6055 } ); 6056 6057 this.focus( event, item ); 6058 } else { 6059 this.focus( event, this._menuItems( this.activeMenu ) 6060 [ !this.active ? "first" : "last" ]() ); 6061 } 6062 }, 6063 6064 previousPage: function( event ) { 6065 var item, base, height; 6066 if ( !this.active ) { 6067 this.next( event ); 6068 return; 6069 } 6070 if ( this.isFirstItem() ) { 6071 return; 6072 } 6073 if ( this._hasScroll() ) { 6074 base = this.active.offset().top; 6075 height = this.element.innerHeight(); 6076 6077 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 6078 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 6079 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 6080 } 6081 6082 this.active.prevAll( ".ui-menu-item" ).each( function() { 6083 item = $( this ); 6084 return item.offset().top - base + height > 0; 6085 } ); 6086 6087 this.focus( event, item ); 6088 } else { 6089 this.focus( event, this._menuItems( this.activeMenu ).first() ); 6090 } 6091 }, 6092 6093 _hasScroll: function() { 6094 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 6095 }, 6096 6097 select: function( event ) { 6098 6099 // TODO: It should never be possible to not have an active item at this 6100 // point, but the tests don't trigger mouseenter before click. 6101 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 6102 var ui = { item: this.active }; 6103 if ( !this.active.has( ".ui-menu" ).length ) { 6104 this.collapseAll( event, true ); 6105 } 6106 this._trigger( "select", event, ui ); 6107 }, 6108 6109 _filterMenuItems: function( character ) { 6110 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 6111 regex = new RegExp( "^" + escapedCharacter, "i" ); 6112 6113 return this.activeMenu 6114 .find( this.options.items ) 6115 6116 // Only match on items, not dividers or other content (#10571) 6117 .filter( ".ui-menu-item" ) 6118 .filter( function() { 6119 return regex.test( 6120 String.prototype.trim.call( 6121 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 6122 } ); 6123 } 6124} ); 6125
6126} ); 6127 6128/*! 6129 * jQuery UI Autocomplete @VERSION 6130 * https://jqueryui.com 6131 * 6132 * Copyright OpenJS Foundation and other contributors 6133 * Released under the MIT license. 6134 * https://jquery.org/license 6135 */ 6136 6137//>>label: Autocomplete 6138//>>group: Widgets 6139//>>description: Lists suggested words as the user is typing. 6140//>>docs: https://api.jqueryui.com/autocomplete/ 6141//>>demos: https://jqueryui.com/autocomplete/ 6142//>>css.structure: ../../themes/base/core.css 6143//>>css.structure: ../../themes/base/autocomplete.css 6144//>>css.theme: ../../themes/base/theme.css 6145 6146( function( factory ) { 6147 "use strict"; 6148 6149 if ( typeof define === "function" && define.amd ) { 6150 6151 // AMD. Register as an anonymous module. 6152 define( 'ui/widgets/autocomplete.js',[ 6153 "jquery", 6154 "./menu", 6155 "../keycode", 6156 "../position", 6157 "../version", 6158 "../widget" 6159 ], factory ); 6160 } else { 6161 6162 // Browser globals 6163 factory( jQuery ); 6164 } 6165} )( function( $ ) { 6166"use strict"; 6167 6168$.widget( "ui.autocomplete", { 6169 version: "@VERSION
vendor: 15,219 bytes, lines 6169-6764
6169", 6170 defaultElement: "<input>", 6171 options: { 6172 appendTo: null, 6173 autoFocus: false, 6174 delay: 300, 6175 minLength: 1, 6176 position: { 6177 my: "left top", 6178 at: "left bottom", 6179 collision: "none" 6180 }, 6181 source: null, 6182 6183 // Callbacks 6184 change: null, 6185 close: null, 6186 focus: null, 6187 open: null, 6188 response: null, 6189 search: null, 6190 select: null 6191 }, 6192 6193 requestIndex: 0, 6194 pending: 0, 6195 liveRegionTimer: null, 6196 6197 _create: function() { 6198 6199 // Some browsers only repeat keydown events, not keypress events, 6200 // so we use the suppressKeyPress flag to determine if we've already 6201 // handled the keydown event. #7269 6202 // Unfortunately the code for & in keypress is the same as the up arrow, 6203 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 6204 // events when we know the keydown event was used to modify the 6205 // search term. #7799 6206 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 6207 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 6208 isTextarea = nodeName === "textarea", 6209 isInput = nodeName === "input"; 6210 6211 // Textareas are always multi-line 6212 // Inputs are always single-line, even if inside a contentEditable element 6213 // All other element types are determined by whether they're contentEditable 6214 this.isMultiLine = isTextarea || 6215 !isInput && this.element.prop( "contentEditable" ) === "true"; 6216 6217 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 6218 this.isNewMenu = true; 6219 6220 this._addClass( "ui-autocomplete-input" ); 6221 this.element.attr( "autocomplete", "off" ); 6222 6223 this._on( this.element, { 6224 keydown: function( event ) { 6225 if ( this.element.prop( "readOnly" ) ) { 6226 suppressKeyPress = true; 6227 suppressInput = true; 6228 suppressKeyPressRepeat = true; 6229 return; 6230 } 6231 6232 suppressKeyPress = false; 6233 suppressInput = false; 6234 suppressKeyPressRepeat = false; 6235 var keyCode = $.ui.keyCode; 6236 switch ( event.keyCode ) { 6237 case keyCode.PAGE_UP: 6238 suppressKeyPress = true; 6239 this._move( "previousPage", event ); 6240 break; 6241 case keyCode.PAGE_DOWN: 6242 suppressKeyPress = true; 6243 this._move( "nextPage", event ); 6244 break; 6245 case keyCode.UP: 6246 suppressKeyPress = true; 6247 this._keyEvent( "previous", event ); 6248 break; 6249 case keyCode.DOWN: 6250 suppressKeyPress = true; 6251 this._keyEvent( "next", event ); 6252 break; 6253 case keyCode.ENTER: 6254 6255 // when menu is open and has focus 6256 if ( this.menu.active ) { 6257 6258 // #6055 - Opera still allows the keypress to occur 6259 // which causes forms to submit 6260 suppressKeyPress = true; 6261 event.preventDefault(); 6262 this.menu.select( event ); 6263 } 6264 break; 6265 case keyCode.TAB: 6266 if ( this.menu.active ) { 6267 this.menu.select( event ); 6268 } 6269 break; 6270 case keyCode.ESCAPE: 6271 if ( this.menu.element.is( ":visible" ) ) { 6272 if ( !this.isMultiLine ) { 6273 this._value( this.term ); 6274 } 6275 this.close( event ); 6276 6277 // Different browsers have different default behavior for escape 6278 // Single press can mean undo or clear 6279 event.preventDefault(); 6280 } 6281 break; 6282 default: 6283 suppressKeyPressRepeat = true; 6284 6285 // search timeout should be triggered before the input value is changed 6286 this._searchTimeout( event ); 6287 break; 6288 } 6289 }, 6290 keypress: function( event ) { 6291 if ( suppressKeyPress ) { 6292 suppressKeyPress = false; 6293 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6294 event.preventDefault(); 6295 } 6296 return; 6297 } 6298 if ( suppressKeyPressRepeat ) { 6299 return; 6300 } 6301 6302 // Replicate some key handlers to allow them to repeat in Firefox and Opera 6303 var keyCode = $.ui.keyCode; 6304 switch ( event.keyCode ) { 6305 case keyCode.PAGE_UP: 6306 this._move( "previousPage", event ); 6307 break; 6308 case keyCode.PAGE_DOWN: 6309 this._move( "nextPage", event ); 6310 break; 6311 case keyCode.UP: 6312 this._keyEvent( "previous", event ); 6313 break; 6314 case keyCode.DOWN: 6315 this._keyEvent( "next", event ); 6316 break; 6317 } 6318 }, 6319 input: function( event ) { 6320 if ( suppressInput ) { 6321 suppressInput = false; 6322 event.preventDefault(); 6323 return; 6324 } 6325 this._searchTimeout( event ); 6326 }, 6327 focus: function() { 6328 this.selectedItem = null; 6329 this.previous = this._value(); 6330 }, 6331 blur: function( event ) { 6332 clearTimeout( this.searching ); 6333 this.close( event ); 6334 this._change( event ); 6335 } 6336 } ); 6337 6338 this._initSource(); 6339 this.menu = $( "<ul>" ) 6340 .appendTo( this._appendTo() ) 6341 .menu( { 6342 6343 // disable ARIA support, the live region takes care of that 6344 role: null 6345 } ) 6346 .hide() 6347 .menu( "instance" ); 6348 6349 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 6350 this._on( this.menu.element, { 6351 mousedown: function( event ) { 6352 6353 // Prevent moving focus out of the text field 6354 event.preventDefault(); 6355 }, 6356 menufocus: function( event, ui ) { 6357 var label, item; 6358 6359 // Support: Firefox 6360 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 6361 if ( this.isNewMenu ) { 6362 this.isNewMenu = false; 6363 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 6364 this.menu.blur(); 6365 6366 this.document.one( "mousemove", function() { 6367 $( event.target ).trigger( event.originalEvent ); 6368 } ); 6369 6370 return; 6371 } 6372 } 6373 6374 item = ui.item.data( "ui-autocomplete-item" ); 6375 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 6376 6377 // use value to match what will end up in the input, if it was a key event 6378 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 6379 this._value( item.value ); 6380 } 6381 } 6382 6383 // Announce the value in the liveRegion 6384 label = ui.item.attr( "aria-label" ) || item.value; 6385 if ( label && String.prototype.trim.call( label ).length ) { 6386 clearTimeout( this.liveRegionTimer ); 6387 this.liveRegionTimer = this._delay( function() { 6388 this.liveRegion.html( $( "<div>" ).text( label ) ); 6389 }, 100 ); 6390 } 6391 }, 6392 menuselect: function( event, ui ) { 6393 var item = ui.item.data( "ui-autocomplete-item" ), 6394 previous = this.previous; 6395 6396 // Only trigger when focus was lost (click on menu) 6397 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { 6398 this.element.trigger( "focus" ); 6399 this.previous = previous; 6400 } 6401 6402 if ( false !== this._trigger( "select", event, { item: item } ) ) { 6403 this._value( item.value ); 6404 } 6405 6406 // reset the term after the select event 6407 // this allows custom select handling to work properly 6408 this.term = this._value(); 6409 6410 this.close( event ); 6411 this.selectedItem = item; 6412 } 6413 } ); 6414 6415 this.liveRegion = $( "<div>", { 6416 role: "status", 6417 "aria-live": "assertive", 6418 "aria-relevant": "additions" 6419 } ) 6420 .appendTo( this.document[ 0 ].body ); 6421 6422 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 6423 6424 // Turning off autocomplete prevents the browser from remembering the 6425 // value when navigating through history, so we re-enable autocomplete 6426 // if the page is unloaded before the widget is destroyed. #7790 6427 this._on( this.window, { 6428 beforeunload: function() { 6429 this.element.removeAttr( "autocomplete" ); 6430 } 6431 } ); 6432 }, 6433 6434 _destroy: function() { 6435 clearTimeout( this.searching ); 6436 this.element.removeAttr( "autocomplete" ); 6437 this.menu.element.remove(); 6438 this.liveRegion.remove(); 6439 }, 6440 6441 _setOption: function( key, value ) { 6442 this._super( key, value ); 6443 if ( key === "source" ) { 6444 this._initSource(); 6445 } 6446 if ( key === "appendTo" ) { 6447 this.menu.element.appendTo( this._appendTo() ); 6448 } 6449 if ( key === "disabled" && value && this.xhr ) { 6450 this.xhr.abort(); 6451 } 6452 }, 6453 6454 _isEventTargetInWidget: function( event ) { 6455 var menuElement = this.menu.element[ 0 ]; 6456 6457 return event.target === this.element[ 0 ] || 6458 event.target === menuElement || 6459 $.contains( menuElement, event.target ); 6460 }, 6461 6462 _closeOnClickOutside: function( event ) { 6463 if ( !this._isEventTargetInWidget( event ) ) { 6464 this.close(); 6465 } 6466 }, 6467 6468 _appendTo: function() { 6469 var element = this.options.appendTo; 6470 6471 if ( element ) { 6472 element = element.jquery || element.nodeType ? 6473 $( element ) : 6474 this.document.find( element ).eq( 0 ); 6475 } 6476 6477 if ( !element || !element[ 0 ] ) { 6478 element = this.element.closest( ".ui-front, dialog" ); 6479 } 6480 6481 if ( !element.length ) { 6482 element = this.document[ 0 ].body; 6483 } 6484 6485 return element; 6486 }, 6487 6488 _initSource: function() { 6489 var array, url, 6490 that = this; 6491 if ( Array.isArray( this.options.source ) ) { 6492 array = this.options.source; 6493 this.source = function( request, response ) { 6494 response( $.ui.autocomplete.filter( array, request.term ) ); 6495 }; 6496 } else if ( typeof this.options.source === "string" ) { 6497 url = this.options.source; 6498 this.source = function( request, response ) { 6499 if ( that.xhr ) { 6500 that.xhr.abort(); 6501 } 6502 that.xhr = $.ajax( { 6503 url: url, 6504 data: request, 6505 dataType: "json", 6506 success: function( data ) { 6507 response( data ); 6508 }, 6509 error: function() { 6510 response( [] ); 6511 } 6512 } ); 6513 }; 6514 } else { 6515 this.source = this.options.source; 6516 } 6517 }, 6518 6519 _searchTimeout: function( event ) { 6520 clearTimeout( this.searching ); 6521 this.searching = this._delay( function() { 6522 6523 // Search if the value has changed, or if the user retypes the same value (see #7434) 6524 var equalValues = this.term === this._value(), 6525 menuVisible = this.menu.element.is( ":visible" ), 6526 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 6527 6528 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 6529 this.selectedItem = null; 6530 this.search( null, event ); 6531 } 6532 }, this.options.delay ); 6533 }, 6534 6535 search: function( value, event ) { 6536 value = value != null ? value : this._value(); 6537 6538 // Always save the actual value, not the one passed as an argument 6539 this.term = this._value(); 6540 6541 if ( value.length < this.options.minLength ) { 6542 return this.close( event ); 6543 } 6544 6545 if ( this._trigger( "search", event ) === false ) { 6546 return; 6547 } 6548 6549 return this._search( value ); 6550 }, 6551 6552 _search: function( value ) { 6553 this.pending++; 6554 this._addClass( "ui-autocomplete-loading" ); 6555 this.cancelSearch = false; 6556 6557 this.source( { term: value }, this._response() ); 6558 }, 6559 6560 _response: function() { 6561 var index = ++this.requestIndex; 6562 6563 return function( content ) { 6564 if ( index === this.requestIndex ) { 6565 this.__response( content ); 6566 } 6567 6568 this.pending--; 6569 if ( !this.pending ) { 6570 this._removeClass( "ui-autocomplete-loading" ); 6571 } 6572 }.bind( this ); 6573 }, 6574 6575 __response: function( content ) { 6576 if ( content ) { 6577 content = this._normalize( content ); 6578 } 6579 this._trigger( "response", null, { content: content } ); 6580 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 6581 this._suggest( content ); 6582 this._trigger( "open" ); 6583 } else { 6584 6585 // use ._close() instead of .close() so we don't cancel future searches 6586 this._close(); 6587 } 6588 }, 6589 6590 close: function( event ) { 6591 this.cancelSearch = true; 6592 this._close( event ); 6593 }, 6594 6595 _close: function( event ) { 6596 6597 // Remove the handler that closes the menu on outside clicks 6598 this._off( this.document, "mousedown" ); 6599 6600 if ( this.menu.element.is( ":visible" ) ) { 6601 this.menu.element.hide(); 6602 this.menu.blur(); 6603 this.isNewMenu = true; 6604 this._trigger( "close", event ); 6605 } 6606 }, 6607 6608 _change: function( event ) { 6609 if ( this.previous !== this._value() ) { 6610 this._trigger( "change", event, { item: this.selectedItem } ); 6611 } 6612 }, 6613 6614 _normalize: function( items ) { 6615 6616 // assume all items have the right format when the first item is complete 6617 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 6618 return items; 6619 } 6620 return $.map( items, function( item ) { 6621 if ( typeof item === "string" ) { 6622 return { 6623 label: item, 6624 value: item 6625 }; 6626 } 6627 return $.extend( {}, item, { 6628 label: item.label || item.value, 6629 value: item.value || item.label 6630 } ); 6631 } ); 6632 }, 6633 6634 _suggest: function( items ) { 6635 var ul = this.menu.element.empty(); 6636 this._renderMenu( ul, items ); 6637 this.isNewMenu = true; 6638 this.menu.refresh(); 6639 6640 // Size and position menu 6641 ul.show(); 6642 this._resizeMenu(); 6643 ul.position( $.extend( { 6644 of: this.element 6645 }, this.options.position ) ); 6646 6647 if ( this.options.autoFocus ) { 6648 this.menu.next(); 6649 } 6650 6651 // Listen for interactions outside of the widget (#6642) 6652 this._on( this.document, { 6653 mousedown: "_closeOnClickOutside" 6654 } ); 6655 }, 6656 6657 _resizeMenu: function() { 6658 var ul = this.menu.element; 6659 ul.outerWidth( Math.max( 6660 6661 // Firefox wraps long text (possibly a rounding bug) 6662 // so we add 1px to avoid the wrapping (#7513) 6663 ul.width( "" ).outerWidth() + 1, 6664 this.element.outerWidth() 6665 ) ); 6666 }, 6667 6668 _renderMenu: function( ul, items ) { 6669 var that = this; 6670 $.each( items, function( index, item ) { 6671 that._renderItemData( ul, item ); 6672 } ); 6673 }, 6674 6675 _renderItemData: function( ul, item ) { 6676 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 6677 }, 6678 6679 _renderItem: function( ul, item ) { 6680 return $( "<li>" ) 6681 .append( $( "<div>" ).text( item.label ) ) 6682 .appendTo( ul ); 6683 }, 6684 6685 _move: function( direction, event ) { 6686 if ( !this.menu.element.is( ":visible" ) ) { 6687 this.search( null, event ); 6688 return; 6689 } 6690 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 6691 this.menu.isLastItem() && /^next/.test( direction ) ) { 6692 6693 if ( !this.isMultiLine ) { 6694 this._value( this.term ); 6695 } 6696 6697 this.menu.blur(); 6698 return; 6699 } 6700 this.menu[ direction ]( event ); 6701 }, 6702 6703 widget: function() { 6704 return this.menu.element; 6705 }, 6706 6707 _value: function() { 6708 return this.valueMethod.apply( this.element, arguments ); 6709 }, 6710 6711 _keyEvent: function( keyEvent, event ) { 6712 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 6713 this._move( keyEvent, event ); 6714 6715 // Prevents moving cursor to beginning/end of the text field in some browsers 6716 event.preventDefault(); 6717 } 6718 } 6719} ); 6720 6721$.extend( $.ui.autocomplete, { 6722 escapeRegex: function( value ) { 6723 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 6724 }, 6725 filter: function( array, term ) { 6726 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 6727 return $.grep( array, function( value ) { 6728 return matcher.test( value.label || value.value || value ); 6729 } ); 6730 } 6731} ); 6732 6733// Live region extension, adding a `messages` option 6734// NOTE: This is an experimental API. We are still investigating 6735// a full solution for string manipulation and internationalization. 6736$.widget( "ui.autocomplete", $.ui.autocomplete, { 6737 options: { 6738 messages: { 6739 noResults: "No search results.", 6740 results: function( amount ) { 6741 return amount + ( amount > 1 ? " results are" : " result is" ) + 6742 " available, use up and down arrow keys to navigate."; 6743 } 6744 } 6745 }, 6746 6747 __response: function( content ) { 6748 var message; 6749 this._superApply( arguments ); 6750 if ( this.options.disabled || this.cancelSearch ) { 6751 return; 6752 } 6753 if ( content && content.length ) { 6754 message = this.options.messages.results( content.length ); 6755 } else { 6756 message = this.options.messages.noResults; 6757 } 6758 clearTimeout( this.liveRegionTimer ); 6759 this.liveRegionTimer = this._delay( function() { 6760 this.liveRegion.html( $( "<div>" ).text( message ) ); 6761 }, 100 ); 6762 } 6763} ); 6764
6765return $.ui.autocomplete; 6766 6767} ); 6768 6769/*! 6770 * jQuery UI Controlgroup @VERSION 6771 * https://jqueryui.com 6772 * 6773 * Copyright OpenJS Foundation and other contributors 6774 * Released under the MIT license. 6775 * https://jquery.org/license 6776 */ 6777 6778//>>label: Controlgroup 6779//>>group: Widgets 6780//>>description: Visually groups form control widgets 6781//>>docs: https://api.jqueryui.com/controlgroup/ 6782//>>demos: https://jqueryui.com/controlgroup/ 6783//>>css.structure: ../../themes/base/core.css 6784//>>css.structure: ../../themes/base/controlgroup.css 6785//>>css.theme: ../../themes/base/theme.css 6786 6787( function( factory ) { 6788 "use strict"; 6789 6790 if ( typeof define === "function" && define.amd ) { 6791 6792 // AMD. Register as an anonymous module. 6793 define( 'ui/widgets/controlgroup.js',[ 6794 "jquery", 6795 "../widget" 6796 ], factory ); 6797 } else { 6798 6799 // Browser globals 6800 factory( jQuery ); 6801 } 6802} )( function( $ ) { 6803"use strict"; 6804 6805var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; 6806 6807return $.widget( "ui.controlgroup", { 6808 version: "@VERSION
vendor: 7,699 bytes, lines 6808-7069
6808", 6809 defaultElement: "<div>", 6810 options: { 6811 direction: "horizontal", 6812 disabled: null, 6813 onlyVisible: true, 6814 items: { 6815 "button": "input[type=button], input[type=submit], input[type=reset], button, a", 6816 "controlgroupLabel": ".ui-controlgroup-label", 6817 "checkboxradio": "input[type='checkbox'], input[type='radio']", 6818 "selectmenu": "select", 6819 "spinner": ".ui-spinner-input" 6820 } 6821 }, 6822 6823 _create: function() { 6824 this._enhance(); 6825 }, 6826 6827 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation 6828 _enhance: function() { 6829 this.element.attr( "role", "toolbar" ); 6830 this.refresh(); 6831 }, 6832 6833 _destroy: function() { 6834 this._callChildMethod( "destroy" ); 6835 this.childWidgets.removeData( "ui-controlgroup-data" ); 6836 this.element.removeAttr( "role" ); 6837 if ( this.options.items.controlgroupLabel ) { 6838 this.element 6839 .find( this.options.items.controlgroupLabel ) 6840 .find( ".ui-controlgroup-label-contents" ) 6841 .contents().unwrap(); 6842 } 6843 }, 6844 6845 _initWidgets: function() { 6846 var that = this, 6847 childWidgets = []; 6848 6849 // First we iterate over each of the items options 6850 $.each( this.options.items, function( widget, selector ) { 6851 var labels; 6852 var options = {}; 6853 6854 // Make sure the widget has a selector set 6855 if ( !selector ) { 6856 return; 6857 } 6858 6859 if ( widget === "controlgroupLabel" ) { 6860 labels = that.element.find( selector ); 6861 labels.each( function() { 6862 var element = $( this ); 6863 6864 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { 6865 return; 6866 } 6867 element.contents() 6868 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); 6869 } ); 6870 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); 6871 childWidgets = childWidgets.concat( labels.get() ); 6872 return; 6873 } 6874 6875 // Make sure the widget actually exists 6876 if ( !$.fn[ widget ] ) { 6877 return; 6878 } 6879 6880 // We assume everything is in the middle to start because we can't determine 6881 // first / last elements until all enhancments are done. 6882 if ( that[ "_" + widget + "Options" ] ) { 6883 options = that[ "_" + widget + "Options" ]( "middle" ); 6884 } else { 6885 options = { classes: {} }; 6886 } 6887 6888 // Find instances of this widget inside controlgroup and init them 6889 that.element 6890 .find( selector ) 6891 .each( function() { 6892 var element = $( this ); 6893 var instance = element[ widget ]( "instance" ); 6894 6895 // We need to clone the default options for this type of widget to avoid 6896 // polluting the variable options which has a wider scope than a single widget. 6897 var instanceOptions = $.widget.extend( {}, options ); 6898 6899 // If the button is the child of a spinner ignore it 6900 // TODO: Find a more generic solution 6901 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { 6902 return; 6903 } 6904 6905 // Create the widget if it doesn't exist 6906 if ( !instance ) { 6907 instance = element[ widget ]()[ widget ]( "instance" ); 6908 } 6909 if ( instance ) { 6910 instanceOptions.classes = 6911 that._resolveClassesValues( instanceOptions.classes, instance ); 6912 } 6913 element[ widget ]( instanceOptions ); 6914 6915 // Store an instance of the controlgroup to be able to reference 6916 // from the outermost element for changing options and refresh 6917 var widgetElement = element[ widget ]( "widget" ); 6918 $.data( widgetElement[ 0 ], "ui-controlgroup-data", 6919 instance ? instance : element[ widget ]( "instance" ) ); 6920 6921 childWidgets.push( widgetElement[ 0 ] ); 6922 } ); 6923 } ); 6924 6925 this.childWidgets = $( $.uniqueSort( childWidgets ) ); 6926 this._addClass( this.childWidgets, "ui-controlgroup-item" ); 6927 }, 6928 6929 _callChildMethod: function( method ) { 6930 this.childWidgets.each( function() { 6931 var element = $( this ), 6932 data = element.data( "ui-controlgroup-data" ); 6933 if ( data && data[ method ] ) { 6934 data[ method ](); 6935 } 6936 } ); 6937 }, 6938 6939 _updateCornerClass: function( element, position ) { 6940 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; 6941 var add = this._buildSimpleOptions( position, "label" ).classes.label; 6942 6943 this._removeClass( element, null, remove ); 6944 this._addClass( element, null, add ); 6945 }, 6946 6947 _buildSimpleOptions: function( position, key ) { 6948 var direction = this.options.direction === "vertical"; 6949 var result = { 6950 classes: {} 6951 }; 6952 result.classes[ key ] = { 6953 "middle": "", 6954 "first": "ui-corner-" + ( direction ? "top" : "left" ), 6955 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), 6956 "only": "ui-corner-all" 6957 }[ position ]; 6958 6959 return result; 6960 }, 6961 6962 _spinnerOptions: function( position ) { 6963 var options = this._buildSimpleOptions( position, "ui-spinner" ); 6964 6965 options.classes[ "ui-spinner-up" ] = ""; 6966 options.classes[ "ui-spinner-down" ] = ""; 6967 6968 return options; 6969 }, 6970 6971 _buttonOptions: function( position ) { 6972 return this._buildSimpleOptions( position, "ui-button" ); 6973 }, 6974 6975 _checkboxradioOptions: function( position ) { 6976 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); 6977 }, 6978 6979 _selectmenuOptions: function( position ) { 6980 var direction = this.options.direction === "vertical"; 6981 return { 6982 width: direction ? "auto" : false, 6983 classes: { 6984 middle: { 6985 "ui-selectmenu-button-open": "", 6986 "ui-selectmenu-button-closed": "" 6987 }, 6988 first: { 6989 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), 6990 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) 6991 }, 6992 last: { 6993 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", 6994 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) 6995 }, 6996 only: { 6997 "ui-selectmenu-button-open": "ui-corner-top", 6998 "ui-selectmenu-button-closed": "ui-corner-all" 6999 } 7000 7001 }[ position ] 7002 }; 7003 }, 7004 7005 _resolveClassesValues: function( classes, instance ) { 7006 var result = {}; 7007 $.each( classes, function( key ) { 7008 var current = instance.options.classes[ key ] || ""; 7009 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); 7010 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); 7011 } ); 7012 return result; 7013 }, 7014 7015 _setOption: function( key, value ) { 7016 if ( key === "direction" ) { 7017 this._removeClass( "ui-controlgroup-" + this.options.direction ); 7018 } 7019 7020 this._super( key, value ); 7021 if ( key === "disabled" ) { 7022 this._callChildMethod( value ? "disable" : "enable" ); 7023 return; 7024 } 7025 7026 this.refresh(); 7027 }, 7028 7029 refresh: function() { 7030 var children, 7031 that = this; 7032 7033 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); 7034 7035 if ( this.options.direction === "horizontal" ) { 7036 this._addClass( null, "ui-helper-clearfix" ); 7037 } 7038 this._initWidgets(); 7039 7040 children = this.childWidgets; 7041 7042 // We filter here because we need to track all childWidgets not just the visible ones 7043 if ( this.options.onlyVisible ) { 7044 children = children.filter( ":visible" ); 7045 } 7046 7047 if ( children.length ) { 7048 7049 // We do this last because we need to make sure all enhancment is done 7050 // before determining first and last 7051 $.each( [ "first", "last" ], function( index, value ) { 7052 var instance = children[ value ]().data( "ui-controlgroup-data" ); 7053 7054 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { 7055 var options = that[ "_" + instance.widgetName + "Options" ]( 7056 children.length === 1 ? "only" : value 7057 ); 7058 options.classes = that._resolveClassesValues( options.classes, instance ); 7059 instance.element[ instance.widgetName ]( options ); 7060 } else { 7061 that._updateCornerClass( children[ value ](), value ); 7062 } 7063 } ); 7064 7065 // Finally call the refresh method on each of the child widgets. 7066 this._callChildMethod( "refresh" ); 7067 } 7068 } 7069} );
vendor: 8,612 bytes, lines 7070-7407
7070} ); 7071 7072/*! 7073 * jQuery UI Checkboxradio @VERSION 7074 * https://jqueryui.com 7075 * 7076 * Copyright OpenJS Foundation and other contributors 7077 * Released under the MIT license. 7078 * https://jquery.org/license 7079 */ 7080 7081//>>label: Checkboxradio 7082//>>group: Widgets 7083//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. 7084//>>docs: https://api.jqueryui.com/checkboxradio/ 7085//>>demos: https://jqueryui.com/checkboxradio/ 7086//>>css.structure: ../../themes/base/core.css 7087//>>css.structure: ../../themes/base/button.css 7088//>>css.structure: ../../themes/base/checkboxradio.css 7089//>>css.theme: ../../themes/base/theme.css 7090 7091( function( factory ) { 7092 "use strict"; 7093 7094 if ( typeof define === "function" && define.amd ) { 7095 7096 // AMD. Register as an anonymous module. 7097 define( 'ui/widgets/checkboxradio.js',[ 7098 "jquery", 7099 "../form-reset-mixin", 7100 "../labels", 7101 "../widget" 7102 ], factory ); 7103 } else { 7104 7105 // Browser globals 7106 factory( jQuery ); 7107 } 7108} )( function( $ ) { 7109"use strict"; 7110 7111$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { 7112 version: "@VERSION", 7113 options: { 7114 disabled: null, 7115 label: null, 7116 icon: true, 7117 classes: { 7118 "ui-checkboxradio-label": "ui-corner-all", 7119 "ui-checkboxradio-icon": "ui-corner-all" 7120 } 7121 }, 7122 7123 _getCreateOptions: function() { 7124 var disabled, labels, labelContents; 7125 var options = this._super() || {}; 7126 7127 // We read the type here, because it makes more sense to throw a element type error first, 7128 // rather then the error for lack of a label. Often if its the wrong type, it 7129 // won't have a label (e.g. calling on a div, btn, etc) 7130 this._readType(); 7131 7132 labels = this.element.labels(); 7133 7134 // If there are multiple labels, use the last one 7135 this.label = $( labels[ labels.length - 1 ] ); 7136 if ( !this.label.length ) { 7137 $.error( "No label found for checkboxradio widget" ); 7138 } 7139 7140 this.originalLabel = ""; 7141 7142 // We need to get the label text but this may also need to make sure it does not contain the 7143 // input itself. 7144 // The label contents could be text, html, or a mix. We wrap all elements 7145 // and read the wrapper's `innerHTML` to get a string representation of 7146 // the label, without the input as part of it. 7147 labelContents = this.label.contents().not( this.element[ 0 ] ); 7148 7149 if ( labelContents.length ) { 7150 this.originalLabel += labelContents 7151 .clone() 7152 .wrapAll( "<div></div>" ) 7153 .parent() 7154 .html(); 7155 } 7156 7157 // Set the label option if we found label text 7158 if ( this.originalLabel ) { 7159 options.label = this.originalLabel; 7160 } 7161 7162 disabled = this.element[ 0 ].disabled; 7163 if ( disabled != null ) { 7164 options.disabled = disabled; 7165 } 7166 return options; 7167 }, 7168 7169 _create: function() { 7170 var checked = this.element[ 0 ].checked; 7171 7172 this._bindFormResetHandler(); 7173 7174 if ( this.options.disabled == null ) { 7175 this.options.disabled = this.element[ 0 ].disabled; 7176 } 7177 7178 this._setOption( "disabled", this.options.disabled ); 7179 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); 7180 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); 7181 7182 if ( this.type === "radio" ) { 7183 this._addClass( this.label, "ui-checkboxradio-radio-label" ); 7184 } 7185 7186 if ( this.options.label && this.options.label !== this.originalLabel ) { 7187 this._updateLabel(); 7188 } else if ( this.originalLabel ) { 7189 this.options.label = this.originalLabel; 7190 } 7191 7192 this._enhance(); 7193 7194 if ( checked ) { 7195 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); 7196 } 7197 7198 this._on( { 7199 change: "_toggleClasses", 7200 focus: function() { 7201 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); 7202 }, 7203 blur: function() { 7204 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); 7205 } 7206 } ); 7207 }, 7208 7209 _readType: function() { 7210 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); 7211 this.type = this.element[ 0 ].type; 7212 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { 7213 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + 7214 " and element.type=" + this.type ); 7215 } 7216 }, 7217 7218 // Support jQuery Mobile enhanced option 7219 _enhance: function() { 7220 this._updateIcon( this.element[ 0 ].checked ); 7221 }, 7222 7223 widget: function() { 7224 return this.label; 7225 }, 7226 7227 _getRadioGroup: function() { 7228 var group; 7229 var name = this.element[ 0 ].name; 7230 var nameSelector = "input[name='" + CSS.escape( name ) + "']"; 7231 7232 if ( !name ) { 7233 return $( [] ); 7234 } 7235 7236 if ( this.form.length ) { 7237 group = $( this.form[ 0 ].elements ).filter( nameSelector ); 7238 } else { 7239 7240 // Not inside a form, check all inputs that also are not inside a form 7241 group = $( nameSelector ).filter( function() { 7242 return $( $( this ).prop( "form" ) ).length === 0; 7243 } ); 7244 } 7245 7246 return group.not( this.element ); 7247 }, 7248 7249 _toggleClasses: function() { 7250 var checked = this.element[ 0 ].checked; 7251 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 7252 7253 if ( this.options.icon && this.type === "checkbox" ) { 7254 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) 7255 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); 7256 } 7257 7258 if ( this.type === "radio" ) { 7259 this._getRadioGroup() 7260 .each( function() { 7261 var instance = $( this ).checkboxradio( "instance" ); 7262 7263 if ( instance ) { 7264 instance._removeClass( instance.label, 7265 "ui-checkboxradio-checked", "ui-state-active" ); 7266 } 7267 } ); 7268 } 7269 }, 7270 7271 _destroy: function() { 7272 this._unbindFormResetHandler(); 7273 7274 if ( this.icon ) { 7275 this.icon.remove(); 7276 this.iconSpace.remove(); 7277 } 7278 }, 7279 7280 _setOption: function( key, value ) { 7281 7282 // We don't allow the value to be set to nothing 7283 if ( key === "label" && !value ) { 7284 return; 7285 } 7286 7287 this._super( key, value ); 7288 7289 if ( key === "disabled" ) { 7290 this._toggleClass( this.label, null, "ui-state-disabled", value ); 7291 this.element[ 0 ].disabled = value; 7292 7293 // Don't refresh when setting disabled 7294 return; 7295 } 7296 this.refresh(); 7297 }, 7298 7299 _updateIcon: function( checked ) { 7300 var toAdd = "ui-icon ui-icon-background "; 7301 7302 if ( this.options.icon ) { 7303 if ( !this.icon ) { 7304 this.icon = $( "<span>" ); 7305 this.iconSpace = $( "<span> </span>" ); 7306 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); 7307 } 7308 7309 if ( this.type === "checkbox" ) { 7310 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; 7311 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); 7312 } else { 7313 toAdd += "ui-icon-blank"; 7314 } 7315 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); 7316 if ( !checked ) { 7317 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); 7318 } 7319 this.icon.prependTo( this.label ).after( this.iconSpace ); 7320 } else if ( this.icon !== undefined ) { 7321 this.icon.remove(); 7322 this.iconSpace.remove(); 7323 delete this.icon; 7324 } 7325 }, 7326 7327 _updateLabel: function() { 7328 7329 // Remove the contents of the label ( minus the icon, icon space, and input ) 7330 var contents = this.label.contents().not( this.element[ 0 ] ); 7331 if ( this.icon ) { 7332 contents = contents.not( this.icon[ 0 ] ); 7333 } 7334 if ( this.iconSpace ) { 7335 contents = contents.not( this.iconSpace[ 0 ] ); 7336 } 7337 contents.remove(); 7338 7339 this.label.append( this.options.label ); 7340 }, 7341 7342 refresh: function() { 7343 var checked = this.element[ 0 ].checked, 7344 isDisabled = this.element[ 0 ].disabled; 7345 7346 this._updateIcon( checked ); 7347 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 7348 if ( this.options.label !== null ) { 7349 this._updateLabel(); 7350 } 7351 7352 if ( isDisabled !== this.options.disabled ) { 7353 this._setOptions( { "disabled": isDisabled } ); 7354 } 7355 } 7356 7357} ] ); 7358 7359return $.ui.checkboxradio; 7360 7361} ); 7362 7363/*! 7364 * jQuery UI Button @VERSION 7365 * https://jqueryui.com 7366 * 7367 * Copyright OpenJS Foundation and other contributors 7368 * Released under the MIT license. 7369 * https://jquery.org/license 7370 */ 7371 7372//>>label: Button 7373//>>group: Widgets 7374//>>description: Enhances a form with themeable buttons. 7375//>>docs: https://api.jqueryui.com/button/ 7376//>>demos: https://jqueryui.com/button/ 7377//>>css.structure: ../../themes/base/core.css 7378//>>css.structure: ../../themes/base/button.css 7379//>>css.theme: ../../themes/base/theme.css 7380 7381( function( factory ) { 7382 "use strict"; 7383 7384 if ( typeof define === "function" && define.amd ) { 7385 7386 // AMD. Register as an anonymous module. 7387 define( 'ui/widgets/button',[ 7388 "jquery", 7389 7390 // These are only for backcompat 7391 // TODO: Remove after 1.12 7392 "./controlgroup", 7393 "./checkboxradio", 7394 7395 "../keycode", 7396 "../widget" 7397 ], factory ); 7398 } else { 7399 7400 // Browser globals 7401 factory( jQuery ); 7402 } 7403} )( function( $ ) { 7404"use strict"; 7405 7406$.widget( "ui.button", { 7407 version: "@VERSION
vendor: 10,694 bytes, lines 7407-7808
7407", 7408 defaultElement: "<button>", 7409 options: { 7410 classes: { 7411 "ui-button": "ui-corner-all" 7412 }, 7413 disabled: null, 7414 icon: null, 7415 iconPosition: "beginning", 7416 label: null, 7417 showLabel: true 7418 }, 7419 7420 _getCreateOptions: function() { 7421 var disabled, 7422 7423 // This is to support cases like in jQuery Mobile where the base widget does have 7424 // an implementation of _getCreateOptions 7425 options = this._super() || {}; 7426 7427 this.isInput = this.element.is( "input" ); 7428 7429 disabled = this.element[ 0 ].disabled; 7430 if ( disabled != null ) { 7431 options.disabled = disabled; 7432 } 7433 7434 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); 7435 if ( this.originalLabel ) { 7436 options.label = this.originalLabel; 7437 } 7438 7439 return options; 7440 }, 7441 7442 _create: function() { 7443 if ( !this.option.showLabel & !this.options.icon ) { 7444 this.options.showLabel = true; 7445 } 7446 7447 // We have to check the option again here even though we did in _getCreateOptions, 7448 // because null may have been passed on init which would override what was set in 7449 // _getCreateOptions 7450 if ( this.options.disabled == null ) { 7451 this.options.disabled = this.element[ 0 ].disabled || false; 7452 } 7453 7454 this.hasTitle = !!this.element.attr( "title" ); 7455 7456 // Check to see if the label needs to be set or if its already correct 7457 if ( this.options.label && this.options.label !== this.originalLabel ) { 7458 if ( this.isInput ) { 7459 this.element.val( this.options.label ); 7460 } else { 7461 this.element.html( this.options.label ); 7462 } 7463 } 7464 this._addClass( "ui-button", "ui-widget" ); 7465 this._setOption( "disabled", this.options.disabled ); 7466 this._enhance(); 7467 7468 if ( this.element.is( "a" ) ) { 7469 this._on( { 7470 "keyup": function( event ) { 7471 if ( event.keyCode === $.ui.keyCode.SPACE ) { 7472 event.preventDefault(); 7473 7474 // If a native click is available use it, so we 7475 // actually cause navigation. Otherwise, just trigger 7476 // a click event. 7477 if ( this.element[ 0 ].click ) { 7478 this.element[ 0 ].click(); 7479 } else { 7480 this.element.trigger( "click" ); 7481 } 7482 } 7483 } 7484 } ); 7485 } 7486 }, 7487 7488 _enhance: function() { 7489 if ( !this.element.is( "button" ) ) { 7490 this.element.attr( "role", "button" ); 7491 } 7492 7493 if ( this.options.icon ) { 7494 this._updateIcon( "icon", this.options.icon ); 7495 this._updateTooltip(); 7496 } 7497 }, 7498 7499 _updateTooltip: function() { 7500 this.title = this.element.attr( "title" ); 7501 7502 if ( !this.options.showLabel && !this.title ) { 7503 this.element.attr( "title", this.options.label ); 7504 } 7505 }, 7506 7507 _updateIcon: function( option, value ) { 7508 var icon = option !== "iconPosition", 7509 position = icon ? this.options.iconPosition : value, 7510 displayBlock = position === "top" || position === "bottom"; 7511 7512 // Create icon 7513 if ( !this.icon ) { 7514 this.icon = $( "<span>" ); 7515 7516 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); 7517 7518 if ( !this.options.showLabel ) { 7519 this._addClass( "ui-button-icon-only" ); 7520 } 7521 } else if ( icon ) { 7522 7523 // If we are updating the icon remove the old icon class 7524 this._removeClass( this.icon, null, this.options.icon ); 7525 } 7526 7527 // If we are updating the icon add the new icon class 7528 if ( icon ) { 7529 this._addClass( this.icon, null, value ); 7530 } 7531 7532 this._attachIcon( position ); 7533 7534 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove 7535 // the iconSpace if there is one. 7536 if ( displayBlock ) { 7537 this._addClass( this.icon, null, "ui-widget-icon-block" ); 7538 if ( this.iconSpace ) { 7539 this.iconSpace.remove(); 7540 } 7541 } else { 7542 7543 // Position is beginning or end so remove the ui-widget-icon-block class and add the 7544 // space if it does not exist 7545 if ( !this.iconSpace ) { 7546 this.iconSpace = $( "<span> </span>" ); 7547 this._addClass( this.iconSpace, "ui-button-icon-space" ); 7548 } 7549 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); 7550 this._attachIconSpace( position ); 7551 } 7552 }, 7553 7554 _destroy: function() { 7555 this.element.removeAttr( "role" ); 7556 7557 if ( this.icon ) { 7558 this.icon.remove(); 7559 } 7560 if ( this.iconSpace ) { 7561 this.iconSpace.remove(); 7562 } 7563 if ( !this.hasTitle ) { 7564 this.element.removeAttr( "title" ); 7565 } 7566 }, 7567 7568 _attachIconSpace: function( iconPosition ) { 7569 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); 7570 }, 7571 7572 _attachIcon: function( iconPosition ) { 7573 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); 7574 }, 7575 7576 _setOptions: function( options ) { 7577 var newShowLabel = options.showLabel === undefined ? 7578 this.options.showLabel : 7579 options.showLabel, 7580 newIcon = options.icon === undefined ? this.options.icon : options.icon; 7581 7582 if ( !newShowLabel && !newIcon ) { 7583 options.showLabel = true; 7584 } 7585 this._super( options ); 7586 }, 7587 7588 _setOption: function( key, value ) { 7589 if ( key === "icon" ) { 7590 if ( value ) { 7591 this._updateIcon( key, value ); 7592 } else if ( this.icon ) { 7593 this.icon.remove(); 7594 if ( this.iconSpace ) { 7595 this.iconSpace.remove(); 7596 } 7597 } 7598 } 7599 7600 if ( key === "iconPosition" ) { 7601 this._updateIcon( key, value ); 7602 } 7603 7604 // Make sure we can't end up with a button that has neither text nor icon 7605 if ( key === "showLabel" ) { 7606 this._toggleClass( "ui-button-icon-only", null, !value ); 7607 this._updateTooltip(); 7608 } 7609 7610 if ( key === "label" ) { 7611 if ( this.isInput ) { 7612 this.element.val( value ); 7613 } else { 7614 7615 // If there is an icon, append it, else nothing then append the value 7616 // this avoids removal of the icon when setting label text 7617 this.element.html( value ); 7618 if ( this.icon ) { 7619 this._attachIcon( this.options.iconPosition ); 7620 this._attachIconSpace( this.options.iconPosition ); 7621 } 7622 } 7623 } 7624 7625 this._super( key, value ); 7626 7627 if ( key === "disabled" ) { 7628 this._toggleClass( null, "ui-state-disabled", value ); 7629 this.element[ 0 ].disabled = value; 7630 if ( value ) { 7631 this.element.trigger( "blur" ); 7632 } 7633 } 7634 }, 7635 7636 refresh: function() { 7637 7638 // Make sure to only check disabled if its an element that supports this otherwise 7639 // check for the disabled class to determine state 7640 var isDisabled = this.element.is( "input, button" ) ? 7641 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); 7642 7643 if ( isDisabled !== this.options.disabled ) { 7644 this._setOptions( { disabled: isDisabled } ); 7645 } 7646 7647 this._updateTooltip(); 7648 } 7649} ); 7650 7651// DEPRECATED 7652if ( $.uiBackCompat === true ) { 7653 7654 // Text and Icons options 7655 $.widget( "ui.button", $.ui.button, { 7656 options: { 7657 text: true, 7658 icons: { 7659 primary: null, 7660 secondary: null 7661 } 7662 }, 7663 7664 _create: function() { 7665 if ( this.options.showLabel && !this.options.text ) { 7666 this.options.showLabel = this.options.text; 7667 } 7668 if ( !this.options.showLabel && this.options.text ) { 7669 this.options.text = this.options.showLabel; 7670 } 7671 if ( !this.options.icon && ( this.options.icons.primary || 7672 this.options.icons.secondary ) ) { 7673 if ( this.options.icons.primary ) { 7674 this.options.icon = this.options.icons.primary; 7675 } else { 7676 this.options.icon = this.options.icons.secondary; 7677 this.options.iconPosition = "end"; 7678 } 7679 } else if ( this.options.icon ) { 7680 this.options.icons.primary = this.options.icon; 7681 } 7682 this._super(); 7683 }, 7684 7685 _setOption: function( key, value ) { 7686 if ( key === "text" ) { 7687 this._super( "showLabel", value ); 7688 return; 7689 } 7690 if ( key === "showLabel" ) { 7691 this.options.text = value; 7692 } 7693 if ( key === "icon" ) { 7694 this.options.icons.primary = value; 7695 } 7696 if ( key === "icons" ) { 7697 if ( value.primary ) { 7698 this._super( "icon", value.primary ); 7699 this._super( "iconPosition", "beginning" ); 7700 } else if ( value.secondary ) { 7701 this._super( "icon", value.secondary ); 7702 this._super( "iconPosition", "end" ); 7703 } 7704 } 7705 this._superApply( arguments ); 7706 } 7707 } ); 7708 7709 $.fn.button = ( function( orig ) { 7710 return function( options ) { 7711 var isMethodCall = typeof options === "string"; 7712 var args = Array.prototype.slice.call( arguments, 1 ); 7713 var returnValue = this; 7714 7715 if ( isMethodCall ) { 7716 7717 // If this is an empty collection, we need to have the instance method 7718 // return undefined instead of the jQuery instance 7719 if ( !this.length && options === "instance" ) { 7720 returnValue = undefined; 7721 } else { 7722 this.each( function() { 7723 var methodValue; 7724 var type = $( this ).attr( "type" ); 7725 var name = type !== "checkbox" && type !== "radio" ? 7726 "button" : 7727 "checkboxradio"; 7728 var instance = $.data( this, "ui-" + name ); 7729 7730 if ( options === "instance" ) { 7731 returnValue = instance; 7732 return false; 7733 } 7734 7735 if ( !instance ) { 7736 return $.error( "cannot call methods on button" + 7737 " prior to initialization; " + 7738 "attempted to call method '" + options + "'" ); 7739 } 7740 7741 if ( typeof instance[ options ] !== "function" || 7742 options.charAt( 0 ) === "_" ) { 7743 return $.error( "no such method '" + options + "' for button" + 7744 " widget instance" ); 7745 } 7746 7747 methodValue = instance[ options ].apply( instance, args ); 7748 7749 if ( methodValue !== instance && methodValue !== undefined ) { 7750 returnValue = methodValue && methodValue.jquery ? 7751 returnValue.pushStack( methodValue.get() ) : 7752 methodValue; 7753 return false; 7754 } 7755 } ); 7756 } 7757 } else { 7758 7759 // Allow multiple hashes to be passed on init 7760 if ( args.length ) { 7761 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 7762 } 7763 7764 this.each( function() { 7765 var type = $( this ).attr( "type" ); 7766 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; 7767 var instance = $.data( this, "ui-" + name ); 7768 7769 if ( instance ) { 7770 instance.option( options || {} ); 7771 if ( instance._init ) { 7772 instance._init(); 7773 } 7774 } else { 7775 if ( name === "button" ) { 7776 orig.call( $( this ), options ); 7777 return; 7778 } 7779 7780 $( this ).checkboxradio( $.extend( { icon: false }, options ) ); 7781 } 7782 } ); 7783 } 7784 7785 return returnValue; 7786 }; 7787 } )( $.fn.button ); 7788 7789 $.fn.buttonset = function() { 7790 if ( !$.ui.controlgroup ) { 7791 $.error( "Controlgroup widget missing" ); 7792 } 7793 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { 7794 return this.controlgroup.apply( this, 7795 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); 7796 } 7797 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { 7798 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); 7799 } 7800 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { 7801 arguments[ 0 ].items = { 7802 button: arguments[ 0 ].items 7803 }; 7804 } 7805 return this.controlgroup.apply( this, arguments ); 7806 }; 7807} 7808
7809return $.ui.button; 7810 7811} ); 7812 7813/* eslint-disable max-len */ 7814/*! 7815 * jQuery UI Datepicker @VERSION 7816 * https://jqueryui.com 7817 * 7818 * Copyright OpenJS Foundation and other contributors 7819 * Released under the MIT license. 7820 * https://jquery.org/license 7821 */ 7822 7823//>>label: Datepicker 7824//>>group: Widgets 7825//>>description: Displays a calendar from an input or inline for selecting dates. 7826//>>docs: https://api.jqueryui.com/datepicker/ 7827//>>demos: https://jqueryui.com/datepicker/ 7828//>>css.structure: ../../themes/base/core.css 7829//>>css.structure: ../../themes/base/datepicker.css 7830//>>css.theme: ../../themes/base/theme.css 7831 7832( function( factory ) { 7833 "use strict"; 7834 7835 if ( typeof define === "function" && define.amd ) { 7836 7837 // AMD. Register as an anonymous module. 7838 define( 'ui/widgets/datepicker.js',[ 7839 "jquery", 7840 "../version", 7841 "../keycode" 7842 ], factory ); 7843 } else { 7844 7845 // Browser globals 7846 factory( jQuery ); 7847 } 7848} )( function( $ ) { 7849"use strict"; 7850 7851$.extend( $.ui, { datepicker: { version: "@VERSION
vendor: 81,332 bytes, lines 7851-10045
7851" } } ); 7852 7853var datepicker_instActive; 7854 7855function datepicker_getZindex( elem ) { 7856 var position, value; 7857 while ( elem.length && elem[ 0 ] !== document ) { 7858 7859 // Ignore z-index if position is set to a value where z-index is ignored by the browser 7860 // This makes behavior of this function consistent across browsers 7861 // WebKit always returns auto if the element is positioned 7862 position = elem.css( "position" ); 7863 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 7864 7865 // IE returns 0 when zIndex is not specified 7866 // other browsers return a string 7867 // we ignore the case of nested elements with an explicit value of 0 7868 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 7869 value = parseInt( elem.css( "zIndex" ), 10 ); 7870 if ( !isNaN( value ) && value !== 0 ) { 7871 return value; 7872 } 7873 } 7874 elem = elem.parent(); 7875 } 7876 7877 return 0; 7878} 7879 7880/* Date picker manager. 7881 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 7882 Settings for (groups of) date pickers are maintained in an instance object, 7883 allowing multiple different settings on the same page. */ 7884 7885function Datepicker() { 7886 this._curInst = null; // The current instance in use 7887 this._keyEvent = false; // If the last event was a key event 7888 this._disabledInputs = []; // List of date picker inputs that have been disabled 7889 this._datepickerShowing = false; // True if the popup picker is showing , false if not 7890 this._inDialog = false; // True if showing within a "dialog", false if not 7891 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 7892 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 7893 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 7894 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 7895 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 7896 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 7897 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 7898 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 7899 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 7900 this.regional = []; // Available regional settings, indexed by language code 7901 this.regional[ "" ] = { // Default regional settings 7902 closeText: "Done", // Display text for close link 7903 prevText: "Prev", // Display text for previous month link 7904 nextText: "Next", // Display text for next month link 7905 currentText: "Today", // Display text for current month link 7906 monthNames: [ "January", "February", "March", "April", "May", "June", 7907 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting 7908 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting 7909 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting 7910 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting 7911 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday 7912 weekHeader: "Wk", // Column header for week of the year 7913 dateFormat: "mm/dd/yy", // See format options on parseDate 7914 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 7915 isRTL: false, // True if right-to-left language, false if left-to-right 7916 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 7917 yearSuffix: "", // Additional text to append to the year in the month headers, 7918 selectMonthLabel: "Select month", // Invisible label for month selector 7919 selectYearLabel: "Select year" // Invisible label for year selector 7920 }; 7921 this._defaults = { // Global defaults for all the date picker instances 7922 showOn: "focus", // "focus" for popup on focus, 7923 // "button" for trigger button, or "both" for either 7924 showAnim: "fadeIn", // Name of jQuery animation for popup 7925 showOptions: {}, // Options for enhanced animations 7926 defaultDate: null, // Used when field is blank: actual date, 7927 // +/-number for offset from today, null for today 7928 appendText: "", // Display text following the input box, e.g. showing the format 7929 buttonText: "...", // Text for trigger button 7930 buttonImage: "", // URL for trigger button image 7931 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 7932 hideIfNoPrevNext: false, // True to hide next/previous month links 7933 // if not applicable, false to just disable them 7934 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 7935 gotoCurrent: false, // True if today link goes back to current selection instead 7936 changeMonth: false, // True if month can be selected directly, false if only prev/next 7937 changeYear: false, // True if year can be selected directly, false if only prev/next 7938 yearRange: "c-10:c+10", // Range of years to display in drop-down, 7939 // either relative to today's year (-nn:+nn), relative to currently displayed year 7940 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 7941 showOtherMonths: false, // True to show dates in other months, false to leave blank 7942 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 7943 showWeek: false, // True to show week of the year, false to not show it 7944 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 7945 // takes a Date and returns the number of the week for it 7946 shortYearCutoff: "+10", // Short year values < this are in the current century, 7947 // > this are in the previous century, 7948 // string value starting with "+" for current year + value 7949 minDate: null, // The earliest selectable date, or null for no limit 7950 maxDate: null, // The latest selectable date, or null for no limit 7951 duration: "fast", // Duration of display/closure 7952 beforeShowDay: null, // Function that takes a date and returns an array with 7953 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 7954 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 7955 beforeShow: null, // Function that takes an input field and 7956 // returns a set of custom settings for the date picker 7957 onSelect: null, // Define a callback function when a date is selected 7958 onChangeMonthYear: null, // Define a callback function when the month or year is changed 7959 onClose: null, // Define a callback function when the datepicker is closed 7960 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated 7961 numberOfMonths: 1, // Number of months to show at a time 7962 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 7963 stepMonths: 1, // Number of months to step back/forward 7964 stepBigMonths: 12, // Number of months to step back/forward for the big links 7965 altField: "", // Selector for an alternate field to store selected dates into 7966 altFormat: "", // The date format to use for the alternate field 7967 constrainInput: true, // The input is constrained by the current date format 7968 showButtonPanel: false, // True to show button panel, false to not show it 7969 autoSize: false, // True to size the input for the date format, false to leave as is 7970 disabled: false // The initial disabled state 7971 }; 7972 $.extend( this._defaults, this.regional[ "" ] ); 7973 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); 7974 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 7975 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 7976} 7977 7978$.extend( Datepicker.prototype, { 7979 7980 /* Class name added to elements to indicate already configured with a date picker. */ 7981 markerClassName: "hasDatepicker", 7982 7983 //Keep track of the maximum number of rows displayed (see #7043) 7984 maxRows: 4, 7985 7986 // TODO rename to "widget" when switching to widget factory 7987 _widgetDatepicker: function() { 7988 return this.dpDiv; 7989 }, 7990 7991 /* Override the default settings for all instances of the date picker. 7992 * @param settings object - the new settings to use as defaults (anonymous object) 7993 * @return the manager object 7994 */ 7995 setDefaults: function( settings ) { 7996 datepicker_extendRemove( this._defaults, settings || {} ); 7997 return this; 7998 }, 7999 8000 /* Attach the date picker to a jQuery selection. 8001 * @param target element - the target input field or division or span 8002 * @param settings object - the new settings to use for this date picker instance (anonymous) 8003 */ 8004 _attachDatepicker: function( target, settings ) { 8005 var nodeName, inline, inst; 8006 nodeName = target.nodeName.toLowerCase(); 8007 inline = ( nodeName === "div" || nodeName === "span" ); 8008 if ( !target.id ) { 8009 this.uuid += 1; 8010 target.id = "dp" + this.uuid; 8011 } 8012 inst = this._newInst( $( target ), inline ); 8013 inst.settings = $.extend( {}, settings || {} ); 8014 if ( nodeName === "input" ) { 8015 this._connectDatepicker( target, inst ); 8016 } else if ( inline ) { 8017 this._inlineDatepicker( target, inst ); 8018 } 8019 }, 8020 8021 /* Create a new instance object. */ 8022 _newInst: function( target, inline ) { 8023 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars 8024 return { id: id, input: target, // associated target 8025 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 8026 drawMonth: 0, drawYear: 0, // month being drawn 8027 inline: inline, // is datepicker inline or not 8028 dpDiv: ( !inline ? this.dpDiv : // presentation div 8029 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; 8030 }, 8031 8032 /* Attach the date picker to an input field. */ 8033 _connectDatepicker: function( target, inst ) { 8034 var input = $( target ); 8035 inst.append = $( [] ); 8036 inst.trigger = $( [] ); 8037 if ( input.hasClass( this.markerClassName ) ) { 8038 return; 8039 } 8040 this._attachments( input, inst ); 8041 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). 8042 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); 8043 this._autoSize( inst ); 8044 $.data( target, "datepicker", inst ); 8045 8046 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 8047 if ( inst.settings.disabled ) { 8048 this._disableDatepicker( target ); 8049 } 8050 }, 8051 8052 /* Make attachments based on settings. */ 8053 _attachments: function( input, inst ) { 8054 var showOn, buttonText, buttonImage, 8055 appendText = this._get( inst, "appendText" ), 8056 isRTL = this._get( inst, "isRTL" ); 8057 8058 if ( inst.append ) { 8059 inst.append.remove(); 8060 } 8061 if ( appendText ) { 8062 inst.append = $( "<span>" ) 8063 .addClass( this._appendClass ) 8064 .text( appendText ); 8065 input[ isRTL ? "before" : "after" ]( inst.append ); 8066 } 8067 8068 input.off( "focus", this._showDatepicker ); 8069 8070 if ( inst.trigger ) { 8071 inst.trigger.remove(); 8072 } 8073 8074 showOn = this._get( inst, "showOn" ); 8075 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field 8076 input.on( "focus", this._showDatepicker ); 8077 } 8078 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked 8079 buttonText = this._get( inst, "buttonText" ); 8080 buttonImage = this._get( inst, "buttonImage" ); 8081 8082 if ( this._get( inst, "buttonImageOnly" ) ) { 8083 inst.trigger = $( "<img>" ) 8084 .addClass( this._triggerClass ) 8085 .attr( { 8086 src: buttonImage, 8087 alt: buttonText, 8088 title: buttonText 8089 } ); 8090 } else { 8091 inst.trigger = $( "<button type='button'>" ) 8092 .addClass( this._triggerClass ); 8093 if ( buttonImage ) { 8094 inst.trigger.html( 8095 $( "<img>" ) 8096 .attr( { 8097 src: buttonImage, 8098 alt: buttonText, 8099 title: buttonText 8100 } ) 8101 ); 8102 } else { 8103 inst.trigger.text( buttonText ); 8104 } 8105 } 8106 8107 input[ isRTL ? "before" : "after" ]( inst.trigger ); 8108 inst.trigger.on( "click", function() { 8109 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { 8110 $.datepicker._hideDatepicker(); 8111 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { 8112 $.datepicker._hideDatepicker(); 8113 $.datepicker._showDatepicker( input[ 0 ] ); 8114 } else { 8115 $.datepicker._showDatepicker( input[ 0 ] ); 8116 } 8117 return false; 8118 } ); 8119 } 8120 }, 8121 8122 /* Apply the maximum length for the date format. */ 8123 _autoSize: function( inst ) { 8124 if ( this._get( inst, "autoSize" ) && !inst.inline ) { 8125 var findMax, max, maxI, i, 8126 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits 8127 dateFormat = this._get( inst, "dateFormat" ); 8128 8129 if ( dateFormat.match( /[DM]/ ) ) { 8130 findMax = function( names ) { 8131 max = 0; 8132 maxI = 0; 8133 for ( i = 0; i < names.length; i++ ) { 8134 if ( names[ i ].length > max ) { 8135 max = names[ i ].length; 8136 maxI = i; 8137 } 8138 } 8139 return maxI; 8140 }; 8141 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? 8142 "monthNames" : "monthNamesShort" ) ) ) ); 8143 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? 8144 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); 8145 } 8146 inst.input.attr( "size", this._formatDate( inst, date ).length ); 8147 } 8148 }, 8149 8150 /* Attach an inline date picker to a div. */ 8151 _inlineDatepicker: function( target, inst ) { 8152 var divSpan = $( target ); 8153 if ( divSpan.hasClass( this.markerClassName ) ) { 8154 return; 8155 } 8156 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 8157 $.data( target, "datepicker", inst ); 8158 this._setDate( inst, this._getDefaultDate( inst ), true ); 8159 this._updateDatepicker( inst ); 8160 this._updateAlternate( inst ); 8161 8162 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 8163 if ( inst.settings.disabled ) { 8164 this._disableDatepicker( target ); 8165 } 8166 8167 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 8168 // https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 8169 inst.dpDiv.css( "display", "block" ); 8170 }, 8171 8172 /* Pop-up the date picker in a "dialog" box. 8173 * @param input element - ignored 8174 * @param date string or Date - the initial date to display 8175 * @param onSelect function - the function to call when a date is selected 8176 * @param settings object - update the dialog date picker instance's settings (anonymous object) 8177 * @param pos int[2] - coordinates for the dialog's position within the screen or 8178 * event - with x/y coordinates or 8179 * leave empty for default (screen centre) 8180 * @return the manager object 8181 */ 8182 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 8183 var id, browserWidth, browserHeight, scrollX, scrollY, 8184 inst = this._dialogInst; // internal instance 8185 8186 if ( !inst ) { 8187 this.uuid += 1; 8188 id = "dp" + this.uuid; 8189 this._dialogInput = $( "<input type='text' id='" + id + 8190 "' style='position: absolute; top: -100px; width: 0px;'/>" ); 8191 this._dialogInput.on( "keydown", this._doKeyDown ); 8192 $( "body" ).append( this._dialogInput ); 8193 inst = this._dialogInst = this._newInst( this._dialogInput, false ); 8194 inst.settings = {}; 8195 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 8196 } 8197 datepicker_extendRemove( inst.settings, settings || {} ); 8198 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); 8199 this._dialogInput.val( date ); 8200 8201 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); 8202 if ( !this._pos ) { 8203 browserWidth = document.documentElement.clientWidth; 8204 browserHeight = document.documentElement.clientHeight; 8205 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 8206 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 8207 this._pos = // should use actual width/height below 8208 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 8209 } 8210 8211 // Move input on screen for focus, but hidden behind dialog 8212 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); 8213 inst.settings.onSelect = onSelect; 8214 this._inDialog = true; 8215 this.dpDiv.addClass( this._dialogClass ); 8216 this._showDatepicker( this._dialogInput[ 0 ] ); 8217 if ( $.blockUI ) { 8218 $.blockUI( this.dpDiv ); 8219 } 8220 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 8221 return this; 8222 }, 8223 8224 /* Detach a datepicker from its control. 8225 * @param target element - the target input field or division or span 8226 */ 8227 _destroyDatepicker: function( target ) { 8228 var nodeName, 8229 $target = $( target ), 8230 inst = $.data( target, "datepicker" ); 8231 8232 if ( !$target.hasClass( this.markerClassName ) ) { 8233 return; 8234 } 8235 8236 nodeName = target.nodeName.toLowerCase(); 8237 $.removeData( target, "datepicker" ); 8238 if ( nodeName === "input" ) { 8239 inst.append.remove(); 8240 inst.trigger.remove(); 8241 $target.removeClass( this.markerClassName ). 8242 off( "focus", this._showDatepicker ). 8243 off( "keydown", this._doKeyDown ). 8244 off( "keypress", this._doKeyPress ). 8245 off( "keyup", this._doKeyUp ); 8246 } else if ( nodeName === "div" || nodeName === "span" ) { 8247 $target.removeClass( this.markerClassName ).empty(); 8248 } 8249 8250 $.datepicker._hideDatepicker(); 8251 if ( datepicker_instActive === inst ) { 8252 datepicker_instActive = null; 8253 this._curInst = null; 8254 } 8255 }, 8256 8257 /* Enable the date picker to a jQuery selection. 8258 * @param target element - the target input field or division or span 8259 */ 8260 _enableDatepicker: function( target ) { 8261 var nodeName, inline, 8262 $target = $( target ), 8263 inst = $.data( target, "datepicker" ); 8264 8265 if ( !$target.hasClass( this.markerClassName ) ) { 8266 return; 8267 } 8268 8269 nodeName = target.nodeName.toLowerCase(); 8270 if ( nodeName === "input" ) { 8271 target.disabled = false; 8272 inst.trigger.filter( "button" ). 8273 each( function() { 8274 this.disabled = false; 8275 } ).end(). 8276 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); 8277 } else if ( nodeName === "div" || nodeName === "span" ) { 8278 inline = $target.children( "." + this._inlineClass ); 8279 inline.children().removeClass( "ui-state-disabled" ); 8280 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 8281 prop( "disabled", false ); 8282 } 8283 this._disabledInputs = $.map( this._disabledInputs, 8284 8285 // Delete entry 8286 function( value ) { 8287 return ( value === target ? null : value ); 8288 } ); 8289 }, 8290 8291 /* Disable the date picker to a jQuery selection. 8292 * @param target element - the target input field or division or span 8293 */ 8294 _disableDatepicker: function( target ) { 8295 var nodeName, inline, 8296 $target = $( target ), 8297 inst = $.data( target, "datepicker" ); 8298 8299 if ( !$target.hasClass( this.markerClassName ) ) { 8300 return; 8301 } 8302 8303 nodeName = target.nodeName.toLowerCase(); 8304 if ( nodeName === "input" ) { 8305 target.disabled = true; 8306 inst.trigger.filter( "button" ). 8307 each( function() { 8308 this.disabled = true; 8309 } ).end(). 8310 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); 8311 } else if ( nodeName === "div" || nodeName === "span" ) { 8312 inline = $target.children( "." + this._inlineClass ); 8313 inline.children().addClass( "ui-state-disabled" ); 8314 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 8315 prop( "disabled", true ); 8316 } 8317 this._disabledInputs = $.map( this._disabledInputs, 8318 8319 // Delete entry 8320 function( value ) { 8321 return ( value === target ? null : value ); 8322 } ); 8323 this._disabledInputs[ this._disabledInputs.length ] = target; 8324 }, 8325 8326 /* Is the first field in a jQuery collection disabled as a datepicker? 8327 * @param target element - the target input field or division or span 8328 * @return boolean - true if disabled, false if enabled 8329 */ 8330 _isDisabledDatepicker: function( target ) { 8331 if ( !target ) { 8332 return false; 8333 } 8334 for ( var i = 0; i < this._disabledInputs.length; i++ ) { 8335 if ( this._disabledInputs[ i ] === target ) { 8336 return true; 8337 } 8338 } 8339 return false; 8340 }, 8341 8342 /* Retrieve the instance data for the target control. 8343 * @param target element - the target input field or division or span 8344 * @return object - the associated instance data 8345 * @throws error if a jQuery problem getting data 8346 */ 8347 _getInst: function( target ) { 8348 try { 8349 return $.data( target, "datepicker" ); 8350 } catch ( _err ) { 8351 throw "Missing instance data for this datepicker"; 8352 } 8353 }, 8354 8355 /* Update or retrieve the settings for a date picker attached to an input field or division. 8356 * @param target element - the target input field or division or span 8357 * @param name object - the new settings to update or 8358 * string - the name of the setting to change or retrieve, 8359 * when retrieving also "all" for all instance settings or 8360 * "defaults" for all global defaults 8361 * @param value any - the new value for the setting 8362 * (omit if above is an object or to retrieve a value) 8363 */ 8364 _optionDatepicker: function( target, name, value ) { 8365 var settings, date, minDate, maxDate, 8366 inst = this._getInst( target ); 8367 8368 if ( arguments.length === 2 && typeof name === "string" ) { 8369 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : 8370 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : 8371 this._get( inst, name ) ) : null ) ); 8372 } 8373 8374 settings = name || {}; 8375 if ( typeof name === "string" ) { 8376 settings = {}; 8377 settings[ name ] = value; 8378 } 8379 8380 if ( inst ) { 8381 if ( this._curInst === inst ) { 8382 this._hideDatepicker(); 8383 } 8384 8385 date = this._getDateDatepicker( target, true ); 8386 minDate = this._getMinMaxDate( inst, "min" ); 8387 maxDate = this._getMinMaxDate( inst, "max" ); 8388 datepicker_extendRemove( inst.settings, settings ); 8389 8390 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 8391 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 8392 inst.settings.minDate = this._formatDate( inst, minDate ); 8393 } 8394 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 8395 inst.settings.maxDate = this._formatDate( inst, maxDate ); 8396 } 8397 if ( "disabled" in settings ) { 8398 if ( settings.disabled ) { 8399 this._disableDatepicker( target ); 8400 } else { 8401 this._enableDatepicker( target ); 8402 } 8403 } 8404 this._attachments( $( target ), inst ); 8405 this._autoSize( inst ); 8406 this._setDate( inst, date ); 8407 this._updateAlternate( inst ); 8408 this._updateDatepicker( inst ); 8409 } 8410 }, 8411 8412 // Change method deprecated 8413 _changeDatepicker: function( target, name, value ) { 8414 this._optionDatepicker( target, name, value ); 8415 }, 8416 8417 /* Redraw the date picker attached to an input field or division. 8418 * @param target element - the target input field or division or span 8419 */ 8420 _refreshDatepicker: function( target ) { 8421 var inst = this._getInst( target ); 8422 if ( inst ) { 8423 this._updateDatepicker( inst ); 8424 } 8425 }, 8426 8427 /* Set the dates for a jQuery selection. 8428 * @param target element - the target input field or division or span 8429 * @param date Date - the new date 8430 */ 8431 _setDateDatepicker: function( target, date ) { 8432 var inst = this._getInst( target ); 8433 if ( inst ) { 8434 this._setDate( inst, date ); 8435 this._updateDatepicker( inst ); 8436 this._updateAlternate( inst ); 8437 } 8438 }, 8439 8440 /* Get the date(s) for the first entry in a jQuery selection. 8441 * @param target element - the target input field or division or span 8442 * @param noDefault boolean - true if no default date is to be used 8443 * @return Date - the current date 8444 */ 8445 _getDateDatepicker: function( target, noDefault ) { 8446 var inst = this._getInst( target ); 8447 if ( inst && !inst.inline ) { 8448 this._setDateFromField( inst, noDefault ); 8449 } 8450 return ( inst ? this._getDate( inst ) : null ); 8451 }, 8452 8453 /* Handle keystrokes. */ 8454 _doKeyDown: function( event ) { 8455 var onSelect, dateStr, sel, 8456 inst = $.datepicker._getInst( event.target ), 8457 handled = true, 8458 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); 8459 8460 inst._keyEvent = true; 8461 if ( $.datepicker._datepickerShowing ) { 8462 switch ( event.keyCode ) { 8463 case 9: $.datepicker._hideDatepicker(); 8464 handled = false; 8465 break; // hide on tab out 8466 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + 8467 $.datepicker._currentClass + ")", inst.dpDiv ); 8468 if ( sel[ 0 ] ) { 8469 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 8470 } 8471 8472 onSelect = $.datepicker._get( inst, "onSelect" ); 8473 if ( onSelect ) { 8474 dateStr = $.datepicker._formatDate( inst ); 8475 8476 // Trigger custom callback 8477 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); 8478 } else { 8479 $.datepicker._hideDatepicker(); 8480 } 8481 8482 return false; // don't submit the form 8483 case 27: $.datepicker._hideDatepicker(); 8484 break; // hide on escape 8485 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 8486 -$.datepicker._get( inst, "stepBigMonths" ) : 8487 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 8488 break; // previous month/year on page up/+ ctrl 8489 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 8490 +$.datepicker._get( inst, "stepBigMonths" ) : 8491 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 8492 break; // next month/year on page down/+ ctrl 8493 case 35: if ( event.ctrlKey || event.metaKey ) { 8494 $.datepicker._clearDate( event.target ); 8495 } 8496 handled = event.ctrlKey || event.metaKey; 8497 break; // clear on ctrl or command +end 8498 case 36: if ( event.ctrlKey || event.metaKey ) { 8499 $.datepicker._gotoToday( event.target ); 8500 } 8501 handled = event.ctrlKey || event.metaKey; 8502 break; // current on ctrl or command +home 8503 case 37: if ( event.ctrlKey || event.metaKey ) { 8504 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); 8505 } 8506 handled = event.ctrlKey || event.metaKey; 8507 8508 // -1 day on ctrl or command +left 8509 if ( event.originalEvent.altKey ) { 8510 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 8511 -$.datepicker._get( inst, "stepBigMonths" ) : 8512 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 8513 } 8514 8515 // next month/year on alt +left on Mac 8516 break; 8517 case 38: if ( event.ctrlKey || event.metaKey ) { 8518 $.datepicker._adjustDate( event.target, -7, "D" ); 8519 } 8520 handled = event.ctrlKey || event.metaKey; 8521 break; // -1 week on ctrl or command +up 8522 case 39: if ( event.ctrlKey || event.metaKey ) { 8523 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); 8524 } 8525 handled = event.ctrlKey || event.metaKey; 8526 8527 // +1 day on ctrl or command +right 8528 if ( event.originalEvent.altKey ) { 8529 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 8530 +$.datepicker._get( inst, "stepBigMonths" ) : 8531 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 8532 } 8533 8534 // next month/year on alt +right 8535 break; 8536 case 40: if ( event.ctrlKey || event.metaKey ) { 8537 $.datepicker._adjustDate( event.target, +7, "D" ); 8538 } 8539 handled = event.ctrlKey || event.metaKey; 8540 break; // +1 week on ctrl or command +down 8541 default: handled = false; 8542 } 8543 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home 8544 $.datepicker._showDatepicker( this ); 8545 } else { 8546 handled = false; 8547 } 8548 8549 if ( handled ) { 8550 event.preventDefault(); 8551 event.stopPropagation(); 8552 } 8553 }, 8554 8555 /* Filter entered characters - based on date format. */ 8556 _doKeyPress: function( event ) { 8557 var chars, chr, 8558 inst = $.datepicker._getInst( event.target ); 8559 8560 if ( $.datepicker._get( inst, "constrainInput" ) ) { 8561 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); 8562 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); 8563 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); 8564 } 8565 }, 8566 8567 /* Synchronise manual entry and field/alternate field. */ 8568 _doKeyUp: function( event ) { 8569 var date, 8570 inst = $.datepicker._getInst( event.target ); 8571 8572 if ( inst.input.val() !== inst.lastVal ) { 8573 try { 8574 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 8575 ( inst.input ? inst.input.val() : null ), 8576 $.datepicker._getFormatConfig( inst ) ); 8577 8578 if ( date ) { // only if valid 8579 $.datepicker._setDateFromField( inst ); 8580 $.datepicker._updateAlternate( inst ); 8581 $.datepicker._updateDatepicker( inst ); 8582 } 8583 } catch ( _err ) { 8584 } 8585 } 8586 return true; 8587 }, 8588 8589 /* Pop-up the date picker for a given input field. 8590 * If false returned from beforeShow event handler do not show. 8591 * @param input element - the input field attached to the date picker or 8592 * event - if triggered by focus 8593 */ 8594 _showDatepicker: function( input ) { 8595 input = input.target || input; 8596 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger 8597 input = $( "input", input.parentNode )[ 0 ]; 8598 } 8599 8600 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here 8601 return; 8602 } 8603 8604 var inst, beforeShow, beforeShowSettings, isFixed, 8605 offset, showAnim, duration; 8606 8607 inst = $.datepicker._getInst( input ); 8608 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { 8609 $.datepicker._curInst.dpDiv.stop( true, true ); 8610 if ( inst && $.datepicker._datepickerShowing ) { 8611 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); 8612 } 8613 } 8614 8615 beforeShow = $.datepicker._get( inst, "beforeShow" ); 8616 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 8617 if ( beforeShowSettings === false ) { 8618 return; 8619 } 8620 datepicker_extendRemove( inst.settings, beforeShowSettings ); 8621 8622 inst.lastVal = null; 8623 $.datepicker._lastInput = input; 8624 $.datepicker._setDateFromField( inst ); 8625 8626 if ( $.datepicker._inDialog ) { // hide cursor 8627 input.value = ""; 8628 } 8629 if ( !$.datepicker._pos ) { // position below input 8630 $.datepicker._pos = $.datepicker._findPos( input ); 8631 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height 8632 } 8633 8634 isFixed = false; 8635 $( input ).parents().each( function() { 8636 isFixed |= $( this ).css( "position" ) === "fixed"; 8637 return !isFixed; 8638 } ); 8639 8640 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; 8641 $.datepicker._pos = null; 8642 8643 //to avoid flashes on Firefox 8644 inst.dpDiv.empty(); 8645 8646 // determine sizing offscreen 8647 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); 8648 $.datepicker._updateDatepicker( inst ); 8649 8650 // fix width for dynamic number of date pickers 8651 // and adjust position before showing 8652 offset = $.datepicker._checkOffset( inst, offset, isFixed ); 8653 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? 8654 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", 8655 left: offset.left + "px", top: offset.top + "px" } ); 8656 8657 if ( !inst.inline ) { 8658 showAnim = $.datepicker._get( inst, "showAnim" ); 8659 duration = $.datepicker._get( inst, "duration" ); 8660 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 8661 $.datepicker._datepickerShowing = true; 8662 8663 if ( $.effects && $.effects.effect[ showAnim ] ) { 8664 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); 8665 } else { 8666 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); 8667 } 8668 8669 if ( $.datepicker._shouldFocusInput( inst ) ) { 8670 inst.input.trigger( "focus" ); 8671 } 8672 8673 $.datepicker._curInst = inst; 8674 } 8675 }, 8676 8677 /* Generate the date picker content. */ 8678 _updateDatepicker: function( inst ) { 8679 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 8680 datepicker_instActive = inst; // for delegate hover events 8681 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 8682 this._attachHandlers( inst ); 8683 8684 var origyearshtml, 8685 numMonths = this._getNumberOfMonths( inst ), 8686 cols = numMonths[ 1 ], 8687 width = 17, 8688 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), 8689 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); 8690 8691 if ( activeCell.length > 0 ) { 8692 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 8693 } 8694 8695 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); 8696 if ( cols > 1 ) { 8697 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); 8698 } 8699 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + 8700 "Class" ]( "ui-datepicker-multi" ); 8701 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + 8702 "Class" ]( "ui-datepicker-rtl" ); 8703 8704 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 8705 inst.input.trigger( "focus" ); 8706 } 8707 8708 // Deffered render of the years select (to avoid flashes on Firefox) 8709 if ( inst.yearshtml ) { 8710 origyearshtml = inst.yearshtml; 8711 setTimeout( function() { 8712 8713 //assure that inst.yearshtml didn't change. 8714 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { 8715 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); 8716 } 8717 origyearshtml = inst.yearshtml = null; 8718 }, 0 ); 8719 } 8720 8721 if ( onUpdateDatepicker ) { 8722 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); 8723 } 8724 }, 8725 8726 _shouldFocusInput: function( inst ) { 8727 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ); 8728 }, 8729 8730 /* Check positioning to remain on screen. */ 8731 _checkOffset: function( inst, offset, isFixed ) { 8732 var dpWidth = inst.dpDiv.outerWidth(), 8733 dpHeight = inst.dpDiv.outerHeight(), 8734 inputWidth = inst.input ? inst.input.outerWidth() : 0, 8735 inputHeight = inst.input ? inst.input.outerHeight() : 0, 8736 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 8737 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 8738 8739 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); 8740 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; 8741 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; 8742 8743 // Now check if datepicker is showing outside window viewport - move to a better place if so. 8744 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? 8745 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 8746 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? 8747 Math.abs( dpHeight + inputHeight ) : 0 ); 8748 8749 return offset; 8750 }, 8751 8752 /* Find an object's position on the screen. */ 8753 _findPos: function( obj ) { 8754 var position, 8755 inst = this._getInst( obj ), 8756 isRTL = this._get( inst, "isRTL" ); 8757 8758 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { 8759 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; 8760 } 8761 8762 position = $( obj ).offset(); 8763 return [ position.left, position.top ]; 8764 }, 8765 8766 /* Hide the date picker from view. 8767 * @param input element - the input field attached to the date picker 8768 */ 8769 _hideDatepicker: function( input ) { 8770 var showAnim, duration, postProcess, onClose, 8771 inst = this._curInst; 8772 8773 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { 8774 return; 8775 } 8776 8777 if ( this._datepickerShowing ) { 8778 showAnim = this._get( inst, "showAnim" ); 8779 duration = this._get( inst, "duration" ); 8780 postProcess = function() { 8781 $.datepicker._tidyDialog( inst ); 8782 }; 8783 8784 if ( $.effects && ( $.effects.effect[ showAnim ] ) ) { 8785 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); 8786 } else { 8787 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : 8788 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); 8789 } 8790 8791 if ( !showAnim ) { 8792 postProcess(); 8793 } 8794 this._datepickerShowing = false; 8795 8796 onClose = this._get( inst, "onClose" ); 8797 if ( onClose ) { 8798 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); 8799 } 8800 8801 this._lastInput = null; 8802 if ( this._inDialog ) { 8803 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); 8804 if ( $.blockUI ) { 8805 $.unblockUI(); 8806 $( "body" ).append( this.dpDiv ); 8807 } 8808 } 8809 this._inDialog = false; 8810 } 8811 }, 8812 8813 /* Tidy up after a dialog display. */ 8814 _tidyDialog: function( inst ) { 8815 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); 8816 }, 8817 8818 /* Close date picker if clicked elsewhere. */ 8819 _checkExternalClick: function( event ) { 8820 if ( !$.datepicker._curInst ) { 8821 return; 8822 } 8823 8824 var $target = $( event.target ), 8825 inst = $.datepicker._getInst( $target[ 0 ] ); 8826 8827 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && 8828 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && 8829 !$target.hasClass( $.datepicker.markerClassName ) && 8830 !$target.closest( "." + $.datepicker._triggerClass ).length && 8831 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || 8832 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { 8833 $.datepicker._hideDatepicker(); 8834 } 8835 }, 8836 8837 /* Adjust one of the date sub-fields. */ 8838 _adjustDate: function( id, offset, period ) { 8839 var target = $( id ), 8840 inst = this._getInst( target[ 0 ] ); 8841 8842 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 8843 return; 8844 } 8845 this._adjustInstDate( inst, offset, period ); 8846 this._updateDatepicker( inst ); 8847 }, 8848 8849 /* Action for current link. */ 8850 _gotoToday: function( id ) { 8851 var date, 8852 target = $( id ), 8853 inst = this._getInst( target[ 0 ] ); 8854 8855 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { 8856 inst.selectedDay = inst.currentDay; 8857 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 8858 inst.drawYear = inst.selectedYear = inst.currentYear; 8859 } else { 8860 date = new Date(); 8861 inst.selectedDay = date.getDate(); 8862 inst.drawMonth = inst.selectedMonth = date.getMonth(); 8863 inst.drawYear = inst.selectedYear = date.getFullYear(); 8864 } 8865 this._notifyChange( inst ); 8866 this._adjustDate( target ); 8867 }, 8868 8869 /* Action for selecting a new month/year. */ 8870 _selectMonthYear: function( id, select, period ) { 8871 var target = $( id ), 8872 inst = this._getInst( target[ 0 ] ); 8873 8874 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = 8875 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = 8876 parseInt( select.options[ select.selectedIndex ].value, 10 ); 8877 8878 this._notifyChange( inst ); 8879 this._adjustDate( target ); 8880 }, 8881 8882 /* Action for selecting a day. */ 8883 _selectDay: function( id, month, year, td ) { 8884 var inst, 8885 target = $( id ); 8886 8887 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 8888 return; 8889 } 8890 8891 inst = this._getInst( target[ 0 ] ); 8892 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); 8893 inst.selectedMonth = inst.currentMonth = month; 8894 inst.selectedYear = inst.currentYear = year; 8895 this._selectDate( id, this._formatDate( inst, 8896 inst.currentDay, inst.currentMonth, inst.currentYear ) ); 8897 }, 8898 8899 /* Erase the input field and hide the date picker. */ 8900 _clearDate: function( id ) { 8901 var target = $( id ); 8902 this._selectDate( target, "" ); 8903 }, 8904 8905 /* Update the input field with the selected date. */ 8906 _selectDate: function( id, dateStr ) { 8907 var onSelect, 8908 target = $( id ), 8909 inst = this._getInst( target[ 0 ] ); 8910 8911 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); 8912 if ( inst.input ) { 8913 inst.input.val( dateStr ); 8914 } 8915 this._updateAlternate( inst ); 8916 8917 onSelect = this._get( inst, "onSelect" ); 8918 if ( onSelect ) { 8919 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback 8920 } else if ( inst.input ) { 8921 inst.input.trigger( "change" ); // fire the change event 8922 } 8923 8924 if ( inst.inline ) { 8925 this._updateDatepicker( inst ); 8926 } else { 8927 this._hideDatepicker(); 8928 this._lastInput = inst.input[ 0 ]; 8929 if ( typeof( inst.input[ 0 ] ) !== "object" ) { 8930 inst.input.trigger( "focus" ); // restore focus 8931 } 8932 this._lastInput = null; 8933 } 8934 }, 8935 8936 /* Update any alternate field to synchronise with the main field. */ 8937 _updateAlternate: function( inst ) { 8938 var altFormat, date, dateStr, 8939 altField = this._get( inst, "altField" ); 8940 8941 if ( altField ) { // update alternate field too 8942 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); 8943 date = this._getDate( inst ); 8944 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 8945 $( document ).find( altField ).val( dateStr ); 8946 } 8947 }, 8948 8949 /* Set as beforeShowDay function to prevent selection of weekends. 8950 * @param date Date - the date to customise 8951 * @return [boolean, string] - is this date selectable?, what is its CSS class? 8952 */ 8953 noWeekends: function( date ) { 8954 var day = date.getDay(); 8955 return [ ( day > 0 && day < 6 ), "" ]; 8956 }, 8957 8958 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 8959 * @param date Date - the date to get the week for 8960 * @return number - the number of the week within the year that contains this date 8961 */ 8962 iso8601Week: function( date ) { 8963 var time, 8964 checkDate = new Date( date.getTime() ); 8965 8966 // Find Thursday of this week starting on Monday 8967 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 8968 8969 time = checkDate.getTime(); 8970 checkDate.setMonth( 0 ); // Compare with Jan 1 8971 checkDate.setDate( 1 ); 8972 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 8973 }, 8974 8975 /* Parse a string value into a date object. 8976 * See formatDate below for the possible formats. 8977 * 8978 * @param format string - the expected format of the date 8979 * @param value string - the date in the above format 8980 * @param settings Object - attributes include: 8981 * shortYearCutoff number - the cutoff year for determining the century (optional) 8982 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 8983 * dayNames string[7] - names of the days from Sunday (optional) 8984 * monthNamesShort string[12] - abbreviated names of the months (optional) 8985 * monthNames string[12] - names of the months (optional) 8986 * @return Date - the extracted date value or null if value is blank 8987 */ 8988 parseDate: function( format, value, settings ) { 8989 if ( format == null || value == null ) { 8990 throw "Invalid arguments"; 8991 } 8992 8993 value = ( typeof value === "object" ? value.toString() : value + "" ); 8994 if ( value === "" ) { 8995 return null; 8996 } 8997 8998 var iFormat, dim, extra, 8999 iValue = 0, 9000 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, 9001 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 9002 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), 9003 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 9004 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 9005 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 9006 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 9007 year = -1, 9008 month = -1, 9009 day = -1, 9010 doy = -1, 9011 literal = false, 9012 date, 9013 9014 // Check whether a format character is doubled 9015 lookAhead = function( match ) { 9016 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 9017 if ( matches ) { 9018 iFormat++; 9019 } 9020 return matches; 9021 }, 9022 9023 // Extract a number from the string value 9024 getNumber = function( match ) { 9025 var isDoubled = lookAhead( match ), 9026 size = ( match === "@" ? 14 : ( match === "!" ? 20 : 9027 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), 9028 minSize = ( match === "y" ? size : 1 ), 9029 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), 9030 num = value.substring( iValue ).match( digits ); 9031 if ( !num ) { 9032 throw "Missing number at position " + iValue; 9033 } 9034 iValue += num[ 0 ].length; 9035 return parseInt( num[ 0 ], 10 ); 9036 }, 9037 9038 // Extract a name from the string value and convert to an index 9039 getName = function( match, shortNames, longNames ) { 9040 var index = -1, 9041 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 9042 return [ [ k, v ] ]; 9043 } ).sort( function( a, b ) { 9044 return -( a[ 1 ].length - b[ 1 ].length ); 9045 } ); 9046 9047 $.each( names, function( i, pair ) { 9048 var name = pair[ 1 ]; 9049 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { 9050 index = pair[ 0 ]; 9051 iValue += name.length; 9052 return false; 9053 } 9054 } ); 9055 if ( index !== -1 ) { 9056 return index + 1; 9057 } else { 9058 throw "Unknown name at position " + iValue; 9059 } 9060 }, 9061 9062 // Confirm that a literal character matches the string value 9063 checkLiteral = function() { 9064 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 9065 throw "Unexpected literal at position " + iValue; 9066 } 9067 iValue++; 9068 }; 9069 9070 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 9071 if ( literal ) { 9072 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 9073 literal = false; 9074 } else { 9075 checkLiteral(); 9076 } 9077 } else { 9078 switch ( format.charAt( iFormat ) ) { 9079 case "d": 9080 day = getNumber( "d" ); 9081 break; 9082 case "D": 9083 getName( "D", dayNamesShort, dayNames ); 9084 break; 9085 case "o": 9086 doy = getNumber( "o" ); 9087 break; 9088 case "m": 9089 month = getNumber( "m" ); 9090 break; 9091 case "M": 9092 month = getName( "M", monthNamesShort, monthNames ); 9093 break; 9094 case "y": 9095 year = getNumber( "y" ); 9096 break; 9097 case "@": 9098 date = new Date( getNumber( "@" ) ); 9099 year = date.getFullYear(); 9100 month = date.getMonth() + 1; 9101 day = date.getDate(); 9102 break; 9103 case "!": 9104 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); 9105 year = date.getFullYear(); 9106 month = date.getMonth() + 1; 9107 day = date.getDate(); 9108 break; 9109 case "'": 9110 if ( lookAhead( "'" ) ) { 9111 checkLiteral(); 9112 } else { 9113 literal = true; 9114 } 9115 break; 9116 default: 9117 checkLiteral(); 9118 } 9119 } 9120 } 9121 9122 if ( iValue < value.length ) { 9123 extra = value.substr( iValue ); 9124 if ( !/^\s+/.test( extra ) ) { 9125 throw "Extra/unparsed characters found in date: " + extra; 9126 } 9127 } 9128 9129 if ( year === -1 ) { 9130 year = new Date().getFullYear(); 9131 } else if ( year < 100 ) { 9132 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 9133 ( year <= shortYearCutoff ? 0 : -100 ); 9134 } 9135 9136 if ( doy > -1 ) { 9137 month = 1; 9138 day = doy; 9139 do { 9140 dim = this._getDaysInMonth( year, month - 1 ); 9141 if ( day <= dim ) { 9142 break; 9143 } 9144 month++; 9145 day -= dim; 9146 } while ( true ); 9147 } 9148 9149 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 9150 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 9151 throw "Invalid date"; // E.g. 31/02/00 9152 } 9153 return date; 9154 }, 9155 9156 /* Standard date formats. */ 9157 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 9158 COOKIE: "D, dd M yy", 9159 ISO_8601: "yy-mm-dd", 9160 RFC_822: "D, d M y", 9161 RFC_850: "DD, dd-M-y", 9162 RFC_1036: "D, d M y", 9163 RFC_1123: "D, d M yy", 9164 RFC_2822: "D, d M yy", 9165 RSS: "D, d M y", // RFC 822 9166 TICKS: "!", 9167 TIMESTAMP: "@", 9168 W3C: "yy-mm-dd", // ISO 8601 9169 9170 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + 9171 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), 9172 9173 /* Format a date object into a string value. 9174 * The format can be combinations of the following: 9175 * d - day of month (no leading zero) 9176 * dd - day of month (two digit) 9177 * o - day of year (no leading zeros) 9178 * oo - day of year (three digit) 9179 * D - day name short 9180 * DD - day name long 9181 * m - month of year (no leading zero) 9182 * mm - month of year (two digit) 9183 * M - month name short 9184 * MM - month name long 9185 * y - year (two digit) 9186 * yy - year (four digit) 9187 * @ - Unix timestamp (ms since 01/01/1970) 9188 * ! - Windows ticks (100ns since 01/01/0001) 9189 * "..." - literal text 9190 * '' - single quote 9191 * 9192 * @param format string - the desired format of the date 9193 * @param date Date - the date value to format 9194 * @param settings Object - attributes include: 9195 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 9196 * dayNames string[7] - names of the days from Sunday (optional) 9197 * monthNamesShort string[12] - abbreviated names of the months (optional) 9198 * monthNames string[12] - names of the months (optional) 9199 * @return string - the date in the above format 9200 */ 9201 formatDate: function( format, date, settings ) { 9202 if ( !date ) { 9203 return ""; 9204 } 9205 9206 var iFormat, 9207 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 9208 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 9209 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 9210 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 9211 9212 // Check whether a format character is doubled 9213 lookAhead = function( match ) { 9214 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 9215 if ( matches ) { 9216 iFormat++; 9217 } 9218 return matches; 9219 }, 9220 9221 // Format a number, with leading zero if necessary 9222 formatNumber = function( match, value, len ) { 9223 var num = "" + value; 9224 if ( lookAhead( match ) ) { 9225 while ( num.length < len ) { 9226 num = "0" + num; 9227 } 9228 } 9229 return num; 9230 }, 9231 9232 // Format a name, short or long as requested 9233 formatName = function( match, value, shortNames, longNames ) { 9234 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); 9235 }, 9236 output = "", 9237 literal = false; 9238 9239 if ( date ) { 9240 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 9241 if ( literal ) { 9242 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 9243 literal = false; 9244 } else { 9245 output += format.charAt( iFormat ); 9246 } 9247 } else { 9248 switch ( format.charAt( iFormat ) ) { 9249 case "d": 9250 output += formatNumber( "d", date.getDate(), 2 ); 9251 break; 9252 case "D": 9253 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); 9254 break; 9255 case "o": 9256 output += formatNumber( "o", 9257 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 9258 break; 9259 case "m": 9260 output += formatNumber( "m", date.getMonth() + 1, 2 ); 9261 break; 9262 case "M": 9263 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); 9264 break; 9265 case "y": 9266 output += ( lookAhead( "y" ) ? date.getFullYear() : 9267 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); 9268 break; 9269 case "@": 9270 output += date.getTime(); 9271 break; 9272 case "!": 9273 output += date.getTime() * 10000 + this._ticksTo1970; 9274 break; 9275 case "'": 9276 if ( lookAhead( "'" ) ) { 9277 output += "'"; 9278 } else { 9279 literal = true; 9280 } 9281 break; 9282 default: 9283 output += format.charAt( iFormat ); 9284 } 9285 } 9286 } 9287 } 9288 return output; 9289 }, 9290 9291 /* Extract all possible characters from the date format. */ 9292 _possibleChars: function( format ) { 9293 var iFormat, 9294 chars = "", 9295 literal = false, 9296 9297 // Check whether a format character is doubled 9298 lookAhead = function( match ) { 9299 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 9300 if ( matches ) { 9301 iFormat++; 9302 } 9303 return matches; 9304 }; 9305 9306 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 9307 if ( literal ) { 9308 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 9309 literal = false; 9310 } else { 9311 chars += format.charAt( iFormat ); 9312 } 9313 } else { 9314 switch ( format.charAt( iFormat ) ) { 9315 case "d": case "m": case "y": case "@": 9316 chars += "0123456789"; 9317 break; 9318 case "D": case "M": 9319 return null; // Accept anything 9320 case "'": 9321 if ( lookAhead( "'" ) ) { 9322 chars += "'"; 9323 } else { 9324 literal = true; 9325 } 9326 break; 9327 default: 9328 chars += format.charAt( iFormat ); 9329 } 9330 } 9331 } 9332 return chars; 9333 }, 9334 9335 /* Get a setting value, defaulting if necessary. */ 9336 _get: function( inst, name ) { 9337 return inst.settings[ name ] !== undefined ? 9338 inst.settings[ name ] : this._defaults[ name ]; 9339 }, 9340 9341 /* Parse existing date and initialise date picker. */ 9342 _setDateFromField: function( inst, noDefault ) { 9343 if ( inst.input.val() === inst.lastVal ) { 9344 return; 9345 } 9346 9347 var dateFormat = this._get( inst, "dateFormat" ), 9348 dates = inst.lastVal = inst.input ? inst.input.val() : null, 9349 defaultDate = this._getDefaultDate( inst ), 9350 date = defaultDate, 9351 settings = this._getFormatConfig( inst ); 9352 9353 try { 9354 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 9355 } catch ( _err ) { 9356 dates = ( noDefault ? "" : dates ); 9357 } 9358 inst.selectedDay = date.getDate(); 9359 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9360 inst.drawYear = inst.selectedYear = date.getFullYear(); 9361 inst.currentDay = ( dates ? date.getDate() : 0 ); 9362 inst.currentMonth = ( dates ? date.getMonth() : 0 ); 9363 inst.currentYear = ( dates ? date.getFullYear() : 0 ); 9364 this._adjustInstDate( inst ); 9365 }, 9366 9367 /* Retrieve the default date shown on opening. */ 9368 _getDefaultDate: function( inst ) { 9369 return this._restrictMinMax( inst, 9370 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); 9371 }, 9372 9373 /* A date may be specified as an exact value or a relative one. */ 9374 _determineDate: function( inst, date, defaultDate ) { 9375 var offsetNumeric = function( offset ) { 9376 var date = new Date(); 9377 date.setDate( date.getDate() + offset ); 9378 return date; 9379 }, 9380 offsetString = function( offset ) { 9381 try { 9382 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 9383 offset, $.datepicker._getFormatConfig( inst ) ); 9384 } catch ( _e ) { 9385 9386 // Ignore 9387 } 9388 9389 var date = ( offset.toLowerCase().match( /^c/ ) ? 9390 $.datepicker._getDate( inst ) : null ) || new Date(), 9391 year = date.getFullYear(), 9392 month = date.getMonth(), 9393 day = date.getDate(), 9394 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 9395 matches = pattern.exec( offset ); 9396 9397 while ( matches ) { 9398 switch ( matches[ 2 ] || "d" ) { 9399 case "d" : case "D" : 9400 day += parseInt( matches[ 1 ], 10 ); break; 9401 case "w" : case "W" : 9402 day += parseInt( matches[ 1 ], 10 ) * 7; break; 9403 case "m" : case "M" : 9404 month += parseInt( matches[ 1 ], 10 ); 9405 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 9406 break; 9407 case "y": case "Y" : 9408 year += parseInt( matches[ 1 ], 10 ); 9409 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 9410 break; 9411 } 9412 matches = pattern.exec( offset ); 9413 } 9414 return new Date( year, month, day ); 9415 }, 9416 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : 9417 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); 9418 9419 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); 9420 if ( newDate ) { 9421 newDate.setHours( 0 ); 9422 newDate.setMinutes( 0 ); 9423 newDate.setSeconds( 0 ); 9424 newDate.setMilliseconds( 0 ); 9425 } 9426 return this._daylightSavingAdjust( newDate ); 9427 }, 9428 9429 /* Handle switch to/from daylight saving. 9430 * Hours may be non-zero on daylight saving cut-over: 9431 * > 12 when midnight changeover, but then cannot generate 9432 * midnight datetime, so jump to 1AM, otherwise reset. 9433 * @param date (Date) the date to check 9434 * @return (Date) the corrected date 9435 */ 9436 _daylightSavingAdjust: function( date ) { 9437 if ( !date ) { 9438 return null; 9439 } 9440 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 9441 return date; 9442 }, 9443 9444 /* Set the date(s) directly. */ 9445 _setDate: function( inst, date, noChange ) { 9446 var clear = !date, 9447 origMonth = inst.selectedMonth, 9448 origYear = inst.selectedYear, 9449 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 9450 9451 inst.selectedDay = inst.currentDay = newDate.getDate(); 9452 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 9453 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 9454 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { 9455 this._notifyChange( inst ); 9456 } 9457 this._adjustInstDate( inst ); 9458 if ( inst.input ) { 9459 inst.input.val( clear ? "" : this._formatDate( inst ) ); 9460 } 9461 }, 9462 9463 /* Retrieve the date(s) directly. */ 9464 _getDate: function( inst ) { 9465 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : 9466 this._daylightSavingAdjust( new Date( 9467 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 9468 return startDate; 9469 }, 9470 9471 /* Attach the onxxx handlers. These are declared statically so 9472 * they work with static code transformers like Caja. 9473 */ 9474 _attachHandlers: function( inst ) { 9475 var stepMonths = this._get( inst, "stepMonths" ), 9476 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 9477 inst.dpDiv.find( "[data-handler]" ).map( function() { 9478 var handler = { 9479 prev: function() { 9480 $.datepicker._adjustDate( id, -stepMonths, "M" ); 9481 }, 9482 next: function() { 9483 $.datepicker._adjustDate( id, +stepMonths, "M" ); 9484 }, 9485 hide: function() { 9486 $.datepicker._hideDatepicker(); 9487 }, 9488 today: function() { 9489 $.datepicker._gotoToday( id ); 9490 }, 9491 selectDay: function() { 9492 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); 9493 return false; 9494 }, 9495 selectMonth: function() { 9496 $.datepicker._selectMonthYear( id, this, "M" ); 9497 return false; 9498 }, 9499 selectYear: function() { 9500 $.datepicker._selectMonthYear( id, this, "Y" ); 9501 return false; 9502 } 9503 }; 9504 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); 9505 } ); 9506 }, 9507 9508 /* Generate the HTML for the current state of the date picker. */ 9509 _generateHTML: function( inst ) { 9510 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 9511 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 9512 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 9513 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 9514 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 9515 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 9516 tempDate = new Date(), 9517 today = this._daylightSavingAdjust( 9518 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 9519 isRTL = this._get( inst, "isRTL" ), 9520 showButtonPanel = this._get( inst, "showButtonPanel" ), 9521 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), 9522 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), 9523 numMonths = this._getNumberOfMonths( inst ), 9524 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), 9525 stepMonths = this._get( inst, "stepMonths" ), 9526 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), 9527 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : 9528 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), 9529 minDate = this._getMinMaxDate( inst, "min" ), 9530 maxDate = this._getMinMaxDate( inst, "max" ), 9531 drawMonth = inst.drawMonth - showCurrentAtPos, 9532 drawYear = inst.drawYear; 9533 9534 if ( drawMonth < 0 ) { 9535 drawMonth += 12; 9536 drawYear--; 9537 } 9538 if ( maxDate ) { 9539 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), 9540 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 9541 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); 9542 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 9543 drawMonth--; 9544 if ( drawMonth < 0 ) { 9545 drawMonth = 11; 9546 drawYear--; 9547 } 9548 } 9549 } 9550 inst.drawMonth = drawMonth; 9551 inst.drawYear = drawYear; 9552 9553 prevText = this._get( inst, "prevText" ); 9554 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, 9555 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), 9556 this._getFormatConfig( inst ) ) ); 9557 9558 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { 9559 prev = $( "<a>" ) 9560 .attr( { 9561 "class": "ui-datepicker-prev ui-corner-all", 9562 "data-handler": "prev", 9563 "data-event": "click", 9564 title: prevText 9565 } ) 9566 .append( 9567 $( "<span>" ) 9568 .addClass( "ui-icon ui-icon-circle-triangle-" + 9569 ( isRTL ? "e" : "w" ) ) 9570 .text( prevText ) 9571 )[ 0 ].outerHTML; 9572 } else if ( hideIfNoPrevNext ) { 9573 prev = ""; 9574 } else { 9575 prev = $( "<a>" ) 9576 .attr( { 9577 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", 9578 title: prevText 9579 } ) 9580 .append( 9581 $( "<span>" ) 9582 .addClass( "ui-icon ui-icon-circle-triangle-" + 9583 ( isRTL ? "e" : "w" ) ) 9584 .text( prevText ) 9585 )[ 0 ].outerHTML; 9586 } 9587 9588 nextText = this._get( inst, "nextText" ); 9589 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, 9590 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), 9591 this._getFormatConfig( inst ) ) ); 9592 9593 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { 9594 next = $( "<a>" ) 9595 .attr( { 9596 "class": "ui-datepicker-next ui-corner-all", 9597 "data-handler": "next", 9598 "data-event": "click", 9599 title: nextText 9600 } ) 9601 .append( 9602 $( "<span>" ) 9603 .addClass( "ui-icon ui-icon-circle-triangle-" + 9604 ( isRTL ? "w" : "e" ) ) 9605 .text( nextText ) 9606 )[ 0 ].outerHTML; 9607 } else if ( hideIfNoPrevNext ) { 9608 next = ""; 9609 } else { 9610 next = $( "<a>" ) 9611 .attr( { 9612 "class": "ui-datepicker-next ui-corner-all ui-state-disabled", 9613 title: nextText 9614 } ) 9615 .append( 9616 $( "<span>" ) 9617 .attr( "class", "ui-icon ui-icon-circle-triangle-" + 9618 ( isRTL ? "w" : "e" ) ) 9619 .text( nextText ) 9620 )[ 0 ].outerHTML; 9621 } 9622 9623 currentText = this._get( inst, "currentText" ); 9624 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); 9625 currentText = ( !navigationAsDateFormat ? currentText : 9626 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); 9627 9628 controls = ""; 9629 if ( !inst.inline ) { 9630 controls = $( "<button>" ) 9631 .attr( { 9632 type: "button", 9633 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", 9634 "data-handler": "hide", 9635 "data-event": "click" 9636 } ) 9637 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; 9638 } 9639 9640 buttonPanel = ""; 9641 if ( showButtonPanel ) { 9642 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) 9643 .append( isRTL ? controls : "" ) 9644 .append( this._isInRange( inst, gotoDate ) ? 9645 $( "<button>" ) 9646 .attr( { 9647 type: "button", 9648 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", 9649 "data-handler": "today", 9650 "data-event": "click" 9651 } ) 9652 .text( currentText ) : 9653 "" ) 9654 .append( isRTL ? "" : controls )[ 0 ].outerHTML; 9655 } 9656 9657 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); 9658 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); 9659 9660 showWeek = this._get( inst, "showWeek" ); 9661 dayNames = this._get( inst, "dayNames" ); 9662 dayNamesMin = this._get( inst, "dayNamesMin" ); 9663 monthNames = this._get( inst, "monthNames" ); 9664 monthNamesShort = this._get( inst, "monthNamesShort" ); 9665 beforeShowDay = this._get( inst, "beforeShowDay" ); 9666 showOtherMonths = this._get( inst, "showOtherMonths" ); 9667 selectOtherMonths = this._get( inst, "selectOtherMonths" ); 9668 defaultDate = this._getDefaultDate( inst ); 9669 html = ""; 9670 9671 for ( row = 0; row < numMonths[ 0 ]; row++ ) { 9672 group = ""; 9673 this.maxRows = 4; 9674 for ( col = 0; col < numMonths[ 1 ]; col++ ) { 9675 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 9676 cornerClass = " ui-corner-all"; 9677 calender = ""; 9678 if ( isMultiMonth ) { 9679 calender += "<div class='ui-datepicker-group"; 9680 if ( numMonths[ 1 ] > 1 ) { 9681 switch ( col ) { 9682 case 0: calender += " ui-datepicker-group-first"; 9683 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; 9684 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; 9685 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; 9686 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 9687 } 9688 } 9689 calender += "'>"; 9690 } 9691 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 9692 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + 9693 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + 9694 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, 9695 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers 9696 "</div><table class='ui-datepicker-calendar'><thead>" + 9697 "<tr>"; 9698 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); 9699 for ( dow = 0; dow < 7; dow++ ) { // days of the week 9700 day = ( dow + firstDay ) % 7; 9701 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + 9702 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; 9703 } 9704 calender += thead + "</tr></thead><tbody>"; 9705 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 9706 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 9707 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 9708 } 9709 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 9710 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate 9711 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) 9712 this.maxRows = numRows; 9713 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 9714 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows 9715 calender += "<tr>"; 9716 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 9717 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); 9718 for ( dow = 0; dow < 7; dow++ ) { // create date picker days 9719 daySettings = ( beforeShowDay ? 9720 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); 9721 otherMonth = ( printDate.getMonth() !== drawMonth ); 9722 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || 9723 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 9724 tbody += "<td class='" + 9725 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends 9726 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months 9727 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key 9728 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? 9729 9730 // or defaultDate is current printedDate and defaultDate is selectedDate 9731 " " + this._dayOverClass : "" ) + // highlight selected day 9732 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days 9733 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates 9734 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day 9735 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) 9736 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title 9737 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions 9738 ( otherMonth && !showOtherMonths ? " " : // display for other months 9739 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 9740 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + 9741 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day 9742 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months 9743 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader 9744 "' data-date='" + printDate.getDate() + // store date as data 9745 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date 9746 printDate.setDate( printDate.getDate() + 1 ); 9747 printDate = this._daylightSavingAdjust( printDate ); 9748 } 9749 calender += tbody + "</tr>"; 9750 } 9751 drawMonth++; 9752 if ( drawMonth > 11 ) { 9753 drawMonth = 0; 9754 drawYear++; 9755 } 9756 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + 9757 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); 9758 group += calender; 9759 } 9760 html += group; 9761 } 9762 html += buttonPanel; 9763 inst._keyEvent = false; 9764 return html; 9765 }, 9766 9767 /* Generate the month and year header. */ 9768 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, 9769 secondary, monthNames, monthNamesShort ) { 9770 9771 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 9772 changeMonth = this._get( inst, "changeMonth" ), 9773 changeYear = this._get( inst, "changeYear" ), 9774 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), 9775 selectMonthLabel = this._get( inst, "selectMonthLabel" ), 9776 selectYearLabel = this._get( inst, "selectYearLabel" ), 9777 html = "<div class='ui-datepicker-title'>", 9778 monthHtml = ""; 9779 9780 // Month selection 9781 if ( secondary || !changeMonth ) { 9782 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; 9783 } else { 9784 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); 9785 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); 9786 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; 9787 for ( month = 0; month < 12; month++ ) { 9788 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { 9789 monthHtml += "<option value='" + month + "'" + 9790 ( month === drawMonth ? " selected='selected'" : "" ) + 9791 ">" + monthNamesShort[ month ] + "</option>"; 9792 } 9793 } 9794 monthHtml += "</select>"; 9795 } 9796 9797 if ( !showMonthAfterYear ) { 9798 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); 9799 } 9800 9801 // Year selection 9802 if ( !inst.yearshtml ) { 9803 inst.yearshtml = ""; 9804 if ( secondary || !changeYear ) { 9805 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 9806 } else { 9807 9808 // determine range of years to display 9809 years = this._get( inst, "yearRange" ).split( ":" ); 9810 thisYear = new Date().getFullYear(); 9811 determineYear = function( value ) { 9812 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : 9813 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : 9814 parseInt( value, 10 ) ) ); 9815 return ( isNaN( year ) ? thisYear : year ); 9816 }; 9817 year = determineYear( years[ 0 ] ); 9818 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); 9819 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); 9820 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); 9821 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; 9822 for ( ; year <= endYear; year++ ) { 9823 inst.yearshtml += "<option value='" + year + "'" + 9824 ( year === drawYear ? " selected='selected'" : "" ) + 9825 ">" + year + "</option>"; 9826 } 9827 inst.yearshtml += "</select>"; 9828 9829 html += inst.yearshtml; 9830 inst.yearshtml = null; 9831 } 9832 } 9833 9834 html += this._get( inst, "yearSuffix" ); 9835 if ( showMonthAfterYear ) { 9836 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; 9837 } 9838 html += "</div>"; // Close datepicker_header 9839 return html; 9840 }, 9841 9842 /* Adjust one of the date sub-fields. */ 9843 _adjustInstDate: function( inst, offset, period ) { 9844 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), 9845 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), 9846 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), 9847 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 9848 9849 inst.selectedDay = date.getDate(); 9850 inst.drawMonth = inst.selectedMonth = date.getMonth(); 9851 inst.drawYear = inst.selectedYear = date.getFullYear(); 9852 if ( period === "M" || period === "Y" ) { 9853 this._notifyChange( inst ); 9854 } 9855 }, 9856 9857 /* Ensure a date is within any min/max bounds. */ 9858 _restrictMinMax: function( inst, date ) { 9859 var minDate = this._getMinMaxDate( inst, "min" ), 9860 maxDate = this._getMinMaxDate( inst, "max" ), 9861 newDate = ( minDate && date < minDate ? minDate : date ); 9862 return ( maxDate && newDate > maxDate ? maxDate : newDate ); 9863 }, 9864 9865 /* Notify change of month/year. */ 9866 _notifyChange: function( inst ) { 9867 var onChange = this._get( inst, "onChangeMonthYear" ); 9868 if ( onChange ) { 9869 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), 9870 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 9871 } 9872 }, 9873 9874 /* Determine the number of months to show. */ 9875 _getNumberOfMonths: function( inst ) { 9876 var numMonths = this._get( inst, "numberOfMonths" ); 9877 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); 9878 }, 9879 9880 /* Determine the current maximum date - ensure no time components are set. */ 9881 _getMinMaxDate: function( inst, minMax ) { 9882 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); 9883 }, 9884 9885 /* Find the number of days in a given month. */ 9886 _getDaysInMonth: function( year, month ) { 9887 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 9888 }, 9889 9890 /* Find the day of the week of the first of a month. */ 9891 _getFirstDayOfMonth: function( year, month ) { 9892 return new Date( year, month, 1 ).getDay(); 9893 }, 9894 9895 /* Determines if we should allow a "next/prev" month display change. */ 9896 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 9897 var numMonths = this._getNumberOfMonths( inst ), 9898 date = this._daylightSavingAdjust( new Date( curYear, 9899 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 9900 9901 if ( offset < 0 ) { 9902 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 9903 } 9904 return this._isInRange( inst, date ); 9905 }, 9906 9907 /* Is the given date in the accepted range? */ 9908 _isInRange: function( inst, date ) { 9909 var yearSplit, currentYear, 9910 minDate = this._getMinMaxDate( inst, "min" ), 9911 maxDate = this._getMinMaxDate( inst, "max" ), 9912 minYear = null, 9913 maxYear = null, 9914 years = this._get( inst, "yearRange" ); 9915 if ( years ) { 9916 yearSplit = years.split( ":" ); 9917 currentYear = new Date().getFullYear(); 9918 minYear = parseInt( yearSplit[ 0 ], 10 ); 9919 maxYear = parseInt( yearSplit[ 1 ], 10 ); 9920 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { 9921 minYear += currentYear; 9922 } 9923 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { 9924 maxYear += currentYear; 9925 } 9926 } 9927 9928 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && 9929 ( !maxDate || date.getTime() <= maxDate.getTime() ) && 9930 ( !minYear || date.getFullYear() >= minYear ) && 9931 ( !maxYear || date.getFullYear() <= maxYear ) ); 9932 }, 9933 9934 /* Provide the configuration settings for formatting/parsing. */ 9935 _getFormatConfig: function( inst ) { 9936 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); 9937 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : 9938 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); 9939 return { shortYearCutoff: shortYearCutoff, 9940 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), 9941 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; 9942 }, 9943 9944 /* Format the given date for display. */ 9945 _formatDate: function( inst, day, month, year ) { 9946 if ( !day ) { 9947 inst.currentDay = inst.selectedDay; 9948 inst.currentMonth = inst.selectedMonth; 9949 inst.currentYear = inst.selectedYear; 9950 } 9951 var date = ( day ? ( typeof day === "object" ? day : 9952 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : 9953 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 9954 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); 9955 } 9956} ); 9957 9958/* 9959 * Bind hover events for datepicker elements. 9960 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 9961 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 9962 */ 9963function datepicker_bindHover( dpDiv ) { 9964 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 9965 return dpDiv.on( "mouseout", selector, function() { 9966 $( this ).removeClass( "ui-state-hover" ); 9967 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 9968 $( this ).removeClass( "ui-datepicker-prev-hover" ); 9969 } 9970 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 9971 $( this ).removeClass( "ui-datepicker-next-hover" ); 9972 } 9973 } ) 9974 .on( "mouseover", selector, datepicker_handleMouseover ); 9975} 9976 9977function datepicker_handleMouseover() { 9978 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 9979 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); 9980 $( this ).addClass( "ui-state-hover" ); 9981 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 9982 $( this ).addClass( "ui-datepicker-prev-hover" ); 9983 } 9984 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 9985 $( this ).addClass( "ui-datepicker-next-hover" ); 9986 } 9987 } 9988} 9989 9990/* jQuery extend now ignores nulls! */ 9991function datepicker_extendRemove( target, props ) { 9992 $.extend( target, props ); 9993 for ( var name in props ) { 9994 if ( props[ name ] == null ) { 9995 target[ name ] = props[ name ]; 9996 } 9997 } 9998 return target; 9999} 10000 10001/* Invoke the datepicker functionality. 10002 @param options string - a command, optionally followed by additional parameters or 10003 Object - settings for attaching new datepicker functionality 10004 @return jQuery object */ 10005$.fn.datepicker = function( options ) { 10006 10007 /* Verify an empty collection wasn't passed - Fixes #6976 */ 10008 if ( !this.length ) { 10009 return this; 10010 } 10011 10012 /* Initialise the date picker. */ 10013 if ( !$.datepicker.initialized ) { 10014 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); 10015 $.datepicker.initialized = true; 10016 } 10017 10018 /* Append datepicker main container to body if not exist. */ 10019 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { 10020 $( "body" ).append( $.datepicker.dpDiv ); 10021 } 10022 10023 var otherArgs = Array.prototype.slice.call( arguments, 1 ); 10024 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { 10025 return $.datepicker[ "_" + options + "Datepicker" ]. 10026 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 10027 } 10028 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { 10029 return $.datepicker[ "_" + options + "Datepicker" ]. 10030 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 10031 } 10032 return this.each( function() { 10033 if ( typeof options === "string" ) { 10034 $.datepicker[ "_" + options + "Datepicker" ] 10035 .apply( $.datepicker, [ this ].concat( otherArgs ) ); 10036 } else { 10037 $.datepicker._attachDatepicker( this, options ); 10038 } 10039 } ); 10040}; 10041 10042$.datepicker = new Datepicker(); // singleton instance 10043$.datepicker.initialized = false; 10044$.datepicker.uuid = new Date().getTime(); 10045$.datepicker.version = "
vendor: 6,584 bytes, lines 10045-10315
10045@VERSION"; 10046 10047return $.datepicker; 10048 10049} ); 10050 10051/*! 10052 * jQuery UI Mouse @VERSION 10053 * https://jqueryui.com 10054 * 10055 * Copyright OpenJS Foundation and other contributors 10056 * Released under the MIT license. 10057 * https://jquery.org/license 10058 */ 10059 10060//>>label: Mouse 10061//>>group: Widgets 10062//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 10063//>>docs: https://api.jqueryui.com/mouse/ 10064 10065( function( factory ) { 10066 "use strict"; 10067 10068 if ( typeof define === "function" && define.amd ) { 10069 10070 // AMD. Register as an anonymous module. 10071 define( 'ui/widgets/mouse.js',[ 10072 "jquery", 10073 "../version", 10074 "../widget" 10075 ], factory ); 10076 } else { 10077 10078 // Browser globals 10079 factory( jQuery ); 10080 } 10081} )( function( $ ) { 10082"use strict"; 10083 10084var mouseHandled = false; 10085$( document ).on( "mouseup", function() { 10086 mouseHandled = false; 10087} ); 10088 10089return $.widget( "ui.mouse", { 10090 version: "@VERSION", 10091 options: { 10092 cancel: "input, textarea, button, select, option", 10093 distance: 1, 10094 delay: 0 10095 }, 10096 _mouseInit: function() { 10097 var that = this; 10098 10099 this.element 10100 .on( "mousedown." + this.widgetName, function( event ) { 10101 return that._mouseDown( event ); 10102 } ) 10103 .on( "click." + this.widgetName, function( event ) { 10104 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 10105 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 10106 event.stopImmediatePropagation(); 10107 return false; 10108 } 10109 } ); 10110 10111 this.started = false; 10112 }, 10113 10114 // TODO: make sure destroying one instance of mouse doesn't mess with 10115 // other instances of mouse 10116 _mouseDestroy: function() { 10117 this.element.off( "." + this.widgetName ); 10118 if ( this._mouseMoveDelegate ) { 10119 this.document 10120 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 10121 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 10122 } 10123 }, 10124 10125 _mouseDown: function( event ) { 10126 10127 // don't let more than one widget handle mouseStart 10128 if ( mouseHandled ) { 10129 return; 10130 } 10131 10132 this._mouseMoved = false; 10133 10134 // We may have missed mouseup (out of window) 10135 if ( this._mouseStarted ) { 10136 this._mouseUp( event ); 10137 } 10138 10139 this._mouseDownEvent = event; 10140 10141 var that = this, 10142 btnIsLeft = event.which === 1, 10143 elIsCancel = typeof this.options.cancel === "string" ? 10144 $( event.target ).closest( this.options.cancel ).length : 10145 false; 10146 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 10147 return true; 10148 } 10149 10150 this.mouseDelayMet = !this.options.delay; 10151 if ( !this.mouseDelayMet ) { 10152 this._mouseDelayTimer = setTimeout( function() { 10153 that.mouseDelayMet = true; 10154 }, this.options.delay ); 10155 } 10156 10157 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 10158 this._mouseStarted = ( this._mouseStart( event ) !== false ); 10159 if ( !this._mouseStarted ) { 10160 event.preventDefault(); 10161 return true; 10162 } 10163 } 10164 10165 // Click event may never have fired (Gecko & Opera) 10166 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 10167 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 10168 } 10169 10170 // These delegates are required to keep context 10171 this._mouseMoveDelegate = function( event ) { 10172 return that._mouseMove( event ); 10173 }; 10174 this._mouseUpDelegate = function( event ) { 10175 return that._mouseUp( event ); 10176 }; 10177 10178 this.document 10179 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 10180 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 10181 10182 event.preventDefault(); 10183 10184 mouseHandled = true; 10185 return true; 10186 }, 10187 10188 _mouseMove: function( event ) { 10189 10190 // Only check for mouseups outside the document if you've moved inside the document 10191 // at least once. 10192 if ( this._mouseMoved && !event.which ) { 10193 10194 // Support: Safari <=8 - 9 10195 // Safari sets which to 0 if you press any of the following keys 10196 // during a drag (#14461) 10197 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 10198 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 10199 this.ignoreMissingWhich = true; 10200 } else if ( !this.ignoreMissingWhich ) { 10201 return this._mouseUp( event ); 10202 } 10203 } 10204 10205 if ( event.which || event.button ) { 10206 this._mouseMoved = true; 10207 } 10208 10209 if ( this._mouseStarted ) { 10210 this._mouseDrag( event ); 10211 return event.preventDefault(); 10212 } 10213 10214 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 10215 this._mouseStarted = 10216 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 10217 if ( this._mouseStarted ) { 10218 this._mouseDrag( event ); 10219 } else { 10220 this._mouseUp( event ); 10221 } 10222 } 10223 10224 return !this._mouseStarted; 10225 }, 10226 10227 _mouseUp: function( event ) { 10228 this.document 10229 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 10230 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 10231 10232 if ( this._mouseStarted ) { 10233 this._mouseStarted = false; 10234 10235 if ( event.target === this._mouseDownEvent.target ) { 10236 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 10237 } 10238 10239 this._mouseStop( event ); 10240 } 10241 10242 if ( this._mouseDelayTimer ) { 10243 clearTimeout( this._mouseDelayTimer ); 10244 delete this._mouseDelayTimer; 10245 } 10246 10247 this.ignoreMissingWhich = false; 10248 mouseHandled = false; 10249 event.preventDefault(); 10250 }, 10251 10252 _mouseDistanceMet: function( event ) { 10253 return ( Math.max( 10254 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 10255 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 10256 ) >= this.options.distance 10257 ); 10258 }, 10259 10260 _mouseDelayMet: function( /* event */ ) { 10261 return this.mouseDelayMet; 10262 }, 10263 10264 // These are placeholder methods, to be overriden by extending plugin 10265 _mouseStart: function( /* event */ ) {}, 10266 _mouseDrag: function( /* event */ ) {}, 10267 _mouseStop: function( /* event */ ) {}, 10268 _mouseCapture: function( /* event */ ) { 10269 return true; 10270 } 10271} ); 10272 10273} ); 10274 10275/*! 10276 * jQuery UI Draggable @VERSION 10277 * https://jqueryui.com 10278 * 10279 * Copyright OpenJS Foundation and other contributors 10280 * Released under the MIT license. 10281 * https://jquery.org/license 10282 */ 10283 10284//>>label: Draggable 10285//>>group: Interactions 10286//>>description: Enables dragging functionality for any element. 10287//>>docs: https://api.jqueryui.com/draggable/ 10288//>>demos: https://jqueryui.com/draggable/ 10289//>>css.structure: ../../themes/base/draggable.css 10290 10291( function( factory ) { 10292 "use strict"; 10293 10294 if ( typeof define === "function" && define.amd ) { 10295 10296 // AMD. Register as an anonymous module. 10297 define( 'ui/widgets/draggable.js',[ 10298 "jquery", 10299 "./mouse", 10300 "../data", 10301 "../plugin", 10302 "../scroll-parent", 10303 "../version", 10304 "../widget" 10305 ], factory ); 10306 } else { 10307 10308 // Browser globals 10309 factory( jQuery ); 10310 } 10311} )( function( $ ) { 10312"use strict"; 10313 10314$.widget( "ui.draggable", $.ui.mouse, { 10315 version: "@VERSION
vendor: 34,601 bytes, lines 10315-11528
10315", 10316 widgetEventPrefix: "drag", 10317 options: { 10318 addClasses: true, 10319 appendTo: "parent", 10320 axis: false, 10321 connectToSortable: false, 10322 containment: false, 10323 cursor: "auto", 10324 cursorAt: false, 10325 grid: false, 10326 handle: false, 10327 helper: "original", 10328 iframeFix: false, 10329 opacity: false, 10330 refreshPositions: false, 10331 revert: false, 10332 revertDuration: 500, 10333 scope: "default", 10334 scroll: true, 10335 scrollSensitivity: 20, 10336 scrollSpeed: 20, 10337 snap: false, 10338 snapMode: "both", 10339 snapTolerance: 20, 10340 stack: false, 10341 zIndex: false, 10342 10343 // Callbacks 10344 drag: null, 10345 start: null, 10346 stop: null 10347 }, 10348 _create: function() { 10349 10350 if ( this.options.helper === "original" ) { 10351 this._setPositionRelative(); 10352 } 10353 if ( this.options.addClasses ) { 10354 this._addClass( "ui-draggable" ); 10355 } 10356 this._setHandleClassName(); 10357 10358 this._mouseInit(); 10359 }, 10360 10361 _setOption: function( key, value ) { 10362 this._super( key, value ); 10363 if ( key === "handle" ) { 10364 this._removeHandleClassName(); 10365 this._setHandleClassName(); 10366 } 10367 }, 10368 10369 _destroy: function() { 10370 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 10371 this.destroyOnClear = true; 10372 return; 10373 } 10374 this._removeHandleClassName(); 10375 this._mouseDestroy(); 10376 }, 10377 10378 _mouseCapture: function( event ) { 10379 var o = this.options; 10380 10381 // Among others, prevent a drag on a resizable-handle 10382 if ( this.helper || o.disabled || 10383 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 10384 return false; 10385 } 10386 10387 //Quit if we're not on a valid handle 10388 this.handle = this._getHandle( event ); 10389 if ( !this.handle ) { 10390 return false; 10391 } 10392 10393 this._blurActiveElement( event ); 10394 10395 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 10396 10397 return true; 10398 10399 }, 10400 10401 _blockFrames: function( selector ) { 10402 this.iframeBlocks = this.document.find( selector ).map( function() { 10403 var iframe = $( this ); 10404 10405 return $( "<div>" ) 10406 .css( "position", "absolute" ) 10407 .appendTo( iframe.parent() ) 10408 .outerWidth( iframe.outerWidth() ) 10409 .outerHeight( iframe.outerHeight() ) 10410 .offset( iframe.offset() )[ 0 ]; 10411 } ); 10412 }, 10413 10414 _unblockFrames: function() { 10415 if ( this.iframeBlocks ) { 10416 this.iframeBlocks.remove(); 10417 delete this.iframeBlocks; 10418 } 10419 }, 10420 10421 _blurActiveElement: function( event ) { 10422 var activeElement = this.document[ 0 ].activeElement, 10423 target = $( event.target ); 10424 10425 // Don't blur if the event occurred on an element that is within 10426 // the currently focused element 10427 // See #10527, #12472 10428 if ( target.closest( activeElement ).length ) { 10429 return; 10430 } 10431 10432 // Blur any element that currently has focus, see #4261 10433 $( activeElement ).trigger( "blur" ); 10434 }, 10435 10436 _mouseStart: function( event ) { 10437 10438 var o = this.options; 10439 10440 //Create and append the visible helper 10441 this.helper = this._createHelper( event ); 10442 10443 this._addClass( this.helper, "ui-draggable-dragging" ); 10444 10445 //Cache the helper size 10446 this._cacheHelperProportions(); 10447 10448 //If ddmanager is used for droppables, set the global draggable 10449 if ( $.ui.ddmanager ) { 10450 $.ui.ddmanager.current = this; 10451 } 10452 10453 /* 10454 * - Position generation - 10455 * This block generates everything position related - it's the core of draggables. 10456 */ 10457 10458 //Cache the margins of the original element 10459 this._cacheMargins(); 10460 10461 //Store the helper's css position 10462 this.cssPosition = this.helper.css( "position" ); 10463 this.scrollParent = this.helper.scrollParent( true ); 10464 this.offsetParent = this.helper.offsetParent(); 10465 this.hasFixedAncestor = this.helper.parents().filter( function() { 10466 return $( this ).css( "position" ) === "fixed"; 10467 } ).length > 0; 10468 10469 //The element's absolute position on the page minus margins 10470 this.positionAbs = this.element.offset(); 10471 this._refreshOffsets( event ); 10472 10473 //Generate the original position 10474 this.originalPosition = this.position = this._generatePosition( event, false ); 10475 this.originalPageX = event.pageX; 10476 this.originalPageY = event.pageY; 10477 10478 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 10479 if ( o.cursorAt ) { 10480 this._adjustOffsetFromHelper( o.cursorAt ); 10481 } 10482 10483 //Set a containment if given in the options 10484 this._setContainment(); 10485 10486 //Trigger event + callbacks 10487 if ( this._trigger( "start", event ) === false ) { 10488 this._clear(); 10489 return false; 10490 } 10491 10492 //Recache the helper size 10493 this._cacheHelperProportions(); 10494 10495 //Prepare the droppable offsets 10496 if ( $.ui.ddmanager && !o.dropBehaviour ) { 10497 $.ui.ddmanager.prepareOffsets( this, event ); 10498 } 10499 10500 // Execute the drag once - this causes the helper not to be visible before getting its 10501 // correct position 10502 this._mouseDrag( event, true ); 10503 10504 // If the ddmanager is used for droppables, inform the manager that dragging has started 10505 // (see #5003) 10506 if ( $.ui.ddmanager ) { 10507 $.ui.ddmanager.dragStart( this, event ); 10508 } 10509 10510 return true; 10511 }, 10512 10513 _refreshOffsets: function( event ) { 10514 this.offset = { 10515 top: this.positionAbs.top - this.margins.top, 10516 left: this.positionAbs.left - this.margins.left, 10517 scroll: false, 10518 parent: this._getParentOffset(), 10519 relative: this._getRelativeOffset() 10520 }; 10521 10522 this.offset.click = { 10523 left: event.pageX - this.offset.left, 10524 top: event.pageY - this.offset.top 10525 }; 10526 }, 10527 10528 _mouseDrag: function( event, noPropagation ) { 10529 10530 // reset any necessary cached properties (see #5009) 10531 if ( this.hasFixedAncestor ) { 10532 this.offset.parent = this._getParentOffset(); 10533 } 10534 10535 //Compute the helpers position 10536 this.position = this._generatePosition( event, true ); 10537 this.positionAbs = this._convertPositionTo( "absolute" ); 10538 10539 //Call plugins and callbacks and use the resulting position if something is returned 10540 if ( !noPropagation ) { 10541 var ui = this._uiHash(); 10542 if ( this._trigger( "drag", event, ui ) === false ) { 10543 this._mouseUp( new $.Event( "mouseup", event ) ); 10544 return false; 10545 } 10546 this.position = ui.position; 10547 } 10548 10549 this.helper[ 0 ].style.left = this.position.left + "px"; 10550 this.helper[ 0 ].style.top = this.position.top + "px"; 10551 10552 if ( $.ui.ddmanager ) { 10553 $.ui.ddmanager.drag( this, event ); 10554 } 10555 10556 return false; 10557 }, 10558 10559 _mouseStop: function( event ) { 10560 10561 //If we are using droppables, inform the manager about the drop 10562 var that = this, 10563 dropped = false; 10564 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 10565 dropped = $.ui.ddmanager.drop( this, event ); 10566 } 10567 10568 //if a drop comes from outside (a sortable) 10569 if ( this.dropped ) { 10570 dropped = this.dropped; 10571 this.dropped = false; 10572 } 10573 10574 if ( ( this.options.revert === "invalid" && !dropped ) || 10575 ( this.options.revert === "valid" && dropped ) || 10576 this.options.revert === true || ( typeof this.options.revert === "function" && 10577 this.options.revert.call( this.element, dropped ) ) 10578 ) { 10579 $( this.helper ).animate( 10580 this.originalPosition, 10581 parseInt( this.options.revertDuration, 10 ), 10582 function() { 10583 if ( that._trigger( "stop", event ) !== false ) { 10584 that._clear(); 10585 } 10586 } 10587 ); 10588 } else { 10589 if ( this._trigger( "stop", event ) !== false ) { 10590 this._clear(); 10591 } 10592 } 10593 10594 return false; 10595 }, 10596 10597 _mouseUp: function( event ) { 10598 this._unblockFrames(); 10599 10600 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 10601 // (see #5003) 10602 if ( $.ui.ddmanager ) { 10603 $.ui.ddmanager.dragStop( this, event ); 10604 } 10605 10606 // Only need to focus if the event occurred on the draggable itself, see #10527 10607 if ( this.handleElement.is( event.target ) ) { 10608 10609 // The interaction is over; whether or not the click resulted in a drag, 10610 // focus the element 10611 this.element.trigger( "focus" ); 10612 } 10613 10614 return $.ui.mouse.prototype._mouseUp.call( this, event ); 10615 }, 10616 10617 cancel: function() { 10618 10619 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 10620 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 10621 } else { 10622 this._clear(); 10623 } 10624 10625 return this; 10626 10627 }, 10628 10629 _getHandle: function( event ) { 10630 return this.options.handle ? 10631 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 10632 true; 10633 }, 10634 10635 _setHandleClassName: function() { 10636 this.handleElement = this.options.handle ? 10637 this.element.find( this.options.handle ) : this.element; 10638 this._addClass( this.handleElement, "ui-draggable-handle" ); 10639 }, 10640 10641 _removeHandleClassName: function() { 10642 this._removeClass( this.handleElement, "ui-draggable-handle" ); 10643 }, 10644 10645 _createHelper: function( event ) { 10646 10647 var o = this.options, 10648 helperIsFunction = typeof o.helper === "function", 10649 helper = helperIsFunction ? 10650 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 10651 ( o.helper === "clone" ? 10652 this.element.clone().removeAttr( "id" ) : 10653 this.element ); 10654 10655 if ( !helper.parents( "body" ).length ) { 10656 helper.appendTo( ( o.appendTo === "parent" ? 10657 this.element[ 0 ].parentNode : 10658 o.appendTo ) ); 10659 } 10660 10661 // https://bugs.jqueryui.com/ticket/9446 10662 // a helper function can return the original element 10663 // which wouldn't have been set to relative in _create 10664 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 10665 this._setPositionRelative(); 10666 } 10667 10668 if ( helper[ 0 ] !== this.element[ 0 ] && 10669 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 10670 helper.css( "position", "absolute" ); 10671 } 10672 10673 return helper; 10674 10675 }, 10676 10677 _setPositionRelative: function() { 10678 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 10679 this.element[ 0 ].style.position = "relative"; 10680 } 10681 }, 10682 10683 _adjustOffsetFromHelper: function( obj ) { 10684 if ( typeof obj === "string" ) { 10685 obj = obj.split( " " ); 10686 } 10687 if ( Array.isArray( obj ) ) { 10688 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 10689 } 10690 if ( "left" in obj ) { 10691 this.offset.click.left = obj.left + this.margins.left; 10692 } 10693 if ( "right" in obj ) { 10694 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 10695 } 10696 if ( "top" in obj ) { 10697 this.offset.click.top = obj.top + this.margins.top; 10698 } 10699 if ( "bottom" in obj ) { 10700 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 10701 } 10702 }, 10703 10704 _isRootNode: function( element ) { 10705 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 10706 }, 10707 10708 _getParentOffset: function() { 10709 10710 //Get the offsetParent and cache its position 10711 var po = this.offsetParent.offset(), 10712 document = this.document[ 0 ]; 10713 10714 // This is a special case where we need to modify a offset calculated on start, since the 10715 // following happened: 10716 // 1. The position of the helper is absolute, so it's position is calculated based on the 10717 // next positioned parent 10718 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 10719 // the document, which means that the scroll is included in the initial calculation of the 10720 // offset of the parent, and never recalculated upon drag 10721 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 10722 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 10723 po.left += this.scrollParent.scrollLeft(); 10724 po.top += this.scrollParent.scrollTop(); 10725 } 10726 10727 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 10728 po = { top: 0, left: 0 }; 10729 } 10730 10731 return { 10732 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 10733 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 10734 }; 10735 10736 }, 10737 10738 _getRelativeOffset: function() { 10739 if ( this.cssPosition !== "relative" ) { 10740 return { top: 0, left: 0 }; 10741 } 10742 10743 var p = this.element.position(), 10744 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 10745 10746 return { 10747 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 10748 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 10749 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 10750 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 10751 }; 10752 10753 }, 10754 10755 _cacheMargins: function() { 10756 this.margins = { 10757 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 10758 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 10759 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 10760 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 10761 }; 10762 }, 10763 10764 _cacheHelperProportions: function() { 10765 this.helperProportions = { 10766 width: this.helper.outerWidth(), 10767 height: this.helper.outerHeight() 10768 }; 10769 }, 10770 10771 _setContainment: function() { 10772 10773 var isUserScrollable, c, ce, 10774 o = this.options, 10775 document = this.document[ 0 ]; 10776 10777 this.relativeContainer = null; 10778 10779 if ( !o.containment ) { 10780 this.containment = null; 10781 return; 10782 } 10783 10784 if ( o.containment === "window" ) { 10785 this.containment = [ 10786 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 10787 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 10788 $( window ).scrollLeft() + $( window ).width() - 10789 this.helperProportions.width - this.margins.left, 10790 $( window ).scrollTop() + 10791 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 10792 this.helperProportions.height - this.margins.top 10793 ]; 10794 return; 10795 } 10796 10797 if ( o.containment === "document" ) { 10798 this.containment = [ 10799 0, 10800 0, 10801 $( document ).width() - this.helperProportions.width - this.margins.left, 10802 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 10803 this.helperProportions.height - this.margins.top 10804 ]; 10805 return; 10806 } 10807 10808 if ( o.containment.constructor === Array ) { 10809 this.containment = o.containment; 10810 return; 10811 } 10812 10813 if ( o.containment === "parent" ) { 10814 o.containment = this.helper[ 0 ].parentNode; 10815 } 10816 10817 c = $( o.containment ); 10818 ce = c[ 0 ]; 10819 10820 if ( !ce ) { 10821 return; 10822 } 10823 10824 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 10825 10826 this.containment = [ 10827 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 10828 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 10829 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 10830 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 10831 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 10832 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 10833 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 10834 this.helperProportions.width - 10835 this.margins.left - 10836 this.margins.right, 10837 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 10838 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 10839 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 10840 this.helperProportions.height - 10841 this.margins.top - 10842 this.margins.bottom 10843 ]; 10844 this.relativeContainer = c; 10845 }, 10846 10847 _convertPositionTo: function( d, pos ) { 10848 10849 if ( !pos ) { 10850 pos = this.position; 10851 } 10852 10853 var mod = d === "absolute" ? 1 : -1, 10854 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 10855 10856 return { 10857 top: ( 10858 10859 // The absolute mouse position 10860 pos.top + 10861 10862 // Only for relative positioned nodes: Relative offset from element to offset parent 10863 this.offset.relative.top * mod + 10864 10865 // The offsetParent's offset without borders (offset + border) 10866 this.offset.parent.top * mod - 10867 ( ( this.cssPosition === "fixed" ? 10868 -this.offset.scroll.top : 10869 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 10870 ), 10871 left: ( 10872 10873 // The absolute mouse position 10874 pos.left + 10875 10876 // Only for relative positioned nodes: Relative offset from element to offset parent 10877 this.offset.relative.left * mod + 10878 10879 // The offsetParent's offset without borders (offset + border) 10880 this.offset.parent.left * mod - 10881 ( ( this.cssPosition === "fixed" ? 10882 -this.offset.scroll.left : 10883 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 10884 ) 10885 }; 10886 10887 }, 10888 10889 _generatePosition: function( event, constrainPosition ) { 10890 10891 var containment, co, top, left, 10892 o = this.options, 10893 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 10894 pageX = event.pageX, 10895 pageY = event.pageY; 10896 10897 // Cache the scroll 10898 if ( !scrollIsRootNode || !this.offset.scroll ) { 10899 this.offset.scroll = { 10900 top: this.scrollParent.scrollTop(), 10901 left: this.scrollParent.scrollLeft() 10902 }; 10903 } 10904 10905 /* 10906 * - Position constraining - 10907 * Constrain the position to a mix of grid, containment. 10908 */ 10909 10910 // If we are not dragging yet, we won't check for options 10911 if ( constrainPosition ) { 10912 if ( this.containment ) { 10913 if ( this.relativeContainer ) { 10914 co = this.relativeContainer.offset(); 10915 containment = [ 10916 this.containment[ 0 ] + co.left, 10917 this.containment[ 1 ] + co.top, 10918 this.containment[ 2 ] + co.left, 10919 this.containment[ 3 ] + co.top 10920 ]; 10921 } else { 10922 containment = this.containment; 10923 } 10924 10925 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 10926 pageX = containment[ 0 ] + this.offset.click.left; 10927 } 10928 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 10929 pageY = containment[ 1 ] + this.offset.click.top; 10930 } 10931 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 10932 pageX = containment[ 2 ] + this.offset.click.left; 10933 } 10934 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 10935 pageY = containment[ 3 ] + this.offset.click.top; 10936 } 10937 } 10938 10939 if ( o.grid ) { 10940 10941 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 10942 // argument errors in IE (see ticket #6950) 10943 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 10944 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 10945 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 10946 top - this.offset.click.top > containment[ 3 ] ) ? 10947 top : 10948 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 10949 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 10950 10951 left = o.grid[ 0 ] ? this.originalPageX + 10952 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 10953 this.originalPageX; 10954 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 10955 left - this.offset.click.left > containment[ 2 ] ) ? 10956 left : 10957 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 10958 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 10959 } 10960 10961 if ( o.axis === "y" ) { 10962 pageX = this.originalPageX; 10963 } 10964 10965 if ( o.axis === "x" ) { 10966 pageY = this.originalPageY; 10967 } 10968 } 10969 10970 return { 10971 top: ( 10972 10973 // The absolute mouse position 10974 pageY - 10975 10976 // Click offset (relative to the element) 10977 this.offset.click.top - 10978 10979 // Only for relative positioned nodes: Relative offset from element to offset parent 10980 this.offset.relative.top - 10981 10982 // The offsetParent's offset without borders (offset + border) 10983 this.offset.parent.top + 10984 ( this.cssPosition === "fixed" ? 10985 -this.offset.scroll.top : 10986 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 10987 ), 10988 left: ( 10989 10990 // The absolute mouse position 10991 pageX - 10992 10993 // Click offset (relative to the element) 10994 this.offset.click.left - 10995 10996 // Only for relative positioned nodes: Relative offset from element to offset parent 10997 this.offset.relative.left - 10998 10999 // The offsetParent's offset without borders (offset + border) 11000 this.offset.parent.left + 11001 ( this.cssPosition === "fixed" ? 11002 -this.offset.scroll.left : 11003 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 11004 ) 11005 }; 11006 11007 }, 11008 11009 _clear: function() { 11010 this._removeClass( this.helper, "ui-draggable-dragging" ); 11011 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 11012 this.helper.remove(); 11013 } 11014 this.helper = null; 11015 this.cancelHelperRemoval = false; 11016 if ( this.destroyOnClear ) { 11017 this.destroy(); 11018 } 11019 }, 11020 11021 // From now on bulk stuff - mainly helpers 11022 11023 _trigger: function( type, event, ui ) { 11024 ui = ui || this._uiHash(); 11025 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 11026 11027 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 11028 if ( /^(drag|start|stop)/.test( type ) ) { 11029 this.positionAbs = this._convertPositionTo( "absolute" ); 11030 ui.offset = this.positionAbs; 11031 } 11032 return $.Widget.prototype._trigger.call( this, type, event, ui ); 11033 }, 11034 11035 plugins: {}, 11036 11037 _uiHash: function() { 11038 return { 11039 helper: this.helper, 11040 position: this.position, 11041 originalPosition: this.originalPosition, 11042 offset: this.positionAbs 11043 }; 11044 } 11045 11046} ); 11047 11048$.ui.plugin.add( "draggable", "connectToSortable", { 11049 start: function( event, ui, draggable ) { 11050 var uiSortable = $.extend( {}, ui, { 11051 item: draggable.element 11052 } ); 11053 11054 draggable.sortables = []; 11055 $( draggable.options.connectToSortable ).each( function() { 11056 var sortable = $( this ).sortable( "instance" ); 11057 11058 if ( sortable && !sortable.options.disabled ) { 11059 draggable.sortables.push( sortable ); 11060 11061 // RefreshPositions is called at drag start to refresh the containerCache 11062 // which is used in drag. This ensures it's initialized and synchronized 11063 // with any changes that might have happened on the page since initialization. 11064 sortable.refreshPositions(); 11065 sortable._trigger( "activate", event, uiSortable ); 11066 } 11067 } ); 11068 }, 11069 stop: function( event, ui, draggable ) { 11070 var uiSortable = $.extend( {}, ui, { 11071 item: draggable.element 11072 } ); 11073 11074 draggable.cancelHelperRemoval = false; 11075 11076 $.each( draggable.sortables, function() { 11077 var sortable = this; 11078 11079 if ( sortable.isOver ) { 11080 sortable.isOver = 0; 11081 11082 // Allow this sortable to handle removing the helper 11083 draggable.cancelHelperRemoval = true; 11084 sortable.cancelHelperRemoval = false; 11085 11086 // Use _storedCSS To restore properties in the sortable, 11087 // as this also handles revert (#9675) since the draggable 11088 // may have modified them in unexpected ways (#8809) 11089 sortable._storedCSS = { 11090 position: sortable.placeholder.css( "position" ), 11091 top: sortable.placeholder.css( "top" ), 11092 left: sortable.placeholder.css( "left" ) 11093 }; 11094 11095 sortable._mouseStop( event ); 11096 11097 // Once drag has ended, the sortable should return to using 11098 // its original helper, not the shared helper from draggable 11099 sortable.options.helper = sortable.options._helper; 11100 } else { 11101 11102 // Prevent this Sortable from removing the helper. 11103 // However, don't set the draggable to remove the helper 11104 // either as another connected Sortable may yet handle the removal. 11105 sortable.cancelHelperRemoval = true; 11106 11107 sortable._trigger( "deactivate", event, uiSortable ); 11108 } 11109 } ); 11110 }, 11111 drag: function( event, ui, draggable ) { 11112 $.each( draggable.sortables, function() { 11113 var innermostIntersecting = false, 11114 sortable = this; 11115 11116 // Copy over variables that sortable's _intersectsWith uses 11117 sortable.positionAbs = draggable.positionAbs; 11118 sortable.helperProportions = draggable.helperProportions; 11119 sortable.offset.click = draggable.offset.click; 11120 11121 if ( sortable._intersectsWith( sortable.containerCache ) ) { 11122 innermostIntersecting = true; 11123 11124 $.each( draggable.sortables, function() { 11125 11126 // Copy over variables that sortable's _intersectsWith uses 11127 this.positionAbs = draggable.positionAbs; 11128 this.helperProportions = draggable.helperProportions; 11129 this.offset.click = draggable.offset.click; 11130 11131 if ( this !== sortable && 11132 this._intersectsWith( this.containerCache ) && 11133 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 11134 innermostIntersecting = false; 11135 } 11136 11137 return innermostIntersecting; 11138 } ); 11139 } 11140 11141 if ( innermostIntersecting ) { 11142 11143 // If it intersects, we use a little isOver variable and set it once, 11144 // so that the move-in stuff gets fired only once. 11145 if ( !sortable.isOver ) { 11146 sortable.isOver = 1; 11147 11148 // Store draggable's parent in case we need to reappend to it later. 11149 draggable._parent = ui.helper.parent(); 11150 11151 sortable.currentItem = ui.helper 11152 .appendTo( sortable.element ) 11153 .data( "ui-sortable-item", true ); 11154 11155 // Store helper option to later restore it 11156 sortable.options._helper = sortable.options.helper; 11157 11158 sortable.options.helper = function() { 11159 return ui.helper[ 0 ]; 11160 }; 11161 11162 // Fire the start events of the sortable with our passed browser event, 11163 // and our own helper (so it doesn't create a new one) 11164 event.target = sortable.currentItem[ 0 ]; 11165 sortable._mouseCapture( event, true ); 11166 sortable._mouseStart( event, true, true ); 11167 11168 // Because the browser event is way off the new appended portlet, 11169 // modify necessary variables to reflect the changes 11170 sortable.offset.click.top = draggable.offset.click.top; 11171 sortable.offset.click.left = draggable.offset.click.left; 11172 sortable.offset.parent.left -= draggable.offset.parent.left - 11173 sortable.offset.parent.left; 11174 sortable.offset.parent.top -= draggable.offset.parent.top - 11175 sortable.offset.parent.top; 11176 11177 draggable._trigger( "toSortable", event ); 11178 11179 // Inform draggable that the helper is in a valid drop zone, 11180 // used solely in the revert option to handle "valid/invalid". 11181 draggable.dropped = sortable.element; 11182 11183 // Need to refreshPositions of all sortables in the case that 11184 // adding to one sortable changes the location of the other sortables (#9675) 11185 $.each( draggable.sortables, function() { 11186 this.refreshPositions(); 11187 } ); 11188 11189 // Hack so receive/update callbacks work (mostly) 11190 draggable.currentItem = draggable.element; 11191 sortable.fromOutside = draggable; 11192 } 11193 11194 if ( sortable.currentItem ) { 11195 sortable._mouseDrag( event ); 11196 11197 // Copy the sortable's position because the draggable's can potentially reflect 11198 // a relative position, while sortable is always absolute, which the dragged 11199 // element has now become. (#8809) 11200 ui.position = sortable.position; 11201 } 11202 } else { 11203 11204 // If it doesn't intersect with the sortable, and it intersected before, 11205 // we fake the drag stop of the sortable, but make sure it doesn't remove 11206 // the helper by using cancelHelperRemoval. 11207 if ( sortable.isOver ) { 11208 11209 sortable.isOver = 0; 11210 sortable.cancelHelperRemoval = true; 11211 11212 // Calling sortable's mouseStop would trigger a revert, 11213 // so revert must be temporarily false until after mouseStop is called. 11214 sortable.options._revert = sortable.options.revert; 11215 sortable.options.revert = false; 11216 11217 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 11218 sortable._mouseStop( event, true ); 11219 11220 // Restore sortable behaviors that were modfied 11221 // when the draggable entered the sortable area (#9481) 11222 sortable.options.revert = sortable.options._revert; 11223 sortable.options.helper = sortable.options._helper; 11224 11225 if ( sortable.placeholder ) { 11226 sortable.placeholder.remove(); 11227 } 11228 11229 // Restore and recalculate the draggable's offset considering the sortable 11230 // may have modified them in unexpected ways. (#8809, #10669) 11231 ui.helper.appendTo( draggable._parent ); 11232 draggable._refreshOffsets( event ); 11233 ui.position = draggable._generatePosition( event, true ); 11234 11235 draggable._trigger( "fromSortable", event ); 11236 11237 // Inform draggable that the helper is no longer in a valid drop zone 11238 draggable.dropped = false; 11239 11240 // Need to refreshPositions of all sortables just in case removing 11241 // from one sortable changes the location of other sortables (#9675) 11242 $.each( draggable.sortables, function() { 11243 this.refreshPositions(); 11244 } ); 11245 } 11246 } 11247 } ); 11248 } 11249} ); 11250 11251$.ui.plugin.add( "draggable", "cursor", { 11252 start: function( event, ui, instance ) { 11253 var t = $( "body" ), 11254 o = instance.options; 11255 11256 if ( t.css( "cursor" ) ) { 11257 o._cursor = t.css( "cursor" ); 11258 } 11259 t.css( "cursor", o.cursor ); 11260 }, 11261 stop: function( event, ui, instance ) { 11262 var o = instance.options; 11263 if ( o._cursor ) { 11264 $( "body" ).css( "cursor", o._cursor ); 11265 } 11266 } 11267} ); 11268 11269$.ui.plugin.add( "draggable", "opacity", { 11270 start: function( event, ui, instance ) { 11271 var t = $( ui.helper ), 11272 o = instance.options; 11273 if ( t.css( "opacity" ) ) { 11274 o._opacity = t.css( "opacity" ); 11275 } 11276 t.css( "opacity", o.opacity ); 11277 }, 11278 stop: function( event, ui, instance ) { 11279 var o = instance.options; 11280 if ( o._opacity ) { 11281 $( ui.helper ).css( "opacity", o._opacity ); 11282 } 11283 } 11284} ); 11285 11286$.ui.plugin.add( "draggable", "scroll", { 11287 start: function( event, ui, i ) { 11288 if ( !i.scrollParentNotHidden ) { 11289 i.scrollParentNotHidden = i.helper.scrollParent( false ); 11290 } 11291 11292 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 11293 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 11294 i.overflowOffset = i.scrollParentNotHidden.offset(); 11295 } 11296 }, 11297 drag: function( event, ui, i ) { 11298 11299 var o = i.options, 11300 scrolled = false, 11301 scrollParent = i.scrollParentNotHidden[ 0 ], 11302 document = i.document[ 0 ]; 11303 11304 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 11305 if ( !o.axis || o.axis !== "x" ) { 11306 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 11307 o.scrollSensitivity ) { 11308 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 11309 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 11310 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 11311 } 11312 } 11313 11314 if ( !o.axis || o.axis !== "y" ) { 11315 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 11316 o.scrollSensitivity ) { 11317 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 11318 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 11319 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 11320 } 11321 } 11322 11323 } else { 11324 11325 if ( !o.axis || o.axis !== "x" ) { 11326 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 11327 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 11328 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 11329 o.scrollSensitivity ) { 11330 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 11331 } 11332 } 11333 11334 if ( !o.axis || o.axis !== "y" ) { 11335 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 11336 scrolled = $( document ).scrollLeft( 11337 $( document ).scrollLeft() - o.scrollSpeed 11338 ); 11339 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 11340 o.scrollSensitivity ) { 11341 scrolled = $( document ).scrollLeft( 11342 $( document ).scrollLeft() + o.scrollSpeed 11343 ); 11344 } 11345 } 11346 11347 } 11348 11349 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 11350 $.ui.ddmanager.prepareOffsets( i, event ); 11351 } 11352 11353 } 11354} ); 11355 11356$.ui.plugin.add( "draggable", "snap", { 11357 start: function( event, ui, i ) { 11358 11359 var o = i.options; 11360 11361 i.snapElements = []; 11362 11363 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 11364 .each( function() { 11365 var $t = $( this ), 11366 $o = $t.offset(); 11367 if ( this !== i.element[ 0 ] ) { 11368 i.snapElements.push( { 11369 item: this, 11370 width: $t.outerWidth(), height: $t.outerHeight(), 11371 top: $o.top, left: $o.left 11372 } ); 11373 } 11374 } ); 11375 11376 }, 11377 drag: function( event, ui, inst ) { 11378 11379 var ts, bs, ls, rs, l, r, t, b, i, first, 11380 o = inst.options, 11381 d = o.snapTolerance, 11382 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 11383 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 11384 11385 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 11386 11387 l = inst.snapElements[ i ].left - inst.margins.left; 11388 r = l + inst.snapElements[ i ].width; 11389 t = inst.snapElements[ i ].top - inst.margins.top; 11390 b = t + inst.snapElements[ i ].height; 11391 11392 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 11393 !$.contains( inst.snapElements[ i ].item.ownerDocument, 11394 inst.snapElements[ i ].item ) ) { 11395 if ( inst.snapElements[ i ].snapping ) { 11396 if ( inst.options.snap.release ) { 11397 inst.options.snap.release.call( 11398 inst.element, 11399 event, 11400 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 11401 ); 11402 } 11403 } 11404 inst.snapElements[ i ].snapping = false; 11405 continue; 11406 } 11407 11408 if ( o.snapMode !== "inner" ) { 11409 ts = Math.abs( t - y2 ) <= d; 11410 bs = Math.abs( b - y1 ) <= d; 11411 ls = Math.abs( l - x2 ) <= d; 11412 rs = Math.abs( r - x1 ) <= d; 11413 if ( ts ) { 11414 ui.position.top = inst._convertPositionTo( "relative", { 11415 top: t - inst.helperProportions.height, 11416 left: 0 11417 } ).top; 11418 } 11419 if ( bs ) { 11420 ui.position.top = inst._convertPositionTo( "relative", { 11421 top: b, 11422 left: 0 11423 } ).top; 11424 } 11425 if ( ls ) { 11426 ui.position.left = inst._convertPositionTo( "relative", { 11427 top: 0, 11428 left: l - inst.helperProportions.width 11429 } ).left; 11430 } 11431 if ( rs ) { 11432 ui.position.left = inst._convertPositionTo( "relative", { 11433 top: 0, 11434 left: r 11435 } ).left; 11436 } 11437 } 11438 11439 first = ( ts || bs || ls || rs ); 11440 11441 if ( o.snapMode !== "outer" ) { 11442 ts = Math.abs( t - y1 ) <= d; 11443 bs = Math.abs( b - y2 ) <= d; 11444 ls = Math.abs( l - x1 ) <= d; 11445 rs = Math.abs( r - x2 ) <= d; 11446 if ( ts ) { 11447 ui.position.top = inst._convertPositionTo( "relative", { 11448 top: t, 11449 left: 0 11450 } ).top; 11451 } 11452 if ( bs ) { 11453 ui.position.top = inst._convertPositionTo( "relative", { 11454 top: b - inst.helperProportions.height, 11455 left: 0 11456 } ).top; 11457 } 11458 if ( ls ) { 11459 ui.position.left = inst._convertPositionTo( "relative", { 11460 top: 0, 11461 left: l 11462 } ).left; 11463 } 11464 if ( rs ) { 11465 ui.position.left = inst._convertPositionTo( "relative", { 11466 top: 0, 11467 left: r - inst.helperProportions.width 11468 } ).left; 11469 } 11470 } 11471 11472 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 11473 if ( inst.options.snap.snap ) { 11474 inst.options.snap.snap.call( 11475 inst.element, 11476 event, 11477 $.extend( inst._uiHash(), { 11478 snapItem: inst.snapElements[ i ].item 11479 } ) ); 11480 } 11481 } 11482 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 11483 11484 } 11485 11486 } 11487} ); 11488 11489$.ui.plugin.add( "draggable", "stack", { 11490 start: function( event, ui, instance ) { 11491 var min, 11492 o = instance.options, 11493 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 11494 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 11495 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 11496 } ); 11497 11498 if ( !group.length ) { 11499 return; 11500 } 11501 11502 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 11503 $( group ).each( function( i ) { 11504 $( this ).css( "zIndex", min + i ); 11505 } ); 11506 this.css( "zIndex", ( min + group.length ) ); 11507 } 11508} ); 11509 11510$.ui.plugin.add( "draggable", "zIndex", { 11511 start: function( event, ui, instance ) { 11512 var t = $( ui.helper ), 11513 o = instance.options; 11514 11515 if ( t.css( "zIndex" ) ) { 11516 o._zIndex = t.css( "zIndex" ); 11517 } 11518 t.css( "zIndex", o.zIndex ); 11519 }, 11520 stop: function( event, ui, instance ) { 11521 var o = instance.options; 11522 11523 if ( o._zIndex ) { 11524 $( ui.helper ).css( "zIndex", o._zIndex ); 11525 } 11526 } 11527} ); 11528
11529return $.ui.draggable; 11530 11531} ); 11532 11533/*! 11534 * jQuery UI Resizable @VERSION 11535 * https://jqueryui.com 11536 * 11537 * Copyright OpenJS Foundation and other contributors 11538 * Released under the MIT license. 11539 * https://jquery.org/license 11540 */ 11541 11542//>>label: Resizable 11543//>>group: Interactions 11544//>>description: Enables resize functionality for any element. 11545//>>docs: https://api.jqueryui.com/resizable/ 11546//>>demos: https://jqueryui.com/resizable/ 11547//>>css.structure: ../../themes/base/core.css 11548//>>css.structure: ../../themes/base/resizable.css 11549//>>css.theme: ../../themes/base/theme.css 11550 11551( function( factory ) { 11552 "use strict"; 11553 11554 if ( typeof define === "function" && define.amd ) { 11555 11556 // AMD. Register as an anonymous module. 11557 define( 'ui/widgets/resizable.js',[ 11558 "jquery", 11559 "./mouse", 11560 "../disable-selection", 11561 "../plugin", 11562 "../version", 11563 "../widget" 11564 ], factory ); 11565 } else { 11566 11567 // Browser globals 11568 factory( jQuery ); 11569 } 11570} )( function( $ ) { 11571"use strict"; 11572 11573$.widget( "ui.resizable", $.ui.mouse, { 11574 version: "@VERSION
vendor: 31,097 bytes, lines 11574-12804
11574", 11575 widgetEventPrefix: "resize", 11576 options: { 11577 alsoResize: false, 11578 animate: false, 11579 animateDuration: "slow", 11580 animateEasing: "swing", 11581 aspectRatio: false, 11582 autoHide: false, 11583 classes: { 11584 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 11585 }, 11586 containment: false, 11587 ghost: false, 11588 grid: false, 11589 handles: "e,s,se", 11590 helper: false, 11591 maxHeight: null, 11592 maxWidth: null, 11593 minHeight: 10, 11594 minWidth: 10, 11595 11596 // See #7960 11597 zIndex: 90, 11598 11599 // Callbacks 11600 resize: null, 11601 start: null, 11602 stop: null 11603 }, 11604 11605 _num: function( value ) { 11606 return parseFloat( value ) || 0; 11607 }, 11608 11609 _isNumber: function( value ) { 11610 return !isNaN( parseFloat( value ) ); 11611 }, 11612 11613 _hasScroll: function( el, a ) { 11614 11615 var scroll, 11616 has = false, 11617 overflow = $( el ).css( "overflow" ); 11618 11619 if ( overflow === "hidden" ) { 11620 return false; 11621 } 11622 if ( overflow === "scroll" ) { 11623 return true; 11624 } 11625 11626 scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop"; 11627 11628 if ( el[ scroll ] > 0 ) { 11629 return true; 11630 } 11631 11632 // TODO: determine which cases actually cause this to happen 11633 // if the element doesn't have the scroll set, see if it's possible to 11634 // set the scroll 11635 try { 11636 el[ scroll ] = 1; 11637 has = ( el[ scroll ] > 0 ); 11638 el[ scroll ] = 0; 11639 } catch ( _e ) { 11640 11641 // `el` might be a string, then setting `scroll` will throw 11642 // an error in strict mode; ignore it. 11643 } 11644 return has; 11645 }, 11646 11647 _create: function() { 11648 11649 var margins, 11650 o = this.options, 11651 that = this; 11652 this._addClass( "ui-resizable" ); 11653 11654 $.extend( this, { 11655 _aspectRatio: !!( o.aspectRatio ), 11656 aspectRatio: o.aspectRatio, 11657 originalElement: this.element, 11658 _proportionallyResizeElements: [], 11659 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 11660 } ); 11661 11662 // Wrap the element if it cannot hold child nodes 11663 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 11664 11665 this.element.wrap( 11666 $( "<div class='ui-wrapper'></div>" ).css( { 11667 overflow: "hidden", 11668 position: this.element.css( "position" ), 11669 width: this.element.outerWidth(), 11670 height: this.element.outerHeight(), 11671 top: this.element.css( "top" ), 11672 left: this.element.css( "left" ) 11673 } ) 11674 ); 11675 11676 this.element = this.element.parent().data( 11677 "ui-resizable", this.element.resizable( "instance" ) 11678 ); 11679 11680 this.elementIsWrapper = true; 11681 11682 margins = { 11683 marginTop: this.originalElement.css( "marginTop" ), 11684 marginRight: this.originalElement.css( "marginRight" ), 11685 marginBottom: this.originalElement.css( "marginBottom" ), 11686 marginLeft: this.originalElement.css( "marginLeft" ) 11687 }; 11688 11689 this.element.css( margins ); 11690 11691 // Support: Safari 11692 // Prevent Safari textarea resize 11693 this.originalResizeStyle = this.originalElement.css( "resize" ); 11694 this.originalElement.css( "resize", "none" ); 11695 11696 this._proportionallyResizeElements.push( this.originalElement.css( { 11697 position: "static", 11698 zoom: 1, 11699 display: "block" 11700 } ) ); 11701 11702 this._proportionallyResize(); 11703 } 11704 11705 this._setupHandles(); 11706 11707 if ( o.autoHide ) { 11708 $( this.element ) 11709 .on( "mouseenter", function() { 11710 if ( o.disabled ) { 11711 return; 11712 } 11713 that._removeClass( "ui-resizable-autohide" ); 11714 that._handles.show(); 11715 } ) 11716 .on( "mouseleave", function() { 11717 if ( o.disabled ) { 11718 return; 11719 } 11720 if ( !that.resizing ) { 11721 that._addClass( "ui-resizable-autohide" ); 11722 that._handles.hide(); 11723 } 11724 } ); 11725 } 11726 11727 this._mouseInit(); 11728 }, 11729 11730 _destroy: function() { 11731 11732 this._mouseDestroy(); 11733 this._addedHandles.remove(); 11734 11735 var wrapper, 11736 _destroy = function( exp ) { 11737 $( exp ) 11738 .removeData( "resizable" ) 11739 .removeData( "ui-resizable" ) 11740 .off( ".resizable" ); 11741 }; 11742 11743 // TODO: Unwrap at same DOM position 11744 if ( this.elementIsWrapper ) { 11745 _destroy( this.element ); 11746 wrapper = this.element; 11747 this.originalElement.css( { 11748 position: wrapper.css( "position" ), 11749 width: wrapper.outerWidth(), 11750 height: wrapper.outerHeight(), 11751 top: wrapper.css( "top" ), 11752 left: wrapper.css( "left" ) 11753 } ).insertAfter( wrapper ); 11754 wrapper.remove(); 11755 } 11756 11757 this.originalElement.css( "resize", this.originalResizeStyle ); 11758 _destroy( this.originalElement ); 11759 11760 return this; 11761 }, 11762 11763 _setOption: function( key, value ) { 11764 this._super( key, value ); 11765 11766 switch ( key ) { 11767 case "handles": 11768 this._removeHandles(); 11769 this._setupHandles(); 11770 break; 11771 case "aspectRatio": 11772 this._aspectRatio = !!value; 11773 break; 11774 default: 11775 break; 11776 } 11777 }, 11778 11779 _setupHandles: function() { 11780 var o = this.options, handle, i, n, hname, axis, that = this; 11781 this.handles = o.handles || 11782 ( !$( ".ui-resizable-handle", this.element ).length ? 11783 "e,s,se" : { 11784 n: ".ui-resizable-n", 11785 e: ".ui-resizable-e", 11786 s: ".ui-resizable-s", 11787 w: ".ui-resizable-w", 11788 se: ".ui-resizable-se", 11789 sw: ".ui-resizable-sw", 11790 ne: ".ui-resizable-ne", 11791 nw: ".ui-resizable-nw" 11792 } ); 11793 11794 this._handles = $(); 11795 this._addedHandles = $(); 11796 if ( this.handles.constructor === String ) { 11797 11798 if ( this.handles === "all" ) { 11799 this.handles = "n,e,s,w,se,sw,ne,nw"; 11800 } 11801 11802 n = this.handles.split( "," ); 11803 this.handles = {}; 11804 11805 for ( i = 0; i < n.length; i++ ) { 11806 11807 handle = String.prototype.trim.call( n[ i ] ); 11808 hname = "ui-resizable-" + handle; 11809 axis = $( "<div>" ); 11810 this._addClass( axis, "ui-resizable-handle " + hname ); 11811 11812 axis.css( { zIndex: o.zIndex } ); 11813 11814 this.handles[ handle ] = ".ui-resizable-" + handle; 11815 if ( !this.element.children( this.handles[ handle ] ).length ) { 11816 this.element.append( axis ); 11817 this._addedHandles = this._addedHandles.add( axis ); 11818 } 11819 } 11820 11821 } 11822 11823 this._renderAxis = function( target ) { 11824 11825 var i, axis, padPos, padWrapper; 11826 11827 target = target || this.element; 11828 11829 for ( i in this.handles ) { 11830 11831 if ( this.handles[ i ].constructor === String ) { 11832 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 11833 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 11834 this.handles[ i ] = $( this.handles[ i ] ); 11835 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 11836 } 11837 11838 if ( this.elementIsWrapper && 11839 this.originalElement[ 0 ] 11840 .nodeName 11841 .match( /^(textarea|input|select|button)$/i ) ) { 11842 axis = $( this.handles[ i ], this.element ); 11843 11844 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 11845 axis.outerHeight() : 11846 axis.outerWidth(); 11847 11848 padPos = [ "padding", 11849 /ne|nw|n/.test( i ) ? "Top" : 11850 /se|sw|s/.test( i ) ? "Bottom" : 11851 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 11852 11853 target.css( padPos, padWrapper ); 11854 11855 this._proportionallyResize(); 11856 } 11857 11858 this._handles = this._handles.add( this.handles[ i ] ); 11859 } 11860 }; 11861 11862 // TODO: make renderAxis a prototype function 11863 this._renderAxis( this.element ); 11864 11865 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 11866 this._handles.disableSelection(); 11867 11868 this._handles.on( "mouseover", function() { 11869 if ( !that.resizing ) { 11870 if ( this.className ) { 11871 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 11872 } 11873 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 11874 } 11875 } ); 11876 11877 if ( o.autoHide ) { 11878 this._handles.hide(); 11879 this._addClass( "ui-resizable-autohide" ); 11880 } 11881 }, 11882 11883 _removeHandles: function() { 11884 this._addedHandles.remove(); 11885 }, 11886 11887 _mouseCapture: function( event ) { 11888 var i, handle, 11889 capture = false; 11890 11891 for ( i in this.handles ) { 11892 handle = $( this.handles[ i ] )[ 0 ]; 11893 if ( handle === event.target || $.contains( handle, event.target ) ) { 11894 capture = true; 11895 } 11896 } 11897 11898 return !this.options.disabled && capture; 11899 }, 11900 11901 _mouseStart: function( event ) { 11902 11903 var curleft, curtop, cursor, calculatedSize, 11904 o = this.options, 11905 el = this.element; 11906 11907 this.resizing = true; 11908 11909 this._renderProxy(); 11910 11911 curleft = this._num( this.helper.css( "left" ) ); 11912 curtop = this._num( this.helper.css( "top" ) ); 11913 11914 if ( o.containment ) { 11915 curleft += $( o.containment ).scrollLeft() || 0; 11916 curtop += $( o.containment ).scrollTop() || 0; 11917 } 11918 11919 this.offset = this.helper.offset(); 11920 this.position = { left: curleft, top: curtop }; 11921 11922 if ( !this._helper ) { 11923 calculatedSize = this._calculateAdjustedElementDimensions( el ); 11924 } 11925 11926 this.size = this._helper ? { 11927 width: this.helper.width(), 11928 height: this.helper.height() 11929 } : { 11930 width: calculatedSize.width, 11931 height: calculatedSize.height 11932 }; 11933 11934 this.originalSize = this._helper ? { 11935 width: el.outerWidth(), 11936 height: el.outerHeight() 11937 } : { 11938 width: calculatedSize.width, 11939 height: calculatedSize.height 11940 }; 11941 11942 this.sizeDiff = { 11943 width: el.outerWidth() - el.width(), 11944 height: el.outerHeight() - el.height() 11945 }; 11946 11947 this.originalPosition = { left: curleft, top: curtop }; 11948 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 11949 11950 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 11951 o.aspectRatio : 11952 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 11953 11954 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 11955 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 11956 11957 this._addClass( "ui-resizable-resizing" ); 11958 this._propagate( "start", event ); 11959 return true; 11960 }, 11961 11962 _mouseDrag: function( event ) { 11963 11964 var data, props, 11965 smp = this.originalMousePosition, 11966 a = this.axis, 11967 dx = ( event.pageX - smp.left ) || 0, 11968 dy = ( event.pageY - smp.top ) || 0, 11969 trigger = this._change[ a ]; 11970 11971 this._updatePrevProperties(); 11972 11973 if ( !trigger ) { 11974 return false; 11975 } 11976 11977 data = trigger.apply( this, [ event, dx, dy ] ); 11978 11979 this._updateVirtualBoundaries( event.shiftKey ); 11980 if ( this._aspectRatio || event.shiftKey ) { 11981 data = this._updateRatio( data, event ); 11982 } 11983 11984 data = this._respectSize( data, event ); 11985 11986 this._updateCache( data ); 11987 11988 this._propagate( "resize", event ); 11989 11990 props = this._applyChanges(); 11991 11992 if ( !this._helper && this._proportionallyResizeElements.length ) { 11993 this._proportionallyResize(); 11994 } 11995 11996 if ( !$.isEmptyObject( props ) ) { 11997 this._updatePrevProperties(); 11998 this._trigger( "resize", event, this.ui() ); 11999 this._applyChanges(); 12000 } 12001 12002 return false; 12003 }, 12004 12005 _mouseStop: function( event ) { 12006 12007 this.resizing = false; 12008 var pr, ista, soffseth, soffsetw, s, left, top, 12009 o = this.options, that = this; 12010 12011 if ( this._helper ) { 12012 12013 pr = this._proportionallyResizeElements; 12014 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 12015 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 12016 soffsetw = ista ? 0 : that.sizeDiff.width; 12017 12018 s = { 12019 width: ( that.helper.width() - soffsetw ), 12020 height: ( that.helper.height() - soffseth ) 12021 }; 12022 left = ( parseFloat( that.element.css( "left" ) ) + 12023 ( that.position.left - that.originalPosition.left ) ) || null; 12024 top = ( parseFloat( that.element.css( "top" ) ) + 12025 ( that.position.top - that.originalPosition.top ) ) || null; 12026 12027 if ( !o.animate ) { 12028 this.element.css( $.extend( s, { top: top, left: left } ) ); 12029 } 12030 12031 that.helper.height( that.size.height ); 12032 that.helper.width( that.size.width ); 12033 12034 if ( this._helper && !o.animate ) { 12035 this._proportionallyResize(); 12036 } 12037 } 12038 12039 $( "body" ).css( "cursor", "auto" ); 12040 12041 this._removeClass( "ui-resizable-resizing" ); 12042 12043 this._propagate( "stop", event ); 12044 12045 if ( this._helper ) { 12046 this.helper.remove(); 12047 } 12048 12049 return false; 12050 12051 }, 12052 12053 _updatePrevProperties: function() { 12054 this.prevPosition = { 12055 top: this.position.top, 12056 left: this.position.left 12057 }; 12058 this.prevSize = { 12059 width: this.size.width, 12060 height: this.size.height 12061 }; 12062 }, 12063 12064 _applyChanges: function() { 12065 var props = {}; 12066 12067 if ( this.position.top !== this.prevPosition.top ) { 12068 props.top = this.position.top + "px"; 12069 } 12070 if ( this.position.left !== this.prevPosition.left ) { 12071 props.left = this.position.left + "px"; 12072 } 12073 12074 this.helper.css( props ); 12075 12076 if ( this.size.width !== this.prevSize.width ) { 12077 props.width = this.size.width + "px"; 12078 this.helper.width( props.width ); 12079 } 12080 if ( this.size.height !== this.prevSize.height ) { 12081 props.height = this.size.height + "px"; 12082 this.helper.height( props.height ); 12083 } 12084 12085 return props; 12086 }, 12087 12088 _updateVirtualBoundaries: function( forceAspectRatio ) { 12089 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 12090 o = this.options; 12091 12092 b = { 12093 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 12094 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 12095 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 12096 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 12097 }; 12098 12099 if ( this._aspectRatio || forceAspectRatio ) { 12100 pMinWidth = b.minHeight * this.aspectRatio; 12101 pMinHeight = b.minWidth / this.aspectRatio; 12102 pMaxWidth = b.maxHeight * this.aspectRatio; 12103 pMaxHeight = b.maxWidth / this.aspectRatio; 12104 12105 if ( pMinWidth > b.minWidth ) { 12106 b.minWidth = pMinWidth; 12107 } 12108 if ( pMinHeight > b.minHeight ) { 12109 b.minHeight = pMinHeight; 12110 } 12111 if ( pMaxWidth < b.maxWidth ) { 12112 b.maxWidth = pMaxWidth; 12113 } 12114 if ( pMaxHeight < b.maxHeight ) { 12115 b.maxHeight = pMaxHeight; 12116 } 12117 } 12118 this._vBoundaries = b; 12119 }, 12120 12121 _updateCache: function( data ) { 12122 this.offset = this.helper.offset(); 12123 if ( this._isNumber( data.left ) ) { 12124 this.position.left = data.left; 12125 } 12126 if ( this._isNumber( data.top ) ) { 12127 this.position.top = data.top; 12128 } 12129 if ( this._isNumber( data.height ) ) { 12130 this.size.height = data.height; 12131 } 12132 if ( this._isNumber( data.width ) ) { 12133 this.size.width = data.width; 12134 } 12135 }, 12136 12137 _updateRatio: function( data ) { 12138 12139 var cpos = this.position, 12140 csize = this.size, 12141 a = this.axis; 12142 12143 if ( this._isNumber( data.height ) ) { 12144 data.width = ( data.height * this.aspectRatio ); 12145 } else if ( this._isNumber( data.width ) ) { 12146 data.height = ( data.width / this.aspectRatio ); 12147 } 12148 12149 if ( a === "sw" ) { 12150 data.left = cpos.left + ( csize.width - data.width ); 12151 data.top = null; 12152 } 12153 if ( a === "nw" ) { 12154 data.top = cpos.top + ( csize.height - data.height ); 12155 data.left = cpos.left + ( csize.width - data.width ); 12156 } 12157 12158 return data; 12159 }, 12160 12161 _respectSize: function( data ) { 12162 12163 var o = this._vBoundaries, 12164 a = this.axis, 12165 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 12166 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 12167 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 12168 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 12169 dw = this.originalPosition.left + this.originalSize.width, 12170 dh = this.originalPosition.top + this.originalSize.height, 12171 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 12172 if ( isminw ) { 12173 data.width = o.minWidth; 12174 } 12175 if ( isminh ) { 12176 data.height = o.minHeight; 12177 } 12178 if ( ismaxw ) { 12179 data.width = o.maxWidth; 12180 } 12181 if ( ismaxh ) { 12182 data.height = o.maxHeight; 12183 } 12184 12185 if ( isminw && cw ) { 12186 data.left = dw - o.minWidth; 12187 } 12188 if ( ismaxw && cw ) { 12189 data.left = dw - o.maxWidth; 12190 } 12191 if ( isminh && ch ) { 12192 data.top = dh - o.minHeight; 12193 } 12194 if ( ismaxh && ch ) { 12195 data.top = dh - o.maxHeight; 12196 } 12197 12198 // Fixing jump error on top/left - bug #2330 12199 if ( !data.width && !data.height && !data.left && data.top ) { 12200 data.top = null; 12201 } else if ( !data.width && !data.height && !data.top && data.left ) { 12202 data.left = null; 12203 } 12204 12205 return data; 12206 }, 12207 12208 _getPaddingPlusBorderDimensions: function( element ) { 12209 var i = 0, 12210 widths = [], 12211 borders = [ 12212 element.css( "borderTopWidth" ), 12213 element.css( "borderRightWidth" ), 12214 element.css( "borderBottomWidth" ), 12215 element.css( "borderLeftWidth" ) 12216 ], 12217 paddings = [ 12218 element.css( "paddingTop" ), 12219 element.css( "paddingRight" ), 12220 element.css( "paddingBottom" ), 12221 element.css( "paddingLeft" ) 12222 ]; 12223 12224 for ( ; i < 4; i++ ) { 12225 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 12226 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 12227 } 12228 12229 return { 12230 height: widths[ 0 ] + widths[ 2 ], 12231 width: widths[ 1 ] + widths[ 3 ] 12232 }; 12233 }, 12234 12235 _calculateAdjustedElementDimensions: function( element ) { 12236 var elWidth, elHeight, paddingBorder, 12237 ce = element.get( 0 ); 12238 12239 if ( element.css( "box-sizing" ) !== "content-box" || 12240 ( !this._hasScroll( ce ) && !this._hasScroll( ce, "left" ) ) ) { 12241 return { 12242 height: parseFloat( element.css( "height" ) ), 12243 width: parseFloat( element.css( "width" ) ) 12244 }; 12245 } 12246 12247 // Check if CSS inline styles are set and use those (usually from previous resizes) 12248 elWidth = parseFloat( ce.style.width ); 12249 elHeight = parseFloat( ce.style.height ); 12250 12251 paddingBorder = this._getPaddingPlusBorderDimensions( element ); 12252 elWidth = isNaN( elWidth ) ? 12253 this._getElementTheoreticalSize( element, paddingBorder, "width" ) : 12254 elWidth; 12255 elHeight = isNaN( elHeight ) ? 12256 this._getElementTheoreticalSize( element, paddingBorder, "height" ) : 12257 elHeight; 12258 12259 return { 12260 height: elHeight, 12261 width: elWidth 12262 }; 12263 }, 12264 12265 _getElementTheoreticalSize: function( element, extraSize, dimension ) { 12266 12267 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 12268 var size = Math.max( 0, Math.ceil( 12269 element.get( 0 )[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 12270 extraSize[ dimension ] - 12271 0.5 12272 12273 // If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size. 12274 // Use an explicit zero to avoid NaN. 12275 // See https://github.com/jquery/jquery/issues/3964 12276 ) ) || 0; 12277 12278 return size; 12279 }, 12280 12281 _proportionallyResize: function() { 12282 12283 if ( !this._proportionallyResizeElements.length ) { 12284 return; 12285 } 12286 12287 var prel, 12288 i = 0, 12289 element = this.helper || this.element; 12290 12291 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 12292 12293 prel = this._proportionallyResizeElements[ i ]; 12294 12295 // TODO: Seems like a bug to cache this.outerDimensions 12296 // considering that we are in a loop. 12297 if ( !this.outerDimensions ) { 12298 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 12299 } 12300 12301 prel.css( { 12302 height: ( element.height() - this.outerDimensions.height ) || 0, 12303 width: ( element.width() - this.outerDimensions.width ) || 0 12304 } ); 12305 12306 } 12307 12308 }, 12309 12310 _renderProxy: function() { 12311 12312 var el = this.element, o = this.options; 12313 this.elementOffset = el.offset(); 12314 12315 if ( this._helper ) { 12316 12317 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); 12318 12319 this._addClass( this.helper, this._helper ); 12320 this.helper.css( { 12321 width: this.element.outerWidth(), 12322 height: this.element.outerHeight(), 12323 position: "absolute", 12324 left: this.elementOffset.left + "px", 12325 top: this.elementOffset.top + "px", 12326 zIndex: ++o.zIndex //TODO: Don't modify option 12327 } ); 12328 12329 this.helper 12330 .appendTo( "body" ) 12331 .disableSelection(); 12332 12333 } else { 12334 this.helper = this.element; 12335 } 12336 12337 }, 12338 12339 _change: { 12340 e: function( event, dx ) { 12341 return { width: this.originalSize.width + dx }; 12342 }, 12343 w: function( event, dx ) { 12344 var cs = this.originalSize, sp = this.originalPosition; 12345 return { left: sp.left + dx, width: cs.width - dx }; 12346 }, 12347 n: function( event, dx, dy ) { 12348 var cs = this.originalSize, sp = this.originalPosition; 12349 return { top: sp.top + dy, height: cs.height - dy }; 12350 }, 12351 s: function( event, dx, dy ) { 12352 return { height: this.originalSize.height + dy }; 12353 }, 12354 se: function( event, dx, dy ) { 12355 return $.extend( this._change.s.apply( this, arguments ), 12356 this._change.e.apply( this, [ event, dx, dy ] ) ); 12357 }, 12358 sw: function( event, dx, dy ) { 12359 return $.extend( this._change.s.apply( this, arguments ), 12360 this._change.w.apply( this, [ event, dx, dy ] ) ); 12361 }, 12362 ne: function( event, dx, dy ) { 12363 return $.extend( this._change.n.apply( this, arguments ), 12364 this._change.e.apply( this, [ event, dx, dy ] ) ); 12365 }, 12366 nw: function( event, dx, dy ) { 12367 return $.extend( this._change.n.apply( this, arguments ), 12368 this._change.w.apply( this, [ event, dx, dy ] ) ); 12369 } 12370 }, 12371 12372 _propagate: function( n, event ) { 12373 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 12374 if ( n !== "resize" ) { 12375 this._trigger( n, event, this.ui() ); 12376 } 12377 }, 12378 12379 plugins: {}, 12380 12381 ui: function() { 12382 return { 12383 originalElement: this.originalElement, 12384 element: this.element, 12385 helper: this.helper, 12386 position: this.position, 12387 size: this.size, 12388 originalSize: this.originalSize, 12389 originalPosition: this.originalPosition 12390 }; 12391 } 12392 12393} ); 12394 12395/* 12396 * Resizable Extensions 12397 */ 12398 12399$.ui.plugin.add( "resizable", "animate", { 12400 12401 stop: function( event ) { 12402 var that = $( this ).resizable( "instance" ), 12403 o = that.options, 12404 pr = that._proportionallyResizeElements, 12405 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 12406 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 12407 soffsetw = ista ? 0 : that.sizeDiff.width, 12408 style = { 12409 width: ( that.size.width - soffsetw ), 12410 height: ( that.size.height - soffseth ) 12411 }, 12412 left = ( parseFloat( that.element.css( "left" ) ) + 12413 ( that.position.left - that.originalPosition.left ) ) || null, 12414 top = ( parseFloat( that.element.css( "top" ) ) + 12415 ( that.position.top - that.originalPosition.top ) ) || null; 12416 12417 that.element.animate( 12418 $.extend( style, top && left ? { top: top, left: left } : {} ), { 12419 duration: o.animateDuration, 12420 easing: o.animateEasing, 12421 step: function() { 12422 12423 var data = { 12424 width: parseFloat( that.element.css( "width" ) ), 12425 height: parseFloat( that.element.css( "height" ) ), 12426 top: parseFloat( that.element.css( "top" ) ), 12427 left: parseFloat( that.element.css( "left" ) ) 12428 }; 12429 12430 if ( pr && pr.length ) { 12431 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 12432 } 12433 12434 // Propagating resize, and updating values for each animation step 12435 that._updateCache( data ); 12436 that._propagate( "resize", event ); 12437 12438 } 12439 } 12440 ); 12441 } 12442 12443} ); 12444 12445$.ui.plugin.add( "resizable", "containment", { 12446 12447 start: function() { 12448 var element, p, co, ch, cw, width, height, 12449 that = $( this ).resizable( "instance" ), 12450 o = that.options, 12451 el = that.element, 12452 oc = o.containment, 12453 ce = ( oc instanceof $ ) ? 12454 oc.get( 0 ) : 12455 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 12456 12457 if ( !ce ) { 12458 return; 12459 } 12460 12461 that.containerElement = $( ce ); 12462 12463 if ( /document/.test( oc ) || oc === document ) { 12464 that.containerOffset = { 12465 left: 0, 12466 top: 0 12467 }; 12468 that.containerPosition = { 12469 left: 0, 12470 top: 0 12471 }; 12472 12473 that.parentData = { 12474 element: $( document ), 12475 left: 0, 12476 top: 0, 12477 width: $( document ).width(), 12478 height: $( document ).height() || document.body.parentNode.scrollHeight 12479 }; 12480 } else { 12481 element = $( ce ); 12482 p = []; 12483 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 12484 p[ i ] = that._num( element.css( "padding" + name ) ); 12485 } ); 12486 12487 that.containerOffset = element.offset(); 12488 that.containerPosition = element.position(); 12489 that.containerSize = { 12490 height: ( element.innerHeight() - p[ 3 ] ), 12491 width: ( element.innerWidth() - p[ 1 ] ) 12492 }; 12493 12494 co = that.containerOffset; 12495 ch = that.containerSize.height; 12496 cw = that.containerSize.width; 12497 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); 12498 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); 12499 12500 that.parentData = { 12501 element: ce, 12502 left: co.left, 12503 top: co.top, 12504 width: width, 12505 height: height 12506 }; 12507 } 12508 }, 12509 12510 resize: function( event ) { 12511 var woset, hoset, isParent, isOffsetRelative, 12512 that = $( this ).resizable( "instance" ), 12513 o = that.options, 12514 co = that.containerOffset, 12515 cp = that.position, 12516 pRatio = that._aspectRatio || event.shiftKey, 12517 cop = { 12518 top: 0, 12519 left: 0 12520 }, 12521 ce = that.containerElement, 12522 continueResize = true; 12523 12524 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 12525 cop = co; 12526 } 12527 12528 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 12529 that.size.width = that.size.width + 12530 ( that._helper ? 12531 ( that.position.left - co.left ) : 12532 ( that.position.left - cop.left ) ); 12533 12534 if ( pRatio ) { 12535 that.size.height = that.size.width / that.aspectRatio; 12536 continueResize = false; 12537 } 12538 that.position.left = o.helper ? co.left : 0; 12539 } 12540 12541 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 12542 that.size.height = that.size.height + 12543 ( that._helper ? 12544 ( that.position.top - co.top ) : 12545 that.position.top ); 12546 12547 if ( pRatio ) { 12548 that.size.width = that.size.height * that.aspectRatio; 12549 continueResize = false; 12550 } 12551 that.position.top = that._helper ? co.top : 0; 12552 } 12553 12554 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 12555 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 12556 12557 if ( isParent && isOffsetRelative ) { 12558 that.offset.left = that.parentData.left + that.position.left; 12559 that.offset.top = that.parentData.top + that.position.top; 12560 } else { 12561 that.offset.left = that.element.offset().left; 12562 that.offset.top = that.element.offset().top; 12563 } 12564 12565 woset = Math.abs( that.sizeDiff.width + 12566 ( that._helper ? 12567 that.offset.left - cop.left : 12568 ( that.offset.left - co.left ) ) ); 12569 12570 hoset = Math.abs( that.sizeDiff.height + 12571 ( that._helper ? 12572 that.offset.top - cop.top : 12573 ( that.offset.top - co.top ) ) ); 12574 12575 if ( woset + that.size.width >= that.parentData.width ) { 12576 that.size.width = that.parentData.width - woset; 12577 if ( pRatio ) { 12578 that.size.height = that.size.width / that.aspectRatio; 12579 continueResize = false; 12580 } 12581 } 12582 12583 if ( hoset + that.size.height >= that.parentData.height ) { 12584 that.size.height = that.parentData.height - hoset; 12585 if ( pRatio ) { 12586 that.size.width = that.size.height * that.aspectRatio; 12587 continueResize = false; 12588 } 12589 } 12590 12591 if ( !continueResize ) { 12592 that.position.left = that.prevPosition.left; 12593 that.position.top = that.prevPosition.top; 12594 that.size.width = that.prevSize.width; 12595 that.size.height = that.prevSize.height; 12596 } 12597 }, 12598 12599 stop: function() { 12600 var that = $( this ).resizable( "instance" ), 12601 o = that.options, 12602 co = that.containerOffset, 12603 cop = that.containerPosition, 12604 ce = that.containerElement, 12605 helper = $( that.helper ), 12606 ho = helper.offset(), 12607 w = helper.outerWidth() - that.sizeDiff.width, 12608 h = helper.outerHeight() - that.sizeDiff.height; 12609 12610 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 12611 $( this ).css( { 12612 left: ho.left - cop.left - co.left, 12613 width: w, 12614 height: h 12615 } ); 12616 } 12617 12618 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 12619 $( this ).css( { 12620 left: ho.left - cop.left - co.left, 12621 width: w, 12622 height: h 12623 } ); 12624 } 12625 } 12626} ); 12627 12628$.ui.plugin.add( "resizable", "alsoResize", { 12629 12630 start: function() { 12631 var that = $( this ).resizable( "instance" ), 12632 o = that.options; 12633 12634 $( o.alsoResize ).each( function() { 12635 var el = $( this ), 12636 elSize = that._calculateAdjustedElementDimensions( el ); 12637 12638 el.data( "ui-resizable-alsoresize", { 12639 width: elSize.width, height: elSize.height, 12640 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 12641 } ); 12642 } ); 12643 }, 12644 12645 resize: function( event, ui ) { 12646 var that = $( this ).resizable( "instance" ), 12647 o = that.options, 12648 os = that.originalSize, 12649 op = that.originalPosition, 12650 delta = { 12651 height: ( that.size.height - os.height ) || 0, 12652 width: ( that.size.width - os.width ) || 0, 12653 top: ( that.position.top - op.top ) || 0, 12654 left: ( that.position.left - op.left ) || 0 12655 }; 12656 12657 $( o.alsoResize ).each( function() { 12658 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 12659 css = el.parents( ui.originalElement[ 0 ] ).length ? 12660 [ "width", "height" ] : 12661 [ "width", "height", "top", "left" ]; 12662 12663 $.each( css, function( i, prop ) { 12664 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 12665 if ( sum && sum >= 0 ) { 12666 style[ prop ] = sum || null; 12667 } 12668 } ); 12669 12670 el.css( style ); 12671 } ); 12672 }, 12673 12674 stop: function() { 12675 $( this ).removeData( "ui-resizable-alsoresize" ); 12676 } 12677} ); 12678 12679$.ui.plugin.add( "resizable", "ghost", { 12680 12681 start: function() { 12682 12683 var that = $( this ).resizable( "instance" ), cs = that.size; 12684 12685 that.ghost = that.originalElement.clone(); 12686 that.ghost.css( { 12687 opacity: 0.25, 12688 display: "block", 12689 position: "relative", 12690 height: cs.height, 12691 width: cs.width, 12692 margin: 0, 12693 left: 0, 12694 top: 0 12695 } ); 12696 12697 that._addClass( that.ghost, "ui-resizable-ghost" ); 12698 12699 // DEPRECATED 12700 // TODO: remove after 1.12 12701 if ( $.uiBackCompat === true && typeof that.options.ghost === "string" ) { 12702 12703 // Ghost option 12704 that.ghost.addClass( this.options.ghost ); 12705 } 12706 12707 that.ghost.appendTo( that.helper ); 12708 12709 }, 12710 12711 resize: function() { 12712 var that = $( this ).resizable( "instance" ); 12713 if ( that.ghost ) { 12714 that.ghost.css( { 12715 position: "relative", 12716 height: that.size.height, 12717 width: that.size.width 12718 } ); 12719 } 12720 }, 12721 12722 stop: function() { 12723 var that = $( this ).resizable( "instance" ); 12724 if ( that.ghost && that.helper ) { 12725 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 12726 } 12727 } 12728 12729} ); 12730 12731$.ui.plugin.add( "resizable", "grid", { 12732 12733 resize: function() { 12734 var outerDimensions, 12735 that = $( this ).resizable( "instance" ), 12736 o = that.options, 12737 cs = that.size, 12738 os = that.originalSize, 12739 op = that.originalPosition, 12740 a = that.axis, 12741 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 12742 gridX = ( grid[ 0 ] || 1 ), 12743 gridY = ( grid[ 1 ] || 1 ), 12744 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 12745 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 12746 newWidth = os.width + ox, 12747 newHeight = os.height + oy, 12748 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 12749 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 12750 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 12751 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 12752 12753 o.grid = grid; 12754 12755 if ( isMinWidth ) { 12756 newWidth += gridX; 12757 } 12758 if ( isMinHeight ) { 12759 newHeight += gridY; 12760 } 12761 if ( isMaxWidth ) { 12762 newWidth -= gridX; 12763 } 12764 if ( isMaxHeight ) { 12765 newHeight -= gridY; 12766 } 12767 12768 if ( /^(se|s|e)$/.test( a ) ) { 12769 that.size.width = newWidth; 12770 that.size.height = newHeight; 12771 } else if ( /^(ne)$/.test( a ) ) { 12772 that.size.width = newWidth; 12773 that.size.height = newHeight; 12774 that.position.top = op.top - oy; 12775 } else if ( /^(sw)$/.test( a ) ) { 12776 that.size.width = newWidth; 12777 that.size.height = newHeight; 12778 that.position.left = op.left - ox; 12779 } else { 12780 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 12781 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 12782 } 12783 12784 if ( newHeight - gridY > 0 ) { 12785 that.size.height = newHeight; 12786 that.position.top = op.top - oy; 12787 } else { 12788 newHeight = gridY - outerDimensions.height; 12789 that.size.height = newHeight; 12790 that.position.top = op.top + os.height - newHeight; 12791 } 12792 if ( newWidth - gridX > 0 ) { 12793 that.size.width = newWidth; 12794 that.position.left = op.left - ox; 12795 } else { 12796 newWidth = gridX - outerDimensions.width; 12797 that.size.width = newWidth; 12798 that.position.left = op.left + os.width - newWidth; 12799 } 12800 } 12801 } 12802 12803} ); 12804
12805return $.ui.resizable; 12806 12807} ); 12808 12809/*! 12810 * jQuery UI Dialog @VERSION 12811 * https://jqueryui.com 12812 * 12813 * Copyright OpenJS Foundation and other contributors 12814 * Released under the MIT license. 12815 * https://jquery.org/license 12816 */ 12817 12818//>>label: Dialog 12819//>>group: Widgets 12820//>>description: Displays customizable dialog windows. 12821//>>docs: https://api.jqueryui.com/dialog/ 12822//>>demos: https://jqueryui.com/dialog/ 12823//>>css.structure: ../../themes/base/core.css 12824//>>css.structure: ../../themes/base/dialog.css 12825//>>css.theme: ../../themes/base/theme.css 12826 12827( function( factory ) { 12828 "use strict"; 12829 12830 if ( typeof define === "function" && define.amd ) { 12831 12832 // AMD. Register as an anonymous module. 12833 define( 'ui/widgets/dialog.js',[ 12834 "jquery", 12835 "./button", 12836 "./draggable", 12837 "./mouse", 12838 "./resizable", 12839 "../focusable", 12840 "../keycode", 12841 "../position", 12842 "../tabbable", 12843 "../unique-id", 12844 "../version", 12845 "../widget" 12846 ], factory ); 12847 } else { 12848 12849 // Browser globals 12850 factory( jQuery ); 12851 } 12852} )( function( $ ) { 12853"use strict"; 12854 12855$.widget( "ui.dialog", { 12856 version: "@VERSION
vendor: 22,317 bytes, lines 12856-13750
12856", 12857 options: { 12858 appendTo: "body", 12859 autoOpen: true, 12860 buttons: [], 12861 classes: { 12862 "ui-dialog": "ui-corner-all", 12863 "ui-dialog-titlebar": "ui-corner-all" 12864 }, 12865 closeOnEscape: true, 12866 closeText: "Close", 12867 draggable: true, 12868 hide: null, 12869 height: "auto", 12870 maxHeight: null, 12871 maxWidth: null, 12872 minHeight: 150, 12873 minWidth: 150, 12874 modal: false, 12875 position: { 12876 my: "center", 12877 at: "center", 12878 of: window, 12879 collision: "fit", 12880 12881 // Ensure the titlebar is always visible 12882 using: function( pos ) { 12883 var topOffset = $( this ).css( pos ).offset().top; 12884 if ( topOffset < 0 ) { 12885 $( this ).css( "top", pos.top - topOffset ); 12886 } 12887 } 12888 }, 12889 resizable: true, 12890 show: null, 12891 title: null, 12892 uiDialogTitleHeadingLevel: 0, 12893 width: 300, 12894 12895 // Callbacks 12896 beforeClose: null, 12897 close: null, 12898 drag: null, 12899 dragStart: null, 12900 dragStop: null, 12901 focus: null, 12902 open: null, 12903 resize: null, 12904 resizeStart: null, 12905 resizeStop: null 12906 }, 12907 12908 sizeRelatedOptions: { 12909 buttons: true, 12910 height: true, 12911 maxHeight: true, 12912 maxWidth: true, 12913 minHeight: true, 12914 minWidth: true, 12915 width: true 12916 }, 12917 12918 resizableRelatedOptions: { 12919 maxHeight: true, 12920 maxWidth: true, 12921 minHeight: true, 12922 minWidth: true 12923 }, 12924 12925 _create: function() { 12926 this.originalCss = { 12927 display: this.element[ 0 ].style.display, 12928 width: this.element[ 0 ].style.width, 12929 minHeight: this.element[ 0 ].style.minHeight, 12930 maxHeight: this.element[ 0 ].style.maxHeight, 12931 height: this.element[ 0 ].style.height 12932 }; 12933 this.originalPosition = { 12934 parent: this.element.parent(), 12935 index: this.element.parent().children().index( this.element ) 12936 }; 12937 this.originalTitle = this.element.attr( "title" ); 12938 if ( this.options.title == null && this.originalTitle != null ) { 12939 this.options.title = this.originalTitle; 12940 } 12941 12942 // Dialogs can't be disabled 12943 if ( this.options.disabled ) { 12944 this.options.disabled = false; 12945 } 12946 12947 this._createWrapper(); 12948 12949 this.element 12950 .show() 12951 .removeAttr( "title" ) 12952 .appendTo( this.uiDialog ); 12953 12954 this._addClass( "ui-dialog-content", "ui-widget-content" ); 12955 12956 this._createTitlebar(); 12957 this._createButtonPane(); 12958 12959 if ( this.options.draggable && $.fn.draggable ) { 12960 this._makeDraggable(); 12961 } 12962 if ( this.options.resizable && $.fn.resizable ) { 12963 this._makeResizable(); 12964 } 12965 12966 this._isOpen = false; 12967 12968 this._trackFocus(); 12969 }, 12970 12971 _init: function() { 12972 if ( this.options.autoOpen ) { 12973 this.open(); 12974 } 12975 }, 12976 12977 _appendTo: function() { 12978 var element = this.options.appendTo; 12979 if ( element && ( element.jquery || element.nodeType ) ) { 12980 return $( element ); 12981 } 12982 return this.document.find( element || "body" ).eq( 0 ); 12983 }, 12984 12985 _destroy: function() { 12986 var next, 12987 originalPosition = this.originalPosition; 12988 12989 this._untrackInstance(); 12990 this._destroyOverlay(); 12991 12992 this.element 12993 .removeUniqueId() 12994 .css( this.originalCss ) 12995 12996 // Without detaching first, the following becomes really slow 12997 .detach(); 12998 12999 this.uiDialog.remove(); 13000 13001 if ( this.originalTitle ) { 13002 this.element.attr( "title", this.originalTitle ); 13003 } 13004 13005 next = originalPosition.parent.children().eq( originalPosition.index ); 13006 13007 // Don't try to place the dialog next to itself (#8613) 13008 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 13009 next.before( this.element ); 13010 } else { 13011 originalPosition.parent.append( this.element ); 13012 } 13013 }, 13014 13015 widget: function() { 13016 return this.uiDialog; 13017 }, 13018 13019 disable: $.noop, 13020 enable: $.noop, 13021 13022 close: function( event ) { 13023 var that = this; 13024 13025 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 13026 return; 13027 } 13028 13029 this._isOpen = false; 13030 this._focusedElement = null; 13031 this._destroyOverlay(); 13032 this._untrackInstance(); 13033 13034 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { 13035 13036 // Hiding a focused element doesn't trigger blur in WebKit 13037 // so in case we have nothing to focus on, explicitly blur the active element 13038 // https://bugs.webkit.org/show_bug.cgi?id=47182 13039 $( this.document[ 0 ].activeElement ).trigger( "blur" ); 13040 } 13041 13042 this._hide( this.uiDialog, this.options.hide, function() { 13043 that._trigger( "close", event ); 13044 } ); 13045 }, 13046 13047 isOpen: function() { 13048 return this._isOpen; 13049 }, 13050 13051 moveToTop: function() { 13052 this._moveToTop(); 13053 }, 13054 13055 _moveToTop: function( event, silent ) { 13056 var moved = false, 13057 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { 13058 return +$( this ).css( "z-index" ); 13059 } ).get(), 13060 zIndexMax = Math.max.apply( null, zIndices ); 13061 13062 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 13063 this.uiDialog.css( "z-index", zIndexMax + 1 ); 13064 moved = true; 13065 } 13066 13067 if ( moved && !silent ) { 13068 this._trigger( "focus", event ); 13069 } 13070 return moved; 13071 }, 13072 13073 open: function() { 13074 var that = this; 13075 if ( this._isOpen ) { 13076 if ( this._moveToTop() ) { 13077 this._focusTabbable(); 13078 } 13079 return; 13080 } 13081 13082 this._isOpen = true; 13083 this.opener = $( this.document[ 0 ].activeElement ); 13084 13085 this._size(); 13086 this._position(); 13087 this._createOverlay(); 13088 this._moveToTop( null, true ); 13089 13090 // Ensure the overlay is moved to the top with the dialog, but only when 13091 // opening. The overlay shouldn't move after the dialog is open so that 13092 // modeless dialogs opened after the modal dialog stack properly. 13093 if ( this.overlay ) { 13094 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 13095 } 13096 13097 this._show( this.uiDialog, this.options.show, function() { 13098 that._focusTabbable(); 13099 that._trigger( "focus" ); 13100 } ); 13101 13102 // Track the dialog immediately upon opening in case a focus event 13103 // somehow occurs outside of the dialog before an element inside the 13104 // dialog is focused (#10152) 13105 this._makeFocusTarget(); 13106 13107 this._trigger( "open" ); 13108 }, 13109 13110 _focusTabbable: function() { 13111 13112 // Set focus to the first match: 13113 // 1. An element that was focused previously 13114 // 2. First element inside the dialog matching [autofocus] 13115 // 3. Tabbable element inside the content element 13116 // 4. Tabbable element inside the buttonpane 13117 // 5. The close button 13118 // 6. The dialog itself 13119 var hasFocus = this._focusedElement; 13120 if ( !hasFocus ) { 13121 hasFocus = this.element.find( "[autofocus]" ); 13122 } 13123 if ( !hasFocus.length ) { 13124 hasFocus = this.element.find( ":tabbable" ); 13125 } 13126 if ( !hasFocus.length ) { 13127 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 13128 } 13129 if ( !hasFocus.length ) { 13130 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 13131 } 13132 if ( !hasFocus.length ) { 13133 hasFocus = this.uiDialog; 13134 } 13135 hasFocus.eq( 0 ).trigger( "focus" ); 13136 }, 13137 13138 _restoreTabbableFocus: function() { 13139 var activeElement = this.document[ 0 ].activeElement, 13140 isActive = this.uiDialog[ 0 ] === activeElement || 13141 $.contains( this.uiDialog[ 0 ], activeElement ); 13142 if ( !isActive ) { 13143 this._focusTabbable(); 13144 } 13145 }, 13146 13147 _keepFocus: function( event ) { 13148 event.preventDefault(); 13149 this._restoreTabbableFocus(); 13150 }, 13151 13152 _createWrapper: function() { 13153 this.uiDialog = $( "<div>" ) 13154 .hide() 13155 .attr( { 13156 13157 // Setting tabIndex makes the div focusable 13158 tabIndex: -1, 13159 role: "dialog", 13160 "aria-modal": this.options.modal ? "true" : null 13161 } ) 13162 .appendTo( this._appendTo() ); 13163 13164 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); 13165 this._on( this.uiDialog, { 13166 keydown: function( event ) { 13167 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 13168 event.keyCode === $.ui.keyCode.ESCAPE ) { 13169 event.preventDefault(); 13170 this.close( event ); 13171 return; 13172 } 13173 13174 // Prevent tabbing out of dialogs 13175 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 13176 return; 13177 } 13178 var tabbables = this.uiDialog.find( ":tabbable" ), 13179 first = tabbables.first(), 13180 last = tabbables.last(); 13181 13182 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && 13183 !event.shiftKey ) { 13184 this._delay( function() { 13185 first.trigger( "focus" ); 13186 } ); 13187 event.preventDefault(); 13188 } else if ( ( event.target === first[ 0 ] || 13189 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { 13190 this._delay( function() { 13191 last.trigger( "focus" ); 13192 } ); 13193 event.preventDefault(); 13194 } 13195 }, 13196 mousedown: function( event ) { 13197 if ( this._moveToTop( event ) ) { 13198 this._focusTabbable(); 13199 } 13200 } 13201 } ); 13202 13203 // We assume that any existing aria-describedby attribute means 13204 // that the dialog content is marked up properly 13205 // otherwise we brute force the content as the description 13206 if ( !this.element.find( "[aria-describedby]" ).length ) { 13207 this.uiDialog.attr( { 13208 "aria-describedby": this.element.uniqueId().attr( "id" ) 13209 } ); 13210 } 13211 }, 13212 13213 _createTitlebar: function() { 13214 var uiDialogTitle; 13215 13216 this.uiDialogTitlebar = $( "<div>" ); 13217 this._addClass( this.uiDialogTitlebar, 13218 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); 13219 this._on( this.uiDialogTitlebar, { 13220 mousedown: function( event ) { 13221 13222 // Don't prevent click on close button (#8838) 13223 // Focusing a dialog that is partially scrolled out of view 13224 // causes the browser to scroll it into view, preventing the click event 13225 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 13226 13227 // Dialog isn't getting focus when dragging (#8063) 13228 this.uiDialog.trigger( "focus" ); 13229 } 13230 } 13231 } ); 13232 13233 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 13234 .button( { 13235 label: $( "<a>" ).text( this.options.closeText ).html(), 13236 icon: "ui-icon-closethick", 13237 showLabel: false 13238 } ) 13239 .appendTo( this.uiDialogTitlebar ); 13240 13241 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); 13242 this._on( this.uiDialogTitlebarClose, { 13243 click: function( event ) { 13244 event.preventDefault(); 13245 this.close( event ); 13246 } 13247 } ); 13248 13249 var uiDialogHeadingLevel = Number.isInteger( this.options.uiDialogTitleHeadingLevel ) && 13250 this.options.uiDialogTitleHeadingLevel > 0 && 13251 this.options.uiDialogTitleHeadingLevel <= 6 ? 13252 "h" + this.options.uiDialogTitleHeadingLevel : "span"; 13253 13254 uiDialogTitle = $( "<" + uiDialogHeadingLevel + ">" ) 13255 .uniqueId().prependTo( this.uiDialogTitlebar ); 13256 this._addClass( uiDialogTitle, "ui-dialog-title" ); 13257 this._title( uiDialogTitle ); 13258 13259 this.uiDialogTitlebar.prependTo( this.uiDialog ); 13260 13261 this.uiDialog.attr( { 13262 "aria-labelledby": uiDialogTitle.attr( "id" ) 13263 } ); 13264 }, 13265 13266 _title: function( title ) { 13267 if ( this.options.title ) { 13268 title.text( this.options.title ); 13269 } else { 13270 title.html( " " ); 13271 } 13272 }, 13273 13274 _createButtonPane: function() { 13275 this.uiDialogButtonPane = $( "<div>" ); 13276 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", 13277 "ui-widget-content ui-helper-clearfix" ); 13278 13279 this.uiButtonSet = $( "<div>" ) 13280 .appendTo( this.uiDialogButtonPane ); 13281 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); 13282 13283 this._createButtons(); 13284 }, 13285 13286 _createButtons: function() { 13287 var that = this, 13288 buttons = this.options.buttons; 13289 13290 // If we already have a button pane, remove it 13291 this.uiDialogButtonPane.remove(); 13292 this.uiButtonSet.empty(); 13293 13294 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { 13295 this._removeClass( this.uiDialog, "ui-dialog-buttons" ); 13296 return; 13297 } 13298 13299 $.each( buttons, function( name, props ) { 13300 var click, buttonOptions; 13301 props = typeof props === "function" ? 13302 { click: props, text: name } : 13303 props; 13304 13305 // Default to a non-submitting button 13306 props = $.extend( { type: "button" }, props ); 13307 13308 // Change the context for the click callback to be the main element 13309 click = props.click; 13310 buttonOptions = { 13311 icon: props.icon, 13312 iconPosition: props.iconPosition, 13313 showLabel: props.showLabel, 13314 13315 // Deprecated options 13316 icons: props.icons, 13317 text: props.text 13318 }; 13319 13320 delete props.click; 13321 delete props.icon; 13322 delete props.iconPosition; 13323 delete props.showLabel; 13324 13325 // Deprecated options 13326 delete props.icons; 13327 if ( typeof props.text === "boolean" ) { 13328 delete props.text; 13329 } 13330 13331 $( "<button></button>", props ) 13332 .button( buttonOptions ) 13333 .appendTo( that.uiButtonSet ) 13334 .on( "click", function() { 13335 click.apply( that.element[ 0 ], arguments ); 13336 } ); 13337 } ); 13338 this._addClass( this.uiDialog, "ui-dialog-buttons" ); 13339 this.uiDialogButtonPane.appendTo( this.uiDialog ); 13340 }, 13341 13342 _makeDraggable: function() { 13343 var that = this, 13344 options = this.options; 13345 13346 function filteredUi( ui ) { 13347 return { 13348 position: ui.position, 13349 offset: ui.offset 13350 }; 13351 } 13352 13353 this.uiDialog.draggable( { 13354 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 13355 handle: ".ui-dialog-titlebar", 13356 containment: "document", 13357 start: function( event, ui ) { 13358 that._addClass( $( this ), "ui-dialog-dragging" ); 13359 that._blockFrames(); 13360 that._trigger( "dragStart", event, filteredUi( ui ) ); 13361 }, 13362 drag: function( event, ui ) { 13363 that._trigger( "drag", event, filteredUi( ui ) ); 13364 }, 13365 stop: function( event, ui ) { 13366 var left = ui.offset.left - that.document.scrollLeft(), 13367 top = ui.offset.top - that.document.scrollTop(); 13368 13369 options.position = { 13370 my: "left top", 13371 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 13372 "top" + ( top >= 0 ? "+" : "" ) + top, 13373 of: that.window 13374 }; 13375 that._removeClass( $( this ), "ui-dialog-dragging" ); 13376 that._unblockFrames(); 13377 that._trigger( "dragStop", event, filteredUi( ui ) ); 13378 } 13379 } ); 13380 }, 13381 13382 _makeResizable: function() { 13383 var that = this, 13384 options = this.options, 13385 handles = options.resizable, 13386 13387 // .ui-resizable has position: relative defined in the stylesheet 13388 // but dialogs have to use absolute or fixed positioning 13389 position = this.uiDialog.css( "position" ), 13390 resizeHandles = typeof handles === "string" ? 13391 handles : 13392 "n,e,s,w,se,sw,ne,nw"; 13393 13394 function filteredUi( ui ) { 13395 return { 13396 originalPosition: ui.originalPosition, 13397 originalSize: ui.originalSize, 13398 position: ui.position, 13399 size: ui.size 13400 }; 13401 } 13402 13403 this.uiDialog.resizable( { 13404 cancel: ".ui-dialog-content", 13405 containment: "document", 13406 alsoResize: this.element, 13407 maxWidth: options.maxWidth, 13408 maxHeight: options.maxHeight, 13409 minWidth: options.minWidth, 13410 minHeight: this._minHeight(), 13411 handles: resizeHandles, 13412 start: function( event, ui ) { 13413 that._addClass( $( this ), "ui-dialog-resizing" ); 13414 that._blockFrames(); 13415 that._trigger( "resizeStart", event, filteredUi( ui ) ); 13416 }, 13417 resize: function( event, ui ) { 13418 that._trigger( "resize", event, filteredUi( ui ) ); 13419 }, 13420 stop: function( event, ui ) { 13421 var offset = that.uiDialog.offset(), 13422 left = offset.left - that.document.scrollLeft(), 13423 top = offset.top - that.document.scrollTop(); 13424 13425 options.height = that.uiDialog.height(); 13426 options.width = that.uiDialog.width(); 13427 options.position = { 13428 my: "left top", 13429 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 13430 "top" + ( top >= 0 ? "+" : "" ) + top, 13431 of: that.window 13432 }; 13433 that._removeClass( $( this ), "ui-dialog-resizing" ); 13434 that._unblockFrames(); 13435 that._trigger( "resizeStop", event, filteredUi( ui ) ); 13436 } 13437 } ) 13438 .css( "position", position ); 13439 }, 13440 13441 _trackFocus: function() { 13442 this._on( this.widget(), { 13443 focusin: function( event ) { 13444 this._makeFocusTarget(); 13445 this._focusedElement = $( event.target ); 13446 } 13447 } ); 13448 }, 13449 13450 _makeFocusTarget: function() { 13451 this._untrackInstance(); 13452 this._trackingInstances().unshift( this ); 13453 }, 13454 13455 _untrackInstance: function() { 13456 var instances = this._trackingInstances(), 13457 exists = $.inArray( this, instances ); 13458 if ( exists !== -1 ) { 13459 instances.splice( exists, 1 ); 13460 } 13461 }, 13462 13463 _trackingInstances: function() { 13464 var instances = this.document.data( "ui-dialog-instances" ); 13465 if ( !instances ) { 13466 instances = []; 13467 this.document.data( "ui-dialog-instances", instances ); 13468 } 13469 return instances; 13470 }, 13471 13472 _minHeight: function() { 13473 var options = this.options; 13474 13475 return options.height === "auto" ? 13476 options.minHeight : 13477 Math.min( options.minHeight, options.height ); 13478 }, 13479 13480 _position: function() { 13481 13482 // Need to show the dialog to get the actual offset in the position plugin 13483 var isVisible = this.uiDialog.is( ":visible" ); 13484 if ( !isVisible ) { 13485 this.uiDialog.show(); 13486 } 13487 this.uiDialog.position( this.options.position ); 13488 if ( !isVisible ) { 13489 this.uiDialog.hide(); 13490 } 13491 }, 13492 13493 _setOptions: function( options ) { 13494 var that = this, 13495 resize = false, 13496 resizableOptions = {}; 13497 13498 $.each( options, function( key, value ) { 13499 that._setOption( key, value ); 13500 13501 if ( key in that.sizeRelatedOptions ) { 13502 resize = true; 13503 } 13504 if ( key in that.resizableRelatedOptions ) { 13505 resizableOptions[ key ] = value; 13506 } 13507 } ); 13508 13509 if ( resize ) { 13510 this._size(); 13511 this._position(); 13512 } 13513 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 13514 this.uiDialog.resizable( "option", resizableOptions ); 13515 } 13516 }, 13517 13518 _setOption: function( key, value ) { 13519 var isDraggable, isResizable, 13520 uiDialog = this.uiDialog; 13521 13522 if ( key === "disabled" ) { 13523 return; 13524 } 13525 13526 this._super( key, value ); 13527 13528 if ( key === "appendTo" ) { 13529 this.uiDialog.appendTo( this._appendTo() ); 13530 } 13531 13532 if ( key === "buttons" ) { 13533 this._createButtons(); 13534 } 13535 13536 if ( key === "closeText" ) { 13537 this.uiDialogTitlebarClose.button( { 13538 13539 // Ensure that we always pass a string 13540 label: $( "<a>" ).text( "" + this.options.closeText ).html() 13541 } ); 13542 } 13543 13544 if ( key === "draggable" ) { 13545 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 13546 if ( isDraggable && !value ) { 13547 uiDialog.draggable( "destroy" ); 13548 } 13549 13550 if ( !isDraggable && value ) { 13551 this._makeDraggable(); 13552 } 13553 } 13554 13555 if ( key === "position" ) { 13556 this._position(); 13557 } 13558 13559 if ( key === "resizable" ) { 13560 13561 // currently resizable, becoming non-resizable 13562 isResizable = uiDialog.is( ":data(ui-resizable)" ); 13563 if ( isResizable && !value ) { 13564 uiDialog.resizable( "destroy" ); 13565 } 13566 13567 // Currently resizable, changing handles 13568 if ( isResizable && typeof value === "string" ) { 13569 uiDialog.resizable( "option", "handles", value ); 13570 } 13571 13572 // Currently non-resizable, becoming resizable 13573 if ( !isResizable && value !== false ) { 13574 this._makeResizable(); 13575 } 13576 } 13577 13578 if ( key === "title" ) { 13579 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 13580 } 13581 13582 if ( key === "modal" ) { 13583 uiDialog.attr( "aria-modal", value ? "true" : null ); 13584 } 13585 }, 13586 13587 _size: function() { 13588 13589 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 13590 // divs will both have width and height set, so we need to reset them 13591 var nonContentHeight, minContentHeight, maxContentHeight, 13592 options = this.options; 13593 13594 // Reset content sizing 13595 this.element.show().css( { 13596 width: "auto", 13597 minHeight: 0, 13598 maxHeight: "none", 13599 height: 0 13600 } ); 13601 13602 if ( options.minWidth > options.width ) { 13603 options.width = options.minWidth; 13604 } 13605 13606 // Reset wrapper sizing 13607 // determine the height of all the non-content elements 13608 nonContentHeight = this.uiDialog.css( { 13609 height: "auto", 13610 width: options.width 13611 } ) 13612 .outerHeight(); 13613 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 13614 maxContentHeight = typeof options.maxHeight === "number" ? 13615 Math.max( 0, options.maxHeight - nonContentHeight ) : 13616 "none"; 13617 13618 if ( options.height === "auto" ) { 13619 this.element.css( { 13620 minHeight: minContentHeight, 13621 maxHeight: maxContentHeight, 13622 height: "auto" 13623 } ); 13624 } else { 13625 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 13626 } 13627 13628 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 13629 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 13630 } 13631 }, 13632 13633 _blockFrames: function() { 13634 this.iframeBlocks = this.document.find( "iframe" ).map( function() { 13635 var iframe = $( this ); 13636 13637 return $( "<div>" ) 13638 .css( { 13639 position: "absolute", 13640 width: iframe.outerWidth(), 13641 height: iframe.outerHeight() 13642 } ) 13643 .appendTo( iframe.parent() ) 13644 .offset( iframe.offset() )[ 0 ]; 13645 } ); 13646 }, 13647 13648 _unblockFrames: function() { 13649 if ( this.iframeBlocks ) { 13650 this.iframeBlocks.remove(); 13651 delete this.iframeBlocks; 13652 } 13653 }, 13654 13655 _allowInteraction: function( event ) { 13656 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 13657 return true; 13658 } 13659 13660 // TODO: Remove hack when datepicker implements 13661 // the .ui-front logic (#8989) 13662 return !!$( event.target ).closest( ".ui-datepicker" ).length; 13663 }, 13664 13665 _createOverlay: function() { 13666 if ( !this.options.modal ) { 13667 return; 13668 } 13669 13670 // We use a delay in case the overlay is created from an 13671 // event that we're going to be cancelling (#2804) 13672 var isOpening = true; 13673 this._delay( function() { 13674 isOpening = false; 13675 } ); 13676 13677 if ( !this.document.data( "ui-dialog-overlays" ) ) { 13678 13679 // Prevent use of anchors and inputs 13680 // This doesn't use `_on()` because it is a shared event handler 13681 // across all open modal dialogs. 13682 this.document.on( "focusin.ui-dialog", function( event ) { 13683 if ( isOpening ) { 13684 return; 13685 } 13686 13687 var instance = this._trackingInstances()[ 0 ]; 13688 if ( !instance._allowInteraction( event ) ) { 13689 event.preventDefault(); 13690 instance._focusTabbable(); 13691 } 13692 }.bind( this ) ); 13693 } 13694 13695 this.overlay = $( "<div>" ) 13696 .appendTo( this._appendTo() ); 13697 13698 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); 13699 this._on( this.overlay, { 13700 mousedown: "_keepFocus" 13701 } ); 13702 this.document.data( "ui-dialog-overlays", 13703 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); 13704 }, 13705 13706 _destroyOverlay: function() { 13707 if ( !this.options.modal ) { 13708 return; 13709 } 13710 13711 if ( this.overlay ) { 13712 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 13713 13714 if ( !overlays ) { 13715 this.document.off( "focusin.ui-dialog" ); 13716 this.document.removeData( "ui-dialog-overlays" ); 13717 } else { 13718 this.document.data( "ui-dialog-overlays", overlays ); 13719 } 13720 13721 this.overlay.remove(); 13722 this.overlay = null; 13723 } 13724 } 13725} ); 13726 13727// DEPRECATED 13728// TODO: switch return back to widget declaration at top of file when this is removed 13729if ( $.uiBackCompat === true ) { 13730 13731 // Backcompat for dialogClass option 13732 $.widget( "ui.dialog", $.ui.dialog, { 13733 options: { 13734 dialogClass: "" 13735 }, 13736 _createWrapper: function() { 13737 this._super(); 13738 this.uiDialog.addClass( this.options.dialogClass ); 13739 }, 13740 _setOption: function( key, value ) { 13741 if ( key === "dialogClass" ) { 13742 this.uiDialog 13743 .removeClass( this.options.dialogClass ) 13744 .addClass( value ); 13745 } 13746 this._superApply( arguments ); 13747 } 13748 } ); 13749} 13750
13751return $.ui.dialog; 13752 13753} ); 13754 13755/*! 13756 * jQuery UI Droppable @VERSION 13757 * https://jqueryui.com 13758 * 13759 * Copyright OpenJS Foundation and other contributors 13760 * Released under the MIT license. 13761 * https://jquery.org/license 13762 */ 13763 13764//>>label: Droppable 13765//>>group: Interactions 13766//>>description: Enables drop targets for draggable elements. 13767//>>docs: https://api.jqueryui.com/droppable/ 13768//>>demos: https://jqueryui.com/droppable/ 13769 13770( function( factory ) { 13771 "use strict"; 13772 13773 if ( typeof define === "function" && define.amd ) { 13774 13775 // AMD. Register as an anonymous module. 13776 define( 'ui/widgets/droppable.js',[ 13777 "jquery", 13778 "./draggable", 13779 "./mouse", 13780 "../version", 13781 "../widget" 13782 ], factory ); 13783 } else { 13784 13785 // Browser globals 13786 factory( jQuery ); 13787 } 13788} )( function( $ ) { 13789"use strict"; 13790 13791$.widget( "ui.droppable", { 13792 version: "@VERSION
vendor: 12,108 bytes, lines 13792-14254
13792", 13793 widgetEventPrefix: "drop", 13794 options: { 13795 accept: "*", 13796 addClasses: true, 13797 greedy: false, 13798 scope: "default", 13799 tolerance: "intersect", 13800 13801 // Callbacks 13802 activate: null, 13803 deactivate: null, 13804 drop: null, 13805 out: null, 13806 over: null 13807 }, 13808 _create: function() { 13809 13810 var proportions, 13811 o = this.options, 13812 accept = o.accept; 13813 13814 this.isover = false; 13815 this.isout = true; 13816 13817 this.accept = typeof accept === "function" ? accept : function( d ) { 13818 return d.is( accept ); 13819 }; 13820 13821 this.proportions = function( /* valueToWrite */ ) { 13822 if ( arguments.length ) { 13823 13824 // Store the droppable's proportions 13825 proportions = arguments[ 0 ]; 13826 } else { 13827 13828 // Retrieve or derive the droppable's proportions 13829 return proportions ? 13830 proportions : 13831 proportions = { 13832 width: this.element[ 0 ].offsetWidth, 13833 height: this.element[ 0 ].offsetHeight 13834 }; 13835 } 13836 }; 13837 13838 this._addToManager( o.scope ); 13839 13840 if ( o.addClasses ) { 13841 this._addClass( "ui-droppable" ); 13842 } 13843 13844 }, 13845 13846 _addToManager: function( scope ) { 13847 13848 // Add the reference and positions to the manager 13849 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 13850 $.ui.ddmanager.droppables[ scope ].push( this ); 13851 }, 13852 13853 _splice: function( drop ) { 13854 var i = 0; 13855 for ( ; i < drop.length; i++ ) { 13856 if ( drop[ i ] === this ) { 13857 drop.splice( i, 1 ); 13858 } 13859 } 13860 }, 13861 13862 _destroy: function() { 13863 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 13864 13865 this._splice( drop ); 13866 }, 13867 13868 _setOption: function( key, value ) { 13869 13870 if ( key === "accept" ) { 13871 this.accept = typeof value === "function" ? value : function( d ) { 13872 return d.is( value ); 13873 }; 13874 } else if ( key === "scope" ) { 13875 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 13876 13877 this._splice( drop ); 13878 this._addToManager( value ); 13879 } 13880 13881 this._super( key, value ); 13882 }, 13883 13884 _activate: function( event ) { 13885 var draggable = $.ui.ddmanager.current; 13886 13887 this._addActiveClass(); 13888 if ( draggable ) { 13889 this._trigger( "activate", event, this.ui( draggable ) ); 13890 } 13891 }, 13892 13893 _deactivate: function( event ) { 13894 var draggable = $.ui.ddmanager.current; 13895 13896 this._removeActiveClass(); 13897 if ( draggable ) { 13898 this._trigger( "deactivate", event, this.ui( draggable ) ); 13899 } 13900 }, 13901 13902 _over: function( event ) { 13903 13904 var draggable = $.ui.ddmanager.current; 13905 13906 // Bail if draggable and droppable are same element 13907 if ( !draggable || ( draggable.currentItem || 13908 draggable.element )[ 0 ] === this.element[ 0 ] ) { 13909 return; 13910 } 13911 13912 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 13913 draggable.element ) ) ) { 13914 this._addHoverClass(); 13915 this._trigger( "over", event, this.ui( draggable ) ); 13916 } 13917 13918 }, 13919 13920 _out: function( event ) { 13921 13922 var draggable = $.ui.ddmanager.current; 13923 13924 // Bail if draggable and droppable are same element 13925 if ( !draggable || ( draggable.currentItem || 13926 draggable.element )[ 0 ] === this.element[ 0 ] ) { 13927 return; 13928 } 13929 13930 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 13931 draggable.element ) ) ) { 13932 this._removeHoverClass(); 13933 this._trigger( "out", event, this.ui( draggable ) ); 13934 } 13935 13936 }, 13937 13938 _drop: function( event, custom ) { 13939 13940 var draggable = custom || $.ui.ddmanager.current, 13941 childrenIntersection = false; 13942 13943 // Bail if draggable and droppable are same element 13944 if ( !draggable || ( draggable.currentItem || 13945 draggable.element )[ 0 ] === this.element[ 0 ] ) { 13946 return false; 13947 } 13948 13949 this.element 13950 .find( ":data(ui-droppable)" ) 13951 .not( ".ui-draggable-dragging" ) 13952 .each( function() { 13953 var inst = $( this ).droppable( "instance" ); 13954 if ( 13955 inst.options.greedy && 13956 !inst.options.disabled && 13957 inst.options.scope === draggable.options.scope && 13958 inst.accept.call( 13959 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 13960 ) && 13961 $.ui.intersect( 13962 draggable, 13963 $.extend( inst, { offset: inst.element.offset() } ), 13964 inst.options.tolerance, event 13965 ) 13966 ) { 13967 childrenIntersection = true; 13968 return false; 13969 } 13970 } ); 13971 if ( childrenIntersection ) { 13972 return false; 13973 } 13974 13975 if ( this.accept.call( this.element[ 0 ], 13976 ( draggable.currentItem || draggable.element ) ) ) { 13977 this._removeActiveClass(); 13978 this._removeHoverClass(); 13979 13980 this._trigger( "drop", event, this.ui( draggable ) ); 13981 return this.element; 13982 } 13983 13984 return false; 13985 13986 }, 13987 13988 ui: function( c ) { 13989 return { 13990 draggable: ( c.currentItem || c.element ), 13991 helper: c.helper, 13992 position: c.position, 13993 offset: c.positionAbs 13994 }; 13995 }, 13996 13997 // Extension points just to make backcompat sane and avoid duplicating logic 13998 // TODO: Remove in 1.14 along with call to it below 13999 _addHoverClass: function() { 14000 this._addClass( "ui-droppable-hover" ); 14001 }, 14002 14003 _removeHoverClass: function() { 14004 this._removeClass( "ui-droppable-hover" ); 14005 }, 14006 14007 _addActiveClass: function() { 14008 this._addClass( "ui-droppable-active" ); 14009 }, 14010 14011 _removeActiveClass: function() { 14012 this._removeClass( "ui-droppable-active" ); 14013 } 14014} ); 14015 14016$.ui.intersect = ( function() { 14017 function isOverAxis( x, reference, size ) { 14018 return ( x >= reference ) && ( x < ( reference + size ) ); 14019 } 14020 14021 return function( draggable, droppable, toleranceMode, event ) { 14022 14023 if ( !droppable.offset ) { 14024 return false; 14025 } 14026 14027 var x1 = ( draggable.positionAbs || 14028 draggable.position.absolute ).left + draggable.margins.left, 14029 y1 = ( draggable.positionAbs || 14030 draggable.position.absolute ).top + draggable.margins.top, 14031 x2 = x1 + draggable.helperProportions.width, 14032 y2 = y1 + draggable.helperProportions.height, 14033 l = droppable.offset.left, 14034 t = droppable.offset.top, 14035 r = l + droppable.proportions().width, 14036 b = t + droppable.proportions().height; 14037 14038 switch ( toleranceMode ) { 14039 case "fit": 14040 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 14041 case "intersect": 14042 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 14043 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 14044 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 14045 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 14046 case "pointer": 14047 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 14048 isOverAxis( event.pageX, l, droppable.proportions().width ); 14049 case "touch": 14050 return ( 14051 ( y1 >= t && y1 <= b ) || // Top edge touching 14052 ( y2 >= t && y2 <= b ) || // Bottom edge touching 14053 ( y1 < t && y2 > b ) // Surrounded vertically 14054 ) && ( 14055 ( x1 >= l && x1 <= r ) || // Left edge touching 14056 ( x2 >= l && x2 <= r ) || // Right edge touching 14057 ( x1 < l && x2 > r ) // Surrounded horizontally 14058 ); 14059 default: 14060 return false; 14061 } 14062 }; 14063} )(); 14064 14065/* 14066 This manager tracks offsets of draggables and droppables 14067*/ 14068$.ui.ddmanager = { 14069 current: null, 14070 droppables: { "default": [] }, 14071 prepareOffsets: function( t, event ) { 14072 14073 var i, j, 14074 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 14075 type = event ? event.type : null, // workaround for #2317 14076 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 14077 14078 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 14079 14080 // No disabled and non-accepted 14081 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 14082 ( t.currentItem || t.element ) ) ) ) { 14083 continue; 14084 } 14085 14086 // Filter out elements in the current dragged item 14087 for ( j = 0; j < list.length; j++ ) { 14088 if ( list[ j ] === m[ i ].element[ 0 ] ) { 14089 m[ i ].proportions().height = 0; 14090 continue droppablesLoop; 14091 } 14092 } 14093 14094 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 14095 if ( !m[ i ].visible ) { 14096 continue; 14097 } 14098 14099 // Activate the droppable if used directly from draggables 14100 if ( type === "mousedown" ) { 14101 m[ i ]._activate.call( m[ i ], event ); 14102 } 14103 14104 m[ i ].offset = m[ i ].element.offset(); 14105 m[ i ].proportions( { 14106 width: m[ i ].element[ 0 ].offsetWidth, 14107 height: m[ i ].element[ 0 ].offsetHeight 14108 } ); 14109 14110 } 14111 14112 }, 14113 drop: function( draggable, event ) { 14114 14115 var dropped = false; 14116 14117 // Create a copy of the droppables in case the list changes during the drop (#9116) 14118 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 14119 14120 if ( !this.options ) { 14121 return; 14122 } 14123 if ( !this.options.disabled && this.visible && 14124 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 14125 dropped = this._drop.call( this, event ) || dropped; 14126 } 14127 14128 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 14129 ( draggable.currentItem || draggable.element ) ) ) { 14130 this.isout = true; 14131 this.isover = false; 14132 this._deactivate.call( this, event ); 14133 } 14134 14135 } ); 14136 return dropped; 14137 14138 }, 14139 dragStart: function( draggable, event ) { 14140 14141 // Listen for scrolling so that if the dragging causes scrolling the position of the 14142 // droppables can be recalculated (see #5003) 14143 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 14144 if ( !draggable.options.refreshPositions ) { 14145 $.ui.ddmanager.prepareOffsets( draggable, event ); 14146 } 14147 } ); 14148 }, 14149 drag: function( draggable, event ) { 14150 14151 // If you have a highly dynamic page, you might try this option. It renders positions 14152 // every time you move the mouse. 14153 if ( draggable.options.refreshPositions ) { 14154 $.ui.ddmanager.prepareOffsets( draggable, event ); 14155 } 14156 14157 // Run through all droppables and check their positions based on specific tolerance options 14158 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 14159 14160 if ( this.options.disabled || this.greedyChild || !this.visible ) { 14161 return; 14162 } 14163 14164 var parentInstance, scope, parent, 14165 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 14166 c = !intersects && this.isover ? 14167 "isout" : 14168 ( intersects && !this.isover ? "isover" : null ); 14169 if ( !c ) { 14170 return; 14171 } 14172 14173 if ( this.options.greedy ) { 14174 14175 // find droppable parents with same scope 14176 scope = this.options.scope; 14177 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 14178 return $( this ).droppable( "instance" ).options.scope === scope; 14179 } ); 14180 14181 if ( parent.length ) { 14182 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 14183 parentInstance.greedyChild = ( c === "isover" ); 14184 } 14185 } 14186 14187 // We just moved into a greedy child 14188 if ( parentInstance && c === "isover" ) { 14189 parentInstance.isover = false; 14190 parentInstance.isout = true; 14191 parentInstance._out.call( parentInstance, event ); 14192 } 14193 14194 this[ c ] = true; 14195 this[ c === "isout" ? "isover" : "isout" ] = false; 14196 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 14197 14198 // We just moved out of a greedy child 14199 if ( parentInstance && c === "isout" ) { 14200 parentInstance.isout = false; 14201 parentInstance.isover = true; 14202 parentInstance._over.call( parentInstance, event ); 14203 } 14204 } ); 14205 14206 }, 14207 dragStop: function( draggable, event ) { 14208 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 14209 14210 // Call prepareOffsets one final time since IE does not fire return scroll events when 14211 // overflow was caused by drag (see #5003) 14212 if ( !draggable.options.refreshPositions ) { 14213 $.ui.ddmanager.prepareOffsets( draggable, event ); 14214 } 14215 } 14216}; 14217 14218// DEPRECATED 14219// TODO: switch return back to widget declaration at top of file when this is removed 14220if ( $.uiBackCompat === true ) { 14221 14222 // Backcompat for activeClass and hoverClass options 14223 $.widget( "ui.droppable", $.ui.droppable, { 14224 options: { 14225 hoverClass: false, 14226 activeClass: false 14227 }, 14228 _addActiveClass: function() { 14229 this._super(); 14230 if ( this.options.activeClass ) { 14231 this.element.addClass( this.options.activeClass ); 14232 } 14233 }, 14234 _removeActiveClass: function() { 14235 this._super(); 14236 if ( this.options.activeClass ) { 14237 this.element.removeClass( this.options.activeClass ); 14238 } 14239 }, 14240 _addHoverClass: function() { 14241 this._super(); 14242 if ( this.options.hoverClass ) { 14243 this.element.addClass( this.options.hoverClass ); 14244 } 14245 }, 14246 _removeHoverClass: function() { 14247 this._super(); 14248 if ( this.options.hoverClass ) { 14249 this.element.removeClass( this.options.hoverClass ); 14250 } 14251 } 14252 } ); 14253} 14254
14255return $.ui.droppable; 14256 14257} ); 14258 14259/*! 14260 * jQuery UI Progressbar @VERSION 14261 * https://jqueryui.com 14262 * 14263 * Copyright OpenJS Foundation and other contributors 14264 * Released under the MIT license. 14265 * https://jquery.org/license 14266 */ 14267 14268//>>label: Progressbar 14269//>>group: Widgets 14270//>>
vendor: 4,842 bytes, lines 14270-14476
14270description: Displays a status indicator for loading state, standard percentage, and other progress indicators. 14271//>>docs: https://api.jqueryui.com/progressbar/ 14272//>>demos: https://jqueryui.com/progressbar/ 14273//>>css.structure: ../../themes/base/core.css 14274//>>css.structure: ../../themes/base/progressbar.css 14275//>>css.theme: ../../themes/base/theme.css 14276 14277( function( factory ) { 14278 "use strict"; 14279 14280 if ( typeof define === "function" && define.amd ) { 14281 14282 // AMD. Register as an anonymous module. 14283 define( 'ui/widgets/progressbar.js',[ 14284 "jquery", 14285 "../version", 14286 "../widget" 14287 ], factory ); 14288 } else { 14289 14290 // Browser globals 14291 factory( jQuery ); 14292 } 14293} )( function( $ ) { 14294"use strict"; 14295 14296return $.widget( "ui.progressbar", { 14297 version: "@VERSION", 14298 options: { 14299 classes: { 14300 "ui-progressbar": "ui-corner-all", 14301 "ui-progressbar-value": "ui-corner-left", 14302 "ui-progressbar-complete": "ui-corner-right" 14303 }, 14304 max: 100, 14305 value: 0, 14306 14307 change: null, 14308 complete: null 14309 }, 14310 14311 min: 0, 14312 14313 _create: function() { 14314 14315 // Constrain initial value 14316 this.oldValue = this.options.value = this._constrainedValue(); 14317 14318 this.element.attr( { 14319 14320 // Only set static values; aria-valuenow and aria-valuemax are 14321 // set inside _refreshValue() 14322 role: "progressbar", 14323 "aria-valuemin": this.min 14324 } ); 14325 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); 14326 14327 this.valueDiv = $( "<div>" ).appendTo( this.element ); 14328 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 14329 this._refreshValue(); 14330 }, 14331 14332 _destroy: function() { 14333 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); 14334 14335 this.valueDiv.remove(); 14336 }, 14337 14338 value: function( newValue ) { 14339 if ( newValue === undefined ) { 14340 return this.options.value; 14341 } 14342 14343 this.options.value = this._constrainedValue( newValue ); 14344 this._refreshValue(); 14345 }, 14346 14347 _constrainedValue: function( newValue ) { 14348 if ( newValue === undefined ) { 14349 newValue = this.options.value; 14350 } 14351 14352 this.indeterminate = newValue === false; 14353 14354 // Sanitize value 14355 if ( typeof newValue !== "number" ) { 14356 newValue = 0; 14357 } 14358 14359 return this.indeterminate ? false : 14360 Math.min( this.options.max, Math.max( this.min, newValue ) ); 14361 }, 14362 14363 _setOptions: function( options ) { 14364 14365 // Ensure "value" option is set after other values (like max) 14366 var value = options.value; 14367 delete options.value; 14368 14369 this._super( options ); 14370 14371 this.options.value = this._constrainedValue( value ); 14372 this._refreshValue(); 14373 }, 14374 14375 _setOption: function( key, value ) { 14376 if ( key === "max" ) { 14377 14378 // Don't allow a max less than min 14379 value = Math.max( this.min, value ); 14380 } 14381 this._super( key, value ); 14382 }, 14383 14384 _setOptionDisabled: function( value ) { 14385 this._super( value ); 14386 14387 this.element.attr( "aria-disabled", value ); 14388 this._toggleClass( null, "ui-state-disabled", !!value ); 14389 }, 14390 14391 _percentage: function() { 14392 return this.indeterminate ? 14393 100 : 14394 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 14395 }, 14396 14397 _refreshValue: function() { 14398 var value = this.options.value, 14399 percentage = this._percentage(); 14400 14401 this.valueDiv 14402 .toggle( this.indeterminate || value > this.min ) 14403 .width( percentage.toFixed( 0 ) + "%" ); 14404 14405 this 14406 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, 14407 value === this.options.max ) 14408 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); 14409 14410 if ( this.indeterminate ) { 14411 this.element.removeAttr( "aria-valuenow" ); 14412 if ( !this.overlayDiv ) { 14413 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); 14414 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); 14415 } 14416 } else { 14417 this.element.attr( { 14418 "aria-valuemax": this.options.max, 14419 "aria-valuenow": value 14420 } ); 14421 if ( this.overlayDiv ) { 14422 this.overlayDiv.remove(); 14423 this.overlayDiv = null; 14424 } 14425 } 14426 14427 if ( this.oldValue !== value ) { 14428 this.oldValue = value; 14429 this._trigger( "change" ); 14430 } 14431 if ( value === this.options.max ) { 14432 this._trigger( "complete" ); 14433 } 14434 } 14435} ); 14436 14437} ); 14438 14439/*! 14440 * jQuery UI Selectable @VERSION 14441 * https://jqueryui.com 14442 * 14443 * Copyright OpenJS Foundation and other contributors 14444 * Released under the MIT license. 14445 * https://jquery.org/license 14446 */ 14447 14448//>>label: Selectable 14449//>>group: Interactions 14450//>>description: Allows groups of elements to be selected with the mouse. 14451//>>docs: https://api.jqueryui.com/selectable/ 14452//>>demos: https://jqueryui.com/selectable/ 14453//>>css.structure: ../../themes/base/selectable.css 14454 14455( function( factory ) { 14456 "use strict"; 14457 14458 if ( typeof define === "function" && define.amd ) { 14459 14460 // AMD. Register as an anonymous module. 14461 define( 'ui/widgets/selectable.js',[ 14462 "jquery", 14463 "./mouse", 14464 "../version", 14465 "../widget" 14466 ], factory ); 14467 } else { 14468 14469 // Browser globals 14470 factory( jQuery ); 14471 } 14472} )( function( $ ) { 14473"use strict"; 14474 14475return $.widget( "ui.selectable", $.ui.mouse, { 14476 version: "@VERSION
vendor: 7,293 bytes, lines 14476-14754
14476", 14477 options: { 14478 appendTo: "body", 14479 autoRefresh: true, 14480 distance: 0, 14481 filter: "*", 14482 tolerance: "touch", 14483 14484 // Callbacks 14485 selected: null, 14486 selecting: null, 14487 start: null, 14488 stop: null, 14489 unselected: null, 14490 unselecting: null 14491 }, 14492 _create: function() { 14493 var that = this; 14494 14495 this._addClass( "ui-selectable" ); 14496 14497 this.dragged = false; 14498 14499 // Cache selectee children based on filter 14500 this.refresh = function() { 14501 that.elementPos = $( that.element[ 0 ] ).offset(); 14502 that.selectees = $( that.options.filter, that.element[ 0 ] ); 14503 that._addClass( that.selectees, "ui-selectee" ); 14504 that.selectees.each( function() { 14505 var $this = $( this ), 14506 selecteeOffset = $this.offset(), 14507 pos = { 14508 left: selecteeOffset.left - that.elementPos.left, 14509 top: selecteeOffset.top - that.elementPos.top 14510 }; 14511 $.data( this, "selectable-item", { 14512 element: this, 14513 $element: $this, 14514 left: pos.left, 14515 top: pos.top, 14516 right: pos.left + $this.outerWidth(), 14517 bottom: pos.top + $this.outerHeight(), 14518 startselected: false, 14519 selected: $this.hasClass( "ui-selected" ), 14520 selecting: $this.hasClass( "ui-selecting" ), 14521 unselecting: $this.hasClass( "ui-unselecting" ) 14522 } ); 14523 } ); 14524 }; 14525 this.refresh(); 14526 14527 this._mouseInit(); 14528 14529 this.helper = $( "<div>" ); 14530 this._addClass( this.helper, "ui-selectable-helper" ); 14531 }, 14532 14533 _destroy: function() { 14534 this.selectees.removeData( "selectable-item" ); 14535 this._mouseDestroy(); 14536 }, 14537 14538 _mouseStart: function( event ) { 14539 var that = this, 14540 options = this.options; 14541 14542 this.opos = [ event.pageX, event.pageY ]; 14543 this.elementPos = $( this.element[ 0 ] ).offset(); 14544 14545 if ( this.options.disabled ) { 14546 return; 14547 } 14548 14549 this.selectees = $( options.filter, this.element[ 0 ] ); 14550 14551 this._trigger( "start", event ); 14552 14553 $( options.appendTo ).append( this.helper ); 14554 14555 // position helper (lasso) 14556 this.helper.css( { 14557 "left": event.pageX, 14558 "top": event.pageY, 14559 "width": 0, 14560 "height": 0 14561 } ); 14562 14563 if ( options.autoRefresh ) { 14564 this.refresh(); 14565 } 14566 14567 this.selectees.filter( ".ui-selected" ).each( function() { 14568 var selectee = $.data( this, "selectable-item" ); 14569 selectee.startselected = true; 14570 if ( !event.metaKey && !event.ctrlKey ) { 14571 that._removeClass( selectee.$element, "ui-selected" ); 14572 selectee.selected = false; 14573 that._addClass( selectee.$element, "ui-unselecting" ); 14574 selectee.unselecting = true; 14575 14576 // selectable UNSELECTING callback 14577 that._trigger( "unselecting", event, { 14578 unselecting: selectee.element 14579 } ); 14580 } 14581 } ); 14582 14583 $( event.target ).parents().addBack().each( function() { 14584 var doSelect, 14585 selectee = $.data( this, "selectable-item" ); 14586 if ( selectee ) { 14587 doSelect = ( !event.metaKey && !event.ctrlKey ) || 14588 !selectee.$element.hasClass( "ui-selected" ); 14589 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 14590 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 14591 selectee.unselecting = !doSelect; 14592 selectee.selecting = doSelect; 14593 selectee.selected = doSelect; 14594 14595 // selectable (UN)SELECTING callback 14596 if ( doSelect ) { 14597 that._trigger( "selecting", event, { 14598 selecting: selectee.element 14599 } ); 14600 } else { 14601 that._trigger( "unselecting", event, { 14602 unselecting: selectee.element 14603 } ); 14604 } 14605 return false; 14606 } 14607 } ); 14608 14609 }, 14610 14611 _mouseDrag: function( event ) { 14612 14613 this.dragged = true; 14614 14615 if ( this.options.disabled ) { 14616 return; 14617 } 14618 14619 var tmp, 14620 that = this, 14621 options = this.options, 14622 x1 = this.opos[ 0 ], 14623 y1 = this.opos[ 1 ], 14624 x2 = event.pageX, 14625 y2 = event.pageY; 14626 14627 if ( x1 > x2 ) { 14628 tmp = x2; x2 = x1; x1 = tmp; 14629 } 14630 if ( y1 > y2 ) { 14631 tmp = y2; y2 = y1; y1 = tmp; 14632 } 14633 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 14634 14635 this.selectees.each( function() { 14636 var selectee = $.data( this, "selectable-item" ), 14637 hit = false, 14638 offset = {}; 14639 14640 //prevent helper from being selected if appendTo: selectable 14641 if ( !selectee || selectee.element === that.element[ 0 ] ) { 14642 return; 14643 } 14644 14645 offset.left = selectee.left + that.elementPos.left; 14646 offset.right = selectee.right + that.elementPos.left; 14647 offset.top = selectee.top + that.elementPos.top; 14648 offset.bottom = selectee.bottom + that.elementPos.top; 14649 14650 if ( options.tolerance === "touch" ) { 14651 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 14652 offset.bottom < y1 ) ); 14653 } else if ( options.tolerance === "fit" ) { 14654 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 14655 offset.bottom < y2 ); 14656 } 14657 14658 if ( hit ) { 14659 14660 // SELECT 14661 if ( selectee.selected ) { 14662 that._removeClass( selectee.$element, "ui-selected" ); 14663 selectee.selected = false; 14664 } 14665 if ( selectee.unselecting ) { 14666 that._removeClass( selectee.$element, "ui-unselecting" ); 14667 selectee.unselecting = false; 14668 } 14669 if ( !selectee.selecting ) { 14670 that._addClass( selectee.$element, "ui-selecting" ); 14671 selectee.selecting = true; 14672 14673 // selectable SELECTING callback 14674 that._trigger( "selecting", event, { 14675 selecting: selectee.element 14676 } ); 14677 } 14678 } else { 14679 14680 // UNSELECT 14681 if ( selectee.selecting ) { 14682 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 14683 that._removeClass( selectee.$element, "ui-selecting" ); 14684 selectee.selecting = false; 14685 that._addClass( selectee.$element, "ui-selected" ); 14686 selectee.selected = true; 14687 } else { 14688 that._removeClass( selectee.$element, "ui-selecting" ); 14689 selectee.selecting = false; 14690 if ( selectee.startselected ) { 14691 that._addClass( selectee.$element, "ui-unselecting" ); 14692 selectee.unselecting = true; 14693 } 14694 14695 // selectable UNSELECTING callback 14696 that._trigger( "unselecting", event, { 14697 unselecting: selectee.element 14698 } ); 14699 } 14700 } 14701 if ( selectee.selected ) { 14702 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 14703 that._removeClass( selectee.$element, "ui-selected" ); 14704 selectee.selected = false; 14705 14706 that._addClass( selectee.$element, "ui-unselecting" ); 14707 selectee.unselecting = true; 14708 14709 // selectable UNSELECTING callback 14710 that._trigger( "unselecting", event, { 14711 unselecting: selectee.element 14712 } ); 14713 } 14714 } 14715 } 14716 } ); 14717 14718 return false; 14719 }, 14720 14721 _mouseStop: function( event ) { 14722 var that = this; 14723 14724 this.dragged = false; 14725 14726 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 14727 var selectee = $.data( this, "selectable-item" ); 14728 that._removeClass( selectee.$element, "ui-unselecting" ); 14729 selectee.unselecting = false; 14730 selectee.startselected = false; 14731 that._trigger( "unselected", event, { 14732 unselected: selectee.element 14733 } ); 14734 } ); 14735 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 14736 var selectee = $.data( this, "selectable-item" ); 14737 that._removeClass( selectee.$element, "ui-selecting" ) 14738 ._addClass( selectee.$element, "ui-selected" ); 14739 selectee.selecting = false; 14740 selectee.selected = true; 14741 selectee.startselected = true; 14742 that._trigger( "selected", event, { 14743 selected: selectee.element 14744 } ); 14745 } ); 14746 this._trigger( "stop", event ); 14747 14748 this.helper.remove(); 14749 14750 return false; 14751 } 14752 14753} ); 14754
vendor: 43,988 bytes, lines 14755-16532
14755} ); 14756 14757/*! 14758 * jQuery UI Selectmenu @VERSION 14759 * https://jqueryui.com 14760 * 14761 * Copyright OpenJS Foundation and other contributors 14762 * Released under the MIT license. 14763 * https://jquery.org/license 14764 */ 14765 14766//>>label: Selectmenu 14767//>>group: Widgets 14768//>>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. 14769//>>docs: https://api.jqueryui.com/selectmenu/ 14770//>>demos: https://jqueryui.com/selectmenu/ 14771//>>css.structure: ../../themes/base/core.css 14772//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css 14773//>>css.theme: ../../themes/base/theme.css 14774 14775( function( factory ) { 14776 "use strict"; 14777 14778 if ( typeof define === "function" && define.amd ) { 14779 14780 // AMD. Register as an anonymous module. 14781 define( 'ui/widgets/selectmenu.js',[ 14782 "jquery", 14783 "./menu", 14784 "../form-reset-mixin", 14785 "../keycode", 14786 "../labels", 14787 "../position", 14788 "../unique-id", 14789 "../version", 14790 "../widget" 14791 ], factory ); 14792 } else { 14793 14794 // Browser globals 14795 factory( jQuery ); 14796 } 14797} )( function( $ ) { 14798"use strict"; 14799 14800return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { 14801 version: "@VERSION", 14802 defaultElement: "<select>", 14803 options: { 14804 appendTo: null, 14805 classes: { 14806 "ui-selectmenu-button-open": "ui-corner-top", 14807 "ui-selectmenu-button-closed": "ui-corner-all" 14808 }, 14809 disabled: null, 14810 icons: { 14811 button: "ui-icon-triangle-1-s" 14812 }, 14813 position: { 14814 my: "left top", 14815 at: "left bottom", 14816 collision: "none" 14817 }, 14818 width: false, 14819 14820 // Callbacks 14821 change: null, 14822 close: null, 14823 focus: null, 14824 open: null, 14825 select: null 14826 }, 14827 14828 _create: function() { 14829 var selectmenuId = this.element.uniqueId().attr( "id" ); 14830 this.ids = { 14831 element: selectmenuId, 14832 button: selectmenuId + "-button", 14833 menu: selectmenuId + "-menu" 14834 }; 14835 14836 this._drawButton(); 14837 this._drawMenu(); 14838 this._bindFormResetHandler(); 14839 14840 this._rendered = false; 14841 this.menuItems = $(); 14842 }, 14843 14844 _drawButton: function() { 14845 var icon, 14846 that = this, 14847 item = this._parseOption( 14848 this.element.find( "option:selected" ), 14849 this.element[ 0 ].selectedIndex 14850 ); 14851 14852 // Associate existing label with the new button 14853 this.labels = this.element.labels().attr( "for", this.ids.button ); 14854 this._on( this.labels, { 14855 click: function( event ) { 14856 this.button.trigger( "focus" ); 14857 event.preventDefault(); 14858 } 14859 } ); 14860 14861 // Hide original select element 14862 this.element.hide(); 14863 14864 // Create button 14865 this.button = $( "<span>", { 14866 tabindex: this.options.disabled ? -1 : 0, 14867 id: this.ids.button, 14868 role: "combobox", 14869 "aria-expanded": "false", 14870 "aria-autocomplete": "list", 14871 "aria-owns": this.ids.menu, 14872 "aria-haspopup": "true", 14873 title: this.element.attr( "title" ) 14874 } ) 14875 .insertAfter( this.element ); 14876 14877 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", 14878 "ui-button ui-widget" ); 14879 14880 icon = $( "<span>" ).appendTo( this.button ); 14881 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); 14882 this.buttonItem = this._renderButtonItem( item ) 14883 .appendTo( this.button ); 14884 14885 if ( this.options.width !== false ) { 14886 this._resizeButton(); 14887 } 14888 14889 this._on( this.button, this._buttonEvents ); 14890 this.button.one( "focusin", function() { 14891 14892 // Delay rendering the menu items until the button receives focus. 14893 // The menu may have already been rendered via a programmatic open. 14894 if ( !that._rendered ) { 14895 that._refreshMenu(); 14896 } 14897 } ); 14898 }, 14899 14900 _drawMenu: function() { 14901 var that = this; 14902 14903 // Create menu 14904 this.menu = $( "<ul>", { 14905 "aria-hidden": "true", 14906 "aria-labelledby": this.ids.button, 14907 id: this.ids.menu 14908 } ); 14909 14910 // Wrap menu 14911 this.menuWrap = $( "<div>" ).append( this.menu ); 14912 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); 14913 this.menuWrap.appendTo( this._appendTo() ); 14914 14915 // Initialize menu widget 14916 this.menuInstance = this.menu 14917 .menu( { 14918 classes: { 14919 "ui-menu": "ui-corner-bottom" 14920 }, 14921 role: "listbox", 14922 select: function( event, ui ) { 14923 event.preventDefault(); 14924 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 14925 }, 14926 focus: function( event, ui ) { 14927 var item = ui.item.data( "ui-selectmenu-item" ); 14928 14929 // Prevent inital focus from firing and check if its a newly focused item 14930 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 14931 that._trigger( "focus", event, { item: item } ); 14932 if ( !that.isOpen ) { 14933 that._select( item, event ); 14934 } 14935 } 14936 that.focusIndex = item.index; 14937 14938 that.button.attr( "aria-activedescendant", 14939 that.menuItems.eq( item.index ).attr( "id" ) ); 14940 } 14941 } ) 14942 .menu( "instance" ); 14943 14944 // Don't close the menu on mouseleave 14945 this.menuInstance._off( this.menu, "mouseleave" ); 14946 14947 // Cancel the menu's collapseAll on document click 14948 this.menuInstance._closeOnDocumentClick = function() { 14949 return false; 14950 }; 14951 14952 // Selects often contain empty items, but never contain dividers 14953 this.menuInstance._isDivider = function() { 14954 return false; 14955 }; 14956 }, 14957 14958 refresh: function() { 14959 this._refreshMenu(); 14960 this.buttonItem.replaceWith( 14961 this.buttonItem = this._renderButtonItem( 14962 14963 // Fall back to an empty object in case there are no options 14964 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} 14965 ) 14966 ); 14967 if ( this.options.width === null ) { 14968 this._resizeButton(); 14969 } 14970 }, 14971 14972 _refreshMenu: function() { 14973 var item, 14974 options = this.element.find( "option" ); 14975 14976 this.menu.empty(); 14977 14978 this._parseOptions( options ); 14979 this._renderMenu( this.menu, this.items ); 14980 14981 this.menuInstance.refresh(); 14982 this.menuItems = this.menu.find( "li" ) 14983 .not( ".ui-selectmenu-optgroup" ) 14984 .find( ".ui-menu-item-wrapper" ); 14985 14986 this._rendered = true; 14987 14988 if ( !options.length ) { 14989 return; 14990 } 14991 14992 item = this._getSelectedItem(); 14993 14994 // Update the menu to have the correct item focused 14995 this.menuInstance.focus( null, item ); 14996 this._setAria( item.data( "ui-selectmenu-item" ) ); 14997 14998 // Set disabled state 14999 this._setOption( "disabled", this.element.prop( "disabled" ) ); 15000 }, 15001 15002 open: function( event ) { 15003 if ( this.options.disabled ) { 15004 return; 15005 } 15006 15007 // If this is the first time the menu is being opened, render the items 15008 if ( !this._rendered ) { 15009 this._refreshMenu(); 15010 } else { 15011 15012 // Menu clears focus on close, reset focus to selected item 15013 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); 15014 this.menuInstance.focus( null, this._getSelectedItem() ); 15015 } 15016 15017 // If there are no options, don't open the menu 15018 if ( !this.menuItems.length ) { 15019 return; 15020 } 15021 15022 this.isOpen = true; 15023 this._toggleAttr(); 15024 this._resizeMenu(); 15025 this._position(); 15026 15027 this._on( this.document, this._documentClick ); 15028 15029 this._trigger( "open", event ); 15030 }, 15031 15032 _position: function() { 15033 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 15034 }, 15035 15036 close: function( event ) { 15037 if ( !this.isOpen ) { 15038 return; 15039 } 15040 15041 this.isOpen = false; 15042 this._toggleAttr(); 15043 15044 this.range = null; 15045 this._off( this.document ); 15046 15047 this._trigger( "close", event ); 15048 }, 15049 15050 widget: function() { 15051 return this.button; 15052 }, 15053 15054 menuWidget: function() { 15055 return this.menu; 15056 }, 15057 15058 _renderButtonItem: function( item ) { 15059 var buttonItem = $( "<span>" ); 15060 15061 this._setText( buttonItem, item.label ); 15062 this._addClass( buttonItem, "ui-selectmenu-text" ); 15063 15064 return buttonItem; 15065 }, 15066 15067 _renderMenu: function( ul, items ) { 15068 var that = this, 15069 currentOptgroup = ""; 15070 15071 $.each( items, function( index, item ) { 15072 var li; 15073 15074 if ( item.optgroup !== currentOptgroup ) { 15075 li = $( "<li>", { 15076 text: item.optgroup 15077 } ); 15078 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + 15079 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 15080 " ui-state-disabled" : 15081 "" ) ); 15082 15083 li.appendTo( ul ); 15084 15085 currentOptgroup = item.optgroup; 15086 } 15087 15088 that._renderItemData( ul, item ); 15089 } ); 15090 }, 15091 15092 _renderItemData: function( ul, item ) { 15093 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 15094 }, 15095 15096 _renderItem: function( ul, item ) { 15097 var li = $( "<li>" ), 15098 wrapper = $( "<div>", { 15099 title: item.element.attr( "title" ) 15100 } ); 15101 15102 if ( item.disabled ) { 15103 this._addClass( li, null, "ui-state-disabled" ); 15104 } 15105 15106 if ( item.hidden ) { 15107 li.prop( "hidden", true ); 15108 } else { 15109 this._setText( wrapper, item.label ); 15110 } 15111 15112 return li.append( wrapper ).appendTo( ul ); 15113 }, 15114 15115 _setText: function( element, value ) { 15116 if ( value ) { 15117 element.text( value ); 15118 } else { 15119 element.html( " " ); 15120 } 15121 }, 15122 15123 _move: function( direction, event ) { 15124 var item, next, 15125 filter = ".ui-menu-item"; 15126 15127 if ( this.isOpen ) { 15128 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 15129 } else { 15130 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 15131 filter += ":not(.ui-state-disabled)"; 15132 } 15133 15134 if ( direction === "first" || direction === "last" ) { 15135 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 15136 } else { 15137 next = item[ direction + "All" ]( filter ).eq( 0 ); 15138 } 15139 15140 if ( next.length ) { 15141 this.menuInstance.focus( event, next ); 15142 } 15143 }, 15144 15145 _getSelectedItem: function() { 15146 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 15147 }, 15148 15149 _toggle: function( event ) { 15150 this[ this.isOpen ? "close" : "open" ]( event ); 15151 }, 15152 15153 _setSelection: function() { 15154 var selection; 15155 15156 if ( !this.range ) { 15157 return; 15158 } 15159 15160 selection = window.getSelection(); 15161 selection.removeAllRanges(); 15162 selection.addRange( this.range ); 15163 }, 15164 15165 _documentClick: { 15166 mousedown: function( event ) { 15167 if ( !this.isOpen ) { 15168 return; 15169 } 15170 15171 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + 15172 CSS.escape( this.ids.button ) ).length ) { 15173 this.close( event ); 15174 } 15175 } 15176 }, 15177 15178 _buttonEvents: { 15179 15180 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 15181 mousedown: function() { 15182 var selection = window.getSelection(); 15183 if ( selection.rangeCount ) { 15184 this.range = selection.getRangeAt( 0 ); 15185 } 15186 }, 15187 15188 click: function( event ) { 15189 this._setSelection(); 15190 this._toggle( event ); 15191 }, 15192 15193 keydown: function( event ) { 15194 var preventDefault = true; 15195 switch ( event.keyCode ) { 15196 case $.ui.keyCode.TAB: 15197 case $.ui.keyCode.ESCAPE: 15198 this.close( event ); 15199 preventDefault = false; 15200 break; 15201 case $.ui.keyCode.ENTER: 15202 if ( this.isOpen ) { 15203 this._selectFocusedItem( event ); 15204 } 15205 break; 15206 case $.ui.keyCode.UP: 15207 if ( event.altKey ) { 15208 this._toggle( event ); 15209 } else { 15210 this._move( "prev", event ); 15211 } 15212 break; 15213 case $.ui.keyCode.DOWN: 15214 if ( event.altKey ) { 15215 this._toggle( event ); 15216 } else { 15217 this._move( "next", event ); 15218 } 15219 break; 15220 case $.ui.keyCode.SPACE: 15221 if ( this.isOpen ) { 15222 this._selectFocusedItem( event ); 15223 } else { 15224 this._toggle( event ); 15225 } 15226 break; 15227 case $.ui.keyCode.LEFT: 15228 this._move( "prev", event ); 15229 break; 15230 case $.ui.keyCode.RIGHT: 15231 this._move( "next", event ); 15232 break; 15233 case $.ui.keyCode.HOME: 15234 case $.ui.keyCode.PAGE_UP: 15235 this._move( "first", event ); 15236 break; 15237 case $.ui.keyCode.END: 15238 case $.ui.keyCode.PAGE_DOWN: 15239 this._move( "last", event ); 15240 break; 15241 default: 15242 this.menu.trigger( event ); 15243 preventDefault = false; 15244 } 15245 15246 if ( preventDefault ) { 15247 event.preventDefault(); 15248 } 15249 } 15250 }, 15251 15252 _selectFocusedItem: function( event ) { 15253 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 15254 if ( !item.hasClass( "ui-state-disabled" ) ) { 15255 this._select( item.data( "ui-selectmenu-item" ), event ); 15256 } 15257 }, 15258 15259 _select: function( item, event ) { 15260 var oldIndex = this.element[ 0 ].selectedIndex; 15261 15262 // Change native select element 15263 this.element[ 0 ].selectedIndex = item.index; 15264 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); 15265 this._setAria( item ); 15266 this._trigger( "select", event, { item: item } ); 15267 15268 if ( item.index !== oldIndex ) { 15269 this._trigger( "change", event, { item: item } ); 15270 } 15271 15272 this.close( event ); 15273 }, 15274 15275 _setAria: function( item ) { 15276 var id = this.menuItems.eq( item.index ).attr( "id" ); 15277 15278 this.button.attr( { 15279 "aria-labelledby": id, 15280 "aria-activedescendant": id 15281 } ); 15282 this.menu.attr( "aria-activedescendant", id ); 15283 }, 15284 15285 _setOption: function( key, value ) { 15286 if ( key === "icons" ) { 15287 var icon = this.button.find( "span.ui-icon" ); 15288 this._removeClass( icon, null, this.options.icons.button ) 15289 ._addClass( icon, null, value.button ); 15290 } 15291 15292 this._super( key, value ); 15293 15294 if ( key === "appendTo" ) { 15295 this.menuWrap.appendTo( this._appendTo() ); 15296 } 15297 15298 if ( key === "width" ) { 15299 this._resizeButton(); 15300 } 15301 }, 15302 15303 _setOptionDisabled: function( value ) { 15304 this._super( value ); 15305 15306 this.menuInstance.option( "disabled", value ); 15307 this.button.attr( "aria-disabled", value ); 15308 this._toggleClass( this.button, null, "ui-state-disabled", value ); 15309 15310 this.element.prop( "disabled", value ); 15311 if ( value ) { 15312 this.button.attr( "tabindex", -1 ); 15313 this.close(); 15314 } else { 15315 this.button.attr( "tabindex", 0 ); 15316 } 15317 }, 15318 15319 _appendTo: function() { 15320 var element = this.options.appendTo; 15321 15322 if ( element ) { 15323 element = element.jquery || element.nodeType ? 15324 $( element ) : 15325 this.document.find( element ).eq( 0 ); 15326 } 15327 15328 if ( !element || !element[ 0 ] ) { 15329 element = this.element.closest( ".ui-front, dialog" ); 15330 } 15331 15332 if ( !element.length ) { 15333 element = this.document[ 0 ].body; 15334 } 15335 15336 return element; 15337 }, 15338 15339 _toggleAttr: function() { 15340 this.button.attr( "aria-expanded", this.isOpen ); 15341 15342 // We can't use two _toggleClass() calls here, because we need to make sure 15343 // we always remove classes first and add them second, otherwise if both classes have the 15344 // same theme class, it will be removed after we add it. 15345 this._removeClass( this.button, "ui-selectmenu-button-" + 15346 ( this.isOpen ? "closed" : "open" ) ) 15347 ._addClass( this.button, "ui-selectmenu-button-" + 15348 ( this.isOpen ? "open" : "closed" ) ) 15349 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); 15350 15351 this.menu.attr( "aria-hidden", !this.isOpen ); 15352 }, 15353 15354 _resizeButton: function() { 15355 var width = this.options.width; 15356 15357 // For `width: false`, just remove inline style and stop 15358 if ( width === false ) { 15359 this.button.css( "width", "" ); 15360 return; 15361 } 15362 15363 // For `width: null`, match the width of the original element 15364 if ( width === null ) { 15365 width = this.element.show().outerWidth(); 15366 this.element.hide(); 15367 } 15368 15369 this.button.outerWidth( width ); 15370 }, 15371 15372 _resizeMenu: function() { 15373 this.menu.outerWidth( Math.max( 15374 this.button.outerWidth(), 15375 this.menu.width( "" ).outerWidth() 15376 ) ); 15377 }, 15378 15379 _getCreateOptions: function() { 15380 var options = this._super(); 15381 15382 options.disabled = this.element.prop( "disabled" ); 15383 15384 return options; 15385 }, 15386 15387 _parseOptions: function( options ) { 15388 var that = this, 15389 data = []; 15390 options.each( function( index, item ) { 15391 data.push( that._parseOption( $( item ), index ) ); 15392 } ); 15393 this.items = data; 15394 }, 15395 15396 _parseOption: function( option, index ) { 15397 var optgroup = option.parent( "optgroup" ); 15398 15399 return { 15400 element: option, 15401 index: index, 15402 value: option.val(), 15403 label: option.text(), 15404 hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ), 15405 optgroup: optgroup.attr( "label" ) || "", 15406 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 15407 }; 15408 }, 15409 15410 _destroy: function() { 15411 this._unbindFormResetHandler(); 15412 this.menuWrap.remove(); 15413 this.button.remove(); 15414 this.element.show(); 15415 this.element.removeUniqueId(); 15416 this.labels.attr( "for", this.ids.element ); 15417 } 15418} ] ); 15419 15420} ); 15421 15422/*! 15423 * jQuery UI Slider @VERSION 15424 * https://jqueryui.com 15425 * 15426 * Copyright OpenJS Foundation and other contributors 15427 * Released under the MIT license. 15428 * https://jquery.org/license 15429 */ 15430 15431//>>label: Slider 15432//>>group: Widgets 15433//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 15434//>>docs: https://api.jqueryui.com/slider/ 15435//>>demos: https://jqueryui.com/slider/ 15436//>>css.structure: ../../themes/base/core.css 15437//>>css.structure: ../../themes/base/slider.css 15438//>>css.theme: ../../themes/base/theme.css 15439 15440( function( factory ) { 15441 "use strict"; 15442 15443 if ( typeof define === "function" && define.amd ) { 15444 15445 // AMD. Register as an anonymous module. 15446 define( 'ui/widgets/slider.js',[ 15447 "jquery", 15448 "./mouse", 15449 "../keycode", 15450 "../version", 15451 "../widget" 15452 ], factory ); 15453 } else { 15454 15455 // Browser globals 15456 factory( jQuery ); 15457 } 15458} )( function( $ ) { 15459"use strict"; 15460 15461return $.widget( "ui.slider", $.ui.mouse, { 15462 version: "@VERSION", 15463 widgetEventPrefix: "slide", 15464 15465 options: { 15466 animate: false, 15467 classes: { 15468 "ui-slider": "ui-corner-all", 15469 "ui-slider-handle": "ui-corner-all", 15470 15471 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 15472 // element, but worked best visually with a variety of themes 15473 "ui-slider-range": "ui-corner-all ui-widget-header" 15474 }, 15475 distance: 0, 15476 max: 100, 15477 min: 0, 15478 orientation: "horizontal", 15479 range: false, 15480 step: 1, 15481 value: 0, 15482 values: null, 15483 15484 // Callbacks 15485 change: null, 15486 slide: null, 15487 start: null, 15488 stop: null 15489 }, 15490 15491 // Number of pages in a slider 15492 // (how many times can you page up/down to go through the whole range) 15493 numPages: 5, 15494 15495 _create: function() { 15496 this._keySliding = false; 15497 this._mouseSliding = false; 15498 this._animateOff = true; 15499 this._handleIndex = null; 15500 this._detectOrientation(); 15501 this._mouseInit(); 15502 this._calculateNewMax(); 15503 15504 this._addClass( "ui-slider ui-slider-" + this.orientation, 15505 "ui-widget ui-widget-content" ); 15506 15507 this._refresh(); 15508 15509 this._animateOff = false; 15510 }, 15511 15512 _refresh: function() { 15513 this._createRange(); 15514 this._createHandles(); 15515 this._setupEvents(); 15516 this._refreshValue(); 15517 }, 15518 15519 _createHandles: function() { 15520 var i, handleCount, 15521 options = this.options, 15522 existingHandles = this.element.find( ".ui-slider-handle" ), 15523 handle = "<span tabindex='0'></span>", 15524 handles = []; 15525 15526 handleCount = ( options.values && options.values.length ) || 1; 15527 15528 if ( existingHandles.length > handleCount ) { 15529 existingHandles.slice( handleCount ).remove(); 15530 existingHandles = existingHandles.slice( 0, handleCount ); 15531 } 15532 15533 for ( i = existingHandles.length; i < handleCount; i++ ) { 15534 handles.push( handle ); 15535 } 15536 15537 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 15538 15539 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 15540 15541 this.handle = this.handles.eq( 0 ); 15542 15543 this.handles.each( function( i ) { 15544 $( this ) 15545 .data( "ui-slider-handle-index", i ) 15546 .attr( "tabIndex", 0 ); 15547 } ); 15548 }, 15549 15550 _createRange: function() { 15551 var options = this.options; 15552 15553 if ( options.range ) { 15554 if ( options.range === true ) { 15555 if ( !options.values ) { 15556 options.values = [ this._valueMin(), this._valueMin() ]; 15557 } else if ( options.values.length && options.values.length !== 2 ) { 15558 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 15559 } else if ( Array.isArray( options.values ) ) { 15560 options.values = options.values.slice( 0 ); 15561 } 15562 } 15563 15564 if ( !this.range || !this.range.length ) { 15565 this.range = $( "<div>" ) 15566 .appendTo( this.element ); 15567 15568 this._addClass( this.range, "ui-slider-range" ); 15569 } else { 15570 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 15571 15572 // Handle range switching from true to min/max 15573 this.range.css( { 15574 "left": "", 15575 "bottom": "" 15576 } ); 15577 } 15578 if ( options.range === "min" || options.range === "max" ) { 15579 this._addClass( this.range, "ui-slider-range-" + options.range ); 15580 } 15581 } else { 15582 if ( this.range ) { 15583 this.range.remove(); 15584 } 15585 this.range = null; 15586 } 15587 }, 15588 15589 _setupEvents: function() { 15590 this._off( this.handles ); 15591 this._on( this.handles, this._handleEvents ); 15592 this._hoverable( this.handles ); 15593 this._focusable( this.handles ); 15594 }, 15595 15596 _destroy: function() { 15597 this.handles.remove(); 15598 if ( this.range ) { 15599 this.range.remove(); 15600 } 15601 15602 this._mouseDestroy(); 15603 }, 15604 15605 _mouseCapture: function( event ) { 15606 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 15607 that = this, 15608 o = this.options; 15609 15610 if ( o.disabled ) { 15611 return false; 15612 } 15613 15614 this.elementSize = { 15615 width: this.element.outerWidth(), 15616 height: this.element.outerHeight() 15617 }; 15618 this.elementOffset = this.element.offset(); 15619 15620 position = { x: event.pageX, y: event.pageY }; 15621 normValue = this._normValueFromMouse( position ); 15622 distance = this._valueMax() - this._valueMin() + 1; 15623 this.handles.each( function( i ) { 15624 var thisDistance = Math.abs( normValue - that.values( i ) ); 15625 if ( ( distance > thisDistance ) || 15626 ( distance === thisDistance && 15627 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 15628 distance = thisDistance; 15629 closestHandle = $( this ); 15630 index = i; 15631 } 15632 } ); 15633 15634 allowed = this._start( event, index ); 15635 if ( allowed === false ) { 15636 return false; 15637 } 15638 this._mouseSliding = true; 15639 15640 this._handleIndex = index; 15641 15642 this._addClass( closestHandle, null, "ui-state-active" ); 15643 closestHandle.trigger( "focus" ); 15644 15645 offset = closestHandle.offset(); 15646 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 15647 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 15648 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 15649 top: event.pageY - offset.top - 15650 ( closestHandle.height() / 2 ) - 15651 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 15652 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 15653 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 15654 }; 15655 15656 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 15657 this._slide( event, index, normValue ); 15658 } 15659 this._animateOff = true; 15660 return true; 15661 }, 15662 15663 _mouseStart: function() { 15664 return true; 15665 }, 15666 15667 _mouseDrag: function( event ) { 15668 var position = { x: event.pageX, y: event.pageY }, 15669 normValue = this._normValueFromMouse( position ); 15670 15671 this._slide( event, this._handleIndex, normValue ); 15672 15673 return false; 15674 }, 15675 15676 _mouseStop: function( event ) { 15677 this._removeClass( this.handles, null, "ui-state-active" ); 15678 this._mouseSliding = false; 15679 15680 this._stop( event, this._handleIndex ); 15681 this._change( event, this._handleIndex ); 15682 15683 this._handleIndex = null; 15684 this._clickOffset = null; 15685 this._animateOff = false; 15686 15687 return false; 15688 }, 15689 15690 _detectOrientation: function() { 15691 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 15692 }, 15693 15694 _normValueFromMouse: function( position ) { 15695 var pixelTotal, 15696 pixelMouse, 15697 percentMouse, 15698 valueTotal, 15699 valueMouse; 15700 15701 if ( this.orientation === "horizontal" ) { 15702 pixelTotal = this.elementSize.width; 15703 pixelMouse = position.x - this.elementOffset.left - 15704 ( this._clickOffset ? this._clickOffset.left : 0 ); 15705 } else { 15706 pixelTotal = this.elementSize.height; 15707 pixelMouse = position.y - this.elementOffset.top - 15708 ( this._clickOffset ? this._clickOffset.top : 0 ); 15709 } 15710 15711 percentMouse = ( pixelMouse / pixelTotal ); 15712 if ( percentMouse > 1 ) { 15713 percentMouse = 1; 15714 } 15715 if ( percentMouse < 0 ) { 15716 percentMouse = 0; 15717 } 15718 if ( this.orientation === "vertical" ) { 15719 percentMouse = 1 - percentMouse; 15720 } 15721 15722 valueTotal = this._valueMax() - this._valueMin(); 15723 valueMouse = this._valueMin() + percentMouse * valueTotal; 15724 15725 return this._trimAlignValue( valueMouse ); 15726 }, 15727 15728 _uiHash: function( index, value, values ) { 15729 var uiHash = { 15730 handle: this.handles[ index ], 15731 handleIndex: index, 15732 value: value !== undefined ? value : this.value() 15733 }; 15734 15735 if ( this._hasMultipleValues() ) { 15736 uiHash.value = value !== undefined ? value : this.values( index ); 15737 uiHash.values = values || this.values(); 15738 } 15739 15740 return uiHash; 15741 }, 15742 15743 _hasMultipleValues: function() { 15744 return this.options.values && this.options.values.length; 15745 }, 15746 15747 _start: function( event, index ) { 15748 return this._trigger( "start", event, this._uiHash( index ) ); 15749 }, 15750 15751 _slide: function( event, index, newVal ) { 15752 var allowed, otherVal, 15753 currentValue = this.value(), 15754 newValues = this.values(); 15755 15756 if ( this._hasMultipleValues() ) { 15757 otherVal = this.values( index ? 0 : 1 ); 15758 currentValue = this.values( index ); 15759 15760 if ( this.options.values.length === 2 && this.options.range === true ) { 15761 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 15762 } 15763 15764 newValues[ index ] = newVal; 15765 } 15766 15767 if ( newVal === currentValue ) { 15768 return; 15769 } 15770 15771 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 15772 15773 // A slide can be canceled by returning false from the slide callback 15774 if ( allowed === false ) { 15775 return; 15776 } 15777 15778 if ( this._hasMultipleValues() ) { 15779 this.values( index, newVal ); 15780 } else { 15781 this.value( newVal ); 15782 } 15783 }, 15784 15785 _stop: function( event, index ) { 15786 this._trigger( "stop", event, this._uiHash( index ) ); 15787 }, 15788 15789 _change: function( event, index ) { 15790 if ( !this._keySliding && !this._mouseSliding ) { 15791 15792 //store the last changed value index for reference when handles overlap 15793 this._lastChangedValue = index; 15794 this._trigger( "change", event, this._uiHash( index ) ); 15795 } 15796 }, 15797 15798 value: function( newValue ) { 15799 if ( arguments.length ) { 15800 this.options.value = this._trimAlignValue( newValue ); 15801 this._refreshValue(); 15802 this._change( null, 0 ); 15803 return; 15804 } 15805 15806 return this._value(); 15807 }, 15808 15809 values: function( index, newValue ) { 15810 var vals, 15811 newValues, 15812 i; 15813 15814 if ( arguments.length > 1 ) { 15815 this.options.values[ index ] = this._trimAlignValue( newValue ); 15816 this._refreshValue(); 15817 this._change( null, index ); 15818 return; 15819 } 15820 15821 if ( arguments.length ) { 15822 if ( Array.isArray( arguments[ 0 ] ) ) { 15823 vals = this.options.values; 15824 newValues = arguments[ 0 ]; 15825 for ( i = 0; i < vals.length; i += 1 ) { 15826 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 15827 this._change( null, i ); 15828 } 15829 this._refreshValue(); 15830 } else { 15831 if ( this._hasMultipleValues() ) { 15832 return this._values( index ); 15833 } else { 15834 return this.value(); 15835 } 15836 } 15837 } else { 15838 return this._values(); 15839 } 15840 }, 15841 15842 _setOption: function( key, value ) { 15843 var i, 15844 valsLength = 0; 15845 15846 if ( key === "range" && this.options.range === true ) { 15847 if ( value === "min" ) { 15848 this.options.value = this._values( 0 ); 15849 this.options.values = null; 15850 } else if ( value === "max" ) { 15851 this.options.value = this._values( this.options.values.length - 1 ); 15852 this.options.values = null; 15853 } 15854 } 15855 15856 if ( Array.isArray( this.options.values ) ) { 15857 valsLength = this.options.values.length; 15858 } 15859 15860 this._super( key, value ); 15861 15862 switch ( key ) { 15863 case "orientation": 15864 this._detectOrientation(); 15865 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 15866 ._addClass( "ui-slider-" + this.orientation ); 15867 this._refreshValue(); 15868 if ( this.options.range ) { 15869 this._refreshRange( value ); 15870 } 15871 15872 // Reset positioning from previous orientation 15873 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 15874 break; 15875 case "value": 15876 this._animateOff = true; 15877 this._refreshValue(); 15878 this._change( null, 0 ); 15879 this._animateOff = false; 15880 break; 15881 case "values": 15882 this._animateOff = true; 15883 this._refreshValue(); 15884 15885 // Start from the last handle to prevent unreachable handles (#9046) 15886 for ( i = valsLength - 1; i >= 0; i-- ) { 15887 this._change( null, i ); 15888 } 15889 this._animateOff = false; 15890 break; 15891 case "step": 15892 case "min": 15893 case "max": 15894 this._animateOff = true; 15895 this._calculateNewMax(); 15896 this._refreshValue(); 15897 this._animateOff = false; 15898 break; 15899 case "range": 15900 this._animateOff = true; 15901 this._refresh(); 15902 this._animateOff = false; 15903 break; 15904 } 15905 }, 15906 15907 _setOptionDisabled: function( value ) { 15908 this._super( value ); 15909 15910 this._toggleClass( null, "ui-state-disabled", !!value ); 15911 }, 15912 15913 //internal value getter 15914 // _value() returns value trimmed by min and max, aligned by step 15915 _value: function() { 15916 var val = this.options.value; 15917 val = this._trimAlignValue( val ); 15918 15919 return val; 15920 }, 15921 15922 //internal values getter 15923 // _values() returns array of values trimmed by min and max, aligned by step 15924 // _values( index ) returns single value trimmed by min and max, aligned by step 15925 _values: function( index ) { 15926 var val, 15927 vals, 15928 i; 15929 15930 if ( arguments.length ) { 15931 val = this.options.values[ index ]; 15932 val = this._trimAlignValue( val ); 15933 15934 return val; 15935 } else if ( this._hasMultipleValues() ) { 15936 15937 // .slice() creates a copy of the array 15938 // this copy gets trimmed by min and max and then returned 15939 vals = this.options.values.slice(); 15940 for ( i = 0; i < vals.length; i += 1 ) { 15941 vals[ i ] = this._trimAlignValue( vals[ i ] ); 15942 } 15943 15944 return vals; 15945 } else { 15946 return []; 15947 } 15948 }, 15949 15950 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 15951 _trimAlignValue: function( val ) { 15952 if ( val <= this._valueMin() ) { 15953 return this._valueMin(); 15954 } 15955 if ( val >= this._valueMax() ) { 15956 return this._valueMax(); 15957 } 15958 var step = ( this.options.step > 0 ) ? this.options.step : 1, 15959 valModStep = ( val - this._valueMin() ) % step, 15960 alignValue = val - valModStep; 15961 15962 if ( Math.abs( valModStep ) * 2 >= step ) { 15963 alignValue += ( valModStep > 0 ) ? step : ( -step ); 15964 } 15965 15966 // Since JavaScript has problems with large floats, round 15967 // the final value to 5 digits after the decimal point (see #4124) 15968 return parseFloat( alignValue.toFixed( 5 ) ); 15969 }, 15970 15971 _calculateNewMax: function() { 15972 var max = this.options.max, 15973 min = this._valueMin(), 15974 step = this.options.step, 15975 aboveMin = Math.round( ( max - min ) / step ) * step; 15976 max = aboveMin + min; 15977 if ( max > this.options.max ) { 15978 15979 //If max is not divisible by step, rounding off may increase its value 15980 max -= step; 15981 } 15982 this.max = parseFloat( max.toFixed( this._precision() ) ); 15983 }, 15984 15985 _precision: function() { 15986 var precision = this._precisionOf( this.options.step ); 15987 if ( this.options.min !== null ) { 15988 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 15989 } 15990 return precision; 15991 }, 15992 15993 _precisionOf: function( num ) { 15994 var str = num.toString(), 15995 decimal = str.indexOf( "." ); 15996 return decimal === -1 ? 0 : str.length - decimal - 1; 15997 }, 15998 15999 _valueMin: function() { 16000 return this.options.min; 16001 }, 16002 16003 _valueMax: function() { 16004 return this.max; 16005 }, 16006 16007 _refreshRange: function( orientation ) { 16008 if ( orientation === "vertical" ) { 16009 this.range.css( { "width": "", "left": "" } ); 16010 } 16011 if ( orientation === "horizontal" ) { 16012 this.range.css( { "height": "", "bottom": "" } ); 16013 } 16014 }, 16015 16016 _refreshValue: function() { 16017 var lastValPercent, valPercent, value, valueMin, valueMax, 16018 oRange = this.options.range, 16019 o = this.options, 16020 that = this, 16021 animate = ( !this._animateOff ) ? o.animate : false, 16022 _set = {}; 16023 16024 if ( this._hasMultipleValues() ) { 16025 this.handles.each( function( i ) { 16026 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 16027 that._valueMin() ) * 100; 16028 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 16029 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 16030 if ( that.options.range === true ) { 16031 if ( that.orientation === "horizontal" ) { 16032 if ( i === 0 ) { 16033 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 16034 left: valPercent + "%" 16035 }, o.animate ); 16036 } 16037 if ( i === 1 ) { 16038 that.range[ animate ? "animate" : "css" ]( { 16039 width: ( valPercent - lastValPercent ) + "%" 16040 }, { 16041 queue: false, 16042 duration: o.animate 16043 } ); 16044 } 16045 } else { 16046 if ( i === 0 ) { 16047 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 16048 bottom: ( valPercent ) + "%" 16049 }, o.animate ); 16050 } 16051 if ( i === 1 ) { 16052 that.range[ animate ? "animate" : "css" ]( { 16053 height: ( valPercent - lastValPercent ) + "%" 16054 }, { 16055 queue: false, 16056 duration: o.animate 16057 } ); 16058 } 16059 } 16060 } 16061 lastValPercent = valPercent; 16062 } ); 16063 } else { 16064 value = this.value(); 16065 valueMin = this._valueMin(); 16066 valueMax = this._valueMax(); 16067 valPercent = ( valueMax !== valueMin ) ? 16068 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 16069 0; 16070 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 16071 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 16072 16073 if ( oRange === "min" && this.orientation === "horizontal" ) { 16074 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 16075 width: valPercent + "%" 16076 }, o.animate ); 16077 } 16078 if ( oRange === "max" && this.orientation === "horizontal" ) { 16079 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 16080 width: ( 100 - valPercent ) + "%" 16081 }, o.animate ); 16082 } 16083 if ( oRange === "min" && this.orientation === "vertical" ) { 16084 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 16085 height: valPercent + "%" 16086 }, o.animate ); 16087 } 16088 if ( oRange === "max" && this.orientation === "vertical" ) { 16089 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 16090 height: ( 100 - valPercent ) + "%" 16091 }, o.animate ); 16092 } 16093 } 16094 }, 16095 16096 _handleEvents: { 16097 keydown: function( event ) { 16098 var allowed, curVal, newVal, step, 16099 index = $( event.target ).data( "ui-slider-handle-index" ); 16100 16101 switch ( event.keyCode ) { 16102 case $.ui.keyCode.HOME: 16103 case $.ui.keyCode.END: 16104 case $.ui.keyCode.PAGE_UP: 16105 case $.ui.keyCode.PAGE_DOWN: 16106 case $.ui.keyCode.UP: 16107 case $.ui.keyCode.RIGHT: 16108 case $.ui.keyCode.DOWN: 16109 case $.ui.keyCode.LEFT: 16110 event.preventDefault(); 16111 if ( !this._keySliding ) { 16112 this._keySliding = true; 16113 this._addClass( $( event.target ), null, "ui-state-active" ); 16114 allowed = this._start( event, index ); 16115 if ( allowed === false ) { 16116 return; 16117 } 16118 } 16119 break; 16120 } 16121 16122 step = this.options.step; 16123 if ( this._hasMultipleValues() ) { 16124 curVal = newVal = this.values( index ); 16125 } else { 16126 curVal = newVal = this.value(); 16127 } 16128 16129 switch ( event.keyCode ) { 16130 case $.ui.keyCode.HOME: 16131 newVal = this._valueMin(); 16132 break; 16133 case $.ui.keyCode.END: 16134 newVal = this._valueMax(); 16135 break; 16136 case $.ui.keyCode.PAGE_UP: 16137 newVal = this._trimAlignValue( 16138 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 16139 ); 16140 break; 16141 case $.ui.keyCode.PAGE_DOWN: 16142 newVal = this._trimAlignValue( 16143 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 16144 break; 16145 case $.ui.keyCode.UP: 16146 case $.ui.keyCode.RIGHT: 16147 if ( curVal === this._valueMax() ) { 16148 return; 16149 } 16150 newVal = this._trimAlignValue( curVal + step ); 16151 break; 16152 case $.ui.keyCode.DOWN: 16153 case $.ui.keyCode.LEFT: 16154 if ( curVal === this._valueMin() ) { 16155 return; 16156 } 16157 newVal = this._trimAlignValue( curVal - step ); 16158 break; 16159 } 16160 16161 this._slide( event, index, newVal ); 16162 }, 16163 keyup: function( event ) { 16164 var index = $( event.target ).data( "ui-slider-handle-index" ); 16165 16166 if ( this._keySliding ) { 16167 this._keySliding = false; 16168 this._stop( event, index ); 16169 this._change( event, index ); 16170 this._removeClass( $( event.target ), null, "ui-state-active" ); 16171 } 16172 } 16173 } 16174} ); 16175 16176} ); 16177 16178/*! 16179 * jQuery UI Sortable @VERSION 16180 * https://jqueryui.com 16181 * 16182 * Copyright OpenJS Foundation and other contributors 16183 * Released under the MIT license. 16184 * https://jquery.org/license 16185 */ 16186 16187//>>label: Sortable 16188//>>group: Interactions 16189//>>description: Enables items in a list to be sorted using the mouse. 16190//>>docs: https://api.jqueryui.com/sortable/ 16191//>>demos: https://jqueryui.com/sortable/ 16192//>>css.structure: ../../themes/base/sortable.css 16193 16194( function( factory ) { 16195 "use strict"; 16196 16197 if ( typeof define === "function" && define.amd ) { 16198 16199 // AMD. Register as an anonymous module. 16200 define( 'ui/widgets/sortable.js',[ 16201 "jquery", 16202 "./mouse", 16203 "../data", 16204 "../scroll-parent", 16205 "../version", 16206 "../widget" 16207 ], factory ); 16208 } else { 16209 16210 // Browser globals 16211 factory( jQuery ); 16212 } 16213} )( function( $ ) { 16214"use strict"; 16215 16216return $.widget( "ui.sortable", $.ui.mouse, { 16217 version: "@VERSION", 16218 widgetEventPrefix: "sort", 16219 ready: false, 16220 options: { 16221 appendTo: "parent", 16222 axis: false, 16223 connectWith: false, 16224 containment: false, 16225 cursor: "auto", 16226 cursorAt: false, 16227 dropOnEmpty: true, 16228 forcePlaceholderSize: false, 16229 forceHelperSize: false, 16230 grid: false, 16231 handle: false, 16232 helper: "original", 16233 items: "> *", 16234 opacity: false, 16235 placeholder: false, 16236 revert: false, 16237 scroll: true, 16238 scrollSensitivity: 20, 16239 scrollSpeed: 20, 16240 scope: "default", 16241 tolerance: "intersect", 16242 zIndex: 1000, 16243 16244 // Callbacks 16245 activate: null, 16246 beforeStop: null, 16247 change: null, 16248 deactivate: null, 16249 out: null, 16250 over: null, 16251 receive: null, 16252 remove: null, 16253 sort: null, 16254 start: null, 16255 stop: null, 16256 update: null 16257 }, 16258 16259 _isOverAxis: function( x, reference, size ) { 16260 return ( x >= reference ) && ( x < ( reference + size ) ); 16261 }, 16262 16263 _isFloating: function( item ) { 16264 return ( /left|right/ ).test( item.css( "float" ) ) || 16265 ( /inline|table-cell/ ).test( item.css( "display" ) ); 16266 }, 16267 16268 _create: function() { 16269 this.containerCache = {}; 16270 this._addClass( "ui-sortable" ); 16271 16272 //Get the items 16273 this.refresh(); 16274 16275 //Let's determine the parent's offset 16276 this.offset = this.element.offset(); 16277 16278 //Initialize mouse events for interaction 16279 this._mouseInit(); 16280 16281 this._setHandleClassName(); 16282 16283 //We're ready to go 16284 this.ready = true; 16285 16286 }, 16287 16288 _setOption: function( key, value ) { 16289 this._super( key, value ); 16290 16291 if ( key === "handle" ) { 16292 this._setHandleClassName(); 16293 } 16294 }, 16295 16296 _setHandleClassName: function() { 16297 var that = this; 16298 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 16299 $.each( this.items, function() { 16300 that._addClass( 16301 this.instance.options.handle ? 16302 this.item.find( this.instance.options.handle ) : 16303 this.item, 16304 "ui-sortable-handle" 16305 ); 16306 } ); 16307 }, 16308 16309 _destroy: function() { 16310 this._mouseDestroy(); 16311 16312 for ( var i = this.items.length - 1; i >= 0; i-- ) { 16313 this.items[ i ].item.removeData( this.widgetName + "-item" ); 16314 } 16315 16316 return this; 16317 }, 16318 16319 _mouseCapture: function( event, overrideHandle ) { 16320 var currentItem = null, 16321 validHandle = false, 16322 that = this; 16323 16324 if ( this.reverting ) { 16325 return false; 16326 } 16327 16328 if ( this.options.disabled || this.options.type === "static" ) { 16329 return false; 16330 } 16331 16332 //We have to refresh the items data once first 16333 this._refreshItems( event ); 16334 16335 //Find out if the clicked node (or one of its parents) is a actual item in this.items 16336 $( event.target ).parents().each( function() { 16337 if ( $.data( this, that.widgetName + "-item" ) === that ) { 16338 currentItem = $( this ); 16339 return false; 16340 } 16341 } ); 16342 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 16343 currentItem = $( event.target ); 16344 } 16345 16346 if ( !currentItem ) { 16347 return false; 16348 } 16349 if ( this.options.handle && !overrideHandle ) { 16350 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 16351 if ( this === event.target ) { 16352 validHandle = true; 16353 } 16354 } ); 16355 if ( !validHandle ) { 16356 return false; 16357 } 16358 } 16359 16360 this.currentItem = currentItem; 16361 this._removeCurrentsFromItems(); 16362 return true; 16363 16364 }, 16365 16366 _mouseStart: function( event, overrideHandle, noActivation ) { 16367 16368 var i, body, 16369 o = this.options; 16370 16371 this.currentContainer = this; 16372 16373 //We only need to call refreshPositions, because the refreshItems call has been moved to 16374 // mouseCapture 16375 this.refreshPositions(); 16376 16377 //Prepare the dragged items parent 16378 this.appendTo = $( o.appendTo !== "parent" ? 16379 o.appendTo : 16380 this.currentItem.parent() ); 16381 16382 //Create and append the visible helper 16383 this.helper = this._createHelper( event ); 16384 16385 //Cache the helper size 16386 this._cacheHelperProportions(); 16387 16388 /* 16389 * - Position generation - 16390 * This block generates everything position related - it's the core of draggables. 16391 */ 16392 16393 //Cache the margins of the original element 16394 this._cacheMargins(); 16395 16396 //The element's absolute position on the page minus margins 16397 this.offset = this.currentItem.offset(); 16398 this.offset = { 16399 top: this.offset.top - this.margins.top, 16400 left: this.offset.left - this.margins.left 16401 }; 16402 16403 $.extend( this.offset, { 16404 click: { //Where the click happened, relative to the element 16405 left: event.pageX - this.offset.left, 16406 top: event.pageY - this.offset.top 16407 }, 16408 16409 // This is a relative to absolute position minus the actual position calculation - 16410 // only used for relative positioned helper 16411 relative: this._getRelativeOffset() 16412 } ); 16413 16414 // After we get the helper offset, but before we get the parent offset we can 16415 // change the helper's position to absolute 16416 // TODO: Still need to figure out a way to make relative sorting possible 16417 this.helper.css( "position", "absolute" ); 16418 this.cssPosition = this.helper.css( "position" ); 16419 16420 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 16421 if ( o.cursorAt ) { 16422 this._adjustOffsetFromHelper( o.cursorAt ); 16423 } 16424 16425 //Cache the former DOM position 16426 this.domPosition = { 16427 prev: this.currentItem.prev()[ 0 ], 16428 parent: this.currentItem.parent()[ 0 ] 16429 }; 16430 16431 // If the helper is not the original, hide the original so it's not playing any role during 16432 // the drag, won't cause anything bad this way 16433 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 16434 this.currentItem.hide(); 16435 } 16436 16437 //Create the placeholder 16438 this._createPlaceholder(); 16439 16440 //Get the next scrolling parent 16441 this.scrollParent = this.placeholder.scrollParent(); 16442 16443 $.extend( this.offset, { 16444 parent: this._getParentOffset() 16445 } ); 16446 16447 //Set a containment if given in the options 16448 if ( o.containment ) { 16449 this._setContainment(); 16450 } 16451 16452 if ( o.cursor && o.cursor !== "auto" ) { // cursor option 16453 body = this.document.find( "body" ); 16454 16455 this._storedStylesheet = 16456 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); 16457 } 16458 16459 // We need to make sure to grab the zIndex before setting the 16460 // opacity, because setting the opacity to anything lower than 1 16461 // causes the zIndex to change from "auto" to 0. 16462 if ( o.zIndex ) { // zIndex option 16463 if ( this.helper.css( "zIndex" ) ) { 16464 this._storedZIndex = this.helper.css( "zIndex" ); 16465 } 16466 this.helper.css( "zIndex", o.zIndex ); 16467 } 16468 16469 if ( o.opacity ) { // opacity option 16470 if ( this.helper.css( "opacity" ) ) { 16471 this._storedOpacity = this.helper.css( "opacity" ); 16472 } 16473 this.helper.css( "opacity", o.opacity ); 16474 } 16475 16476 //Prepare scrolling 16477 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 16478 this.scrollParent[ 0 ].tagName !== "HTML" ) { 16479 this.overflowOffset = this.scrollParent.offset(); 16480 } 16481 16482 //Call callbacks 16483 this._trigger( "start", event, this._uiHash() ); 16484 16485 //Recache the helper size 16486 if ( !this._preserveHelperProportions ) { 16487 this._cacheHelperProportions(); 16488 } 16489 16490 //Post "activate" events to possible containers 16491 if ( !noActivation ) { 16492 for ( i = this.containers.length - 1; i >= 0; i-- ) { 16493 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 16494 } 16495 } 16496 16497 //Prepare possible droppables 16498 if ( $.ui.ddmanager ) { 16499 $.ui.ddmanager.current = this; 16500 } 16501 16502 if ( $.ui.ddmanager && !o.dropBehaviour ) { 16503 $.ui.ddmanager.prepareOffsets( this, event ); 16504 } 16505 16506 this.dragging = true; 16507 16508 this._addClass( this.helper, "ui-sortable-helper" ); 16509 16510 //Move the helper, if needed 16511 if ( !this.helper.parent().is( this.appendTo ) ) { 16512 this.helper.detach().appendTo( this.appendTo ); 16513 16514 //Update position 16515 this.offset.parent = this._getParentOffset(); 16516 } 16517 16518 //Generate the original position 16519 this.position = this.originalPosition = this._generatePosition( event ); 16520 this.originalPageX = event.pageX; 16521 this.originalPageY = event.pageY; 16522 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); 16523 16524 this._mouseDrag( event ); 16525 16526 return true; 16527 16528 }, 16529 16530 _scroll: function( event ) { 16531 var o = this.options, 16532 scrolled = false;
vendor: 38,195 bytes, lines 16533-17759
16533 16534 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 16535 this.scrollParent[ 0 ].tagName !== "HTML" ) { 16536 16537 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - 16538 event.pageY < o.scrollSensitivity ) { 16539 this.scrollParent[ 0 ].scrollTop = 16540 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 16541 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { 16542 this.scrollParent[ 0 ].scrollTop = 16543 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 16544 } 16545 16546 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - 16547 event.pageX < o.scrollSensitivity ) { 16548 this.scrollParent[ 0 ].scrollLeft = scrolled = 16549 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 16550 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { 16551 this.scrollParent[ 0 ].scrollLeft = scrolled = 16552 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 16553 } 16554 16555 } else { 16556 16557 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { 16558 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); 16559 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < 16560 o.scrollSensitivity ) { 16561 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); 16562 } 16563 16564 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { 16565 scrolled = this.document.scrollLeft( 16566 this.document.scrollLeft() - o.scrollSpeed 16567 ); 16568 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < 16569 o.scrollSensitivity ) { 16570 scrolled = this.document.scrollLeft( 16571 this.document.scrollLeft() + o.scrollSpeed 16572 ); 16573 } 16574 16575 } 16576 16577 return scrolled; 16578 }, 16579 16580 _mouseDrag: function( event ) { 16581 var i, item, itemElement, intersection, 16582 o = this.options; 16583 16584 //Compute the helpers position 16585 this.position = this._generatePosition( event ); 16586 this.positionAbs = this._convertPositionTo( "absolute" ); 16587 16588 //Set the helper position 16589 if ( !this.options.axis || this.options.axis !== "y" ) { 16590 this.helper[ 0 ].style.left = this.position.left + "px"; 16591 } 16592 if ( !this.options.axis || this.options.axis !== "x" ) { 16593 this.helper[ 0 ].style.top = this.position.top + "px"; 16594 } 16595 16596 //Do scrolling 16597 if ( o.scroll ) { 16598 if ( this._scroll( event ) !== false ) { 16599 16600 //Update item positions used in position checks 16601 this._refreshItemPositions( true ); 16602 16603 if ( $.ui.ddmanager && !o.dropBehaviour ) { 16604 $.ui.ddmanager.prepareOffsets( this, event ); 16605 } 16606 } 16607 } 16608 16609 this.dragDirection = { 16610 vertical: this._getDragVerticalDirection(), 16611 horizontal: this._getDragHorizontalDirection() 16612 }; 16613 16614 //Rearrange 16615 for ( i = this.items.length - 1; i >= 0; i-- ) { 16616 16617 //Cache variables and intersection, continue if no intersection 16618 item = this.items[ i ]; 16619 itemElement = item.item[ 0 ]; 16620 intersection = this._intersectsWithPointer( item ); 16621 if ( !intersection ) { 16622 continue; 16623 } 16624 16625 // Only put the placeholder inside the current Container, skip all 16626 // items from other containers. This works because when moving 16627 // an item from one container to another the 16628 // currentContainer is switched before the placeholder is moved. 16629 // 16630 // Without this, moving items in "sub-sortables" can cause 16631 // the placeholder to jitter between the outer and inner container. 16632 if ( item.instance !== this.currentContainer ) { 16633 continue; 16634 } 16635 16636 // Cannot intersect with itself 16637 // no useless actions that have been done before 16638 // no action if the item moved is the parent of the item checked 16639 if ( itemElement !== this.currentItem[ 0 ] && 16640 this.placeholder[ intersection === 1 ? 16641 "next" : "prev" ]()[ 0 ] !== itemElement && 16642 !$.contains( this.placeholder[ 0 ], itemElement ) && 16643 ( this.options.type === "semi-dynamic" ? 16644 !$.contains( this.element[ 0 ], itemElement ) : 16645 true 16646 ) 16647 ) { 16648 16649 this.direction = intersection === 1 ? "down" : "up"; 16650 16651 if ( this.options.tolerance === "pointer" || 16652 this._intersectsWithSides( item ) ) { 16653 this._rearrange( event, item ); 16654 } else { 16655 break; 16656 } 16657 16658 this._trigger( "change", event, this._uiHash() ); 16659 break; 16660 } 16661 } 16662 16663 //Post events to containers 16664 this._contactContainers( event ); 16665 16666 //Interconnect with droppables 16667 if ( $.ui.ddmanager ) { 16668 $.ui.ddmanager.drag( this, event ); 16669 } 16670 16671 //Call callbacks 16672 this._trigger( "sort", event, this._uiHash() ); 16673 16674 this.lastPositionAbs = this.positionAbs; 16675 return false; 16676 16677 }, 16678 16679 _mouseStop: function( event, noPropagation ) { 16680 16681 if ( !event ) { 16682 return; 16683 } 16684 16685 //If we are using droppables, inform the manager about the drop 16686 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 16687 $.ui.ddmanager.drop( this, event ); 16688 } 16689 16690 if ( this.options.revert ) { 16691 var that = this, 16692 cur = this.placeholder.offset(), 16693 axis = this.options.axis, 16694 animation = {}; 16695 16696 if ( !axis || axis === "x" ) { 16697 animation.left = cur.left - this.offset.parent.left - this.margins.left + 16698 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 16699 0 : 16700 this.offsetParent[ 0 ].scrollLeft 16701 ); 16702 } 16703 if ( !axis || axis === "y" ) { 16704 animation.top = cur.top - this.offset.parent.top - this.margins.top + 16705 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 16706 0 : 16707 this.offsetParent[ 0 ].scrollTop 16708 ); 16709 } 16710 this.reverting = true; 16711 $( this.helper ).animate( 16712 animation, 16713 parseInt( this.options.revert, 10 ) || 500, 16714 function() { 16715 that._clear( event ); 16716 } 16717 ); 16718 } else { 16719 this._clear( event, noPropagation ); 16720 } 16721 16722 return false; 16723 16724 }, 16725 16726 cancel: function() { 16727 16728 if ( this.dragging ) { 16729 16730 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); 16731 16732 if ( this.options.helper === "original" ) { 16733 this.currentItem.css( this._storedCSS ); 16734 this._removeClass( this.currentItem, "ui-sortable-helper" ); 16735 } else { 16736 this.currentItem.show(); 16737 } 16738 16739 //Post deactivating events to containers 16740 for ( var i = this.containers.length - 1; i >= 0; i-- ) { 16741 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); 16742 if ( this.containers[ i ].containerCache.over ) { 16743 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); 16744 this.containers[ i ].containerCache.over = 0; 16745 } 16746 } 16747 16748 } 16749 16750 if ( this.placeholder ) { 16751 16752 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 16753 // it unbinds ALL events from the original node! 16754 if ( this.placeholder[ 0 ].parentNode ) { 16755 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 16756 } 16757 if ( this.options.helper !== "original" && this.helper && 16758 this.helper[ 0 ].parentNode ) { 16759 this.helper.remove(); 16760 } 16761 16762 $.extend( this, { 16763 helper: null, 16764 dragging: false, 16765 reverting: false, 16766 _noFinalSort: null 16767 } ); 16768 16769 if ( this.domPosition.prev ) { 16770 $( this.domPosition.prev ).after( this.currentItem ); 16771 } else { 16772 $( this.domPosition.parent ).prepend( this.currentItem ); 16773 } 16774 } 16775 16776 return this; 16777 16778 }, 16779 16780 serialize: function( o ) { 16781 16782 var items = this._getItemsAsjQuery( o && o.connected ), 16783 str = []; 16784 o = o || {}; 16785 16786 $( items ).each( function() { 16787 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) 16788 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); 16789 if ( res ) { 16790 str.push( 16791 ( o.key || res[ 1 ] + "[]" ) + 16792 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); 16793 } 16794 } ); 16795 16796 if ( !str.length && o.key ) { 16797 str.push( o.key + "=" ); 16798 } 16799 16800 return str.join( "&" ); 16801 16802 }, 16803 16804 toArray: function( o ) { 16805 16806 var items = this._getItemsAsjQuery( o && o.connected ), 16807 ret = []; 16808 16809 o = o || {}; 16810 16811 items.each( function() { 16812 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); 16813 } ); 16814 return ret; 16815 16816 }, 16817 16818 /* Be careful with the following core functions */ 16819 _intersectsWith: function( item ) { 16820 16821 var x1 = this.positionAbs.left, 16822 x2 = x1 + this.helperProportions.width, 16823 y1 = this.positionAbs.top, 16824 y2 = y1 + this.helperProportions.height, 16825 l = item.left, 16826 r = l + item.width, 16827 t = item.top, 16828 b = t + item.height, 16829 dyClick = this.offset.click.top, 16830 dxClick = this.offset.click.left, 16831 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && 16832 ( y1 + dyClick ) < b ), 16833 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && 16834 ( x1 + dxClick ) < r ), 16835 isOverElement = isOverElementHeight && isOverElementWidth; 16836 16837 if ( this.options.tolerance === "pointer" || 16838 this.options.forcePointerForContainers || 16839 ( this.options.tolerance !== "pointer" && 16840 this.helperProportions[ this.floating ? "width" : "height" ] > 16841 item[ this.floating ? "width" : "height" ] ) 16842 ) { 16843 return isOverElement; 16844 } else { 16845 16846 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half 16847 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half 16848 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half 16849 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half 16850 16851 } 16852 }, 16853 16854 _intersectsWithPointer: function( item ) { 16855 var verticalDirection, horizontalDirection, 16856 isOverElementHeight = ( this.options.axis === "x" ) || 16857 this._isOverAxis( 16858 this.positionAbs.top + this.offset.click.top, item.top, item.height ), 16859 isOverElementWidth = ( this.options.axis === "y" ) || 16860 this._isOverAxis( 16861 this.positionAbs.left + this.offset.click.left, item.left, item.width ), 16862 isOverElement = isOverElementHeight && isOverElementWidth; 16863 16864 if ( !isOverElement ) { 16865 return false; 16866 } 16867 16868 verticalDirection = this.dragDirection.vertical; 16869 horizontalDirection = this.dragDirection.horizontal; 16870 16871 return this.floating ? 16872 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : 16873 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); 16874 16875 }, 16876 16877 _intersectsWithSides: function( item ) { 16878 16879 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + 16880 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), 16881 isOverRightHalf = this._isOverAxis( this.positionAbs.left + 16882 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), 16883 verticalDirection = this.dragDirection.vertical, 16884 horizontalDirection = this.dragDirection.horizontal; 16885 16886 if ( this.floating && horizontalDirection ) { 16887 return ( ( horizontalDirection === "right" && isOverRightHalf ) || 16888 ( horizontalDirection === "left" && !isOverRightHalf ) ); 16889 } else { 16890 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || 16891 ( verticalDirection === "up" && !isOverBottomHalf ) ); 16892 } 16893 16894 }, 16895 16896 _getDragVerticalDirection: function() { 16897 var delta = this.positionAbs.top - this.lastPositionAbs.top; 16898 return delta !== 0 && ( delta > 0 ? "down" : "up" ); 16899 }, 16900 16901 _getDragHorizontalDirection: function() { 16902 var delta = this.positionAbs.left - this.lastPositionAbs.left; 16903 return delta !== 0 && ( delta > 0 ? "right" : "left" ); 16904 }, 16905 16906 refresh: function( event ) { 16907 this._refreshItems( event ); 16908 this._setHandleClassName(); 16909 this.refreshPositions(); 16910 return this; 16911 }, 16912 16913 _connectWith: function() { 16914 var options = this.options; 16915 return options.connectWith.constructor === String ? 16916 [ options.connectWith ] : 16917 options.connectWith; 16918 }, 16919 16920 _getItemsAsjQuery: function( connected ) { 16921 16922 var i, j, cur, inst, 16923 items = [], 16924 queries = [], 16925 connectWith = this._connectWith(); 16926 16927 if ( connectWith && connected ) { 16928 for ( i = connectWith.length - 1; i >= 0; i-- ) { 16929 cur = $( connectWith[ i ], this.document[ 0 ] ); 16930 for ( j = cur.length - 1; j >= 0; j-- ) { 16931 inst = $.data( cur[ j ], this.widgetFullName ); 16932 if ( inst && inst !== this && !inst.options.disabled ) { 16933 queries.push( [ typeof inst.options.items === "function" ? 16934 inst.options.items.call( inst.element ) : 16935 $( inst.options.items, inst.element ) 16936 .not( ".ui-sortable-helper" ) 16937 .not( ".ui-sortable-placeholder" ), inst ] ); 16938 } 16939 } 16940 } 16941 } 16942 16943 queries.push( [ typeof this.options.items === "function" ? 16944 this.options.items 16945 .call( this.element, null, { options: this.options, item: this.currentItem } ) : 16946 $( this.options.items, this.element ) 16947 .not( ".ui-sortable-helper" ) 16948 .not( ".ui-sortable-placeholder" ), this ] ); 16949 16950 function addItems() { 16951 items.push( this ); 16952 } 16953 for ( i = queries.length - 1; i >= 0; i-- ) { 16954 queries[ i ][ 0 ].each( addItems ); 16955 } 16956 16957 return $( items ); 16958 16959 }, 16960 16961 _removeCurrentsFromItems: function() { 16962 16963 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); 16964 16965 this.items = $.grep( this.items, function( item ) { 16966 for ( var j = 0; j < list.length; j++ ) { 16967 if ( list[ j ] === item.item[ 0 ] ) { 16968 return false; 16969 } 16970 } 16971 return true; 16972 } ); 16973 16974 }, 16975 16976 _refreshItems: function( event ) { 16977 16978 this.items = []; 16979 this.containers = [ this ]; 16980 16981 var i, j, cur, inst, targetData, _queries, item, queriesLength, 16982 items = this.items, 16983 queries = [ [ typeof this.options.items === "function" ? 16984 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : 16985 $( this.options.items, this.element ), this ] ], 16986 connectWith = this._connectWith(); 16987 16988 //Shouldn't be run the first time through due to massive slow-down 16989 if ( connectWith && this.ready ) { 16990 for ( i = connectWith.length - 1; i >= 0; i-- ) { 16991 cur = $( connectWith[ i ], this.document[ 0 ] ); 16992 for ( j = cur.length - 1; j >= 0; j-- ) { 16993 inst = $.data( cur[ j ], this.widgetFullName ); 16994 if ( inst && inst !== this && !inst.options.disabled ) { 16995 queries.push( [ typeof inst.options.items === "function" ? 16996 inst.options.items 16997 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : 16998 $( inst.options.items, inst.element ), inst ] ); 16999 this.containers.push( inst ); 17000 } 17001 } 17002 } 17003 } 17004 17005 for ( i = queries.length - 1; i >= 0; i-- ) { 17006 targetData = queries[ i ][ 1 ]; 17007 _queries = queries[ i ][ 0 ]; 17008 17009 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { 17010 item = $( _queries[ j ] ); 17011 17012 // Data for target checking (mouse manager) 17013 item.data( this.widgetName + "-item", targetData ); 17014 17015 items.push( { 17016 item: item, 17017 instance: targetData, 17018 width: 0, height: 0, 17019 left: 0, top: 0 17020 } ); 17021 } 17022 } 17023 17024 }, 17025 17026 _refreshItemPositions: function( fast ) { 17027 var i, item, t, p; 17028 17029 for ( i = this.items.length - 1; i >= 0; i-- ) { 17030 item = this.items[ i ]; 17031 17032 //We ignore calculating positions of all connected containers when we're not over them 17033 if ( this.currentContainer && item.instance !== this.currentContainer && 17034 item.item[ 0 ] !== this.currentItem[ 0 ] ) { 17035 continue; 17036 } 17037 17038 t = this.options.toleranceElement ? 17039 $( this.options.toleranceElement, item.item ) : 17040 item.item; 17041 17042 if ( !fast ) { 17043 item.width = t.outerWidth(); 17044 item.height = t.outerHeight(); 17045 } 17046 17047 p = t.offset(); 17048 item.left = p.left; 17049 item.top = p.top; 17050 } 17051 }, 17052 17053 refreshPositions: function( fast ) { 17054 17055 // Determine whether items are being displayed horizontally 17056 this.floating = this.items.length ? 17057 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 17058 false; 17059 17060 // This has to be redone because due to the item being moved out/into the offsetParent, 17061 // the offsetParent's position will change 17062 if ( this.offsetParent && this.helper ) { 17063 this.offset.parent = this._getParentOffset(); 17064 } 17065 17066 this._refreshItemPositions( fast ); 17067 17068 var i, p; 17069 17070 if ( this.options.custom && this.options.custom.refreshContainers ) { 17071 this.options.custom.refreshContainers.call( this ); 17072 } else { 17073 for ( i = this.containers.length - 1; i >= 0; i-- ) { 17074 p = this.containers[ i ].element.offset(); 17075 this.containers[ i ].containerCache.left = p.left; 17076 this.containers[ i ].containerCache.top = p.top; 17077 this.containers[ i ].containerCache.width = 17078 this.containers[ i ].element.outerWidth(); 17079 this.containers[ i ].containerCache.height = 17080 this.containers[ i ].element.outerHeight(); 17081 } 17082 } 17083 17084 return this; 17085 }, 17086 17087 _createPlaceholder: function( that ) { 17088 that = that || this; 17089 var className, nodeName, 17090 o = that.options; 17091 17092 if ( !o.placeholder || o.placeholder.constructor === String ) { 17093 className = o.placeholder; 17094 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); 17095 o.placeholder = { 17096 element: function() { 17097 17098 var element = $( "<" + nodeName + ">", that.document[ 0 ] ); 17099 17100 that._addClass( element, "ui-sortable-placeholder", 17101 className || that.currentItem[ 0 ].className ) 17102 ._removeClass( element, "ui-sortable-helper" ); 17103 17104 if ( nodeName === "tbody" ) { 17105 that._createTrPlaceholder( 17106 that.currentItem.find( "tr" ).eq( 0 ), 17107 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 17108 ); 17109 } else if ( nodeName === "tr" ) { 17110 that._createTrPlaceholder( that.currentItem, element ); 17111 } else if ( nodeName === "img" ) { 17112 element.attr( "src", that.currentItem.attr( "src" ) ); 17113 } 17114 17115 if ( !className ) { 17116 element.css( "visibility", "hidden" ); 17117 } 17118 17119 return element; 17120 }, 17121 update: function( container, p ) { 17122 17123 // 1. If a className is set as 'placeholder option, we don't force sizes - 17124 // the class is responsible for that 17125 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a 17126 // class name is specified 17127 if ( className && !o.forcePlaceholderSize ) { 17128 return; 17129 } 17130 17131 // If the element doesn't have a actual height or width by itself (without 17132 // styles coming from a stylesheet), it receives the inline height and width 17133 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height 17134 // anyway since we're populating them with <td>s above, but they're unlikely to 17135 // be the correct height on their own if the row heights are dynamic, so we'll 17136 // always assign the height of the dragged item given forcePlaceholderSize 17137 // is true. 17138 if ( !p.height() || ( o.forcePlaceholderSize && 17139 ( nodeName === "tbody" || nodeName === "tr" ) ) ) { 17140 p.height( 17141 that.currentItem.innerHeight() - 17142 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - 17143 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); 17144 } 17145 if ( !p.width() ) { 17146 p.width( 17147 that.currentItem.innerWidth() - 17148 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - 17149 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); 17150 } 17151 } 17152 }; 17153 } 17154 17155 //Create the placeholder 17156 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); 17157 17158 //Append it after the actual current item 17159 that.currentItem.after( that.placeholder ); 17160 17161 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 17162 o.placeholder.update( that, that.placeholder ); 17163 17164 }, 17165 17166 _createTrPlaceholder: function( sourceTr, targetTr ) { 17167 var that = this; 17168 17169 sourceTr.children().each( function() { 17170 $( "<td> </td>", that.document[ 0 ] ) 17171 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 17172 .appendTo( targetTr ); 17173 } ); 17174 }, 17175 17176 _contactContainers: function( event ) { 17177 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, 17178 floating, axis, 17179 innermostContainer = null, 17180 innermostIndex = null; 17181 17182 // Get innermost container that intersects with item 17183 for ( i = this.containers.length - 1; i >= 0; i-- ) { 17184 17185 // Never consider a container that's located within the item itself 17186 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { 17187 continue; 17188 } 17189 17190 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { 17191 17192 // If we've already found a container and it's more "inner" than this, then continue 17193 if ( innermostContainer && 17194 $.contains( 17195 this.containers[ i ].element[ 0 ], 17196 innermostContainer.element[ 0 ] ) ) { 17197 continue; 17198 } 17199 17200 innermostContainer = this.containers[ i ]; 17201 innermostIndex = i; 17202 17203 } else { 17204 17205 // container doesn't intersect. trigger "out" event if necessary 17206 if ( this.containers[ i ].containerCache.over ) { 17207 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); 17208 this.containers[ i ].containerCache.over = 0; 17209 } 17210 } 17211 17212 } 17213 17214 // If no intersecting containers found, return 17215 if ( !innermostContainer ) { 17216 return; 17217 } 17218 17219 // Move the item into the container if it's not there already 17220 if ( this.containers.length === 1 ) { 17221 if ( !this.containers[ innermostIndex ].containerCache.over ) { 17222 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 17223 this.containers[ innermostIndex ].containerCache.over = 1; 17224 } 17225 } else { 17226 17227 // When entering a new container, we will find the item with the least distance and 17228 // append our item near it 17229 dist = 10000; 17230 itemWithLeastDistance = null; 17231 floating = innermostContainer.floating || this._isFloating( this.currentItem ); 17232 posProperty = floating ? "left" : "top"; 17233 sizeProperty = floating ? "width" : "height"; 17234 axis = floating ? "pageX" : "pageY"; 17235 17236 for ( j = this.items.length - 1; j >= 0; j-- ) { 17237 if ( !$.contains( 17238 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) 17239 ) { 17240 continue; 17241 } 17242 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { 17243 continue; 17244 } 17245 17246 cur = this.items[ j ].item.offset()[ posProperty ]; 17247 nearBottom = false; 17248 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 17249 nearBottom = true; 17250 } 17251 17252 if ( Math.abs( event[ axis ] - cur ) < dist ) { 17253 dist = Math.abs( event[ axis ] - cur ); 17254 itemWithLeastDistance = this.items[ j ]; 17255 this.direction = nearBottom ? "up" : "down"; 17256 } 17257 } 17258 17259 //Check if dropOnEmpty is enabled 17260 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { 17261 return; 17262 } 17263 17264 if ( this.currentContainer === this.containers[ innermostIndex ] ) { 17265 if ( !this.currentContainer.containerCache.over ) { 17266 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 17267 this.currentContainer.containerCache.over = 1; 17268 } 17269 return; 17270 } 17271 17272 if ( itemWithLeastDistance ) { 17273 this._rearrange( event, itemWithLeastDistance, null, true ); 17274 } else { 17275 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); 17276 } 17277 this._trigger( "change", event, this._uiHash() ); 17278 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); 17279 this.currentContainer = this.containers[ innermostIndex ]; 17280 17281 //Update the placeholder 17282 this.options.placeholder.update( this.currentContainer, this.placeholder ); 17283 17284 //Update scrollParent 17285 this.scrollParent = this.placeholder.scrollParent(); 17286 17287 //Update overflowOffset 17288 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 17289 this.scrollParent[ 0 ].tagName !== "HTML" ) { 17290 this.overflowOffset = this.scrollParent.offset(); 17291 } 17292 17293 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 17294 this.containers[ innermostIndex ].containerCache.over = 1; 17295 } 17296 17297 }, 17298 17299 _createHelper: function( event ) { 17300 17301 var o = this.options, 17302 helper = typeof o.helper === "function" ? 17303 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : 17304 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); 17305 17306 //Add the helper to the DOM if that didn't happen already 17307 if ( !helper.parents( "body" ).length ) { 17308 this.appendTo[ 0 ].appendChild( helper[ 0 ] ); 17309 } 17310 17311 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { 17312 this._storedCSS = { 17313 width: this.currentItem[ 0 ].style.width, 17314 height: this.currentItem[ 0 ].style.height, 17315 position: this.currentItem.css( "position" ), 17316 top: this.currentItem.css( "top" ), 17317 left: this.currentItem.css( "left" ) 17318 }; 17319 } 17320 17321 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { 17322 helper.width( this.currentItem.width() ); 17323 } 17324 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { 17325 helper.height( this.currentItem.height() ); 17326 } 17327 17328 return helper; 17329 17330 }, 17331 17332 _adjustOffsetFromHelper: function( obj ) { 17333 if ( typeof obj === "string" ) { 17334 obj = obj.split( " " ); 17335 } 17336 if ( Array.isArray( obj ) ) { 17337 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 17338 } 17339 if ( "left" in obj ) { 17340 this.offset.click.left = obj.left + this.margins.left; 17341 } 17342 if ( "right" in obj ) { 17343 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 17344 } 17345 if ( "top" in obj ) { 17346 this.offset.click.top = obj.top + this.margins.top; 17347 } 17348 if ( "bottom" in obj ) { 17349 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 17350 } 17351 }, 17352 17353 _getParentOffset: function() { 17354 17355 //Get the offsetParent and cache its position 17356 this.offsetParent = this.helper.offsetParent(); 17357 var po = this.offsetParent.offset(); 17358 17359 // This is a special case where we need to modify a offset calculated on start, since the 17360 // following happened: 17361 // 1. The position of the helper is absolute, so it's position is calculated based on the 17362 // next positioned parent 17363 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 17364 // the document, which means that the scroll is included in the initial calculation of the 17365 // offset of the parent, and never recalculated upon drag 17366 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && 17367 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 17368 po.left += this.scrollParent.scrollLeft(); 17369 po.top += this.scrollParent.scrollTop(); 17370 } 17371 17372 // This needs to be actually done for all browsers, since pageX/pageY includes 17373 // this information. 17374 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ) { 17375 po = { top: 0, left: 0 }; 17376 } 17377 17378 return { 17379 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 17380 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 17381 }; 17382 17383 }, 17384 17385 _getRelativeOffset: function() { 17386 17387 if ( this.cssPosition === "relative" ) { 17388 var p = this.currentItem.position(); 17389 return { 17390 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 17391 this.scrollParent.scrollTop(), 17392 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 17393 this.scrollParent.scrollLeft() 17394 }; 17395 } else { 17396 return { top: 0, left: 0 }; 17397 } 17398 17399 }, 17400 17401 _cacheMargins: function() { 17402 this.margins = { 17403 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), 17404 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) 17405 }; 17406 }, 17407 17408 _cacheHelperProportions: function() { 17409 this.helperProportions = { 17410 width: this.helper.outerWidth(), 17411 height: this.helper.outerHeight() 17412 }; 17413 }, 17414 17415 _setContainment: function() { 17416 17417 var ce, co, over, 17418 o = this.options; 17419 if ( o.containment === "parent" ) { 17420 o.containment = this.helper[ 0 ].parentNode; 17421 } 17422 if ( o.containment === "document" || o.containment === "window" ) { 17423 this.containment = [ 17424 0 - this.offset.relative.left - this.offset.parent.left, 17425 0 - this.offset.relative.top - this.offset.parent.top, 17426 o.containment === "document" ? 17427 this.document.width() : 17428 this.window.width() - this.helperProportions.width - this.margins.left, 17429 ( o.containment === "document" ? 17430 ( this.document.height() || document.body.parentNode.scrollHeight ) : 17431 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight 17432 ) - this.helperProportions.height - this.margins.top 17433 ]; 17434 } 17435 17436 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { 17437 ce = $( o.containment )[ 0 ]; 17438 co = $( o.containment ).offset(); 17439 over = ( $( ce ).css( "overflow" ) !== "hidden" ); 17440 17441 this.containment = [ 17442 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + 17443 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, 17444 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + 17445 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, 17446 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 17447 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - 17448 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - 17449 this.helperProportions.width - this.margins.left, 17450 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 17451 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - 17452 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - 17453 this.helperProportions.height - this.margins.top 17454 ]; 17455 } 17456 17457 }, 17458 17459 _convertPositionTo: function( d, pos ) { 17460 17461 if ( !pos ) { 17462 pos = this.position; 17463 } 17464 var mod = d === "absolute" ? 1 : -1, 17465 scroll = this.cssPosition === "absolute" && 17466 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 17467 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 17468 this.offsetParent : 17469 this.scrollParent, 17470 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 17471 17472 return { 17473 top: ( 17474 17475 // The absolute mouse position 17476 pos.top + 17477 17478 // Only for relative positioned nodes: Relative offset from element to offset parent 17479 this.offset.relative.top * mod + 17480 17481 // The offsetParent's offset without borders (offset + border) 17482 this.offset.parent.top * mod - 17483 ( ( this.cssPosition === "fixed" ? 17484 -this.scrollParent.scrollTop() : 17485 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) 17486 ), 17487 left: ( 17488 17489 // The absolute mouse position 17490 pos.left + 17491 17492 // Only for relative positioned nodes: Relative offset from element to offset parent 17493 this.offset.relative.left * mod + 17494 17495 // The offsetParent's offset without borders (offset + border) 17496 this.offset.parent.left * mod - 17497 ( ( this.cssPosition === "fixed" ? 17498 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : 17499 scroll.scrollLeft() ) * mod ) 17500 ) 17501 }; 17502 17503 }, 17504 17505 _generatePosition: function( event ) { 17506 17507 var top, left, 17508 o = this.options, 17509 pageX = event.pageX, 17510 pageY = event.pageY, 17511 scroll = this.cssPosition === "absolute" && 17512 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 17513 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 17514 this.offsetParent : 17515 this.scrollParent, 17516 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 17517 17518 // This is another very weird special case that only happens for relative elements: 17519 // 1. If the css position is relative 17520 // 2. and the scroll parent is the document or similar to the offset parent 17521 // we have to refresh the relative offset during the scroll so there are no jumps 17522 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 17523 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { 17524 this.offset.relative = this._getRelativeOffset(); 17525 } 17526 17527 /* 17528 * - Position constraining - 17529 * Constrain the position to a mix of grid, containment. 17530 */ 17531 17532 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options 17533 17534 if ( this.containment ) { 17535 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { 17536 pageX = this.containment[ 0 ] + this.offset.click.left; 17537 } 17538 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { 17539 pageY = this.containment[ 1 ] + this.offset.click.top; 17540 } 17541 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { 17542 pageX = this.containment[ 2 ] + this.offset.click.left; 17543 } 17544 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { 17545 pageY = this.containment[ 3 ] + this.offset.click.top; 17546 } 17547 } 17548 17549 if ( o.grid ) { 17550 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / 17551 o.grid[ 1 ] ) * o.grid[ 1 ]; 17552 pageY = this.containment ? 17553 ( ( top - this.offset.click.top >= this.containment[ 1 ] && 17554 top - this.offset.click.top <= this.containment[ 3 ] ) ? 17555 top : 17556 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? 17557 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : 17558 top; 17559 17560 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / 17561 o.grid[ 0 ] ) * o.grid[ 0 ]; 17562 pageX = this.containment ? 17563 ( ( left - this.offset.click.left >= this.containment[ 0 ] && 17564 left - this.offset.click.left <= this.containment[ 2 ] ) ? 17565 left : 17566 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? 17567 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : 17568 left; 17569 } 17570 17571 } 17572 17573 return { 17574 top: ( 17575 17576 // The absolute mouse position 17577 pageY - 17578 17579 // Click offset (relative to the element) 17580 this.offset.click.top - 17581 17582 // Only for relative positioned nodes: Relative offset from element to offset parent 17583 this.offset.relative.top - 17584 17585 // The offsetParent's offset without borders (offset + border) 17586 this.offset.parent.top + 17587 ( ( this.cssPosition === "fixed" ? 17588 -this.scrollParent.scrollTop() : 17589 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) 17590 ), 17591 left: ( 17592 17593 // The absolute mouse position 17594 pageX - 17595 17596 // Click offset (relative to the element) 17597 this.offset.click.left - 17598 17599 // Only for relative positioned nodes: Relative offset from element to offset parent 17600 this.offset.relative.left - 17601 17602 // The offsetParent's offset without borders (offset + border) 17603 this.offset.parent.left + 17604 ( ( this.cssPosition === "fixed" ? 17605 -this.scrollParent.scrollLeft() : 17606 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 17607 ) 17608 }; 17609 17610 }, 17611 17612 _rearrange: function( event, i, a, hardRefresh ) { 17613 17614 if ( a ) { 17615 a[ 0 ].appendChild( this.placeholder[ 0 ] ); 17616 } else { 17617 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], 17618 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); 17619 } 17620 17621 //Various things done here to improve the performance: 17622 // 1. we create a setTimeout, that calls refreshPositions 17623 // 2. on the instance, we have a counter variable, that get's higher after every append 17624 // 3. on the local scope, we copy the counter variable, and check in the timeout, 17625 // if it's still the same 17626 // 4. this lets only the last addition to the timeout stack through 17627 this.counter = this.counter ? ++this.counter : 1; 17628 var counter = this.counter; 17629 17630 this._delay( function() { 17631 if ( counter === this.counter ) { 17632 17633 //Precompute after each DOM insertion, NOT on mousemove 17634 this.refreshPositions( !hardRefresh ); 17635 } 17636 } ); 17637 17638 }, 17639 17640 _clear: function( event, noPropagation ) { 17641 17642 this.reverting = false; 17643 17644 // We delay all events that have to be triggered to after the point where the placeholder 17645 // has been removed and everything else normalized again 17646 var i, 17647 delayedTriggers = []; 17648 17649 // We first have to update the dom position of the actual currentItem 17650 // Note: don't do it if the current item is already removed (by a user), or it gets 17651 // reappended (see #4088) 17652 if ( !this._noFinalSort && this.currentItem.parent().length ) { 17653 this.placeholder.before( this.currentItem ); 17654 } 17655 this._noFinalSort = null; 17656 17657 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { 17658 for ( i in this._storedCSS ) { 17659 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { 17660 this._storedCSS[ i ] = ""; 17661 } 17662 } 17663 this.currentItem.css( this._storedCSS ); 17664 this._removeClass( this.currentItem, "ui-sortable-helper" ); 17665 } else { 17666 this.currentItem.show(); 17667 } 17668 17669 if ( this.fromOutside && !noPropagation ) { 17670 delayedTriggers.push( function( event ) { 17671 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); 17672 } ); 17673 } 17674 if ( ( this.fromOutside || 17675 this.domPosition.prev !== 17676 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || 17677 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { 17678 17679 // Trigger update callback if the DOM position has changed 17680 delayedTriggers.push( function( event ) { 17681 this._trigger( "update", event, this._uiHash() ); 17682 } ); 17683 } 17684 17685 // Check if the items Container has Changed and trigger appropriate 17686 // events. 17687 if ( this !== this.currentContainer ) { 17688 if ( !noPropagation ) { 17689 delayedTriggers.push( function( event ) { 17690 this._trigger( "remove", event, this._uiHash() ); 17691 } ); 17692 delayedTriggers.push( ( function( c ) { 17693 return function( event ) { 17694 c._trigger( "receive", event, this._uiHash( this ) ); 17695 }; 17696 } ).call( this, this.currentContainer ) ); 17697 delayedTriggers.push( ( function( c ) { 17698 return function( event ) { 17699 c._trigger( "update", event, this._uiHash( this ) ); 17700 }; 17701 } ).call( this, this.currentContainer ) ); 17702 } 17703 } 17704 17705 //Post events to containers 17706 function delayEvent( type, instance, container ) { 17707 return function( event ) { 17708 container._trigger( type, event, instance._uiHash( instance ) ); 17709 }; 17710 } 17711 for ( i = this.containers.length - 1; i >= 0; i-- ) { 17712 if ( !noPropagation ) { 17713 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 17714 } 17715 if ( this.containers[ i ].containerCache.over ) { 17716 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 17717 this.containers[ i ].containerCache.over = 0; 17718 } 17719 } 17720 17721 //Do what was originally in plugins 17722 if ( this._storedStylesheet ) { 17723 this._storedStylesheet.remove(); 17724 this._storedStylesheet = null; 17725 } 17726 if ( this._storedOpacity ) { 17727 this.helper.css( "opacity", this._storedOpacity ); 17728 } 17729 if ( this._storedZIndex ) { 17730 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); 17731 } 17732 17733 this.dragging = false; 17734 17735 if ( !noPropagation ) { 17736 this._trigger( "beforeStop", event, this._uiHash() ); 17737 } 17738 17739 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 17740 // it unbinds ALL events from the original node! 17741 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 17742 17743 if ( !this.cancelHelperRemoval ) { 17744 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 17745 this.helper.remove(); 17746 } 17747 this.helper = null; 17748 } 17749 17750 if ( !noPropagation ) { 17751 for ( i = 0; i < delayedTriggers.length; i++ ) { 17752 17753 // Trigger all delayed events 17754 delayedTriggers[ i ].call( this, event ); 17755 } 17756 this._trigger( "stop", event, this._uiHash() ); 17757 } 17758 17759 this.fromOutside = false;
vendor: 1,654 bytes, lines 17760-17838
17760 return !this.cancelHelperRemoval; 17761 17762 }, 17763 17764 _trigger: function() { 17765 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { 17766 this.cancel(); 17767 } 17768 }, 17769 17770 _uiHash: function( _inst ) { 17771 var inst = _inst || this; 17772 return { 17773 helper: inst.helper, 17774 placeholder: inst.placeholder || $( [] ), 17775 position: inst.position, 17776 originalPosition: inst.originalPosition, 17777 offset: inst.positionAbs, 17778 item: inst.currentItem, 17779 sender: _inst ? _inst.element : null 17780 }; 17781 } 17782 17783} ); 17784 17785} ); 17786 17787/*! 17788 * jQuery UI Spinner @VERSION 17789 * https://jqueryui.com 17790 * 17791 * Copyright OpenJS Foundation and other contributors 17792 * Released under the MIT license. 17793 * https://jquery.org/license 17794 */ 17795 17796//>>label: Spinner 17797//>>group: Widgets 17798//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 17799//>>docs: https://api.jqueryui.com/spinner/ 17800//>>demos: https://jqueryui.com/spinner/ 17801//>>css.structure: ../../themes/base/core.css 17802//>>css.structure: ../../themes/base/spinner.css 17803//>>css.theme: ../../themes/base/theme.css 17804 17805( function( factory ) { 17806 "use strict"; 17807 17808 if ( typeof define === "function" && define.amd ) { 17809 17810 // AMD. Register as an anonymous module. 17811 define( 'ui/widgets/spinner.js',[ 17812 "jquery", 17813 "./button", 17814 "../version", 17815 "../keycode", 17816 "../widget" 17817 ], factory ); 17818 } else { 17819 17820 // Browser globals 17821 factory( jQuery ); 17822 } 17823} )( function( $ ) { 17824"use strict"; 17825 17826function spinnerModifier( fn ) { 17827 return function() { 17828 var previous = this.element.val(); 17829 fn.apply( this, arguments ); 17830 this._refresh(); 17831 if ( previous !== this.element.val() ) { 17832 this._trigger( "change" ); 17833 } 17834 }; 17835} 17836 17837$.widget( "ui.spinner", { 17838 version: "@VERSION
vendor: 13,205 bytes, lines 17838-18364
17838", 17839 defaultElement: "<input>", 17840 widgetEventPrefix: "spin", 17841 options: { 17842 classes: { 17843 "ui-spinner": "ui-corner-all", 17844 "ui-spinner-down": "ui-corner-br", 17845 "ui-spinner-up": "ui-corner-tr" 17846 }, 17847 culture: null, 17848 icons: { 17849 down: "ui-icon-triangle-1-s", 17850 up: "ui-icon-triangle-1-n" 17851 }, 17852 incremental: true, 17853 max: null, 17854 min: null, 17855 numberFormat: null, 17856 page: 10, 17857 step: 1, 17858 17859 change: null, 17860 spin: null, 17861 start: null, 17862 stop: null 17863 }, 17864 17865 _create: function() { 17866 17867 // handle string values that need to be parsed 17868 this._setOption( "max", this.options.max ); 17869 this._setOption( "min", this.options.min ); 17870 this._setOption( "step", this.options.step ); 17871 17872 // Only format if there is a value, prevents the field from being marked 17873 // as invalid in Firefox, see #9573. 17874 if ( this.value() !== "" ) { 17875 17876 // Format the value, but don't constrain. 17877 this._value( this.element.val(), true ); 17878 } 17879 17880 this._draw(); 17881 this._on( this._events ); 17882 this._refresh(); 17883 17884 // Turning off autocomplete prevents the browser from remembering the 17885 // value when navigating through history, so we re-enable autocomplete 17886 // if the page is unloaded before the widget is destroyed. #7790 17887 this._on( this.window, { 17888 beforeunload: function() { 17889 this.element.removeAttr( "autocomplete" ); 17890 } 17891 } ); 17892 }, 17893 17894 _getCreateOptions: function() { 17895 var options = this._super(); 17896 var element = this.element; 17897 17898 $.each( [ "min", "max", "step" ], function( i, option ) { 17899 var value = element.attr( option ); 17900 if ( value != null && value.length ) { 17901 options[ option ] = value; 17902 } 17903 } ); 17904 17905 return options; 17906 }, 17907 17908 _events: { 17909 keydown: function( event ) { 17910 if ( this._start( event ) && this._keydown( event ) ) { 17911 event.preventDefault(); 17912 } 17913 }, 17914 keyup: "_stop", 17915 focus: function() { 17916 this.previous = this.element.val(); 17917 }, 17918 blur: function( event ) { 17919 this._stop(); 17920 this._refresh(); 17921 if ( this.previous !== this.element.val() ) { 17922 this._trigger( "change", event ); 17923 } 17924 }, 17925 wheel: function( event ) { 17926 var activeElement = this.document[ 0 ].activeElement; 17927 var isActive = this.element[ 0 ] === activeElement; 17928 var delta = event.deltaY || event.originalEvent && event.originalEvent.deltaY; 17929 17930 if ( !isActive || !delta ) { 17931 return; 17932 } 17933 17934 if ( !this.spinning && !this._start( event ) ) { 17935 return false; 17936 } 17937 17938 this._spin( ( delta > 0 ? -1 : 1 ) * this.options.step, event ); 17939 clearTimeout( this.mousewheelTimer ); 17940 this.mousewheelTimer = this._delay( function() { 17941 if ( this.spinning ) { 17942 this._stop( event ); 17943 } 17944 }, 100 ); 17945 event.preventDefault(); 17946 }, 17947 17948 // DEPRECATED 17949 // Kept for backwards compatibility. Please use the modern `wheel` 17950 // event. The `delta` parameter is provided by the jQuery Mousewheel 17951 // plugin if one is loaded. 17952 mousewheel: function( event, delta ) { 17953 if ( !event.isTrigger ) { 17954 17955 // If this is not a trigger call, the `wheel` handler will 17956 // fire as well, let's not duplicate it. 17957 return; 17958 } 17959 17960 var wheelEvent = $.Event( event ); 17961 wheelEvent.type = "wheel"; 17962 if ( delta ) { 17963 wheelEvent.deltaY = -delta; 17964 } 17965 return this._events.wheel.call( this, wheelEvent ); 17966 }, 17967 17968 "mousedown .ui-spinner-button": function( event ) { 17969 var previous; 17970 17971 // We never want the buttons to have focus; whenever the user is 17972 // interacting with the spinner, the focus should be on the input. 17973 // If the input is focused then this.previous is properly set from 17974 // when the input first received focus. If the input is not focused 17975 // then we need to set this.previous based on the value before spinning. 17976 previous = this.element[ 0 ] === this.document[ 0 ].activeElement ? 17977 this.previous : this.element.val(); 17978 function checkFocus() { 17979 var isActive = this.element[ 0 ] === this.document[ 0 ].activeElement; 17980 if ( !isActive ) { 17981 this.element.trigger( "focus" ); 17982 this.previous = previous; 17983 } 17984 } 17985 17986 // Ensure focus is on (or stays on) the text field 17987 event.preventDefault(); 17988 checkFocus.call( this ); 17989 17990 if ( this._start( event ) === false ) { 17991 return; 17992 } 17993 17994 this._repeat( null, $( event.currentTarget ) 17995 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 17996 }, 17997 "mouseup .ui-spinner-button": "_stop", 17998 "mouseenter .ui-spinner-button": function( event ) { 17999 18000 // button will add ui-state-active if mouse was down while mouseleave and kept down 18001 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 18002 return; 18003 } 18004 18005 if ( this._start( event ) === false ) { 18006 return false; 18007 } 18008 this._repeat( null, $( event.currentTarget ) 18009 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 18010 }, 18011 18012 // TODO: do we really want to consider this a stop? 18013 // shouldn't we just stop the repeater and wait until mouseup before 18014 // we trigger the stop event? 18015 "mouseleave .ui-spinner-button": "_stop" 18016 }, 18017 18018 // Support mobile enhanced option and make backcompat more sane 18019 _enhance: function() { 18020 this.uiSpinner = this.element 18021 .attr( "autocomplete", "off" ) 18022 .wrap( "<span>" ) 18023 .parent() 18024 18025 // Add buttons 18026 .append( 18027 "<a></a><a></a>" 18028 ); 18029 }, 18030 18031 _draw: function() { 18032 this._enhance(); 18033 18034 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 18035 this._addClass( "ui-spinner-input" ); 18036 18037 this.element.attr( "role", "spinbutton" ); 18038 18039 // Button bindings 18040 this.buttons = this.uiSpinner.children( "a" ) 18041 .attr( "tabIndex", -1 ) 18042 .attr( "aria-hidden", true ) 18043 .button( { 18044 classes: { 18045 "ui-button": "" 18046 } 18047 } ); 18048 18049 // TODO: Right now button does not support classes this is already updated in button PR 18050 this._removeClass( this.buttons, "ui-corner-all" ); 18051 18052 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 18053 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 18054 this.buttons.first().button( { 18055 "icon": this.options.icons.up, 18056 "showLabel": false 18057 } ); 18058 this.buttons.last().button( { 18059 "icon": this.options.icons.down, 18060 "showLabel": false 18061 } ); 18062 18063 // IE 6 doesn't understand height: 50% for the buttons 18064 // unless the wrapper has an explicit height 18065 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 18066 this.uiSpinner.height() > 0 ) { 18067 this.uiSpinner.height( this.uiSpinner.height() ); 18068 } 18069 }, 18070 18071 _keydown: function( event ) { 18072 var options = this.options, 18073 keyCode = $.ui.keyCode; 18074 18075 switch ( event.keyCode ) { 18076 case keyCode.UP: 18077 this._repeat( null, 1, event ); 18078 return true; 18079 case keyCode.DOWN: 18080 this._repeat( null, -1, event ); 18081 return true; 18082 case keyCode.PAGE_UP: 18083 this._repeat( null, options.page, event ); 18084 return true; 18085 case keyCode.PAGE_DOWN: 18086 this._repeat( null, -options.page, event ); 18087 return true; 18088 } 18089 18090 return false; 18091 }, 18092 18093 _start: function( event ) { 18094 if ( !this.spinning && this._trigger( "start", event ) === false ) { 18095 return false; 18096 } 18097 18098 if ( !this.counter ) { 18099 this.counter = 1; 18100 } 18101 this.spinning = true; 18102 return true; 18103 }, 18104 18105 _repeat: function( i, steps, event ) { 18106 i = i || 500; 18107 18108 clearTimeout( this.timer ); 18109 this.timer = this._delay( function() { 18110 this._repeat( 40, steps, event ); 18111 }, i ); 18112 18113 this._spin( steps * this.options.step, event ); 18114 }, 18115 18116 _spin: function( step, event ) { 18117 var value = this.value() || 0; 18118 18119 if ( !this.counter ) { 18120 this.counter = 1; 18121 } 18122 18123 value = this._adjustValue( value + step * this._increment( this.counter ) ); 18124 18125 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 18126 this._value( value ); 18127 this.counter++; 18128 } 18129 }, 18130 18131 _increment: function( i ) { 18132 var incremental = this.options.incremental; 18133 18134 if ( incremental ) { 18135 return typeof incremental === "function" ? 18136 incremental( i ) : 18137 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 18138 } 18139 18140 return 1; 18141 }, 18142 18143 _precision: function() { 18144 var precision = this._precisionOf( this.options.step ); 18145 if ( this.options.min !== null ) { 18146 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 18147 } 18148 return precision; 18149 }, 18150 18151 _precisionOf: function( num ) { 18152 var str = num.toString(), 18153 decimal = str.indexOf( "." ); 18154 return decimal === -1 ? 0 : str.length - decimal - 1; 18155 }, 18156 18157 _adjustValue: function( value ) { 18158 var base, aboveMin, 18159 options = this.options; 18160 18161 // Make sure we're at a valid step 18162 // - find out where we are relative to the base (min or 0) 18163 base = options.min !== null ? options.min : 0; 18164 aboveMin = value - base; 18165 18166 // - round to the nearest step 18167 aboveMin = Math.round( aboveMin / options.step ) * options.step; 18168 18169 // - rounding is based on 0, so adjust back to our base 18170 value = base + aboveMin; 18171 18172 // Fix precision from bad JS floating point math 18173 value = parseFloat( value.toFixed( this._precision() ) ); 18174 18175 // Clamp the value 18176 if ( options.max !== null && value > options.max ) { 18177 return options.max; 18178 } 18179 if ( options.min !== null && value < options.min ) { 18180 return options.min; 18181 } 18182 18183 return value; 18184 }, 18185 18186 _stop: function( event ) { 18187 if ( !this.spinning ) { 18188 return; 18189 } 18190 18191 clearTimeout( this.timer ); 18192 clearTimeout( this.mousewheelTimer ); 18193 this.counter = 0; 18194 this.spinning = false; 18195 this._trigger( "stop", event ); 18196 }, 18197 18198 _setOption: function( key, value ) { 18199 var prevValue, first, last; 18200 18201 if ( key === "culture" || key === "numberFormat" ) { 18202 prevValue = this._parse( this.element.val() ); 18203 this.options[ key ] = value; 18204 this.element.val( this._format( prevValue ) ); 18205 return; 18206 } 18207 18208 if ( key === "max" || key === "min" || key === "step" ) { 18209 if ( typeof value === "string" ) { 18210 value = this._parse( value ); 18211 } 18212 } 18213 if ( key === "icons" ) { 18214 first = this.buttons.first().find( ".ui-icon" ); 18215 this._removeClass( first, null, this.options.icons.up ); 18216 this._addClass( first, null, value.up ); 18217 last = this.buttons.last().find( ".ui-icon" ); 18218 this._removeClass( last, null, this.options.icons.down ); 18219 this._addClass( last, null, value.down ); 18220 } 18221 18222 this._super( key, value ); 18223 }, 18224 18225 _setOptionDisabled: function( value ) { 18226 this._super( value ); 18227 18228 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 18229 this.element.prop( "disabled", !!value ); 18230 this.buttons.button( value ? "disable" : "enable" ); 18231 }, 18232 18233 _setOptions: spinnerModifier( function( options ) { 18234 this._super( options ); 18235 } ), 18236 18237 _parse: function( val ) { 18238 if ( typeof val === "string" && val !== "" ) { 18239 val = window.Globalize && this.options.numberFormat ? 18240 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 18241 } 18242 return val === "" || isNaN( val ) ? null : val; 18243 }, 18244 18245 _format: function( value ) { 18246 if ( value === "" ) { 18247 return ""; 18248 } 18249 return window.Globalize && this.options.numberFormat ? 18250 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 18251 value; 18252 }, 18253 18254 _refresh: function() { 18255 this.element.attr( { 18256 "aria-valuemin": this.options.min, 18257 "aria-valuemax": this.options.max, 18258 18259 // TODO: what should we do with values that can't be parsed? 18260 "aria-valuenow": this._parse( this.element.val() ) 18261 } ); 18262 }, 18263 18264 isValid: function() { 18265 var value = this.value(); 18266 18267 // Null is invalid 18268 if ( value === null ) { 18269 return false; 18270 } 18271 18272 // If value gets adjusted, it's invalid 18273 return value === this._adjustValue( value ); 18274 }, 18275 18276 // Update the value without triggering change 18277 _value: function( value, allowAny ) { 18278 var parsed; 18279 if ( value !== "" ) { 18280 parsed = this._parse( value ); 18281 if ( parsed !== null ) { 18282 if ( !allowAny ) { 18283 parsed = this._adjustValue( parsed ); 18284 } 18285 value = this._format( parsed ); 18286 } 18287 } 18288 this.element.val( value ); 18289 this._refresh(); 18290 }, 18291 18292 _destroy: function() { 18293 this.element 18294 .prop( "disabled", false ) 18295 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 18296 18297 this.uiSpinner.replaceWith( this.element ); 18298 }, 18299 18300 stepUp: spinnerModifier( function( steps ) { 18301 this._stepUp( steps ); 18302 } ), 18303 _stepUp: function( steps ) { 18304 if ( this._start() ) { 18305 this._spin( ( steps || 1 ) * this.options.step ); 18306 this._stop(); 18307 } 18308 }, 18309 18310 stepDown: spinnerModifier( function( steps ) { 18311 this._stepDown( steps ); 18312 } ), 18313 _stepDown: function( steps ) { 18314 if ( this._start() ) { 18315 this._spin( ( steps || 1 ) * -this.options.step ); 18316 this._stop(); 18317 } 18318 }, 18319 18320 pageUp: spinnerModifier( function( pages ) { 18321 this._stepUp( ( pages || 1 ) * this.options.page ); 18322 } ), 18323 18324 pageDown: spinnerModifier( function( pages ) { 18325 this._stepDown( ( pages || 1 ) * this.options.page ); 18326 } ), 18327 18328 value: function( newVal ) { 18329 if ( !arguments.length ) { 18330 return this._parse( this.element.val() ); 18331 } 18332 spinnerModifier( this._value ).call( this, newVal ); 18333 }, 18334 18335 widget: function() { 18336 return this.uiSpinner; 18337 } 18338} ); 18339 18340// DEPRECATED 18341// TODO: switch return back to widget declaration at top of file when this is removed 18342if ( $.uiBackCompat === true ) { 18343 18344 // Backcompat for spinner html extension points 18345 $.widget( "ui.spinner", $.ui.spinner, { 18346 _enhance: function() { 18347 this.uiSpinner = this.element 18348 .attr( "autocomplete", "off" ) 18349 .wrap( this._uiSpinnerHtml() ) 18350 .parent() 18351 18352 // Add buttons 18353 .append( this._buttonHtml() ); 18354 }, 18355 _uiSpinnerHtml: function() { 18356 return "<span>"; 18357 }, 18358 18359 _buttonHtml: function() { 18360 return "<a></a><a></a>"; 18361 } 18362 } ); 18363} 18364
18365return $.ui.spinner; 18366 18367} ); 18368 18369/*! 18370 * jQuery UI Tabs @VERSION 18371 * https://jqueryui.com 18372 * 18373 * Copyright OpenJS Foundation and other contributors 18374 * Released under the MIT license. 18375 * https://jquery.org/license 18376 */ 18377 18378//>>label: Tabs 18379//>>group: Widgets 18380//>>description: Transforms a set of container elements into a tab structure. 18381//>>docs: https://api.jqueryui.com/tabs/ 18382//>>demos: https://jqueryui.com/tabs/ 18383//>>css.structure: ../../themes/base/core.css 18384//>>css.structure: ../../themes/base/tabs.css 18385//>>css.theme: ../../themes/base/theme.css 18386 18387( function( factory ) { 18388 "use strict"; 18389 18390 if ( typeof define === "function" && define.amd ) { 18391 18392 // AMD. Register as an anonymous module. 18393 define( 'ui/widgets/tabs.js',[ 18394 "jquery", 18395 "../keycode", 18396 "../unique-id", 18397 "../version", 18398 "../widget" 18399 ], factory ); 18400 } else { 18401 18402 // Browser globals 18403 factory( jQuery ); 18404 } 18405} )( function( $ ) { 18406"use strict"; 18407 18408$.widget( "ui.tabs", { 18409 version: "@VERSION
vendor: 22,588 bytes, lines 18409-19278
18409", 18410 delay: 300, 18411 options: { 18412 active: null, 18413 classes: { 18414 "ui-tabs": "ui-corner-all", 18415 "ui-tabs-nav": "ui-corner-all", 18416 "ui-tabs-panel": "ui-corner-bottom", 18417 "ui-tabs-tab": "ui-corner-top" 18418 }, 18419 collapsible: false, 18420 event: "click", 18421 heightStyle: "content", 18422 hide: null, 18423 show: null, 18424 18425 // Callbacks 18426 activate: null, 18427 beforeActivate: null, 18428 beforeLoad: null, 18429 load: null 18430 }, 18431 18432 _isLocal: function( anchor ) { 18433 var anchorUrl = new URL( anchor.href ), 18434 locationUrl = new URL( location.href ); 18435 18436 return anchor.hash.length > 1 && 18437 18438 // `href` may contain a hash but also username & password; 18439 // we want to ignore them, so we check the three fields 18440 // below instead. 18441 anchorUrl.origin === locationUrl.origin && 18442 anchorUrl.pathname === locationUrl.pathname && 18443 anchorUrl.search === locationUrl.search; 18444 }, 18445 18446 _create: function() { 18447 var that = this, 18448 options = this.options; 18449 18450 this.running = false; 18451 18452 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 18453 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 18454 18455 this._processTabs(); 18456 options.active = this._initialActive(); 18457 18458 // Take disabling tabs via class attribute from HTML 18459 // into account and update option properly. 18460 if ( Array.isArray( options.disabled ) ) { 18461 options.disabled = $.uniqueSort( options.disabled.concat( 18462 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 18463 return that.tabs.index( li ); 18464 } ) 18465 ) ).sort(); 18466 } 18467 18468 // Check for length avoids error when initializing empty list 18469 if ( this.options.active !== false && this.anchors.length ) { 18470 this.active = this._findActive( options.active ); 18471 } else { 18472 this.active = $(); 18473 } 18474 18475 this._refresh(); 18476 18477 if ( this.active.length ) { 18478 this.load( options.active ); 18479 } 18480 }, 18481 18482 _initialActive: function() { 18483 var active = this.options.active, 18484 collapsible = this.options.collapsible, 18485 locationHash = location.hash.substring( 1 ), 18486 locationHashDecoded = decodeURIComponent( locationHash ); 18487 18488 if ( active === null ) { 18489 18490 // check the fragment identifier in the URL 18491 if ( locationHash ) { 18492 this.tabs.each( function( i, tab ) { 18493 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 18494 active = i; 18495 return false; 18496 } 18497 } ); 18498 18499 // If not found, decode the hash & try again. 18500 // See the comment in `_processTabs` under the `_isLocal` check 18501 // for more information. 18502 if ( active === null ) { 18503 this.tabs.each( function( i, tab ) { 18504 if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) { 18505 active = i; 18506 return false; 18507 } 18508 } ); 18509 } 18510 } 18511 18512 // Check for a tab marked active via a class 18513 if ( active === null ) { 18514 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 18515 } 18516 18517 // No active tab, set to false 18518 if ( active === null || active === -1 ) { 18519 active = this.tabs.length ? 0 : false; 18520 } 18521 } 18522 18523 // Handle numbers: negative, out of range 18524 if ( active !== false ) { 18525 active = this.tabs.index( this.tabs.eq( active ) ); 18526 if ( active === -1 ) { 18527 active = collapsible ? false : 0; 18528 } 18529 } 18530 18531 // Don't allow collapsible: false and active: false 18532 if ( !collapsible && active === false && this.anchors.length ) { 18533 active = 0; 18534 } 18535 18536 return active; 18537 }, 18538 18539 _getCreateEventData: function() { 18540 return { 18541 tab: this.active, 18542 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 18543 }; 18544 }, 18545 18546 _tabKeydown: function( event ) { 18547 var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ), 18548 selectedIndex = this.tabs.index( focusedTab ), 18549 goingForward = true; 18550 18551 if ( this._handlePageNav( event ) ) { 18552 return; 18553 } 18554 18555 switch ( event.keyCode ) { 18556 case $.ui.keyCode.RIGHT: 18557 case $.ui.keyCode.DOWN: 18558 selectedIndex++; 18559 break; 18560 case $.ui.keyCode.UP: 18561 case $.ui.keyCode.LEFT: 18562 goingForward = false; 18563 selectedIndex--; 18564 break; 18565 case $.ui.keyCode.END: 18566 selectedIndex = this.anchors.length - 1; 18567 break; 18568 case $.ui.keyCode.HOME: 18569 selectedIndex = 0; 18570 break; 18571 case $.ui.keyCode.SPACE: 18572 18573 // Activate only, no collapsing 18574 event.preventDefault(); 18575 clearTimeout( this.activating ); 18576 this._activate( selectedIndex ); 18577 return; 18578 case $.ui.keyCode.ENTER: 18579 18580 // Toggle (cancel delayed activation, allow collapsing) 18581 event.preventDefault(); 18582 clearTimeout( this.activating ); 18583 18584 // Determine if we should collapse or activate 18585 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 18586 return; 18587 default: 18588 return; 18589 } 18590 18591 // Focus the appropriate tab, based on which key was pressed 18592 event.preventDefault(); 18593 clearTimeout( this.activating ); 18594 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 18595 18596 // Navigating with control/command key will prevent automatic activation 18597 if ( !event.ctrlKey && !event.metaKey ) { 18598 18599 // Update aria-selected immediately so that AT think the tab is already selected. 18600 // Otherwise AT may confuse the user by stating that they need to activate the tab, 18601 // but the tab will already be activated by the time the announcement finishes. 18602 focusedTab.attr( "aria-selected", "false" ); 18603 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 18604 18605 this.activating = this._delay( function() { 18606 this.option( "active", selectedIndex ); 18607 }, this.delay ); 18608 } 18609 }, 18610 18611 _panelKeydown: function( event ) { 18612 if ( this._handlePageNav( event ) ) { 18613 return; 18614 } 18615 18616 // Ctrl+up moves focus to the current tab 18617 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 18618 event.preventDefault(); 18619 this.active.trigger( "focus" ); 18620 } 18621 }, 18622 18623 // Alt+page up/down moves focus to the previous/next tab (and activates) 18624 _handlePageNav: function( event ) { 18625 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 18626 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 18627 return true; 18628 } 18629 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 18630 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 18631 return true; 18632 } 18633 }, 18634 18635 _findNextTab: function( index, goingForward ) { 18636 var lastTabIndex = this.tabs.length - 1; 18637 18638 function constrain() { 18639 if ( index > lastTabIndex ) { 18640 index = 0; 18641 } 18642 if ( index < 0 ) { 18643 index = lastTabIndex; 18644 } 18645 return index; 18646 } 18647 18648 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 18649 index = goingForward ? index + 1 : index - 1; 18650 } 18651 18652 return index; 18653 }, 18654 18655 _focusNextTab: function( index, goingForward ) { 18656 index = this._findNextTab( index, goingForward ); 18657 this.tabs.eq( index ).trigger( "focus" ); 18658 return index; 18659 }, 18660 18661 _setOption: function( key, value ) { 18662 if ( key === "active" ) { 18663 18664 // _activate() will handle invalid values and update this.options 18665 this._activate( value ); 18666 return; 18667 } 18668 18669 this._super( key, value ); 18670 18671 if ( key === "collapsible" ) { 18672 this._toggleClass( "ui-tabs-collapsible", null, value ); 18673 18674 // Setting collapsible: false while collapsed; open first panel 18675 if ( !value && this.options.active === false ) { 18676 this._activate( 0 ); 18677 } 18678 } 18679 18680 if ( key === "event" ) { 18681 this._setupEvents( value ); 18682 } 18683 18684 if ( key === "heightStyle" ) { 18685 this._setupHeightStyle( value ); 18686 } 18687 }, 18688 18689 refresh: function() { 18690 var options = this.options, 18691 lis = this.tablist.children( ":has(a[href])" ); 18692 18693 // Get disabled tabs from class attribute from HTML 18694 // this will get converted to a boolean if needed in _refresh() 18695 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 18696 return lis.index( tab ); 18697 } ); 18698 18699 this._processTabs(); 18700 18701 // Was collapsed or no tabs 18702 if ( options.active === false || !this.anchors.length ) { 18703 options.active = false; 18704 this.active = $(); 18705 18706 // was active, but active tab is gone 18707 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 18708 18709 // all remaining tabs are disabled 18710 if ( this.tabs.length === options.disabled.length ) { 18711 options.active = false; 18712 this.active = $(); 18713 18714 // activate previous tab 18715 } else { 18716 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 18717 } 18718 18719 // was active, active tab still exists 18720 } else { 18721 18722 // make sure active index is correct 18723 options.active = this.tabs.index( this.active ); 18724 } 18725 18726 this._refresh(); 18727 }, 18728 18729 _refresh: function() { 18730 this._setOptionDisabled( this.options.disabled ); 18731 this._setupEvents( this.options.event ); 18732 this._setupHeightStyle( this.options.heightStyle ); 18733 18734 this.tabs.not( this.active ).attr( { 18735 "aria-selected": "false", 18736 "aria-expanded": "false", 18737 tabIndex: -1 18738 } ); 18739 this.panels.not( this._getPanelForTab( this.active ) ) 18740 .hide() 18741 .attr( { 18742 "aria-hidden": "true" 18743 } ); 18744 18745 // Make sure one tab is in the tab order 18746 if ( !this.active.length ) { 18747 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 18748 } else { 18749 this.active 18750 .attr( { 18751 "aria-selected": "true", 18752 "aria-expanded": "true", 18753 tabIndex: 0 18754 } ); 18755 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 18756 this._getPanelForTab( this.active ) 18757 .show() 18758 .attr( { 18759 "aria-hidden": "false" 18760 } ); 18761 } 18762 }, 18763 18764 _processTabs: function() { 18765 var that = this, 18766 prevTabs = this.tabs, 18767 prevAnchors = this.anchors, 18768 prevPanels = this.panels; 18769 18770 this.tablist = this._getList().attr( "role", "tablist" ); 18771 this._addClass( this.tablist, "ui-tabs-nav", 18772 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 18773 18774 // Prevent users from focusing disabled tabs via click 18775 this.tablist 18776 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 18777 if ( $( this ).is( ".ui-state-disabled" ) ) { 18778 event.preventDefault(); 18779 } 18780 } ); 18781 18782 this.tabs = this.tablist.find( "> li:has(a[href])" ) 18783 .attr( { 18784 role: "tab", 18785 tabIndex: -1 18786 } ); 18787 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 18788 18789 this.anchors = this.tabs.map( function() { 18790 return $( "a", this )[ 0 ]; 18791 } ) 18792 .attr( { 18793 tabIndex: -1 18794 } ); 18795 this._addClass( this.anchors, "ui-tabs-anchor" ); 18796 18797 this.panels = $(); 18798 18799 this.anchors.each( function( i, anchor ) { 18800 var selector, panel, panelId, 18801 anchorId = $( anchor ).uniqueId().attr( "id" ), 18802 tab = $( anchor ).closest( "li" ), 18803 originalAriaControls = tab.attr( "aria-controls" ); 18804 18805 // Inline tab 18806 if ( that._isLocal( anchor ) ) { 18807 18808 // The "scrolling to a fragment" section of the HTML spec: 18809 // https://html.spec.whatwg.org/#scrolling-to-a-fragment 18810 // uses a concept of document's indicated part: 18811 // https://html.spec.whatwg.org/#the-indicated-part-of-the-document 18812 // Slightly below there's an algorithm to compute the indicated 18813 // part: 18814 // https://html.spec.whatwg.org/#the-indicated-part-of-the-document 18815 // First, the algorithm tries the hash as-is, without decoding. 18816 // Then, if one is not found, the same is attempted with a decoded 18817 // hash. Replicate this logic. 18818 selector = anchor.hash; 18819 panelId = selector.substring( 1 ); 18820 panel = that.element.find( "#" + CSS.escape( panelId ) ); 18821 if ( !panel.length ) { 18822 panelId = decodeURIComponent( panelId ); 18823 panel = that.element.find( "#" + CSS.escape( panelId ) ); 18824 } 18825 18826 // remote tab 18827 } else { 18828 18829 // If the tab doesn't already have aria-controls, 18830 // generate an id by using a throw-away element 18831 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 18832 selector = "#" + panelId; 18833 panel = that.element.find( selector ); 18834 if ( !panel.length ) { 18835 panel = that._createPanel( panelId ); 18836 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 18837 } 18838 panel.attr( "aria-live", "polite" ); 18839 } 18840 18841 if ( panel.length ) { 18842 that.panels = that.panels.add( panel ); 18843 } 18844 if ( originalAriaControls ) { 18845 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 18846 } 18847 tab.attr( { 18848 "aria-controls": panelId, 18849 "aria-labelledby": anchorId 18850 } ); 18851 panel.attr( "aria-labelledby", anchorId ); 18852 } ); 18853 18854 this.panels.attr( "role", "tabpanel" ); 18855 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 18856 18857 // Avoid memory leaks (#10056) 18858 if ( prevTabs ) { 18859 this._off( prevTabs.not( this.tabs ) ); 18860 this._off( prevAnchors.not( this.anchors ) ); 18861 this._off( prevPanels.not( this.panels ) ); 18862 } 18863 }, 18864 18865 // Allow overriding how to find the list for rare usage scenarios (#7715) 18866 _getList: function() { 18867 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 18868 }, 18869 18870 _createPanel: function( id ) { 18871 return $( "<div>" ) 18872 .attr( "id", id ) 18873 .data( "ui-tabs-destroy", true ); 18874 }, 18875 18876 _setOptionDisabled: function( disabled ) { 18877 var currentItem, li, i; 18878 18879 if ( Array.isArray( disabled ) ) { 18880 if ( !disabled.length ) { 18881 disabled = false; 18882 } else if ( disabled.length === this.anchors.length ) { 18883 disabled = true; 18884 } 18885 } 18886 18887 // Disable tabs 18888 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 18889 currentItem = $( li ); 18890 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 18891 currentItem.attr( "aria-disabled", "true" ); 18892 this._addClass( currentItem, null, "ui-state-disabled" ); 18893 } else { 18894 currentItem.removeAttr( "aria-disabled" ); 18895 this._removeClass( currentItem, null, "ui-state-disabled" ); 18896 } 18897 } 18898 18899 this.options.disabled = disabled; 18900 18901 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 18902 disabled === true ); 18903 }, 18904 18905 _setupEvents: function( event ) { 18906 var events = {}; 18907 if ( event ) { 18908 $.each( event.split( " " ), function( index, eventName ) { 18909 events[ eventName ] = "_eventHandler"; 18910 } ); 18911 } 18912 18913 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 18914 18915 // Always prevent the default action, even when disabled 18916 this._on( true, this.anchors, { 18917 click: function( event ) { 18918 event.preventDefault(); 18919 } 18920 } ); 18921 this._on( this.anchors, events ); 18922 this._on( this.tabs, { keydown: "_tabKeydown" } ); 18923 this._on( this.panels, { keydown: "_panelKeydown" } ); 18924 18925 this._focusable( this.tabs ); 18926 this._hoverable( this.tabs ); 18927 }, 18928 18929 _setupHeightStyle: function( heightStyle ) { 18930 var maxHeight, 18931 parent = this.element.parent(); 18932 18933 if ( heightStyle === "fill" ) { 18934 maxHeight = parent.height(); 18935 maxHeight -= this.element.outerHeight() - this.element.height(); 18936 18937 this.element.siblings( ":visible" ).each( function() { 18938 var elem = $( this ), 18939 position = elem.css( "position" ); 18940 18941 if ( position === "absolute" || position === "fixed" ) { 18942 return; 18943 } 18944 maxHeight -= elem.outerHeight( true ); 18945 } ); 18946 18947 this.element.children().not( this.panels ).each( function() { 18948 maxHeight -= $( this ).outerHeight( true ); 18949 } ); 18950 18951 this.panels.each( function() { 18952 $( this ).height( Math.max( 0, maxHeight - 18953 $( this ).innerHeight() + $( this ).height() ) ); 18954 } ) 18955 .css( "overflow", "auto" ); 18956 } else if ( heightStyle === "auto" ) { 18957 maxHeight = 0; 18958 this.panels.each( function() { 18959 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 18960 } ).height( maxHeight ); 18961 } 18962 }, 18963 18964 _eventHandler: function( event ) { 18965 var options = this.options, 18966 active = this.active, 18967 anchor = $( event.currentTarget ), 18968 tab = anchor.closest( "li" ), 18969 clickedIsActive = tab[ 0 ] === active[ 0 ], 18970 collapsing = clickedIsActive && options.collapsible, 18971 toShow = collapsing ? $() : this._getPanelForTab( tab ), 18972 toHide = !active.length ? $() : this._getPanelForTab( active ), 18973 eventData = { 18974 oldTab: active, 18975 oldPanel: toHide, 18976 newTab: collapsing ? $() : tab, 18977 newPanel: toShow 18978 }; 18979 18980 event.preventDefault(); 18981 18982 if ( tab.hasClass( "ui-state-disabled" ) || 18983 18984 // tab is already loading 18985 tab.hasClass( "ui-tabs-loading" ) || 18986 18987 // can't switch durning an animation 18988 this.running || 18989 18990 // click on active header, but not collapsible 18991 ( clickedIsActive && !options.collapsible ) || 18992 18993 // allow canceling activation 18994 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 18995 return; 18996 } 18997 18998 options.active = collapsing ? false : this.tabs.index( tab ); 18999 19000 this.active = clickedIsActive ? $() : tab; 19001 if ( this.xhr ) { 19002 this.xhr.abort(); 19003 } 19004 19005 if ( !toHide.length && !toShow.length ) { 19006 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 19007 } 19008 19009 if ( toShow.length ) { 19010 this.load( this.tabs.index( tab ), event ); 19011 } 19012 this._toggle( event, eventData ); 19013 }, 19014 19015 // Handles show/hide for selecting tabs 19016 _toggle: function( event, eventData ) { 19017 var that = this, 19018 toShow = eventData.newPanel, 19019 toHide = eventData.oldPanel; 19020 19021 this.running = true; 19022 19023 function complete() { 19024 that.running = false; 19025 that._trigger( "activate", event, eventData ); 19026 } 19027 19028 function show() { 19029 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 19030 19031 if ( toShow.length && that.options.show ) { 19032 that._show( toShow, that.options.show, complete ); 19033 } else { 19034 toShow.show(); 19035 complete(); 19036 } 19037 } 19038 19039 // Start out by hiding, then showing, then completing 19040 if ( toHide.length && this.options.hide ) { 19041 this._hide( toHide, this.options.hide, function() { 19042 that._removeClass( eventData.oldTab.closest( "li" ), 19043 "ui-tabs-active", "ui-state-active" ); 19044 show(); 19045 } ); 19046 } else { 19047 this._removeClass( eventData.oldTab.closest( "li" ), 19048 "ui-tabs-active", "ui-state-active" ); 19049 toHide.hide(); 19050 show(); 19051 } 19052 19053 toHide.attr( "aria-hidden", "true" ); 19054 eventData.oldTab.attr( { 19055 "aria-selected": "false", 19056 "aria-expanded": "false" 19057 } ); 19058 19059 // If we're switching tabs, remove the old tab from the tab order. 19060 // If we're opening from collapsed state, remove the previous tab from the tab order. 19061 // If we're collapsing, then keep the collapsing tab in the tab order. 19062 if ( toShow.length && toHide.length ) { 19063 eventData.oldTab.attr( "tabIndex", -1 ); 19064 } else if ( toShow.length ) { 19065 this.tabs.filter( function() { 19066 return $( this ).attr( "tabIndex" ) === 0; 19067 } ) 19068 .attr( "tabIndex", -1 ); 19069 } 19070 19071 toShow.attr( "aria-hidden", "false" ); 19072 eventData.newTab.attr( { 19073 "aria-selected": "true", 19074 "aria-expanded": "true", 19075 tabIndex: 0 19076 } ); 19077 }, 19078 19079 _activate: function( index ) { 19080 var anchor, 19081 active = this._findActive( index ); 19082 19083 // Trying to activate the already active panel 19084 if ( active[ 0 ] === this.active[ 0 ] ) { 19085 return; 19086 } 19087 19088 // Trying to collapse, simulate a click on the current active header 19089 if ( !active.length ) { 19090 active = this.active; 19091 } 19092 19093 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 19094 this._eventHandler( { 19095 target: anchor, 19096 currentTarget: anchor, 19097 preventDefault: $.noop 19098 } ); 19099 }, 19100 19101 _findActive: function( index ) { 19102 return index === false ? $() : this.tabs.eq( index ); 19103 }, 19104 19105 _getIndex: function( index ) { 19106 19107 // meta-function to give users option to provide a href string instead of a numerical index. 19108 if ( typeof index === "string" ) { 19109 index = this.anchors.index( this.anchors.filter( "[href$='" + 19110 CSS.escape( index ) + "']" ) ); 19111 } 19112 19113 return index; 19114 }, 19115 19116 _destroy: function() { 19117 if ( this.xhr ) { 19118 this.xhr.abort(); 19119 } 19120 19121 this.tablist 19122 .removeAttr( "role" ) 19123 .off( this.eventNamespace ); 19124 19125 this.anchors 19126 .removeAttr( "role tabIndex" ) 19127 .removeUniqueId(); 19128 19129 this.tabs.add( this.panels ).each( function() { 19130 if ( $.data( this, "ui-tabs-destroy" ) ) { 19131 $( this ).remove(); 19132 } else { 19133 $( this ).removeAttr( "role tabIndex " + 19134 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 19135 } 19136 } ); 19137 19138 this.tabs.each( function() { 19139 var li = $( this ), 19140 prev = li.data( "ui-tabs-aria-controls" ); 19141 if ( prev ) { 19142 li 19143 .attr( "aria-controls", prev ) 19144 .removeData( "ui-tabs-aria-controls" ); 19145 } else { 19146 li.removeAttr( "aria-controls" ); 19147 } 19148 } ); 19149 19150 this.panels.show(); 19151 19152 if ( this.options.heightStyle !== "content" ) { 19153 this.panels.css( "height", "" ); 19154 } 19155 }, 19156 19157 enable: function( index ) { 19158 var disabled = this.options.disabled; 19159 if ( disabled === false ) { 19160 return; 19161 } 19162 19163 if ( index === undefined ) { 19164 disabled = false; 19165 } else { 19166 index = this._getIndex( index ); 19167 if ( Array.isArray( disabled ) ) { 19168 disabled = $.map( disabled, function( num ) { 19169 return num !== index ? num : null; 19170 } ); 19171 } else { 19172 disabled = $.map( this.tabs, function( li, num ) { 19173 return num !== index ? num : null; 19174 } ); 19175 } 19176 } 19177 this._setOptionDisabled( disabled ); 19178 }, 19179 19180 disable: function( index ) { 19181 var disabled = this.options.disabled; 19182 if ( disabled === true ) { 19183 return; 19184 } 19185 19186 if ( index === undefined ) { 19187 disabled = true; 19188 } else { 19189 index = this._getIndex( index ); 19190 if ( $.inArray( index, disabled ) !== -1 ) { 19191 return; 19192 } 19193 if ( Array.isArray( disabled ) ) { 19194 disabled = $.merge( [ index ], disabled ).sort(); 19195 } else { 19196 disabled = [ index ]; 19197 } 19198 } 19199 this._setOptionDisabled( disabled ); 19200 }, 19201 19202 load: function( index, event ) { 19203 index = this._getIndex( index ); 19204 var that = this, 19205 tab = this.tabs.eq( index ), 19206 anchor = tab.find( ".ui-tabs-anchor" ), 19207 panel = this._getPanelForTab( tab ), 19208 eventData = { 19209 tab: tab, 19210 panel: panel 19211 }, 19212 complete = function( jqXHR, status ) { 19213 if ( status === "abort" ) { 19214 that.panels.stop( false, true ); 19215 } 19216 19217 that._removeClass( tab, "ui-tabs-loading" ); 19218 panel.removeAttr( "aria-busy" ); 19219 19220 if ( jqXHR === that.xhr ) { 19221 delete that.xhr; 19222 } 19223 }; 19224 19225 // Not remote 19226 if ( this._isLocal( anchor[ 0 ] ) ) { 19227 return; 19228 } 19229 19230 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 19231 19232 if ( this.xhr.statusText !== "canceled" ) { 19233 this._addClass( tab, "ui-tabs-loading" ); 19234 panel.attr( "aria-busy", "true" ); 19235 19236 this.xhr 19237 .done( function( response, status, jqXHR ) { 19238 panel.html( response ); 19239 that._trigger( "load", event, eventData ); 19240 19241 complete( jqXHR, status ); 19242 } ) 19243 .fail( function( jqXHR, status ) { 19244 complete( jqXHR, status ); 19245 } ); 19246 } 19247 }, 19248 19249 _ajaxSettings: function( anchor, event, eventData ) { 19250 var that = this; 19251 return { 19252 url: anchor.attr( "href" ), 19253 beforeSend: function( jqXHR, settings ) { 19254 return that._trigger( "beforeLoad", event, 19255 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 19256 } 19257 }; 19258 }, 19259 19260 _getPanelForTab: function( tab ) { 19261 var id = $( tab ).attr( "aria-controls" ); 19262 return this.element.find( "#" + CSS.escape( id ) ); 19263 } 19264} ); 19265 19266// DEPRECATED 19267// TODO: Switch return back to widget declaration at top of file when this is removed 19268if ( $.uiBackCompat === true ) { 19269 19270 // Backcompat for ui-tab class (now ui-tabs-tab) 19271 $.widget( "ui.tabs", $.ui.tabs, { 19272 _processTabs: function() { 19273 this._superApply( arguments ); 19274 this._addClass( this.tabs, "ui-tab" ); 19275 } 19276 } ); 19277} 19278
19279return $.ui.tabs; 19280 19281} ); 19282 19283/*! 19284 * jQuery UI Tooltip @VERSION 19285 * https://jqueryui.com 19286 * 19287 * Copyright OpenJS Foundation and other contributors 19288 * Released under the MIT license. 19289 * https://jquery.org/license 19290 */ 19291 19292//>>label: Tooltip 19293//>>group: Widgets 19294//>>description: Shows additional information for any element on hover or focus. 19295//>>docs: https://api.jqueryui.com/tooltip/ 19296//>>demos: https://jqueryui.com/tooltip/ 19297//>>css.structure: ../../themes/base/core.css 19298//>>css.structure: ../../themes/base/tooltip.css 19299//>>css.theme: ../../themes/base/theme.css 19300 19301( function( factory ) { 19302 "use strict"; 19303 19304 if ( typeof define === "function" && define.amd ) { 19305 19306 // AMD. Register as an anonymous module. 19307 define( 'ui/widgets/tooltip.js',[ 19308 "jquery", 19309 "../keycode", 19310 "../position", 19311 "../unique-id", 19312 "../version", 19313 "../widget" 19314 ], factory ); 19315 } else { 19316 19317 // Browser globals 19318 factory( jQuery ); 19319 } 19320} )( function( $ ) { 19321"use strict"; 19322 19323$.widget( "ui.tooltip", { 19324 version: "@VERSION
vendor: 13,338 bytes, lines 19324-19801
19324", 19325 options: { 19326 classes: { 19327 "ui-tooltip": "ui-corner-all ui-widget-shadow" 19328 }, 19329 content: function() { 19330 var title = $( this ).attr( "title" ); 19331 19332 // Escape title, since we're going from an attribute to raw HTML 19333 return $( "<a>" ).text( title ).html(); 19334 }, 19335 hide: true, 19336 19337 // Disabled elements have inconsistent behavior across browsers (#8661) 19338 items: "[title]:not([disabled])", 19339 position: { 19340 my: "left top+15", 19341 at: "left bottom", 19342 collision: "flipfit flip" 19343 }, 19344 show: true, 19345 track: false, 19346 19347 // Callbacks 19348 close: null, 19349 open: null 19350 }, 19351 19352 _addDescribedBy: function( elem, id ) { 19353 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 19354 describedby.push( id ); 19355 elem 19356 .data( "ui-tooltip-id", id ) 19357 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); 19358 }, 19359 19360 _removeDescribedBy: function( elem ) { 19361 var id = elem.data( "ui-tooltip-id" ), 19362 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 19363 index = $.inArray( id, describedby ); 19364 19365 if ( index !== -1 ) { 19366 describedby.splice( index, 1 ); 19367 } 19368 19369 elem.removeData( "ui-tooltip-id" ); 19370 describedby = String.prototype.trim.call( describedby.join( " " ) ); 19371 if ( describedby ) { 19372 elem.attr( "aria-describedby", describedby ); 19373 } else { 19374 elem.removeAttr( "aria-describedby" ); 19375 } 19376 }, 19377 19378 _create: function() { 19379 this._on( { 19380 mouseover: "open", 19381 focusin: "open" 19382 } ); 19383 19384 // IDs of generated tooltips, needed for destroy 19385 this.tooltips = {}; 19386 19387 // IDs of parent tooltips where we removed the title attribute 19388 this.parents = {}; 19389 19390 // Append the aria-live region so tooltips announce correctly 19391 this.liveRegion = $( "<div>" ) 19392 .attr( { 19393 role: "log", 19394 "aria-live": "assertive", 19395 "aria-relevant": "additions" 19396 } ) 19397 .appendTo( this.document[ 0 ].body ); 19398 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 19399 19400 this.disabledTitles = $( [] ); 19401 }, 19402 19403 _setOption: function( key, value ) { 19404 var that = this; 19405 19406 this._super( key, value ); 19407 19408 if ( key === "content" ) { 19409 $.each( this.tooltips, function( id, tooltipData ) { 19410 that._updateContent( tooltipData.element ); 19411 } ); 19412 } 19413 }, 19414 19415 _setOptionDisabled: function( value ) { 19416 this[ value ? "_disable" : "_enable" ](); 19417 }, 19418 19419 _disable: function() { 19420 var that = this; 19421 19422 // Close open tooltips 19423 $.each( this.tooltips, function( id, tooltipData ) { 19424 var event = $.Event( "blur" ); 19425 event.target = event.currentTarget = tooltipData.element[ 0 ]; 19426 that.close( event, true ); 19427 } ); 19428 19429 // Remove title attributes to prevent native tooltips 19430 this.disabledTitles = this.disabledTitles.add( 19431 this.element.find( this.options.items ).addBack() 19432 .filter( function() { 19433 var element = $( this ); 19434 if ( element.is( "[title]" ) ) { 19435 return element 19436 .data( "ui-tooltip-title", element.attr( "title" ) ) 19437 .removeAttr( "title" ); 19438 } 19439 } ) 19440 ); 19441 }, 19442 19443 _enable: function() { 19444 19445 // restore title attributes 19446 this.disabledTitles.each( function() { 19447 var element = $( this ); 19448 if ( element.data( "ui-tooltip-title" ) ) { 19449 element.attr( "title", element.data( "ui-tooltip-title" ) ); 19450 } 19451 } ); 19452 this.disabledTitles = $( [] ); 19453 }, 19454 19455 open: function( event ) { 19456 var that = this, 19457 target = $( event ? event.target : this.element ) 19458 19459 // we need closest here due to mouseover bubbling, 19460 // but always pointing at the same event target 19461 .closest( this.options.items ); 19462 19463 // No element to show a tooltip for or the tooltip is already open 19464 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 19465 return; 19466 } 19467 19468 if ( target.attr( "title" ) ) { 19469 target.data( "ui-tooltip-title", target.attr( "title" ) ); 19470 } 19471 19472 target.data( "ui-tooltip-open", true ); 19473 19474 // Kill parent tooltips, custom or native, for hover 19475 if ( event && event.type === "mouseover" ) { 19476 target.parents().each( function() { 19477 var parent = $( this ), 19478 blurEvent; 19479 if ( parent.data( "ui-tooltip-open" ) ) { 19480 blurEvent = $.Event( "blur" ); 19481 blurEvent.target = blurEvent.currentTarget = this; 19482 that.close( blurEvent, true ); 19483 } 19484 if ( parent.attr( "title" ) ) { 19485 parent.uniqueId(); 19486 that.parents[ this.id ] = { 19487 element: this, 19488 title: parent.attr( "title" ) 19489 }; 19490 parent.attr( "title", "" ); 19491 } 19492 } ); 19493 } 19494 19495 this._registerCloseHandlers( event, target ); 19496 this._updateContent( target, event ); 19497 }, 19498 19499 _updateContent: function( target, event ) { 19500 var content, 19501 contentOption = this.options.content, 19502 that = this, 19503 eventType = event ? event.type : null; 19504 19505 if ( typeof contentOption === "string" || contentOption.nodeType || 19506 contentOption.jquery ) { 19507 return this._open( event, target, contentOption ); 19508 } 19509 19510 content = contentOption.call( target[ 0 ], function( response ) { 19511 19512 // Ignore async response if tooltip was closed already 19513 if ( !target.data( "ui-tooltip-open" ) ) { 19514 return; 19515 } 19516 19517 // JQuery creates a special event for focusin when it doesn't 19518 // exist natively. To improve performance, the native event 19519 // object is reused and the type is changed. Therefore, we can't 19520 // rely on the type being correct after the event finished 19521 // bubbling, so we set it back to the previous value. (#8740) 19522 if ( event ) { 19523 event.type = eventType; 19524 } 19525 that._open( event, target, response ); 19526 } ); 19527 if ( content ) { 19528 this._open( event, target, content ); 19529 } 19530 }, 19531 19532 _open: function( event, target, content ) { 19533 var tooltipData, tooltip, delayedShow, a11yContent, 19534 positionOption = $.extend( {}, this.options.position ); 19535 19536 if ( !content ) { 19537 return; 19538 } 19539 19540 // Content can be updated multiple times. If the tooltip already 19541 // exists, then just update the content and bail. 19542 tooltipData = this._find( target ); 19543 if ( tooltipData ) { 19544 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 19545 return; 19546 } 19547 19548 // If we have a title, clear it to prevent the native tooltip 19549 // we have to check first to avoid defining a title if none exists 19550 // (we don't want to cause an element to start matching [title]) 19551 // 19552 // We use removeAttr only for key events, to allow IE to export the correct 19553 // accessible attributes. For mouse events, set to empty string to avoid 19554 // native tooltip showing up (happens only when removing inside mouseover). 19555 if ( target.is( "[title]" ) ) { 19556 if ( event && event.type === "mouseover" ) { 19557 target.attr( "title", "" ); 19558 } else { 19559 target.removeAttr( "title" ); 19560 } 19561 } 19562 19563 tooltipData = this._tooltip( target ); 19564 tooltip = tooltipData.tooltip; 19565 this._addDescribedBy( target, tooltip.attr( "id" ) ); 19566 tooltip.find( ".ui-tooltip-content" ).html( content ); 19567 19568 // Support: Voiceover on OS X, JAWS on IE <= 9 19569 // JAWS announces deletions even when aria-relevant="additions" 19570 // Voiceover will sometimes re-read the entire log region's contents from the beginning 19571 this.liveRegion.children().hide(); 19572 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 19573 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 19574 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 19575 a11yContent.appendTo( this.liveRegion ); 19576 19577 function position( event ) { 19578 positionOption.of = event; 19579 if ( tooltip.is( ":hidden" ) ) { 19580 return; 19581 } 19582 tooltip.position( positionOption ); 19583 } 19584 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 19585 this._on( this.document, { 19586 mousemove: position 19587 } ); 19588 19589 // trigger once to override element-relative positioning 19590 position( event ); 19591 } else { 19592 tooltip.position( $.extend( { 19593 of: target 19594 }, this.options.position ) ); 19595 } 19596 19597 tooltip.hide(); 19598 19599 this._show( tooltip, this.options.show ); 19600 19601 // Handle tracking tooltips that are shown with a delay (#8644). As soon 19602 // as the tooltip is visible, position the tooltip using the most recent 19603 // event. 19604 // Adds the check to add the timers only when both delay and track options are set (#14682) 19605 if ( this.options.track && this.options.show && this.options.show.delay ) { 19606 delayedShow = this.delayedShow = setInterval( function() { 19607 if ( tooltip.is( ":visible" ) ) { 19608 position( positionOption.of ); 19609 clearInterval( delayedShow ); 19610 } 19611 }, 13 ); 19612 } 19613 19614 this._trigger( "open", event, { tooltip: tooltip } ); 19615 }, 19616 19617 _registerCloseHandlers: function( event, target ) { 19618 var events = { 19619 keyup: function( event ) { 19620 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 19621 var fakeEvent = $.Event( event ); 19622 fakeEvent.currentTarget = target[ 0 ]; 19623 this.close( fakeEvent, true ); 19624 } 19625 } 19626 }; 19627 19628 // Only bind remove handler for delegated targets. Non-delegated 19629 // tooltips will handle this in destroy. 19630 if ( target[ 0 ] !== this.element[ 0 ] ) { 19631 events.remove = function() { 19632 var targetElement = this._find( target ); 19633 if ( targetElement ) { 19634 this._removeTooltip( targetElement.tooltip ); 19635 } 19636 }; 19637 } 19638 19639 if ( !event || event.type === "mouseover" ) { 19640 events.mouseleave = "close"; 19641 } 19642 if ( !event || event.type === "focusin" ) { 19643 events.focusout = "close"; 19644 } 19645 this._on( true, target, events ); 19646 }, 19647 19648 close: function( event ) { 19649 var tooltip, 19650 that = this, 19651 target = $( event ? event.currentTarget : this.element ), 19652 tooltipData = this._find( target ); 19653 19654 // The tooltip may already be closed 19655 if ( !tooltipData ) { 19656 19657 // We set ui-tooltip-open immediately upon open (in open()), but only set the 19658 // additional data once there's actually content to show (in _open()). So even if the 19659 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 19660 // the period between open() and _open(). 19661 target.removeData( "ui-tooltip-open" ); 19662 return; 19663 } 19664 19665 tooltip = tooltipData.tooltip; 19666 19667 // Disabling closes the tooltip, so we need to track when we're closing 19668 // to avoid an infinite loop in case the tooltip becomes disabled on close 19669 if ( tooltipData.closing ) { 19670 return; 19671 } 19672 19673 // Clear the interval for delayed tracking tooltips 19674 clearInterval( this.delayedShow ); 19675 19676 // Only set title if we had one before (see comment in _open()) 19677 // If the title attribute has changed since open(), don't restore 19678 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 19679 target.attr( "title", target.data( "ui-tooltip-title" ) ); 19680 } 19681 19682 this._removeDescribedBy( target ); 19683 19684 tooltipData.hiding = true; 19685 tooltip.stop( true ); 19686 this._hide( tooltip, this.options.hide, function() { 19687 that._removeTooltip( $( this ) ); 19688 } ); 19689 19690 target.removeData( "ui-tooltip-open" ); 19691 this._off( target, "mouseleave focusout keyup" ); 19692 19693 // Remove 'remove' binding only on delegated targets 19694 if ( target[ 0 ] !== this.element[ 0 ] ) { 19695 this._off( target, "remove" ); 19696 } 19697 this._off( this.document, "mousemove" ); 19698 19699 if ( event && event.type === "mouseleave" ) { 19700 $.each( this.parents, function( id, parent ) { 19701 $( parent.element ).attr( "title", parent.title ); 19702 delete that.parents[ id ]; 19703 } ); 19704 } 19705 19706 tooltipData.closing = true; 19707 this._trigger( "close", event, { tooltip: tooltip } ); 19708 if ( !tooltipData.hiding ) { 19709 tooltipData.closing = false; 19710 } 19711 }, 19712 19713 _tooltip: function( element ) { 19714 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 19715 content = $( "<div>" ).appendTo( tooltip ), 19716 id = tooltip.uniqueId().attr( "id" ); 19717 19718 this._addClass( content, "ui-tooltip-content" ); 19719 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 19720 19721 tooltip.appendTo( this._appendTo( element ) ); 19722 19723 return this.tooltips[ id ] = { 19724 element: element, 19725 tooltip: tooltip 19726 }; 19727 }, 19728 19729 _find: function( target ) { 19730 var id = target.data( "ui-tooltip-id" ); 19731 return id ? this.tooltips[ id ] : null; 19732 }, 19733 19734 _removeTooltip: function( tooltip ) { 19735 19736 // Clear the interval for delayed tracking tooltips 19737 clearInterval( this.delayedShow ); 19738 19739 tooltip.remove(); 19740 delete this.tooltips[ tooltip.attr( "id" ) ]; 19741 }, 19742 19743 _appendTo: function( target ) { 19744 var element = target.closest( ".ui-front, dialog" ); 19745 19746 if ( !element.length ) { 19747 element = this.document[ 0 ].body; 19748 } 19749 19750 return element; 19751 }, 19752 19753 _destroy: function() { 19754 var that = this; 19755 19756 // Close open tooltips 19757 $.each( this.tooltips, function( id, tooltipData ) { 19758 19759 // Delegate to close method to handle common cleanup 19760 var event = $.Event( "blur" ), 19761 element = tooltipData.element; 19762 event.target = event.currentTarget = element[ 0 ]; 19763 that.close( event, true ); 19764 19765 // Remove immediately; destroying an open tooltip doesn't use the 19766 // hide animation 19767 $( "#" + id ).remove(); 19768 19769 // Restore the title 19770 if ( element.data( "ui-tooltip-title" ) ) { 19771 19772 // If the title attribute has changed since open(), don't restore 19773 if ( !element.attr( "title" ) ) { 19774 element.attr( "title", element.data( "ui-tooltip-title" ) ); 19775 } 19776 element.removeData( "ui-tooltip-title" ); 19777 } 19778 } ); 19779 this.liveRegion.remove(); 19780 } 19781} ); 19782 19783// DEPRECATED 19784// TODO: Switch return back to widget declaration at top of file when this is removed 19785if ( $.uiBackCompat === true ) { 19786 19787 // Backcompat for tooltipClass option 19788 $.widget( "ui.tooltip", $.ui.tooltip, { 19789 options: { 19790 tooltipClass: null 19791 }, 19792 _tooltip: function() { 19793 var tooltipData = this._superApply( arguments ); 19794 if ( this.options.tooltipClass ) { 19795 tooltipData.tooltip.addClass( this.options.tooltipClass ); 19796 } 19797 return tooltipData; 19798 } 19799 } ); 19800} 19801
19802return $.ui.tooltip; 19803 19804} );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.