1Drupal.locale = { 'strings': {"":{"Next":"Next","Jan":"Jan","Feb":"Feb","April":"April","May":"May","June":"June","July":"July","September":"September","October":"October","November":"November","Nov":"Nov","February":"February","March":"March","Mar":"Mar","Apr":"Apr","Jun":"Jun","Jul":"Jul","Aug":"Aug","Sep":"Sep","Oct":"Oct","Dec":"Dec","Su":"Su","Mo":"Mo","Tu":"Tu","We":"We","Th":"Th","Fr":"Fr","Sa":"Sa"}} };; 2/*! http://tinynav.viljamis.com v1.2 by @viljamis */ 3(function ($, window, i) { 4 $.fn.tinyNav = function (options) { 5 6 // Default settings 7 var settings = $.extend({ 8 'active' : 'selected', // String: Set the "active" class 9 'header' : '', // String: Specify text for "header" and show header instead of the active item 10 'indent' : '- ', // String: Specify text for indenting sub-items 11 'label' : '' // String: sets the <label> text for the <select> (if not set, no label will be added) 12 }, options); 13 14 return this.each(function () { 15 16 // Used for namespacing 17 i++; 18 19 var $nav = $(this), 20 // Namespacing 21 namespace = 'tinynav', 22 namespace_i = namespace + i, 23 l_namespace_i = '.l_' + namespace_i, 24 $select = $('<select/>').attr("id", namespace_i).addClass(namespace + ' ' + namespace_i); 25 26 if ($nav.is('ul,ol')) { 27 28 if (settings.header !== '') { 29 $select.append( 30 $('<option/>').text(settings.header) 31 ); 32 } 33 34 // Build options 35 var options = ''; 36 37 $nav 38 .addClass('l_' + namespace_i) 39 .find('a') 40 .each(function () { 41 options += '<option class="opt" value="' + $(this).attr('href') + '">'; 42 var j; 43 for (j = 0; j < $(this).parents('ul, ol').length - 1; j++) { 44 options += settings.indent; 45 } 46 options += $(this).text() + '</option>'; 47 }); 48 49 var dis = false; 50 51 $nav 52 .addClass('l_' + namespace_i) 53 .find('span') 54 .each(function () { 55 options += '<option selected="selected" disabled="disabled" value=" ">'; 56 var j; 57 dis=true; 58 for (j = 0; j < $(this).parents('ul, ol').length - 1; j++) { 59 options += settings.indent; 60 } 61 options += $(this).text() + '</option>'; 62 }); 63 64 // Append options into a select 65 $select.append(options); 66 67 /*if(dis){ 68 69 $select.attr("disabled","disabled"); 70 71 } 72 */ 73 74 if($select.find(".opt").length == 0){ 75 $select.attr("disabled","disabled"); 76 } 77 78 // Select the active item 79 if (!settings.header) { 80 $select 81 .find(':eq(' + $(l_namespace_i + ' li') 82 .index($(l_namespace_i + ' li.' + settings.active)) + ')') 83 .attr('selected', true); 84 } 85 86 // Change window location 87 $select.change(function () { 88 window.location.href = $(this).val(); 89 }); 90 91 92 93 // Inject select 94 $(l_namespace_i).after($select); 95 96 // Inject label 97 if (settings.label) { 98 $select.before( 99 $("<label/>") 100 .attr("for", namespace_i) 101 .addClass(namespace + '_label ' + namespace_i + '_label') 102 .append(settings.label) 103 ); 104 } 105 106 } 107 108 }); 109 110 }; 111})(jQuery, this, 0); 112 113 114; 115/** 116 * jquery.scrollFollow.js 117 * Copyright (c) 2008 Net Perspective (http://kitchen.net-perspective.com/) 118 * Licensed under the MIT License (http://www.opensource.org/licenses/mit-license.php) 119 * 120 * @author R.A. Ray 121 * 122 * @projectDescription jQuery plugin for allowing an element to animate down as the user scrolls the page. 123 * 124 * @version 0.4.0 125 * 126 * @requires jquery.js (tested with 1.2.6) 127 * @requires ui.core.js (tested with 1.7) 128 * 129 * @optional jquery.cookie.js (http://www.stilbuero.de/2006/09/17/cookie-plugin-for-jquery/) 130 * @optional jquery.easing.js (http://gsgd.co.uk/sandbox/jquery/easing/ - tested with 1.3) 131 * 132 * @param speed int - Duration of animation (in milliseconds) 133 * default: 500 134 * @param offset int - Number of pixels box should remain from top of viewport 135 * default: 0 136 * @param easing string - Any one of the easing options from the easing plugin - Requires jQuery Easing Plugin < http://gsgd.co.uk/sandbox/jquery/easing/ > 137 * default: 'linear' 138 * @param container string - ID of the containing div 139 * default: box's immediate parent 140 * @param killSwitch string - ID of the On/Off toggle element 141 * default: 'killSwitch' 142 * @param onText string - killSwitch text to be displayed if sliding is enabled 143 * default: 'Turn Slide Off' 144 * @param offText string - killSwitch text to be displayed if sliding is disabled 145 * default: 'Turn Slide On' 146 * @param relativeTo string - Scroll animation can be relative to either the 'top' or 'bottom' of the viewport 147 * default: 'top' 148 * @param delay int - Time between the end of the scroll and the beginning of the animation in milliseconds 149 * default: 0 150 */ 151 152( function( $ ) { 153 154 $.scrollFollow = function ( box, options ) 155 { 156 // Convert box into a jQuery object 157 box = $( box ); 158 159 // 'box' is the object to be animated 160 var position = box.css( 'position' ); 161 162 function ani() 163 { 164 // The script runs on every scroll which really means many times during a scroll. 165 // We don't want multiple slides to queue up. 166 box.queue( [ ] ); 167 168 // A bunch of values we need to determine where to animate to
169 var viewportHeight = parseInt( $( window ).height() ); 170 var pageScroll = parseInt( $( document ).scrollTop() ); 171 var parentTop = parseInt( box.cont.offset().top ); 172 var parentHeight = parseInt( box.cont.prop( 'offsetHeight' ) ); 173 var boxHeight = parseInt( box.prop( 'offsetHeight' ) + ( parseInt( box.css( 'marginTop' ) ) || 0 ) + ( parseInt( box.css( 'marginBottom' ) ) || 0 ) ); 174 var aniTop; 175 176 // Make sure the user wants the animation to happen 177 if ( isActive ) 178 { 179 // If the box should animate relative to the top of the window 180 if ( options.relativeTo == 'top' ) 181 { 182 // Don't animate until the top of the window is close enough to the top of the box 183 if ( box.initialOffsetTop >= ( pageScroll + options.offset ) ) 184 { 185 aniTop = box.initialTop; 186 } 187 else 188 { 189 aniTop = Math.min( ( Math.max( ( -parentTop ), ( pageScroll - box.initialOffsetTop + box.initialTop ) ) + options.offset ), ( parentHeight - boxHeight - box.paddingAdjustment ) ); 190 } 191 } 192 // If the box should animate relative to the bottom of the window 193 else if ( options.relativeTo == 'bottom' ) 194 { 195 // Don't animate until the bottom of the window is close enough to the bottom of the box 196 if ( ( box.initialOffsetTop + boxHeight ) >= ( pageScroll + options.offset + viewportHeight ) ) 197 { 198 aniTop = box.initialTop; 199 } 200 else 201 { 202 aniTop = Math.min( ( pageScroll + viewportHeight - boxHeight - options.offset ), ( parentHeight - boxHeight ) ); 203 } 204 } 205 206 // Checks to see if the relevant scroll was the last one 207 // "-20" is to account for inaccuracy in the timeout 208 if ( ( new Date().getTime() - box.lastScroll ) >= ( options.delay - 20 ) ) 209 { 210 box.animate( 211 { 212 top: aniTop 213 }, options.speed, options.easing 214 ); 215 } 216 } 217 }; 218 219 // For user-initiated stopping of the slide 220 var isActive = true; 221 222 if ( $.cookie != undefined ) 223 { 224 if( $.cookie( 'scrollFollowSetting' + box.prop( 'id' ) ) == 'false' ) 225 { 226 var isActive = false; 227 228 $( '#' + options.killSwitch ).text( options.offText ) 229 .toggle( 230 function () 231 { 232 isActive = true; 233 234 $( this ).text( options.onText ); 235 236 $.cookie( 'scrollFollowSetting' + box.prop( 'id' ), true, { expires: 365, path: '/'} ); 237 238 ani(); 239 }, 240 function () 241 { 242 isActive = false; 243 244 $( this ).text( options.offText ); 245 246 box.animate( 247 { 248 top: box.initialTop 249 }, options.speed, options.easing 250 ); 251 252 $.cookie( 'scrollFollowSetting' + box.prop( 'id' ), false, { expires: 365, path: '/'} ); 253 } 254 ); 255 } 256 else 257 { 258 $( '#' + options.killSwitch ).text( options.onText ) 259 .toggle( 260 function () 261 { 262 isActive = false; 263 264 $( this ).text( options.offText ); 265 266 box.animate( 267 { 268 top: box.initialTop 269 }, 0 270 ); 271 272 $.cookie( 'scrollFollowSetting' + box.prop( 'id' ), false, { expires: 365, path: '/'} ); 273 }, 274 function () 275 { 276 isActive = true; 277 278 $( this ).text( options.onText ); 279 280 $.cookie( 'scrollFollowSetting' + box.prop( 'id' ), true, { expires: 365, path: '/'} ); 281 282 ani(); 283 } 284 ); 285 } 286 } 287 288 // If no parent ID was specified, and the immediate parent does not have an ID 289 // options.container will be undefined. So we need to figure out the parent element. 290 if ( options.container == '') 291 { 292 box.cont = box.parent(); 293 } 294 else 295 { 296 box.cont = $( '#' + options.container ); 297 } 298 299 // Finds the default positioning of the box. 300 box.initialOffsetTop = parseInt( box.offset().top ); 301 box.initialTop = parseInt( box.css( 'top' ) ) || 0; 302 303 // Hack to fix different treatment of boxes positioned 'absolute' and 'relative' 304 if ( box.css( 'position' ) == 'relative' ) 305 { 306 box.paddingAdjustment = parseInt( box.cont.css( 'paddingTop' ) ) + parseInt( box.cont.css( 'paddingBottom' ) ); 307 } 308 else 309 { 310 box.paddingAdjustment = 0; 311 } 312 313 // Animate the box when the page is scrolled 314 $( window ).scroll( function () 315 { 316 // Sets up the delay of the animation 317 $.fn.scrollFollow.interval = setTimeout( function(){ ani();} , options.delay ); 318 319 // To check against right before setting the animation 320 box.lastScroll = new Date().getTime(); 321 } 322 ); 323 324 // Animate the box when the page is resized 325 $( window ).resize( function () 326 { 327 // Sets up the delay of the animation 328 $.fn.scrollFollow.interval = setTimeout( function(){ ani();} , options.delay ); 329 330 // To check against right before setting the animation 331 box.lastScroll = new Date().getTime(); 332 } 333 ); 334 335 // Run an initial animation on page load 336 box.lastScroll = 0; 337 338 ani(); 339 }; 340 341 $.fn.scrollFollow = function ( options ) 342 { 343 options = options || {}; 344 options.relativeTo = options.relativeTo || 'top'; 345 options.speed = options.speed || 500; 346 options.offset = options.offset || 0; 347 options.easing = options.easing || 'swing'; 348 options.container = options.container || this.parent().prop( 'id' ); 349 options.killSwitch = options.killSwitch || 'killSwitch'; 350 options.onText = options.onText || 'Turn Slide Off'; 351 options.offText = options.offText || 'Turn Slide On'; 352 options.delay = options.delay || 0; 353 354 this.each( function() 355 { 356 new $.scrollFollow( this, options ); 357 } 358 ); 359 360 return this; 361 }; 362})( jQuery ); 363 364 365 366// JavaScript Document;
vendor: 106,687 bytes, lines 367-4172
367/*! jQuery UI - v1.11.1 - 2014-08-13 368* http://jqueryui.com 369* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.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, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js 370* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ 371 372(function( factory ) { 373 if ( typeof define === "function" && define.amd ) { 374 375 // AMD. Register as an anonymous module. 376 define([ "jquery" ], factory ); 377 } else { 378 379 // Browser globals 380 factory( jQuery ); 381 } 382}(function( $ ) { 383/*! 384 * jQuery UI Core 1.11.1 385 * http://jqueryui.com 386 * 387 * Copyright 2014 jQuery Foundation and other contributors 388 * Released under the MIT license. 389 * http://jquery.org/license 390 * 391 * http://api.jqueryui.com/category/ui-core/ 392 */ 393 394 395// $.ui might exist from components with no dependencies, e.g., $.ui.position 396$.ui = $.ui || {}; 397 398$.extend( $.ui, { 399 version: "1.11.1", 400 401 keyCode: { 402 BACKSPACE: 8, 403 COMMA: 188, 404 DELETE: 46, 405 DOWN: 40, 406 END: 35, 407 ENTER: 13, 408 ESCAPE: 27, 409 HOME: 36, 410 LEFT: 37, 411 PAGE_DOWN: 34, 412 PAGE_UP: 33, 413 PERIOD: 190, 414 RIGHT: 39, 415 SPACE: 32, 416 TAB: 9, 417 UP: 38 418 } 419}); 420 421// plugins 422$.fn.extend({ 423 scrollParent: function( includeHidden ) { 424 var position = this.css( "position" ), 425 excludeStaticParent = position === "absolute", 426 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 427 scrollParent = this.parents().filter( function() { 428 var parent = $( this ); 429 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 430 return false; 431 } 432 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); 433 }).eq( 0 ); 434 435 return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; 436 }, 437 438 uniqueId: (function() { 439 var uuid = 0; 440 441 return function() { 442 return this.each(function() { 443 if ( !this.id ) { 444 this.id = "ui-id-" + ( ++uuid ); 445 } 446 }); 447 }; 448 })(), 449 450 removeUniqueId: function() { 451 return this.each(function() { 452 if ( /^ui-id-\d+$/.test( this.id ) ) { 453 $( this ).removeAttr( "id" ); 454 } 455 }); 456 } 457}); 458 459// selectors 460function focusable( element, isTabIndexNotNaN ) { 461 var map, mapName, img, 462 nodeName = element.nodeName.toLowerCase(); 463 if ( "area" === nodeName ) { 464 map = element.parentNode; 465 mapName = map.name; 466 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 467 return false; 468 } 469 img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; 470 return !!img && visible( img ); 471 } 472 return ( /input|select|textarea|button|object/.test( nodeName ) ? 473 !element.disabled : 474 "a" === nodeName ? 475 element.href || isTabIndexNotNaN : 476 isTabIndexNotNaN) && 477 // the element and all of its ancestors must be visible 478 visible( element ); 479} 480 481function visible( element ) { 482 return $.expr.filters.visible( element ) && 483 !$( element ).parents().addBack().filter(function() { 484 return $.css( this, "visibility" ) === "hidden"; 485 }).length; 486} 487 488$.extend( $.expr[ ":" ], { 489 data: $.expr.createPseudo ? 490 $.expr.createPseudo(function( dataName ) { 491 return function( elem ) { 492 return !!$.data( elem, dataName ); 493 }; 494 }) : 495 // support: jQuery <1.8 496 function( elem, i, match ) { 497 return !!$.data( elem, match[ 3 ] ); 498 }, 499 500 focusable: function( element ) { 501 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 502 }, 503 504 tabbable: function( element ) { 505 var tabIndex = $.attr( element, "tabindex" ), 506 isTabIndexNaN = isNaN( tabIndex ); 507 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 508 } 509}); 510 511// support: jQuery <1.8 512if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 513 $.each( [ "Width", "Height" ], function( i, name ) { 514 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 515 type = name.toLowerCase(), 516 orig = { 517 innerWidth: $.fn.innerWidth, 518 innerHeight: $.fn.innerHeight, 519 outerWidth: $.fn.outerWidth, 520 outerHeight: $.fn.outerHeight 521 }; 522 523 function reduce( elem, size, border, margin ) { 524 $.each( side, function() { 525 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 526 if ( border ) { 527 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 528 } 529 if ( margin ) { 530 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 531 } 532 }); 533 return size; 534 } 535 536 $.fn[ "inner" + name ] = function( size ) { 537 if ( size === undefined ) { 538 return orig[ "inner" + name ].call( this ); 539 } 540 541 return this.each(function() { 542 $( this ).css( type, reduce( this, size ) + "px" ); 543 }); 544 }; 545 546 $.fn[ "outer" + name] = function( size, margin ) { 547 if ( typeof size !== "number" ) { 548 return orig[ "outer" + name ].call( this, size ); 549 } 550 551 return this.each(function() { 552 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 553 }); 554 }; 555 }); 556} 557 558// support: jQuery <1.8 559if ( !$.fn.addBack ) { 560 $.fn.addBack = function( selector ) { 561 return this.add( selector == null ? 562 this.prevObject : this.prevObject.filter( selector ) 563 ); 564 }; 565} 566 567// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 568if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 569 $.fn.removeData = (function( removeData ) { 570 return function( key ) { 571 if ( arguments.length ) { 572 return removeData.call( this, $.camelCase( key ) ); 573 } else { 574 return removeData.call( this ); 575 } 576 }; 577 })( $.fn.removeData ); 578} 579 580// deprecated 581$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 582 583$.fn.extend({ 584 focus: (function( orig ) { 585 return function( delay, fn ) { 586 return typeof delay === "number" ? 587 this.each(function() { 588 var elem = this; 589 setTimeout(function() { 590 $( elem ).focus(); 591 if ( fn ) { 592 fn.call( elem ); 593 } 594 }, delay ); 595 }) : 596 orig.apply( this, arguments ); 597 }; 598 })( $.fn.focus ), 599 600 disableSelection: (function() { 601 var eventType = "onselectstart" in document.createElement( "div" ) ? 602 "selectstart" : 603 "mousedown"; 604 605 return function() { 606 return this.bind( eventType + ".ui-disableSelection", function( event ) { 607 event.preventDefault(); 608 }); 609 }; 610 })(), 611 612 enableSelection: function() { 613 return this.unbind( ".ui-disableSelection" ); 614 }, 615 616 zIndex: function( zIndex ) { 617 if ( zIndex !== undefined ) { 618 return this.css( "zIndex", zIndex ); 619 } 620 621 if ( this.length ) { 622 var elem = $( this[ 0 ] ), position, value; 623 while ( elem.length && elem[ 0 ] !== document ) { 624 // Ignore z-index if position is set to a value where z-index is ignored by the browser 625 // This makes behavior of this function consistent across browsers 626 // WebKit always returns auto if the element is positioned 627 position = elem.css( "position" ); 628 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 629 // IE returns 0 when zIndex is not specified 630 // other browsers return a string 631 // we ignore the case of nested elements with an explicit value of 0 632 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 633 value = parseInt( elem.css( "zIndex" ), 10 ); 634 if ( !isNaN( value ) && value !== 0 ) { 635 return value; 636 } 637 } 638 elem = elem.parent(); 639 } 640 } 641 642 return 0; 643 } 644}); 645 646// $.ui.plugin is deprecated. Use $.widget() extensions instead. 647$.ui.plugin = { 648 add: function( module, option, set ) { 649 var i, 650 proto = $.ui[ module ].prototype; 651 for ( i in set ) { 652 proto.plugins[ i ] = proto.plugins[ i ] || []; 653 proto.plugins[ i ].push( [ option, set[ i ] ] ); 654 } 655 }, 656 call: function( instance, name, args, allowDisconnected ) { 657 var i, 658 set = instance.plugins[ name ]; 659 660 if ( !set ) { 661 return; 662 } 663 664 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 665 return; 666 } 667 668 for ( i = 0; i < set.length; i++ ) { 669 if ( instance.options[ set[ i ][ 0 ] ] ) { 670 set[ i ][ 1 ].apply( instance.element, args ); 671 } 672 } 673 } 674}; 675 676 677/*! 678 * jQuery UI Widget 1.11.1 679 * http://jqueryui.com 680 * 681 * Copyright 2014 jQuery Foundation and other contributors 682 * Released under the MIT license. 683 * http://jquery.org/license 684 * 685 * http://api.jqueryui.com/jQuery.widget/ 686 */ 687 688 689var widget_uuid = 0, 690 widget_slice = Array.prototype.slice; 691 692$.cleanData = (function( orig ) { 693 return function( elems ) { 694 var events, elem, i; 695 for ( i = 0; (elem = elems[i]) != null; i++ ) { 696 try { 697 698 // Only trigger remove when necessary to save time 699 events = $._data( elem, "events" ); 700 if ( events && events.remove ) { 701 $( elem ).triggerHandler( "remove" ); 702 } 703 704 // http://bugs.jquery.com/ticket/8235 705 } catch( e ) {} 706 } 707 orig( elems ); 708 }; 709})( $.cleanData ); 710 711$.widget = function( name, base, prototype ) { 712 var fullName, existingConstructor, constructor, basePrototype, 713 // proxiedPrototype allows the provided prototype to remain unmodified 714 // so that it can be used as a mixin for multiple widgets (#8876) 715 proxiedPrototype = {}, 716 namespace = name.split( "." )[ 0 ]; 717 718 name = name.split( "." )[ 1 ]; 719 fullName = namespace + "-" + name; 720 721 if ( !prototype ) { 722 prototype = base; 723 base = $.Widget; 724 } 725 726 // create selector for plugin 727 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 728 return !!$.data( elem, fullName ); 729 }; 730 731 $[ namespace ] = $[ namespace ] || {}; 732 existingConstructor = $[ namespace ][ name ]; 733 constructor = $[ namespace ][ name ] = function( options, element ) { 734 // allow instantiation without "new" keyword 735 if ( !this._createWidget ) { 736 return new constructor( options, element ); 737 } 738 739 // allow instantiation without initializing for simple inheritance 740 // must use "new" keyword (the code above always passes args) 741 if ( arguments.length ) { 742 this._createWidget( options, element ); 743 } 744 }; 745 // extend with the existing constructor to carry over any static properties 746 $.extend( constructor, existingConstructor, { 747 version: prototype.version, 748 // copy the object used to create the prototype in case we need to 749 // redefine the widget later 750 _proto: $.extend( {}, prototype ), 751 // track widgets that inherit from this widget in case this widget is 752 // redefined after a widget inherits from it 753 _childConstructors: [] 754 }); 755 756 basePrototype = new base(); 757 // we need to make the options hash a property directly on the new instance 758 // otherwise we'll modify the options hash on the prototype that we're 759 // inheriting from 760 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 761 $.each( prototype, function( prop, value ) { 762 if ( !$.isFunction( value ) ) { 763 proxiedPrototype[ prop ] = value; 764 return; 765 } 766 proxiedPrototype[ prop ] = (function() { 767 var _super = function() { 768 return base.prototype[ prop ].apply( this, arguments ); 769 }, 770 _superApply = function( args ) { 771 return base.prototype[ prop ].apply( this, args ); 772 }; 773 return function() { 774 var __super = this._super, 775 __superApply = this._superApply, 776 returnValue; 777 778 this._super = _super; 779 this._superApply = _superApply; 780 781 returnValue = value.apply( this, arguments ); 782 783 this._super = __super; 784 this._superApply = __superApply; 785 786 return returnValue; 787 }; 788 })(); 789 }); 790 constructor.prototype = $.widget.extend( basePrototype, { 791 // TODO: remove support for widgetEventPrefix 792 // always use the name + a colon as the prefix, e.g., draggable:start 793 // don't prefix for widgets that aren't DOM-based 794 widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name 795 }, proxiedPrototype, { 796 constructor: constructor, 797 namespace: namespace, 798 widgetName: name, 799 widgetFullName: fullName 800 }); 801 802 // If this widget is being redefined then we need to find all widgets that 803 // are inheriting from it and redefine all of them so that they inherit from 804 // the new version of this widget. We're essentially trying to replace one 805 // level in the prototype chain. 806 if ( existingConstructor ) { 807 $.each( existingConstructor._childConstructors, function( i, child ) { 808 var childPrototype = child.prototype; 809 810 // redefine the child widget using the same prototype that was 811 // originally used, but inherit from the new version of the base 812 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 813 }); 814 // remove the list of existing child constructors from the old constructor 815 // so the old child constructors can be garbage collected 816 delete existingConstructor._childConstructors; 817 } else { 818 base._childConstructors.push( constructor ); 819 } 820 821 $.widget.bridge( name, constructor ); 822 823 return constructor; 824}; 825 826$.widget.extend = function( target ) { 827 var input = widget_slice.call( arguments, 1 ), 828 inputIndex = 0, 829 inputLength = input.length, 830 key, 831 value; 832 for ( ; inputIndex < inputLength; inputIndex++ ) { 833 for ( key in input[ inputIndex ] ) { 834 value = input[ inputIndex ][ key ]; 835 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 836 // Clone objects 837 if ( $.isPlainObject( value ) ) { 838 target[ key ] = $.isPlainObject( target[ key ] ) ? 839 $.widget.extend( {}, target[ key ], value ) : 840 // Don't extend strings, arrays, etc. with objects 841 $.widget.extend( {}, value ); 842 // Copy everything else by reference 843 } else { 844 target[ key ] = value; 845 } 846 } 847 } 848 } 849 return target; 850}; 851 852$.widget.bridge = function( name, object ) { 853 var fullName = object.prototype.widgetFullName || name; 854 $.fn[ name ] = function( options ) { 855 var isMethodCall = typeof options === "string", 856 args = widget_slice.call( arguments, 1 ), 857 returnValue = this; 858 859 // allow multiple hashes to be passed on init 860 options = !isMethodCall && args.length ? 861 $.widget.extend.apply( null, [ options ].concat(args) ) : 862 options; 863 864 if ( isMethodCall ) { 865 this.each(function() { 866 var methodValue, 867 instance = $.data( this, fullName ); 868 if ( options === "instance" ) { 869 returnValue = instance; 870 return false; 871 } 872 if ( !instance ) { 873 return $.error( "cannot call methods on " + name + " prior to initialization; " + 874 "attempted to call method '" + options + "'" ); 875 } 876 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 877 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 878 } 879 methodValue = instance[ options ].apply( instance, args ); 880 if ( methodValue !== instance && methodValue !== undefined ) { 881 returnValue = methodValue && methodValue.jquery ? 882 returnValue.pushStack( methodValue.get() ) : 883 methodValue; 884 return false; 885 } 886 }); 887 } else { 888 this.each(function() { 889 var instance = $.data( this, fullName ); 890 if ( instance ) { 891 instance.option( options || {} ); 892 if ( instance._init ) { 893 instance._init(); 894 } 895 } else { 896 $.data( this, fullName, new object( options, this ) ); 897 } 898 }); 899 } 900 901 return returnValue; 902 }; 903}; 904 905$.Widget = function( /* options, element */ ) {}; 906$.Widget._childConstructors = []; 907 908$.Widget.prototype = { 909 widgetName: "widget", 910 widgetEventPrefix: "", 911 defaultElement: "<div>", 912 options: { 913 disabled: false, 914 915 // callbacks 916 create: null 917 }, 918 _createWidget: function( options, element ) { 919 element = $( element || this.defaultElement || this )[ 0 ]; 920 this.element = $( element ); 921 this.uuid = widget_uuid++; 922 this.eventNamespace = "." + this.widgetName + this.uuid; 923 this.options = $.widget.extend( {}, 924 this.options, 925 this._getCreateOptions(), 926 options ); 927 928 this.bindings = $(); 929 this.hoverable = $(); 930 this.focusable = $(); 931 932 if ( element !== this ) { 933 $.data( element, this.widgetFullName, this ); 934 this._on( true, this.element, { 935 remove: function( event ) { 936 if ( event.target === element ) { 937 this.destroy(); 938 } 939 } 940 }); 941 this.document = $( element.style ? 942 // element within the document 943 element.ownerDocument : 944 // element is window or document 945 element.document || element ); 946 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 947 } 948 949 this._create(); 950 this._trigger( "create", null, this._getCreateEventData() ); 951 this._init(); 952 }, 953 _getCreateOptions: $.noop, 954 _getCreateEventData: $.noop, 955 _create: $.noop, 956 _init: $.noop, 957 958 destroy: function() { 959 this._destroy(); 960 // we can probably remove the unbind calls in 2.0 961 // all event bindings should go through this._on() 962 this.element 963 .unbind( this.eventNamespace ) 964 .removeData( this.widgetFullName ) 965 // support: jquery <1.6.3 966 // http://bugs.jquery.com/ticket/9413 967 .removeData( $.camelCase( this.widgetFullName ) ); 968 this.widget() 969 .unbind( this.eventNamespace ) 970 .removeAttr( "aria-disabled" ) 971 .removeClass( 972 this.widgetFullName + "-disabled " + 973 "ui-state-disabled" ); 974 975 // clean up events and states 976 this.bindings.unbind( this.eventNamespace ); 977 this.hoverable.removeClass( "ui-state-hover" ); 978 this.focusable.removeClass( "ui-state-focus" ); 979 }, 980 _destroy: $.noop, 981 982 widget: function() { 983 return this.element; 984 }, 985 986 option: function( key, value ) { 987 var options = key, 988 parts, 989 curOption, 990 i; 991 992 if ( arguments.length === 0 ) { 993 // don't return a reference to the internal hash 994 return $.widget.extend( {}, this.options ); 995 } 996 997 if ( typeof key === "string" ) { 998 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 999 options = {}; 1000 parts = key.split( "." ); 1001 key = parts.shift(); 1002 if ( parts.length ) { 1003 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 1004 for ( i = 0; i < parts.length - 1; i++ ) { 1005 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 1006 curOption = curOption[ parts[ i ] ]; 1007 } 1008 key = parts.pop(); 1009 if ( arguments.length === 1 ) { 1010 return curOption[ key ] === undefined ? null : curOption[ key ]; 1011 } 1012 curOption[ key ] = value; 1013 } else { 1014 if ( arguments.length === 1 ) { 1015 return this.options[ key ] === undefined ? null : this.options[ key ]; 1016 } 1017 options[ key ] = value; 1018 } 1019 } 1020 1021 this._setOptions( options ); 1022 1023 return this; 1024 }, 1025 _setOptions: function( options ) { 1026 var key; 1027 1028 for ( key in options ) { 1029 this._setOption( key, options[ key ] ); 1030 } 1031 1032 return this; 1033 }, 1034 _setOption: function( key, value ) { 1035 this.options[ key ] = value; 1036 1037 if ( key === "disabled" ) { 1038 this.widget() 1039 .toggleClass( this.widgetFullName + "-disabled", !!value ); 1040 1041 // If the widget is becoming disabled, then nothing is interactive 1042 if ( value ) { 1043 this.hoverable.removeClass( "ui-state-hover" ); 1044 this.focusable.removeClass( "ui-state-focus" ); 1045 } 1046 } 1047 1048 return this; 1049 }, 1050 1051 enable: function() { 1052 return this._setOptions({ disabled: false }); 1053 }, 1054 disable: function() { 1055 return this._setOptions({ disabled: true }); 1056 }, 1057 1058 _on: function( suppressDisabledCheck, element, handlers ) { 1059 var delegateElement, 1060 instance = this; 1061 1062 // no suppressDisabledCheck flag, shuffle arguments 1063 if ( typeof suppressDisabledCheck !== "boolean" ) { 1064 handlers = element; 1065 element = suppressDisabledCheck; 1066 suppressDisabledCheck = false; 1067 } 1068 1069 // no element argument, shuffle and use this.element 1070 if ( !handlers ) { 1071 handlers = element; 1072 element = this.element; 1073 delegateElement = this.widget(); 1074 } else { 1075 element = delegateElement = $( element ); 1076 this.bindings = this.bindings.add( element ); 1077 } 1078 1079 $.each( handlers, function( event, handler ) { 1080 function handlerProxy() { 1081 // allow widgets to customize the disabled handling 1082 // - disabled as an array instead of boolean 1083 // - disabled class as method for disabling individual parts 1084 if ( !suppressDisabledCheck && 1085 ( instance.options.disabled === true || 1086 $( this ).hasClass( "ui-state-disabled" ) ) ) { 1087 return; 1088 } 1089 return ( typeof handler === "string" ? instance[ handler ] : handler ) 1090 .apply( instance, arguments ); 1091 } 1092 1093 // copy the guid so direct unbinding works 1094 if ( typeof handler !== "string" ) { 1095 handlerProxy.guid = handler.guid = 1096 handler.guid || handlerProxy.guid || $.guid++; 1097 } 1098 1099 var match = event.match( /^([\w:-]*)\s*(.*)$/ ), 1100 eventName = match[1] + instance.eventNamespace, 1101 selector = match[2]; 1102 if ( selector ) { 1103 delegateElement.delegate( selector, eventName, handlerProxy ); 1104 } else { 1105 element.bind( eventName, handlerProxy ); 1106 } 1107 }); 1108 }, 1109 1110 _off: function( element, eventName ) { 1111 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 1112 element.unbind( eventName ).undelegate( eventName ); 1113 }, 1114 1115 _delay: function( handler, delay ) { 1116 function handlerProxy() { 1117 return ( typeof handler === "string" ? instance[ handler ] : handler ) 1118 .apply( instance, arguments ); 1119 } 1120 var instance = this; 1121 return setTimeout( handlerProxy, delay || 0 ); 1122 }, 1123 1124 _hoverable: function( element ) { 1125 this.hoverable = this.hoverable.add( element ); 1126 this._on( element, { 1127 mouseenter: function( event ) { 1128 $( event.currentTarget ).addClass( "ui-state-hover" ); 1129 }, 1130 mouseleave: function( event ) { 1131 $( event.currentTarget ).removeClass( "ui-state-hover" ); 1132 } 1133 }); 1134 }, 1135 1136 _focusable: function( element ) { 1137 this.focusable = this.focusable.add( element ); 1138 this._on( element, { 1139 focusin: function( event ) { 1140 $( event.currentTarget ).addClass( "ui-state-focus" ); 1141 }, 1142 focusout: function( event ) { 1143 $( event.currentTarget ).removeClass( "ui-state-focus" ); 1144 } 1145 }); 1146 }, 1147 1148 _trigger: function( type, event, data ) { 1149 var prop, orig, 1150 callback = this.options[ type ]; 1151 1152 data = data || {}; 1153 event = $.Event( event ); 1154 event.type = ( type === this.widgetEventPrefix ? 1155 type : 1156 this.widgetEventPrefix + type ).toLowerCase(); 1157 // the original event may come from any element 1158 // so we need to reset the target on the new event 1159 event.target = this.element[ 0 ]; 1160 1161 // copy original event properties over to the new event 1162 orig = event.originalEvent; 1163 if ( orig ) { 1164 for ( prop in orig ) { 1165 if ( !( prop in event ) ) { 1166 event[ prop ] = orig[ prop ]; 1167 } 1168 } 1169 } 1170 1171 this.element.trigger( event, data ); 1172 return !( $.isFunction( callback ) && 1173 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 1174 event.isDefaultPrevented() ); 1175 } 1176}; 1177 1178$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 1179 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 1180 if ( typeof options === "string" ) { 1181 options = { effect: options }; 1182 } 1183 var hasOptions, 1184 effectName = !options ? 1185 method : 1186 options === true || typeof options === "number" ? 1187 defaultEffect : 1188 options.effect || defaultEffect; 1189 options = options || {}; 1190 if ( typeof options === "number" ) { 1191 options = { duration: options }; 1192 } 1193 hasOptions = !$.isEmptyObject( options ); 1194 options.complete = callback; 1195 if ( options.delay ) { 1196 element.delay( options.delay ); 1197 } 1198 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 1199 element[ method ]( options ); 1200 } else if ( effectName !== method && element[ effectName ] ) { 1201 element[ effectName ]( options.duration, options.easing, callback ); 1202 } else { 1203 element.queue(function( next ) { 1204 $( this )[ method ](); 1205 if ( callback ) { 1206 callback.call( element[ 0 ] ); 1207 } 1208 next(); 1209 }); 1210 } 1211 }; 1212}); 1213 1214var widget = $.widget; 1215 1216 1217/*! 1218 * jQuery UI Mouse 1.11.1 1219 * http://jqueryui.com 1220 * 1221 * Copyright 2014 jQuery Foundation and other contributors 1222 * Released under the MIT license. 1223 * http://jquery.org/license 1224 * 1225 * http://api.jqueryui.com/mouse/ 1226 */ 1227 1228 1229var mouseHandled = false; 1230$( document ).mouseup( function() { 1231 mouseHandled = false; 1232}); 1233 1234var mouse = $.widget("ui.mouse", { 1235 version: "1.11.1", 1236 options: { 1237 cancel: "input,textarea,button,select,option", 1238 distance: 1, 1239 delay: 0 1240 }, 1241 _mouseInit: function() { 1242 var that = this; 1243 1244 this.element 1245 .bind("mousedown." + this.widgetName, function(event) { 1246 return that._mouseDown(event); 1247 }) 1248 .bind("click." + this.widgetName, function(event) { 1249 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 1250 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 1251 event.stopImmediatePropagation(); 1252 return false; 1253 } 1254 }); 1255 1256 this.started = false; 1257 }, 1258 1259 // TODO: make sure destroying one instance of mouse doesn't mess with 1260 // other instances of mouse 1261 _mouseDestroy: function() { 1262 this.element.unbind("." + this.widgetName); 1263 if ( this._mouseMoveDelegate ) { 1264 this.document 1265 .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) 1266 .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); 1267 } 1268 }, 1269 1270 _mouseDown: function(event) { 1271 // don't let more than one widget handle mouseStart 1272 if ( mouseHandled ) { 1273 return; 1274 } 1275 1276 // we may have missed mouseup (out of window) 1277 (this._mouseStarted && this._mouseUp(event)); 1278 1279 this._mouseDownEvent = event; 1280 1281 var that = this, 1282 btnIsLeft = (event.which === 1), 1283 // event.target.nodeName works around a bug in IE 8 with 1284 // disabled inputs (#7620) 1285 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 1286 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 1287 return true; 1288 } 1289 1290 this.mouseDelayMet = !this.options.delay; 1291 if (!this.mouseDelayMet) { 1292 this._mouseDelayTimer = setTimeout(function() { 1293 that.mouseDelayMet = true; 1294 }, this.options.delay); 1295 } 1296 1297 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 1298 this._mouseStarted = (this._mouseStart(event) !== false); 1299 if (!this._mouseStarted) { 1300 event.preventDefault(); 1301 return true; 1302 } 1303 } 1304 1305 // Click event may never have fired (Gecko & Opera) 1306 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 1307 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 1308 } 1309 1310 // these delegates are required to keep context 1311 this._mouseMoveDelegate = function(event) { 1312 return that._mouseMove(event); 1313 }; 1314 this._mouseUpDelegate = function(event) { 1315 return that._mouseUp(event); 1316 }; 1317 1318 this.document 1319 .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1320 .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1321 1322 event.preventDefault(); 1323 1324 mouseHandled = true; 1325 return true; 1326 }, 1327 1328 _mouseMove: function(event) { 1329 // IE mouseup check - mouseup happened when mouse was out of window 1330 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 1331 return this._mouseUp(event); 1332 1333 // Iframe mouseup check - mouseup occurred in another document 1334 } else if ( !event.which ) { 1335 return this._mouseUp( event ); 1336 } 1337 1338 if (this._mouseStarted) { 1339 this._mouseDrag(event); 1340 return event.preventDefault(); 1341 } 1342 1343 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 1344 this._mouseStarted = 1345 (this._mouseStart(this._mouseDownEvent, event) !== false); 1346 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 1347 } 1348 1349 return !this._mouseStarted; 1350 }, 1351 1352 _mouseUp: function(event) { 1353 this.document 1354 .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 1355 .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); 1356 1357 if (this._mouseStarted) { 1358 this._mouseStarted = false; 1359 1360 if (event.target === this._mouseDownEvent.target) { 1361 $.data(event.target, this.widgetName + ".preventClickEvent", true); 1362 } 1363 1364 this._mouseStop(event); 1365 } 1366 1367 mouseHandled = false; 1368 return false; 1369 }, 1370 1371 _mouseDistanceMet: function(event) { 1372 return (Math.max( 1373 Math.abs(this._mouseDownEvent.pageX - event.pageX), 1374 Math.abs(this._mouseDownEvent.pageY - event.pageY) 1375 ) >= this.options.distance 1376 ); 1377 }, 1378 1379 _mouseDelayMet: function(/* event */) { 1380 return this.mouseDelayMet; 1381 }, 1382 1383 // These are placeholder methods, to be overriden by extending plugin 1384 _mouseStart: function(/* event */) {}, 1385 _mouseDrag: function(/* event */) {}, 1386 _mouseStop: function(/* event */) {}, 1387 _mouseCapture: function(/* event */) { return true; } 1388}); 1389 1390 1391/*! 1392 * jQuery UI Position 1.11.1 1393 * http://jqueryui.com 1394 * 1395 * Copyright 2014 jQuery Foundation and other contributors 1396 * Released under the MIT license. 1397 * http://jquery.org/license 1398 * 1399 * http://api.jqueryui.com/position/ 1400 */ 1401 1402(function() { 1403 1404$.ui = $.ui || {}; 1405 1406var cachedScrollbarWidth, supportsOffsetFractions, 1407 max = Math.max, 1408 abs = Math.abs, 1409 round = Math.round, 1410 rhorizontal = /left|center|right/, 1411 rvertical = /top|center|bottom/, 1412 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 1413 rposition = /^\w+/, 1414 rpercent = /%$/, 1415 _position = $.fn.position; 1416 1417function getOffsets( offsets, width, height ) { 1418 return [ 1419 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 1420 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 1421 ]; 1422} 1423 1424function parseCss( element, property ) { 1425 return parseInt( $.css( element, property ), 10 ) || 0; 1426} 1427 1428function getDimensions( elem ) { 1429 var raw = elem[0]; 1430 if ( raw.nodeType === 9 ) { 1431 return { 1432 width: elem.width(), 1433 height: elem.height(), 1434 offset: { top: 0, left: 0 } 1435 }; 1436 } 1437 if ( $.isWindow( raw ) ) { 1438 return { 1439 width: elem.width(), 1440 height: elem.height(), 1441 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 1442 }; 1443 } 1444 if ( raw.preventDefault ) { 1445 return { 1446 width: 0, 1447 height: 0, 1448 offset: { top: raw.pageY, left: raw.pageX } 1449 }; 1450 } 1451 return { 1452 width: elem.outerWidth(), 1453 height: elem.outerHeight(), 1454 offset: elem.offset() 1455 }; 1456} 1457 1458$.position = { 1459 scrollbarWidth: function() { 1460 if ( cachedScrollbarWidth !== undefined ) { 1461 return cachedScrollbarWidth; 1462 } 1463 var w1, w2, 1464 div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 1465 innerDiv = div.children()[0]; 1466 1467 $( "body" ).append( div ); 1468 w1 = innerDiv.offsetWidth; 1469 div.css( "overflow", "scroll" ); 1470 1471 w2 = innerDiv.offsetWidth; 1472 1473 if ( w1 === w2 ) { 1474 w2 = div[0].clientWidth; 1475 } 1476 1477 div.remove(); 1478 1479 return (cachedScrollbarWidth = w1 - w2); 1480 }, 1481 getScrollInfo: function( within ) { 1482 var overflowX = within.isWindow || within.isDocument ? "" : 1483 within.element.css( "overflow-x" ), 1484 overflowY = within.isWindow || within.isDocument ? "" : 1485 within.element.css( "overflow-y" ), 1486 hasOverflowX = overflowX === "scroll" || 1487 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 1488 hasOverflowY = overflowY === "scroll" || 1489 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 1490 return { 1491 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 1492 height: hasOverflowX ? $.position.scrollbarWidth() : 0 1493 }; 1494 }, 1495 getWithinInfo: function( element ) { 1496 var withinElement = $( element || window ), 1497 isWindow = $.isWindow( withinElement[0] ), 1498 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; 1499 return { 1500 element: withinElement, 1501 isWindow: isWindow, 1502 isDocument: isDocument, 1503 offset: withinElement.offset() || { left: 0, top: 0 }, 1504 scrollLeft: withinElement.scrollLeft(), 1505 scrollTop: withinElement.scrollTop(), 1506 1507 // support: jQuery 1.6.x 1508 // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows 1509 width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), 1510 height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() 1511 }; 1512 } 1513}; 1514 1515$.fn.position = function( options ) { 1516 if ( !options || !options.of ) { 1517 return _position.apply( this, arguments ); 1518 } 1519 1520 // make a copy, we don't want to modify arguments 1521 options = $.extend( {}, options ); 1522 1523 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 1524 target = $( options.of ), 1525 within = $.position.getWithinInfo( options.within ), 1526 scrollInfo = $.position.getScrollInfo( within ), 1527 collision = ( options.collision || "flip" ).split( " " ), 1528 offsets = {}; 1529 1530 dimensions = getDimensions( target ); 1531 if ( target[0].preventDefault ) { 1532 // force left top to allow flipping 1533 options.at = "left top"; 1534 } 1535 targetWidth = dimensions.width; 1536 targetHeight = dimensions.height; 1537 targetOffset = dimensions.offset; 1538 // clone to reuse original targetOffset later 1539 basePosition = $.extend( {}, targetOffset ); 1540 1541 // force my and at to have valid horizontal and vertical positions 1542 // if a value is missing or invalid, it will be converted to center 1543 $.each( [ "my", "at" ], function() { 1544 var pos = ( options[ this ] || "" ).split( " " ), 1545 horizontalOffset, 1546 verticalOffset; 1547 1548 if ( pos.length === 1) { 1549 pos = rhorizontal.test( pos[ 0 ] ) ? 1550 pos.concat( [ "center" ] ) : 1551 rvertical.test( pos[ 0 ] ) ? 1552 [ "center" ].concat( pos ) : 1553 [ "center", "center" ]; 1554 } 1555 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 1556 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 1557 1558 // calculate offsets 1559 horizontalOffset = roffset.exec( pos[ 0 ] ); 1560 verticalOffset = roffset.exec( pos[ 1 ] ); 1561 offsets[ this ] = [ 1562 horizontalOffset ? horizontalOffset[ 0 ] : 0, 1563 verticalOffset ? verticalOffset[ 0 ] : 0 1564 ]; 1565 1566 // reduce to just the positions without the offsets 1567 options[ this ] = [ 1568 rposition.exec( pos[ 0 ] )[ 0 ], 1569 rposition.exec( pos[ 1 ] )[ 0 ] 1570 ]; 1571 }); 1572 1573 // normalize collision option 1574 if ( collision.length === 1 ) { 1575 collision[ 1 ] = collision[ 0 ]; 1576 } 1577 1578 if ( options.at[ 0 ] === "right" ) { 1579 basePosition.left += targetWidth; 1580 } else if ( options.at[ 0 ] === "center" ) { 1581 basePosition.left += targetWidth / 2; 1582 } 1583 1584 if ( options.at[ 1 ] === "bottom" ) { 1585 basePosition.top += targetHeight; 1586 } else if ( options.at[ 1 ] === "center" ) { 1587 basePosition.top += targetHeight / 2; 1588 } 1589 1590 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 1591 basePosition.left += atOffset[ 0 ]; 1592 basePosition.top += atOffset[ 1 ]; 1593 1594 return this.each(function() { 1595 var collisionPosition, using, 1596 elem = $( this ), 1597 elemWidth = elem.outerWidth(), 1598 elemHeight = elem.outerHeight(), 1599 marginLeft = parseCss( this, "marginLeft" ), 1600 marginTop = parseCss( this, "marginTop" ), 1601 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 1602 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 1603 position = $.extend( {}, basePosition ), 1604 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 1605 1606 if ( options.my[ 0 ] === "right" ) { 1607 position.left -= elemWidth; 1608 } else if ( options.my[ 0 ] === "center" ) { 1609 position.left -= elemWidth / 2; 1610 } 1611 1612 if ( options.my[ 1 ] === "bottom" ) { 1613 position.top -= elemHeight; 1614 } else if ( options.my[ 1 ] === "center" ) { 1615 position.top -= elemHeight / 2; 1616 } 1617 1618 position.left += myOffset[ 0 ]; 1619 position.top += myOffset[ 1 ]; 1620 1621 // if the browser doesn't support fractions, then round for consistent results 1622 if ( !supportsOffsetFractions ) { 1623 position.left = round( position.left ); 1624 position.top = round( position.top ); 1625 } 1626 1627 collisionPosition = { 1628 marginLeft: marginLeft, 1629 marginTop: marginTop 1630 }; 1631 1632 $.each( [ "left", "top" ], function( i, dir ) { 1633 if ( $.ui.position[ collision[ i ] ] ) { 1634 $.ui.position[ collision[ i ] ][ dir ]( position, { 1635 targetWidth: targetWidth, 1636 targetHeight: targetHeight, 1637 elemWidth: elemWidth, 1638 elemHeight: elemHeight, 1639 collisionPosition: collisionPosition, 1640 collisionWidth: collisionWidth, 1641 collisionHeight: collisionHeight, 1642 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1643 my: options.my, 1644 at: options.at, 1645 within: within, 1646 elem: elem 1647 }); 1648 } 1649 }); 1650 1651 if ( options.using ) { 1652 // adds feedback as second argument to using callback, if present 1653 using = function( props ) { 1654 var left = targetOffset.left - position.left, 1655 right = left + targetWidth - elemWidth, 1656 top = targetOffset.top - position.top, 1657 bottom = top + targetHeight - elemHeight, 1658 feedback = { 1659 target: { 1660 element: target, 1661 left: targetOffset.left, 1662 top: targetOffset.top, 1663 width: targetWidth, 1664 height: targetHeight 1665 }, 1666 element: { 1667 element: elem, 1668 left: position.left, 1669 top: position.top, 1670 width: elemWidth, 1671 height: elemHeight 1672 }, 1673 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1674 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1675 }; 1676 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1677 feedback.horizontal = "center"; 1678 } 1679 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1680 feedback.vertical = "middle"; 1681 } 1682 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1683 feedback.important = "horizontal"; 1684 } else { 1685 feedback.important = "vertical"; 1686 } 1687 options.using.call( this, props, feedback ); 1688 }; 1689 } 1690 1691 elem.offset( $.extend( position, { using: using } ) ); 1692 }); 1693}; 1694 1695$.ui.position = { 1696 fit: { 1697 left: function( position, data ) { 1698 var within = data.within, 1699 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1700 outerWidth = within.width, 1701 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1702 overLeft = withinOffset - collisionPosLeft, 1703 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1704 newOverRight; 1705 1706 // element is wider than within 1707 if ( data.collisionWidth > outerWidth ) { 1708 // element is initially over the left side of within 1709 if ( overLeft > 0 && overRight <= 0 ) { 1710 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 1711 position.left += overLeft - newOverRight; 1712 // element is initially over right side of within 1713 } else if ( overRight > 0 && overLeft <= 0 ) { 1714 position.left = withinOffset; 1715 // element is initially over both left and right sides of within 1716 } else { 1717 if ( overLeft > overRight ) { 1718 position.left = withinOffset + outerWidth - data.collisionWidth; 1719 } else { 1720 position.left = withinOffset; 1721 } 1722 } 1723 // too far left -> align with left edge 1724 } else if ( overLeft > 0 ) { 1725 position.left += overLeft; 1726 // too far right -> align with right edge 1727 } else if ( overRight > 0 ) { 1728 position.left -= overRight; 1729 // adjust based on position and margin 1730 } else { 1731 position.left = max( position.left - collisionPosLeft, position.left ); 1732 } 1733 }, 1734 top: function( position, data ) { 1735 var within = data.within, 1736 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1737 outerHeight = data.within.height, 1738 collisionPosTop = position.top - data.collisionPosition.marginTop, 1739 overTop = withinOffset - collisionPosTop, 1740 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1741 newOverBottom; 1742 1743 // element is taller than within 1744 if ( data.collisionHeight > outerHeight ) { 1745 // element is initially over the top of within 1746 if ( overTop > 0 && overBottom <= 0 ) { 1747 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 1748 position.top += overTop - newOverBottom; 1749 // element is initially over bottom of within 1750 } else if ( overBottom > 0 && overTop <= 0 ) { 1751 position.top = withinOffset; 1752 // element is initially over both top and bottom of within 1753 } else { 1754 if ( overTop > overBottom ) { 1755 position.top = withinOffset + outerHeight - data.collisionHeight; 1756 } else { 1757 position.top = withinOffset; 1758 } 1759 } 1760 // too far up -> align with top 1761 } else if ( overTop > 0 ) { 1762 position.top += overTop; 1763 // too far down -> align with bottom edge 1764 } else if ( overBottom > 0 ) { 1765 position.top -= overBottom; 1766 // adjust based on position and margin 1767 } else { 1768 position.top = max( position.top - collisionPosTop, position.top ); 1769 } 1770 } 1771 }, 1772 flip: { 1773 left: function( position, data ) { 1774 var within = data.within, 1775 withinOffset = within.offset.left + within.scrollLeft, 1776 outerWidth = within.width, 1777 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1778 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1779 overLeft = collisionPosLeft - offsetLeft, 1780 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1781 myOffset = data.my[ 0 ] === "left" ? 1782 -data.elemWidth : 1783 data.my[ 0 ] === "right" ? 1784 data.elemWidth : 1785 0, 1786 atOffset = data.at[ 0 ] === "left" ? 1787 data.targetWidth : 1788 data.at[ 0 ] === "right" ? 1789 -data.targetWidth : 1790 0, 1791 offset = -2 * data.offset[ 0 ], 1792 newOverRight, 1793 newOverLeft; 1794 1795 if ( overLeft < 0 ) { 1796 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 1797 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1798 position.left += myOffset + atOffset + offset; 1799 } 1800 } else if ( overRight > 0 ) { 1801 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 1802 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1803 position.left += myOffset + atOffset + offset; 1804 } 1805 } 1806 }, 1807 top: function( position, data ) { 1808 var within = data.within, 1809 withinOffset = within.offset.top + within.scrollTop, 1810 outerHeight = within.height, 1811 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1812 collisionPosTop = position.top - data.collisionPosition.marginTop, 1813 overTop = collisionPosTop - offsetTop, 1814 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1815 top = data.my[ 1 ] === "top", 1816 myOffset = top ? 1817 -data.elemHeight : 1818 data.my[ 1 ] === "bottom" ? 1819 data.elemHeight : 1820 0, 1821 atOffset = data.at[ 1 ] === "top" ? 1822 data.targetHeight : 1823 data.at[ 1 ] === "bottom" ? 1824 -data.targetHeight : 1825 0, 1826 offset = -2 * data.offset[ 1 ], 1827 newOverTop, 1828 newOverBottom; 1829 if ( overTop < 0 ) { 1830 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 1831 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 1832 position.top += myOffset + atOffset + offset; 1833 } 1834 } else if ( overBottom > 0 ) { 1835 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 1836 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 1837 position.top += myOffset + atOffset + offset; 1838 } 1839 } 1840 } 1841 }, 1842 flipfit: { 1843 left: function() { 1844 $.ui.position.flip.left.apply( this, arguments ); 1845 $.ui.position.fit.left.apply( this, arguments ); 1846 }, 1847 top: function() { 1848 $.ui.position.flip.top.apply( this, arguments ); 1849 $.ui.position.fit.top.apply( this, arguments ); 1850 } 1851 } 1852}; 1853 1854// fraction support test 1855(function() { 1856 var testElement, testElementParent, testElementStyle, offsetLeft, i, 1857 body = document.getElementsByTagName( "body" )[ 0 ], 1858 div = document.createElement( "div" ); 1859 1860 //Create a "fake body" for testing based on method used in jQuery.support 1861 testElement = document.createElement( body ? "div" : "body" ); 1862 testElementStyle = { 1863 visibility: "hidden", 1864 width: 0, 1865 height: 0, 1866 border: 0, 1867 margin: 0, 1868 background: "none" 1869 }; 1870 if ( body ) { 1871 $.extend( testElementStyle, { 1872 position: "absolute", 1873 left: "-1000px", 1874 top: "-1000px" 1875 }); 1876 } 1877 for ( i in testElementStyle ) { 1878 testElement.style[ i ] = testElementStyle[ i ]; 1879 } 1880 testElement.appendChild( div ); 1881 testElementParent = body || document.documentElement; 1882 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 1883 1884 div.style.cssText = "position: absolute; left: 10.7432222px;"; 1885 1886 offsetLeft = $( div ).offset().left; 1887 supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; 1888 1889 testElement.innerHTML = ""; 1890 testElementParent.removeChild( testElement ); 1891})(); 1892 1893})(); 1894 1895var position = $.ui.position; 1896 1897 1898/*! 1899 * jQuery UI Accordion 1.11.1 1900 * http://jqueryui.com 1901 * 1902 * Copyright 2014 jQuery Foundation and other contributors 1903 * Released under the MIT license. 1904 * http://jquery.org/license 1905 * 1906 * http://api.jqueryui.com/accordion/ 1907 */ 1908 1909 1910var accordion = $.widget( "ui.accordion", { 1911 version: "1.11.1", 1912 options: { 1913 active: 0, 1914 animate: {}, 1915 collapsible: false, 1916 event: "click", 1917 header: "> li > :first-child,> :not(li):even", 1918 heightStyle: "auto", 1919 icons: { 1920 activeHeader: "ui-icon-triangle-1-s", 1921 header: "ui-icon-triangle-1-e" 1922 }, 1923 1924 // callbacks 1925 activate: null, 1926 beforeActivate: null 1927 }, 1928 1929 hideProps: { 1930 borderTopWidth: "hide", 1931 borderBottomWidth: "hide", 1932 paddingTop: "hide", 1933 paddingBottom: "hide", 1934 height: "hide" 1935 }, 1936 1937 showProps: { 1938 borderTopWidth: "show", 1939 borderBottomWidth: "show", 1940 paddingTop: "show", 1941 paddingBottom: "show", 1942 height: "show" 1943 }, 1944 1945 _create: function() { 1946 var options = this.options; 1947 this.prevShow = this.prevHide = $(); 1948 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 1949 // ARIA 1950 .attr( "role", "tablist" ); 1951 1952 // don't allow collapsible: false and active: false / null 1953 if ( !options.collapsible && (options.active === false || options.active == null) ) { 1954 options.active = 0; 1955 } 1956 1957 this._processPanels(); 1958 // handle negative values 1959 if ( options.active < 0 ) { 1960 options.active += this.headers.length; 1961 } 1962 this._refresh(); 1963 }, 1964 1965 _getCreateEventData: function() { 1966 return { 1967 header: this.active, 1968 panel: !this.active.length ? $() : this.active.next() 1969 }; 1970 }, 1971 1972 _createIcons: function() { 1973 var icons = this.options.icons; 1974 if ( icons ) { 1975 $( "<span>" ) 1976 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 1977 .prependTo( this.headers ); 1978 this.active.children( ".ui-accordion-header-icon" ) 1979 .removeClass( icons.header ) 1980 .addClass( icons.activeHeader ); 1981 this.headers.addClass( "ui-accordion-icons" ); 1982 } 1983 }, 1984 1985 _destroyIcons: function() { 1986 this.headers 1987 .removeClass( "ui-accordion-icons" ) 1988 .children( ".ui-accordion-header-icon" ) 1989 .remove(); 1990 }, 1991 1992 _destroy: function() { 1993 var contents; 1994 1995 // clean up main element 1996 this.element 1997 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 1998 .removeAttr( "role" ); 1999 2000 // clean up headers 2001 this.headers 2002 .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + 2003 "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) 2004 .removeAttr( "role" ) 2005 .removeAttr( "aria-expanded" ) 2006 .removeAttr( "aria-selected" ) 2007 .removeAttr( "aria-controls" ) 2008 .removeAttr( "tabIndex" ) 2009 .removeUniqueId(); 2010 2011 this._destroyIcons(); 2012 2013 // clean up content panels 2014 contents = this.headers.next() 2015 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + 2016 "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 2017 .css( "display", "" ) 2018 .removeAttr( "role" ) 2019 .removeAttr( "aria-hidden" ) 2020 .removeAttr( "aria-labelledby" ) 2021 .removeUniqueId(); 2022 2023 if ( this.options.heightStyle !== "content" ) { 2024 contents.css( "height", "" ); 2025 } 2026 }, 2027 2028 _setOption: function( key, value ) { 2029 if ( key === "active" ) { 2030 // _activate() will handle invalid values and update this.options 2031 this._activate( value ); 2032 return; 2033 } 2034 2035 if ( key === "event" ) { 2036 if ( this.options.event ) { 2037 this._off( this.headers, this.options.event ); 2038 } 2039 this._setupEvents( value ); 2040 } 2041 2042 this._super( key, value ); 2043 2044 // setting collapsible: false while collapsed; open first panel 2045 if ( key === "collapsible" && !value && this.options.active === false ) { 2046 this._activate( 0 ); 2047 } 2048 2049 if ( key === "icons" ) { 2050 this._destroyIcons(); 2051 if ( value ) { 2052 this._createIcons(); 2053 } 2054 } 2055 2056 // #5332 - opacity doesn't cascade to positioned elements in IE 2057 // so we need to add the disabled class to the headers and panels 2058 if ( key === "disabled" ) { 2059 this.element 2060 .toggleClass( "ui-state-disabled", !!value ) 2061 .attr( "aria-disabled", value ); 2062 this.headers.add( this.headers.next() ) 2063 .toggleClass( "ui-state-disabled", !!value ); 2064 } 2065 }, 2066 2067 _keydown: function( event ) { 2068 if ( event.altKey || event.ctrlKey ) { 2069 return; 2070 } 2071 2072 var keyCode = $.ui.keyCode, 2073 length = this.headers.length, 2074 currentIndex = this.headers.index( event.target ), 2075 toFocus = false; 2076 2077 switch ( event.keyCode ) { 2078 case keyCode.RIGHT: 2079 case keyCode.DOWN: 2080 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 2081 break; 2082 case keyCode.LEFT: 2083 case keyCode.UP: 2084 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 2085 break; 2086 case keyCode.SPACE: 2087 case keyCode.ENTER: 2088 this._eventHandler( event ); 2089 break; 2090 case keyCode.HOME: 2091 toFocus = this.headers[ 0 ]; 2092 break; 2093 case keyCode.END: 2094 toFocus = this.headers[ length - 1 ]; 2095 break; 2096 } 2097 2098 if ( toFocus ) { 2099 $( event.target ).attr( "tabIndex", -1 ); 2100 $( toFocus ).attr( "tabIndex", 0 ); 2101 toFocus.focus(); 2102 event.preventDefault(); 2103 } 2104 }, 2105 2106 _panelKeyDown: function( event ) { 2107 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 2108 $( event.currentTarget ).prev().focus(); 2109 } 2110 }, 2111 2112 refresh: function() { 2113 var options = this.options; 2114 this._processPanels(); 2115 2116 // was collapsed or no panel 2117 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 2118 options.active = false; 2119 this.active = $(); 2120 // active false only when collapsible is true 2121 } else if ( options.active === false ) { 2122 this._activate( 0 ); 2123 // was active, but active panel is gone 2124 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 2125 // all remaining panel are disabled 2126 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 2127 options.active = false; 2128 this.active = $(); 2129 // activate previous panel 2130 } else { 2131 this._activate( Math.max( 0, options.active - 1 ) ); 2132 } 2133 // was active, active panel still exists 2134 } else { 2135 // make sure active index is correct 2136 options.active = this.headers.index( this.active ); 2137 } 2138 2139 this._destroyIcons(); 2140 2141 this._refresh(); 2142 }, 2143 2144 _processPanels: function() { 2145 this.headers = this.element.find( this.options.header ) 2146 .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); 2147 2148 this.headers.next() 2149 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 2150 .filter( ":not(.ui-accordion-content-active)" ) 2151 .hide(); 2152 }, 2153 2154 _refresh: function() { 2155 var maxHeight, 2156 options = this.options, 2157 heightStyle = options.heightStyle, 2158 parent = this.element.parent(); 2159 2160 this.active = this._findActive( options.active ) 2161 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 2162 .removeClass( "ui-corner-all" ); 2163 this.active.next() 2164 .addClass( "ui-accordion-content-active" ) 2165 .show(); 2166 2167 this.headers 2168 .attr( "role", "tab" ) 2169 .each(function() { 2170 var header = $( this ), 2171 headerId = header.uniqueId().attr( "id" ), 2172 panel = header.next(), 2173 panelId = panel.uniqueId().attr( "id" ); 2174 header.attr( "aria-controls", panelId ); 2175 panel.attr( "aria-labelledby", headerId ); 2176 }) 2177 .next() 2178 .attr( "role", "tabpanel" ); 2179 2180 this.headers 2181 .not( this.active ) 2182 .attr({ 2183 "aria-selected": "false", 2184 "aria-expanded": "false", 2185 tabIndex: -1 2186 }) 2187 .next() 2188 .attr({ 2189 "aria-hidden": "true" 2190 }) 2191 .hide(); 2192 2193 // make sure at least one header is in the tab order 2194 if ( !this.active.length ) { 2195 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 2196 } else { 2197 this.active.attr({ 2198 "aria-selected": "true", 2199 "aria-expanded": "true", 2200 tabIndex: 0 2201 }) 2202 .next() 2203 .attr({ 2204 "aria-hidden": "false" 2205 }); 2206 } 2207 2208 this._createIcons(); 2209 2210 this._setupEvents( options.event ); 2211 2212 if ( heightStyle === "fill" ) { 2213 maxHeight = parent.height(); 2214 this.element.siblings( ":visible" ).each(function() { 2215 var elem = $( this ), 2216 position = elem.css( "position" ); 2217 2218 if ( position === "absolute" || position === "fixed" ) { 2219 return; 2220 } 2221 maxHeight -= elem.outerHeight( true ); 2222 }); 2223 2224 this.headers.each(function() { 2225 maxHeight -= $( this ).outerHeight( true ); 2226 }); 2227 2228 this.headers.next() 2229 .each(function() { 2230 $( this ).height( Math.max( 0, maxHeight - 2231 $( this ).innerHeight() + $( this ).height() ) ); 2232 }) 2233 .css( "overflow", "auto" ); 2234 } else if ( heightStyle === "auto" ) { 2235 maxHeight = 0; 2236 this.headers.next() 2237 .each(function() { 2238 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 2239 }) 2240 .height( maxHeight ); 2241 } 2242 }, 2243 2244 _activate: function( index ) { 2245 var active = this._findActive( index )[ 0 ]; 2246 2247 // trying to activate the already active panel 2248 if ( active === this.active[ 0 ] ) { 2249 return; 2250 } 2251 2252 // trying to collapse, simulate a click on the currently active header 2253 active = active || this.active[ 0 ]; 2254 2255 this._eventHandler({ 2256 target: active, 2257 currentTarget: active, 2258 preventDefault: $.noop 2259 }); 2260 }, 2261 2262 _findActive: function( selector ) { 2263 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 2264 }, 2265 2266 _setupEvents: function( event ) { 2267 var events = { 2268 keydown: "_keydown" 2269 }; 2270 if ( event ) { 2271 $.each( event.split( " " ), function( index, eventName ) { 2272 events[ eventName ] = "_eventHandler"; 2273 }); 2274 } 2275 2276 this._off( this.headers.add( this.headers.next() ) ); 2277 this._on( this.headers, events ); 2278 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 2279 this._hoverable( this.headers ); 2280 this._focusable( this.headers ); 2281 }, 2282 2283 _eventHandler: function( event ) { 2284 var options = this.options, 2285 active = this.active, 2286 clicked = $( event.currentTarget ), 2287 clickedIsActive = clicked[ 0 ] === active[ 0 ], 2288 collapsing = clickedIsActive && options.collapsible, 2289 toShow = collapsing ? $() : clicked.next(), 2290 toHide = active.next(), 2291 eventData = { 2292 oldHeader: active, 2293 oldPanel: toHide, 2294 newHeader: collapsing ? $() : clicked, 2295 newPanel: toShow 2296 }; 2297 2298 event.preventDefault(); 2299 2300 if ( 2301 // click on active header, but not collapsible 2302 ( clickedIsActive && !options.collapsible ) || 2303 // allow canceling activation 2304 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 2305 return; 2306 } 2307 2308 options.active = collapsing ? false : this.headers.index( clicked ); 2309 2310 // when the call to ._toggle() comes after the class changes 2311 // it causes a very odd bug in IE 8 (see #6720) 2312 this.active = clickedIsActive ? $() : clicked; 2313 this._toggle( eventData ); 2314 2315 // switch classes 2316 // corner classes on the previously active header stay after the animation 2317 active.removeClass( "ui-accordion-header-active ui-state-active" ); 2318 if ( options.icons ) { 2319 active.children( ".ui-accordion-header-icon" ) 2320 .removeClass( options.icons.activeHeader ) 2321 .addClass( options.icons.header ); 2322 } 2323 2324 if ( !clickedIsActive ) { 2325 clicked 2326 .removeClass( "ui-corner-all" ) 2327 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 2328 if ( options.icons ) { 2329 clicked.children( ".ui-accordion-header-icon" ) 2330 .removeClass( options.icons.header ) 2331 .addClass( options.icons.activeHeader ); 2332 } 2333 2334 clicked 2335 .next() 2336 .addClass( "ui-accordion-content-active" ); 2337 } 2338 }, 2339 2340 _toggle: function( data ) { 2341 var toShow = data.newPanel, 2342 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 2343 2344 // handle activating a panel during the animation for another activation 2345 this.prevShow.add( this.prevHide ).stop( true, true ); 2346 this.prevShow = toShow; 2347 this.prevHide = toHide; 2348 2349 if ( this.options.animate ) { 2350 this._animate( toShow, toHide, data ); 2351 } else { 2352 toHide.hide(); 2353 toShow.show(); 2354 this._toggleComplete( data ); 2355 } 2356 2357 toHide.attr({ 2358 "aria-hidden": "true" 2359 }); 2360 toHide.prev().attr( "aria-selected", "false" ); 2361 // if we're switching panels, remove the old header from the tab order 2362 // if we're opening from collapsed state, remove the previous header from the tab order 2363 // if we're collapsing, then keep the collapsing header in the tab order 2364 if ( toShow.length && toHide.length ) { 2365 toHide.prev().attr({ 2366 "tabIndex": -1, 2367 "aria-expanded": "false" 2368 }); 2369 } else if ( toShow.length ) { 2370 this.headers.filter(function() { 2371 return $( this ).attr( "tabIndex" ) === 0; 2372 }) 2373 .attr( "tabIndex", -1 ); 2374 } 2375 2376 toShow 2377 .attr( "aria-hidden", "false" ) 2378 .prev() 2379 .attr({ 2380 "aria-selected": "true", 2381 tabIndex: 0, 2382 "aria-expanded": "true" 2383 }); 2384 }, 2385 2386 _animate: function( toShow, toHide, data ) { 2387 var total, easing, duration, 2388 that = this, 2389 adjust = 0, 2390 down = toShow.length && 2391 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 2392 animate = this.options.animate || {}, 2393 options = down && animate.down || animate, 2394 complete = function() { 2395 that._toggleComplete( data ); 2396 }; 2397 2398 if ( typeof options === "number" ) { 2399 duration = options; 2400 } 2401 if ( typeof options === "string" ) { 2402 easing = options; 2403 } 2404 // fall back from options to animation in case of partial down settings 2405 easing = easing || options.easing || animate.easing; 2406 duration = duration || options.duration || animate.duration; 2407 2408 if ( !toHide.length ) { 2409 return toShow.animate( this.showProps, duration, easing, complete ); 2410 } 2411 if ( !toShow.length ) { 2412 return toHide.animate( this.hideProps, duration, easing, complete ); 2413 } 2414 2415 total = toShow.show().outerHeight(); 2416 toHide.animate( this.hideProps, { 2417 duration: duration, 2418 easing: easing, 2419 step: function( now, fx ) { 2420 fx.now = Math.round( now ); 2421 } 2422 }); 2423 toShow 2424 .hide() 2425 .animate( this.showProps, { 2426 duration: duration, 2427 easing: easing, 2428 complete: complete, 2429 step: function( now, fx ) { 2430 fx.now = Math.round( now ); 2431 if ( fx.prop !== "height" ) { 2432 adjust += fx.now; 2433 } else if ( that.options.heightStyle !== "content" ) { 2434 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 2435 adjust = 0; 2436 } 2437 } 2438 }); 2439 }, 2440 2441 _toggleComplete: function( data ) { 2442 var toHide = data.oldPanel; 2443 2444 toHide 2445 .removeClass( "ui-accordion-content-active" ) 2446 .prev() 2447 .removeClass( "ui-corner-top" ) 2448 .addClass( "ui-corner-all" ); 2449 2450 // Work around for rendering bug in IE (#5421) 2451 if ( toHide.length ) { 2452 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 2453 } 2454 this._trigger( "activate", null, data ); 2455 } 2456}); 2457 2458 2459/*! 2460 * jQuery UI Menu 1.11.1 2461 * http://jqueryui.com 2462 * 2463 * Copyright 2014 jQuery Foundation and other contributors 2464 * Released under the MIT license. 2465 * http://jquery.org/license 2466 * 2467 * http://api.jqueryui.com/menu/ 2468 */ 2469 2470 2471var menu = $.widget( "ui.menu", { 2472 version: "1.11.1", 2473 defaultElement: "<ul>", 2474 delay: 300, 2475 options: { 2476 icons: { 2477 submenu: "ui-icon-carat-1-e" 2478 }, 2479 items: "> *", 2480 menus: "ul", 2481 position: { 2482 my: "left-1 top", 2483 at: "right top" 2484 }, 2485 role: "menu", 2486 2487 // callbacks 2488 blur: null, 2489 focus: null, 2490 select: null 2491 }, 2492 2493 _create: function() { 2494 this.activeMenu = this.element; 2495 2496 // Flag used to prevent firing of the click handler 2497 // as the event bubbles up through nested menus 2498 this.mouseHandled = false; 2499 this.element 2500 .uniqueId() 2501 .addClass( "ui-menu ui-widget ui-widget-content" ) 2502 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 2503 .attr({ 2504 role: this.options.role, 2505 tabIndex: 0 2506 }); 2507 2508 if ( this.options.disabled ) { 2509 this.element 2510 .addClass( "ui-state-disabled" ) 2511 .attr( "aria-disabled", "true" ); 2512 } 2513 2514 this._on({ 2515 // Prevent focus from sticking to links inside menu after clicking 2516 // them (focus should always stay on UL during navigation). 2517 "mousedown .ui-menu-item": function( event ) { 2518 event.preventDefault(); 2519 }, 2520 "click .ui-menu-item": function( event ) { 2521 var target = $( event.target ); 2522 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 2523 this.select( event ); 2524 2525 // Only set the mouseHandled flag if the event will bubble, see #9469. 2526 if ( !event.isPropagationStopped() ) { 2527 this.mouseHandled = true; 2528 } 2529 2530 // Open submenu on click 2531 if ( target.has( ".ui-menu" ).length ) { 2532 this.expand( event ); 2533 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { 2534 2535 // Redirect focus to the menu 2536 this.element.trigger( "focus", [ true ] ); 2537 2538 // If the active item is on the top level, let it stay active. 2539 // Otherwise, blur the active item since it is no longer visible. 2540 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 2541 clearTimeout( this.timer ); 2542 } 2543 } 2544 } 2545 }, 2546 "mouseenter .ui-menu-item": function( event ) { 2547 var target = $( event.currentTarget ); 2548 // Remove ui-state-active class from siblings of the newly focused menu item 2549 // to avoid a jump caused by adjacent elements both having a class with a border 2550 target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" ); 2551 this.focus( event, target ); 2552 }, 2553 mouseleave: "collapseAll", 2554 "mouseleave .ui-menu": "collapseAll", 2555 focus: function( event, keepActiveItem ) { 2556 // If there's already an active item, keep it active 2557 // If not, activate the first item 2558 var item = this.active || this.element.find( this.options.items ).eq( 0 ); 2559 2560 if ( !keepActiveItem ) { 2561 this.focus( event, item ); 2562 } 2563 }, 2564 blur: function( event ) { 2565 this._delay(function() { 2566 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 2567 this.collapseAll( event ); 2568 } 2569 }); 2570 }, 2571 keydown: "_keydown" 2572 }); 2573 2574 this.refresh(); 2575 2576 // Clicks outside of a menu collapse any open menus 2577 this._on( this.document, { 2578 click: function( event ) { 2579 if ( this._closeOnDocumentClick( event ) ) { 2580 this.collapseAll( event ); 2581 } 2582 2583 // Reset the mouseHandled flag 2584 this.mouseHandled = false; 2585 } 2586 }); 2587 }, 2588 2589 _destroy: function() { 2590 // Destroy (sub)menus 2591 this.element 2592 .removeAttr( "aria-activedescendant" ) 2593 .find( ".ui-menu" ).addBack() 2594 .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" ) 2595 .removeAttr( "role" ) 2596 .removeAttr( "tabIndex" ) 2597 .removeAttr( "aria-labelledby" ) 2598 .removeAttr( "aria-expanded" ) 2599 .removeAttr( "aria-hidden" ) 2600 .removeAttr( "aria-disabled" ) 2601 .removeUniqueId() 2602 .show(); 2603 2604 // Destroy menu items 2605 this.element.find( ".ui-menu-item" ) 2606 .removeClass( "ui-menu-item" ) 2607 .removeAttr( "role" ) 2608 .removeAttr( "aria-disabled" ) 2609 .removeUniqueId() 2610 .removeClass( "ui-state-hover" ) 2611 .removeAttr( "tabIndex" ) 2612 .removeAttr( "role" ) 2613 .removeAttr( "aria-haspopup" ) 2614 .children().each( function() { 2615 var elem = $( this ); 2616 if ( elem.data( "ui-menu-submenu-carat" ) ) { 2617 elem.remove(); 2618 } 2619 }); 2620 2621 // Destroy menu dividers 2622 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 2623 }, 2624 2625 _keydown: function( event ) { 2626 var match, prev, character, skip, regex, 2627 preventDefault = true; 2628 2629 function escape( value ) { 2630 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 2631 } 2632 2633 switch ( event.keyCode ) { 2634 case $.ui.keyCode.PAGE_UP: 2635 this.previousPage( event ); 2636 break; 2637 case $.ui.keyCode.PAGE_DOWN: 2638 this.nextPage( event ); 2639 break; 2640 case $.ui.keyCode.HOME: 2641 this._move( "first", "first", event ); 2642 break; 2643 case $.ui.keyCode.END: 2644 this._move( "last", "last", event ); 2645 break; 2646 case $.ui.keyCode.UP: 2647 this.previous( event ); 2648 break; 2649 case $.ui.keyCode.DOWN: 2650 this.next( event ); 2651 break; 2652 case $.ui.keyCode.LEFT: 2653 this.collapse( event ); 2654 break; 2655 case $.ui.keyCode.RIGHT: 2656 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 2657 this.expand( event ); 2658 } 2659 break; 2660 case $.ui.keyCode.ENTER: 2661 case $.ui.keyCode.SPACE: 2662 this._activate( event ); 2663 break; 2664 case $.ui.keyCode.ESCAPE: 2665 this.collapse( event ); 2666 break; 2667 default: 2668 preventDefault = false; 2669 prev = this.previousFilter || ""; 2670 character = String.fromCharCode( event.keyCode ); 2671 skip = false; 2672 2673 clearTimeout( this.filterTimer ); 2674 2675 if ( character === prev ) { 2676 skip = true; 2677 } else { 2678 character = prev + character; 2679 } 2680 2681 regex = new RegExp( "^" + escape( character ), "i" ); 2682 match = this.activeMenu.find( this.options.items ).filter(function() { 2683 return regex.test( $( this ).text() ); 2684 }); 2685 match = skip && match.index( this.active.next() ) !== -1 ? 2686 this.active.nextAll( ".ui-menu-item" ) : 2687 match; 2688 2689 // If no matches on the current filter, reset to the last character pressed 2690 // to move down the menu to the first item that starts with that character 2691 if ( !match.length ) { 2692 character = String.fromCharCode( event.keyCode ); 2693 regex = new RegExp( "^" + escape( character ), "i" ); 2694 match = this.activeMenu.find( this.options.items ).filter(function() { 2695 return regex.test( $( this ).text() ); 2696 }); 2697 } 2698 2699 if ( match.length ) { 2700 this.focus( event, match ); 2701 if ( match.length > 1 ) { 2702 this.previousFilter = character; 2703 this.filterTimer = this._delay(function() { 2704 delete this.previousFilter; 2705 }, 1000 ); 2706 } else { 2707 delete this.previousFilter; 2708 } 2709 } else { 2710 delete this.previousFilter; 2711 } 2712 } 2713 2714 if ( preventDefault ) { 2715 event.preventDefault(); 2716 } 2717 }, 2718 2719 _activate: function( event ) { 2720 if ( !this.active.is( ".ui-state-disabled" ) ) { 2721 if ( this.active.is( "[aria-haspopup='true']" ) ) { 2722 this.expand( event ); 2723 } else { 2724 this.select( event ); 2725 } 2726 } 2727 }, 2728 2729 refresh: function() { 2730 var menus, items, 2731 that = this, 2732 icon = this.options.icons.submenu, 2733 submenus = this.element.find( this.options.menus ); 2734 2735 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); 2736 2737 // Initialize nested menus 2738 submenus.filter( ":not(.ui-menu)" ) 2739 .addClass( "ui-menu ui-widget ui-widget-content ui-front" ) 2740 .hide() 2741 .attr({ 2742 role: this.options.role, 2743 "aria-hidden": "true", 2744 "aria-expanded": "false" 2745 }) 2746 .each(function() { 2747 var menu = $( this ), 2748 item = menu.parent(), 2749 submenuCarat = $( "<span>" ) 2750 .addClass( "ui-menu-icon ui-icon " + icon ) 2751 .data( "ui-menu-submenu-carat", true ); 2752 2753 item 2754 .attr( "aria-haspopup", "true" ) 2755 .prepend( submenuCarat ); 2756 menu.attr( "aria-labelledby", item.attr( "id" ) ); 2757 }); 2758 2759 menus = submenus.add( this.element ); 2760 items = menus.find( this.options.items ); 2761 2762 // Initialize menu-items containing spaces and/or dashes only as dividers 2763 items.not( ".ui-menu-item" ).each(function() { 2764 var item = $( this ); 2765 if ( that._isDivider( item ) ) { 2766 item.addClass( "ui-widget-content ui-menu-divider" ); 2767 } 2768 }); 2769 2770 // Don't refresh list items that are already adapted 2771 items.not( ".ui-menu-item, .ui-menu-divider" ) 2772 .addClass( "ui-menu-item" ) 2773 .uniqueId() 2774 .attr({ 2775 tabIndex: -1, 2776 role: this._itemRole() 2777 }); 2778 2779 // Add aria-disabled attribute to any disabled menu item 2780 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 2781 2782 // If the active item has been removed, blur the menu 2783 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 2784 this.blur(); 2785 } 2786 }, 2787 2788 _itemRole: function() { 2789 return { 2790 menu: "menuitem", 2791 listbox: "option" 2792 }[ this.options.role ]; 2793 }, 2794 2795 _setOption: function( key, value ) { 2796 if ( key === "icons" ) { 2797 this.element.find( ".ui-menu-icon" ) 2798 .removeClass( this.options.icons.submenu ) 2799 .addClass( value.submenu ); 2800 } 2801 if ( key === "disabled" ) { 2802 this.element 2803 .toggleClass( "ui-state-disabled", !!value ) 2804 .attr( "aria-disabled", value ); 2805 } 2806 this._super( key, value ); 2807 }, 2808 2809 focus: function( event, item ) { 2810 var nested, focused; 2811 this.blur( event, event && event.type === "focus" ); 2812 2813 this._scrollIntoView( item ); 2814 2815 this.active = item.first(); 2816 focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" ); 2817 // Only update aria-activedescendant if there's a role 2818 // otherwise we assume focus is managed elsewhere 2819 if ( this.options.role ) { 2820 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 2821 } 2822 2823 // Highlight active parent menu item, if any 2824 this.active 2825 .parent() 2826 .closest( ".ui-menu-item" ) 2827 .addClass( "ui-state-active" ); 2828 2829 if ( event && event.type === "keydown" ) { 2830 this._close(); 2831 } else { 2832 this.timer = this._delay(function() { 2833 this._close(); 2834 }, this.delay ); 2835 } 2836 2837 nested = item.children( ".ui-menu" ); 2838 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 2839 this._startOpening(nested); 2840 } 2841 this.activeMenu = item.parent(); 2842 2843 this._trigger( "focus", event, { item: item } ); 2844 }, 2845 2846 _scrollIntoView: function( item ) { 2847 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 2848 if ( this._hasScroll() ) { 2849 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 2850 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 2851 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 2852 scroll = this.activeMenu.scrollTop(); 2853 elementHeight = this.activeMenu.height(); 2854 itemHeight = item.outerHeight(); 2855 2856 if ( offset < 0 ) { 2857 this.activeMenu.scrollTop( scroll + offset ); 2858 } else if ( offset + itemHeight > elementHeight ) { 2859 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 2860 } 2861 } 2862 }, 2863 2864 blur: function( event, fromFocus ) { 2865 if ( !fromFocus ) { 2866 clearTimeout( this.timer ); 2867 } 2868 2869 if ( !this.active ) { 2870 return; 2871 } 2872 2873 this.active.removeClass( "ui-state-focus" ); 2874 this.active = null; 2875 2876 this._trigger( "blur", event, { item: this.active } ); 2877 }, 2878 2879 _startOpening: function( submenu ) { 2880 clearTimeout( this.timer ); 2881 2882 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 2883 // shift in the submenu position when mousing over the carat icon 2884 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 2885 return; 2886 } 2887 2888 this.timer = this._delay(function() { 2889 this._close(); 2890 this._open( submenu ); 2891 }, this.delay ); 2892 }, 2893 2894 _open: function( submenu ) { 2895 var position = $.extend({ 2896 of: this.active 2897 }, this.options.position ); 2898 2899 clearTimeout( this.timer ); 2900 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 2901 .hide() 2902 .attr( "aria-hidden", "true" ); 2903 2904 submenu 2905 .show() 2906 .removeAttr( "aria-hidden" ) 2907 .attr( "aria-expanded", "true" ) 2908 .position( position ); 2909 }, 2910 2911 collapseAll: function( event, all ) { 2912 clearTimeout( this.timer ); 2913 this.timer = this._delay(function() { 2914 // If we were passed an event, look for the submenu that contains the event 2915 var currentMenu = all ? this.element : 2916 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 2917 2918 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 2919 if ( !currentMenu.length ) { 2920 currentMenu = this.element; 2921 } 2922 2923 this._close( currentMenu ); 2924 2925 this.blur( event ); 2926 this.activeMenu = currentMenu; 2927 }, this.delay ); 2928 }, 2929 2930 // With no arguments, closes the currently active menu - if nothing is active 2931 // it closes all menus. If passed an argument, it will search for menus BELOW 2932 _close: function( startMenu ) { 2933 if ( !startMenu ) { 2934 startMenu = this.active ? this.active.parent() : this.element; 2935 } 2936 2937 startMenu 2938 .find( ".ui-menu" ) 2939 .hide() 2940 .attr( "aria-hidden", "true" ) 2941 .attr( "aria-expanded", "false" ) 2942 .end() 2943 .find( ".ui-state-active" ).not( ".ui-state-focus" ) 2944 .removeClass( "ui-state-active" ); 2945 }, 2946 2947 _closeOnDocumentClick: function( event ) { 2948 return !$( event.target ).closest( ".ui-menu" ).length; 2949 }, 2950 2951 _isDivider: function( item ) { 2952 2953 // Match hyphen, em dash, en dash 2954 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 2955 }, 2956 2957 collapse: function( event ) { 2958 var newItem = this.active && 2959 this.active.parent().closest( ".ui-menu-item", this.element ); 2960 if ( newItem && newItem.length ) { 2961 this._close(); 2962 this.focus( event, newItem ); 2963 } 2964 }, 2965 2966 expand: function( event ) { 2967 var newItem = this.active && 2968 this.active 2969 .children( ".ui-menu " ) 2970 .find( this.options.items ) 2971 .first(); 2972 2973 if ( newItem && newItem.length ) { 2974 this._open( newItem.parent() ); 2975 2976 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 2977 this._delay(function() { 2978 this.focus( event, newItem ); 2979 }); 2980 } 2981 }, 2982 2983 next: function( event ) { 2984 this._move( "next", "first", event ); 2985 }, 2986 2987 previous: function( event ) { 2988 this._move( "prev", "last", event ); 2989 }, 2990 2991 isFirstItem: function() { 2992 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 2993 }, 2994 2995 isLastItem: function() { 2996 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 2997 }, 2998 2999 _move: function( direction, filter, event ) { 3000 var next; 3001 if ( this.active ) { 3002 if ( direction === "first" || direction === "last" ) { 3003 next = this.active 3004 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 3005 .eq( -1 ); 3006 } else { 3007 next = this.active 3008 [ direction + "All" ]( ".ui-menu-item" ) 3009 .eq( 0 ); 3010 } 3011 } 3012 if ( !next || !next.length || !this.active ) { 3013 next = this.activeMenu.find( this.options.items )[ filter ](); 3014 } 3015 3016 this.focus( event, next ); 3017 }, 3018 3019 nextPage: function( event ) { 3020 var item, base, height; 3021 3022 if ( !this.active ) { 3023 this.next( event ); 3024 return; 3025 } 3026 if ( this.isLastItem() ) { 3027 return; 3028 } 3029 if ( this._hasScroll() ) { 3030 base = this.active.offset().top; 3031 height = this.element.height(); 3032 this.active.nextAll( ".ui-menu-item" ).each(function() { 3033 item = $( this ); 3034 return item.offset().top - base - height < 0; 3035 }); 3036 3037 this.focus( event, item ); 3038 } else { 3039 this.focus( event, this.activeMenu.find( this.options.items ) 3040 [ !this.active ? "first" : "last" ]() ); 3041 } 3042 }, 3043 3044 previousPage: function( event ) { 3045 var item, base, height; 3046 if ( !this.active ) { 3047 this.next( event ); 3048 return; 3049 } 3050 if ( this.isFirstItem() ) { 3051 return; 3052 } 3053 if ( this._hasScroll() ) { 3054 base = this.active.offset().top; 3055 height = this.element.height(); 3056 this.active.prevAll( ".ui-menu-item" ).each(function() { 3057 item = $( this ); 3058 return item.offset().top - base + height > 0; 3059 }); 3060 3061 this.focus( event, item ); 3062 } else { 3063 this.focus( event, this.activeMenu.find( this.options.items ).first() ); 3064 } 3065 }, 3066 3067 _hasScroll: function() { 3068 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 3069 }, 3070 3071 select: function( event ) { 3072 // TODO: It should never be possible to not have an active item at this 3073 // point, but the tests don't trigger mouseenter before click. 3074 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 3075 var ui = { item: this.active }; 3076 if ( !this.active.has( ".ui-menu" ).length ) { 3077 this.collapseAll( event, true ); 3078 } 3079 this._trigger( "select", event, ui ); 3080 } 3081}); 3082 3083 3084/*! 3085 * jQuery UI Autocomplete 1.11.1 3086 * http://jqueryui.com 3087 * 3088 * Copyright 2014 jQuery Foundation and other contributors 3089 * Released under the MIT license. 3090 * http://jquery.org/license 3091 * 3092 * http://api.jqueryui.com/autocomplete/ 3093 */ 3094 3095 3096$.widget( "ui.autocomplete", { 3097 version: "1.11.1", 3098 defaultElement: "<input>", 3099 options: { 3100 appendTo: null, 3101 autoFocus: false, 3102 delay: 300, 3103 minLength: 1, 3104 position: { 3105 my: "left top", 3106 at: "left bottom", 3107 collision: "none" 3108 }, 3109 source: null, 3110 3111 // callbacks 3112 change: null, 3113 close: null, 3114 focus: null, 3115 open: null, 3116 response: null, 3117 search: null, 3118 select: null 3119 }, 3120 3121 requestIndex: 0, 3122 pending: 0, 3123 3124 _create: function() { 3125 // Some browsers only repeat keydown events, not keypress events, 3126 // so we use the suppressKeyPress flag to determine if we've already 3127 // handled the keydown event. #7269 3128 // Unfortunately the code for & in keypress is the same as the up arrow, 3129 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 3130 // events when we know the keydown event was used to modify the 3131 // search term. #7799 3132 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 3133 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 3134 isTextarea = nodeName === "textarea", 3135 isInput = nodeName === "input"; 3136 3137 this.isMultiLine = 3138 // Textareas are always multi-line 3139 isTextarea ? true : 3140 // Inputs are always single-line, even if inside a contentEditable element 3141 // IE also treats inputs as contentEditable 3142 isInput ? false : 3143 // All other element types are determined by whether or not they're contentEditable 3144 this.element.prop( "isContentEditable" ); 3145 3146 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 3147 this.isNewMenu = true; 3148 3149 this.element 3150 .addClass( "ui-autocomplete-input" ) 3151 .attr( "autocomplete", "off" ); 3152 3153 this._on( this.element, { 3154 keydown: function( event ) { 3155 if ( this.element.prop( "readOnly" ) ) { 3156 suppressKeyPress = true; 3157 suppressInput = true; 3158 suppressKeyPressRepeat = true; 3159 return; 3160 } 3161 3162 suppressKeyPress = false; 3163 suppressInput = false; 3164 suppressKeyPressRepeat = false; 3165 var keyCode = $.ui.keyCode; 3166 switch ( event.keyCode ) { 3167 case keyCode.PAGE_UP: 3168 suppressKeyPress = true; 3169 this._move( "previousPage", event ); 3170 break; 3171 case keyCode.PAGE_DOWN: 3172 suppressKeyPress = true; 3173 this._move( "nextPage", event ); 3174 break; 3175 case keyCode.UP: 3176 suppressKeyPress = true; 3177 this._keyEvent( "previous", event ); 3178 break; 3179 case keyCode.DOWN: 3180 suppressKeyPress = true; 3181 this._keyEvent( "next", event ); 3182 break; 3183 case keyCode.ENTER: 3184 // when menu is open and has focus 3185 if ( this.menu.active ) { 3186 // #6055 - Opera still allows the keypress to occur 3187 // which causes forms to submit 3188 suppressKeyPress = true; 3189 event.preventDefault(); 3190 this.menu.select( event ); 3191 } 3192 break; 3193 case keyCode.TAB: 3194 if ( this.menu.active ) { 3195 this.menu.select( event ); 3196 } 3197 break; 3198 case keyCode.ESCAPE: 3199 if ( this.menu.element.is( ":visible" ) ) { 3200 if ( !this.isMultiLine ) { 3201 this._value( this.term ); 3202 } 3203 this.close( event ); 3204 // Different browsers have different default behavior for escape 3205 // Single press can mean undo or clear 3206 // Double press in IE means clear the whole form 3207 event.preventDefault(); 3208 } 3209 break; 3210 default: 3211 suppressKeyPressRepeat = true; 3212 // search timeout should be triggered before the input value is changed 3213 this._searchTimeout( event ); 3214 break; 3215 } 3216 }, 3217 keypress: function( event ) { 3218 if ( suppressKeyPress ) { 3219 suppressKeyPress = false; 3220 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 3221 event.preventDefault(); 3222 } 3223 return; 3224 } 3225 if ( suppressKeyPressRepeat ) { 3226 return; 3227 } 3228 3229 // replicate some key handlers to allow them to repeat in Firefox and Opera 3230 var keyCode = $.ui.keyCode; 3231 switch ( event.keyCode ) { 3232 case keyCode.PAGE_UP: 3233 this._move( "previousPage", event ); 3234 break; 3235 case keyCode.PAGE_DOWN: 3236 this._move( "nextPage", event ); 3237 break; 3238 case keyCode.UP: 3239 this._keyEvent( "previous", event ); 3240 break; 3241 case keyCode.DOWN: 3242 this._keyEvent( "next", event ); 3243 break; 3244 } 3245 }, 3246 input: function( event ) { 3247 if ( suppressInput ) { 3248 suppressInput = false; 3249 event.preventDefault(); 3250 return; 3251 } 3252 this._searchTimeout( event ); 3253 }, 3254 focus: function() { 3255 this.selectedItem = null; 3256 this.previous = this._value(); 3257 }, 3258 blur: function( event ) { 3259 if ( this.cancelBlur ) { 3260 delete this.cancelBlur; 3261 return; 3262 } 3263 3264 clearTimeout( this.searching ); 3265 this.close( event ); 3266 this._change( event ); 3267 } 3268 }); 3269 3270 this._initSource(); 3271 this.menu = $( "<ul>" ) 3272 .addClass( "ui-autocomplete ui-front" ) 3273 .appendTo( this._appendTo() ) 3274 .menu({ 3275 // disable ARIA support, the live region takes care of that 3276 role: null 3277 }) 3278 .hide() 3279 .menu( "instance" ); 3280 3281 this._on( this.menu.element, { 3282 mousedown: function( event ) { 3283 // prevent moving focus out of the text field 3284 event.preventDefault(); 3285 3286 // IE doesn't prevent moving focus even with event.preventDefault() 3287 // so we set a flag to know when we should ignore the blur event 3288 this.cancelBlur = true; 3289 this._delay(function() { 3290 delete this.cancelBlur; 3291 }); 3292 3293 // clicking on the scrollbar causes focus to shift to the body 3294 // but we can't detect a mouseup or a click immediately afterward 3295 // so we have to track the next mousedown and close the menu if 3296 // the user clicks somewhere outside of the autocomplete 3297 var menuElement = this.menu.element[ 0 ]; 3298 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 3299 this._delay(function() { 3300 var that = this; 3301 this.document.one( "mousedown", function( event ) { 3302 if ( event.target !== that.element[ 0 ] && 3303 event.target !== menuElement && 3304 !$.contains( menuElement, event.target ) ) { 3305 that.close(); 3306 } 3307 }); 3308 }); 3309 } 3310 }, 3311 menufocus: function( event, ui ) { 3312 var label, item; 3313 // support: Firefox 3314 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 3315 if ( this.isNewMenu ) { 3316 this.isNewMenu = false; 3317 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 3318 this.menu.blur(); 3319 3320 this.document.one( "mousemove", function() { 3321 $( event.target ).trigger( event.originalEvent ); 3322 }); 3323 3324 return; 3325 } 3326 } 3327 3328 item = ui.item.data( "ui-autocomplete-item" ); 3329 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 3330 // use value to match what will end up in the input, if it was a key event 3331 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 3332 this._value( item.value ); 3333 } 3334 } 3335 3336 // Announce the value in the liveRegion 3337 label = ui.item.attr( "aria-label" ) || item.value; 3338 if ( label && $.trim( label ).length ) { 3339 this.liveRegion.children().hide(); 3340 $( "<div>" ).text( label ).appendTo( this.liveRegion ); 3341 } 3342 }, 3343 menuselect: function( event, ui ) { 3344 var item = ui.item.data( "ui-autocomplete-item" ), 3345 previous = this.previous; 3346 3347 // only trigger when focus was lost (click on menu) 3348 if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { 3349 this.element.focus(); 3350 this.previous = previous; 3351 // #6109 - IE triggers two focus events and the second 3352 // is asynchronous, so we need to reset the previous 3353 // term synchronously and asynchronously :-( 3354 this._delay(function() { 3355 this.previous = previous; 3356 this.selectedItem = item; 3357 }); 3358 } 3359 3360 if ( false !== this._trigger( "select", event, { item: item } ) ) { 3361 this._value( item.value ); 3362 } 3363 // reset the term after the select event 3364 // this allows custom select handling to work properly 3365 this.term = this._value(); 3366 3367 this.close( event ); 3368 this.selectedItem = item; 3369 } 3370 }); 3371 3372 this.liveRegion = $( "<span>", { 3373 role: "status", 3374 "aria-live": "assertive", 3375 "aria-relevant": "additions" 3376 }) 3377 .addClass( "ui-helper-hidden-accessible" ) 3378 .appendTo( this.document[ 0 ].body ); 3379 3380 // turning off autocomplete prevents the browser from remembering the 3381 // value when navigating through history, so we re-enable autocomplete 3382 // if the page is unloaded before the widget is destroyed. #7790 3383 this._on( this.window, { 3384 beforeunload: function() { 3385 this.element.removeAttr( "autocomplete" ); 3386 } 3387 }); 3388 }, 3389 3390 _destroy: function() { 3391 clearTimeout( this.searching ); 3392 this.element 3393 .removeClass( "ui-autocomplete-input" ) 3394 .removeAttr( "autocomplete" ); 3395 this.menu.element.remove(); 3396 this.liveRegion.remove(); 3397 }, 3398 3399 _setOption: function( key, value ) { 3400 this._super( key, value ); 3401 if ( key === "source" ) { 3402 this._initSource(); 3403 } 3404 if ( key === "appendTo" ) { 3405 this.menu.element.appendTo( this._appendTo() ); 3406 } 3407 if ( key === "disabled" && value && this.xhr ) { 3408 this.xhr.abort(); 3409 } 3410 }, 3411 3412 _appendTo: function() { 3413 var element = this.options.appendTo; 3414 3415 if ( element ) { 3416 element = element.jquery || element.nodeType ? 3417 $( element ) : 3418 this.document.find( element ).eq( 0 ); 3419 } 3420 3421 if ( !element || !element[ 0 ] ) { 3422 element = this.element.closest( ".ui-front" ); 3423 } 3424 3425 if ( !element.length ) { 3426 element = this.document[ 0 ].body; 3427 } 3428 3429 return element; 3430 }, 3431 3432 _initSource: function() { 3433 var array, url, 3434 that = this; 3435 if ( $.isArray( this.options.source ) ) { 3436 array = this.options.source; 3437 this.source = function( request, response ) { 3438 response( $.ui.autocomplete.filter( array, request.term ) ); 3439 }; 3440 } else if ( typeof this.options.source === "string" ) { 3441 url = this.options.source; 3442 this.source = function( request, response ) { 3443 if ( that.xhr ) { 3444 that.xhr.abort(); 3445 } 3446 that.xhr = $.ajax({ 3447 url: url, 3448 data: request, 3449 dataType: "json", 3450 success: function( data ) { 3451 response( data ); 3452 }, 3453 error: function() { 3454 response([]); 3455 } 3456 }); 3457 }; 3458 } else { 3459 this.source = this.options.source; 3460 } 3461 }, 3462 3463 _searchTimeout: function( event ) { 3464 clearTimeout( this.searching ); 3465 this.searching = this._delay(function() { 3466 3467 // Search if the value has changed, or if the user retypes the same value (see #7434) 3468 var equalValues = this.term === this._value(), 3469 menuVisible = this.menu.element.is( ":visible" ), 3470 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 3471 3472 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 3473 this.selectedItem = null; 3474 this.search( null, event ); 3475 } 3476 }, this.options.delay ); 3477 }, 3478 3479 search: function( value, event ) { 3480 value = value != null ? value : this._value(); 3481 3482 // always save the actual value, not the one passed as an argument 3483 this.term = this._value(); 3484 3485 if ( value.length < this.options.minLength ) { 3486 return this.close( event ); 3487 } 3488 3489 if ( this._trigger( "search", event ) === false ) { 3490 return; 3491 } 3492 3493 return this._search( value ); 3494 }, 3495 3496 _search: function( value ) { 3497 this.pending++; 3498 this.element.addClass( "ui-autocomplete-loading" ); 3499 this.cancelSearch = false; 3500 3501 this.source( { term: value }, this._response() ); 3502 }, 3503 3504 _response: function() { 3505 var index = ++this.requestIndex; 3506 3507 return $.proxy(function( content ) { 3508 if ( index === this.requestIndex ) { 3509 this.__response( content ); 3510 } 3511 3512 this.pending--; 3513 if ( !this.pending ) { 3514 this.element.removeClass( "ui-autocomplete-loading" ); 3515 } 3516 }, this ); 3517 }, 3518 3519 __response: function( content ) { 3520 if ( content ) { 3521 content = this._normalize( content ); 3522 } 3523 this._trigger( "response", null, { content: content } ); 3524 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 3525 this._suggest( content ); 3526 this._trigger( "open" ); 3527 } else { 3528 // use ._close() instead of .close() so we don't cancel future searches 3529 this._close(); 3530 } 3531 }, 3532 3533 close: function( event ) { 3534 this.cancelSearch = true; 3535 this._close( event ); 3536 }, 3537 3538 _close: function( event ) { 3539 if ( this.menu.element.is( ":visible" ) ) { 3540 this.menu.element.hide(); 3541 this.menu.blur(); 3542 this.isNewMenu = true; 3543 this._trigger( "close", event ); 3544 } 3545 }, 3546 3547 _change: function( event ) { 3548 if ( this.previous !== this._value() ) { 3549 this._trigger( "change", event, { item: this.selectedItem } ); 3550 } 3551 }, 3552 3553 _normalize: function( items ) { 3554 // assume all items have the right format when the first item is complete 3555 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 3556 return items; 3557 } 3558 return $.map( items, function( item ) { 3559 if ( typeof item === "string" ) { 3560 return { 3561 label: item, 3562 value: item 3563 }; 3564 } 3565 return $.extend( {}, item, { 3566 label: item.label || item.value, 3567 value: item.value || item.label 3568 }); 3569 }); 3570 }, 3571 3572 _suggest: function( items ) { 3573 var ul = this.menu.element.empty(); 3574 this._renderMenu( ul, items ); 3575 this.isNewMenu = true; 3576 this.menu.refresh(); 3577 3578 // size and position menu 3579 ul.show(); 3580 this._resizeMenu(); 3581 ul.position( $.extend({ 3582 of: this.element 3583 }, this.options.position ) ); 3584 3585 if ( this.options.autoFocus ) { 3586 this.menu.next(); 3587 } 3588 }, 3589 3590 _resizeMenu: function() { 3591 var ul = this.menu.element; 3592 ul.outerWidth( Math.max( 3593 // Firefox wraps long text (possibly a rounding bug) 3594 // so we add 1px to avoid the wrapping (#7513) 3595 ul.width( "" ).outerWidth() + 1, 3596 this.element.outerWidth() 3597 ) ); 3598 }, 3599 3600 _renderMenu: function( ul, items ) { 3601 var that = this; 3602 $.each( items, function( index, item ) { 3603 that._renderItemData( ul, item ); 3604 }); 3605 }, 3606 3607 _renderItemData: function( ul, item ) { 3608 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 3609 }, 3610 3611 _renderItem: function( ul, item ) { 3612 return $( "<li>" ).text( item.label ).appendTo( ul ); 3613 }, 3614 3615 _move: function( direction, event ) { 3616 if ( !this.menu.element.is( ":visible" ) ) { 3617 this.search( null, event ); 3618 return; 3619 } 3620 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 3621 this.menu.isLastItem() && /^next/.test( direction ) ) { 3622 3623 if ( !this.isMultiLine ) { 3624 this._value( this.term ); 3625 } 3626 3627 this.menu.blur(); 3628 return; 3629 } 3630 this.menu[ direction ]( event ); 3631 }, 3632 3633 widget: function() { 3634 return this.menu.element; 3635 }, 3636 3637 _value: function() { 3638 return this.valueMethod.apply( this.element, arguments ); 3639 }, 3640 3641 _keyEvent: function( keyEvent, event ) { 3642 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 3643 this._move( keyEvent, event ); 3644 3645 // prevents moving cursor to beginning/end of the text field in some browsers 3646 event.preventDefault(); 3647 } 3648 } 3649}); 3650 3651$.extend( $.ui.autocomplete, { 3652 escapeRegex: function( value ) { 3653 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 3654 }, 3655 filter: function( array, term ) { 3656 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 3657 return $.grep( array, function( value ) { 3658 return matcher.test( value.label || value.value || value ); 3659 }); 3660 } 3661}); 3662 3663// live region extension, adding a `messages` option 3664// NOTE: This is an experimental API. We are still investigating 3665// a full solution for string manipulation and internationalization. 3666$.widget( "ui.autocomplete", $.ui.autocomplete, { 3667 options: { 3668 messages: { 3669 noResults: "No search results.", 3670 results: function( amount ) { 3671 return amount + ( amount > 1 ? " results are" : " result is" ) + 3672 " available, use up and down arrow keys to navigate."; 3673 } 3674 } 3675 }, 3676 3677 __response: function( content ) { 3678 var message; 3679 this._superApply( arguments ); 3680 if ( this.options.disabled || this.cancelSearch ) { 3681 return; 3682 } 3683 if ( content && content.length ) { 3684 message = this.options.messages.results( content.length ); 3685 } else { 3686 message = this.options.messages.noResults; 3687 } 3688 this.liveRegion.children().hide(); 3689 $( "<div>" ).text( message ).appendTo( this.liveRegion ); 3690 } 3691}); 3692 3693var autocomplete = $.ui.autocomplete; 3694 3695 3696/*! 3697 * jQuery UI Button 1.11.1 3698 * http://jqueryui.com 3699 * 3700 * Copyright 2014 jQuery Foundation and other contributors 3701 * Released under the MIT license. 3702 * http://jquery.org/license 3703 * 3704 * http://api.jqueryui.com/button/ 3705 */ 3706 3707 3708var lastActive, 3709 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 3710 typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", 3711 formResetHandler = function() { 3712 var form = $( this ); 3713 setTimeout(function() { 3714 form.find( ":ui-button" ).button( "refresh" ); 3715 }, 1 ); 3716 }, 3717 radioGroup = function( radio ) { 3718 var name = radio.name, 3719 form = radio.form, 3720 radios = $( [] ); 3721 if ( name ) { 3722 name = name.replace( /'/g, "\\'" ); 3723 if ( form ) { 3724 radios = $( form ).find( "[name='" + name + "'][type=radio]" ); 3725 } else { 3726 radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument ) 3727 .filter(function() { 3728 return !this.form; 3729 }); 3730 } 3731 } 3732 return radios; 3733 }; 3734 3735$.widget( "ui.button", { 3736 version: "1.11.1", 3737 defaultElement: "<button>", 3738 options: { 3739 disabled: null, 3740 text: true, 3741 label: null, 3742 icons: { 3743 primary: null, 3744 secondary: null 3745 } 3746 }, 3747 _create: function() { 3748 this.element.closest( "form" ) 3749 .unbind( "reset" + this.eventNamespace ) 3750 .bind( "reset" + this.eventNamespace, formResetHandler ); 3751 3752 if ( typeof this.options.disabled !== "boolean" ) { 3753 this.options.disabled = !!this.element.prop( "disabled" ); 3754 } else { 3755 this.element.prop( "disabled", this.options.disabled ); 3756 } 3757 3758 this._determineButtonType(); 3759 this.hasTitle = !!this.buttonElement.attr( "title" ); 3760 3761 var that = this, 3762 options = this.options, 3763 toggleButton = this.type === "checkbox" || this.type === "radio", 3764 activeClass = !toggleButton ? "ui-state-active" : ""; 3765 3766 if ( options.label === null ) { 3767 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 3768 } 3769 3770 this._hoverable( this.buttonElement ); 3771 3772 this.buttonElement 3773 .addClass( baseClasses ) 3774 .attr( "role", "button" ) 3775 .bind( "mouseenter" + this.eventNamespace, function() { 3776 if ( options.disabled ) { 3777 return; 3778 } 3779 if ( this === lastActive ) { 3780 $( this ).addClass( "ui-state-active" ); 3781 } 3782 }) 3783 .bind( "mouseleave" + this.eventNamespace, function() { 3784 if ( options.disabled ) { 3785 return; 3786 } 3787 $( this ).removeClass( activeClass ); 3788 }) 3789 .bind( "click" + this.eventNamespace, function( event ) { 3790 if ( options.disabled ) { 3791 event.preventDefault(); 3792 event.stopImmediatePropagation(); 3793 } 3794 }); 3795 3796 // Can't use _focusable() because the element that receives focus 3797 // and the element that gets the ui-state-focus class are different 3798 this._on({ 3799 focus: function() { 3800 this.buttonElement.addClass( "ui-state-focus" ); 3801 }, 3802 blur: function() { 3803 this.buttonElement.removeClass( "ui-state-focus" ); 3804 } 3805 }); 3806 3807 if ( toggleButton ) { 3808 this.element.bind( "change" + this.eventNamespace, function() { 3809 that.refresh(); 3810 }); 3811 } 3812 3813 if ( this.type === "checkbox" ) { 3814 this.buttonElement.bind( "click" + this.eventNamespace, function() { 3815 if ( options.disabled ) { 3816 return false; 3817 } 3818 }); 3819 } else if ( this.type === "radio" ) { 3820 this.buttonElement.bind( "click" + this.eventNamespace, function() { 3821 if ( options.disabled ) { 3822 return false; 3823 } 3824 $( this ).addClass( "ui-state-active" ); 3825 that.buttonElement.attr( "aria-pressed", "true" ); 3826 3827 var radio = that.element[ 0 ]; 3828 radioGroup( radio ) 3829 .not( radio ) 3830 .map(function() { 3831 return $( this ).button( "widget" )[ 0 ]; 3832 }) 3833 .removeClass( "ui-state-active" ) 3834 .attr( "aria-pressed", "false" ); 3835 }); 3836 } else { 3837 this.buttonElement 3838 .bind( "mousedown" + this.eventNamespace, function() { 3839 if ( options.disabled ) { 3840 return false; 3841 } 3842 $( this ).addClass( "ui-state-active" ); 3843 lastActive = this; 3844 that.document.one( "mouseup", function() { 3845 lastActive = null; 3846 }); 3847 }) 3848 .bind( "mouseup" + this.eventNamespace, function() { 3849 if ( options.disabled ) { 3850 return false; 3851 } 3852 $( this ).removeClass( "ui-state-active" ); 3853 }) 3854 .bind( "keydown" + this.eventNamespace, function(event) { 3855 if ( options.disabled ) { 3856 return false; 3857 } 3858 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 3859 $( this ).addClass( "ui-state-active" ); 3860 } 3861 }) 3862 // see #8559, we bind to blur here in case the button element loses 3863 // focus between keydown and keyup, it would be left in an "active" state 3864 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 3865 $( this ).removeClass( "ui-state-active" ); 3866 }); 3867 3868 if ( this.buttonElement.is("a") ) { 3869 this.buttonElement.keyup(function(event) { 3870 if ( event.keyCode === $.ui.keyCode.SPACE ) { 3871 // TODO pass through original event correctly (just as 2nd argument doesn't work) 3872 $( this ).click(); 3873 } 3874 }); 3875 } 3876 } 3877 3878 this._setOption( "disabled", options.disabled ); 3879 this._resetButton(); 3880 }, 3881 3882 _determineButtonType: function() { 3883 var ancestor, labelSelector, checked; 3884 3885 if ( this.element.is("[type=checkbox]") ) { 3886 this.type = "checkbox"; 3887 } else if ( this.element.is("[type=radio]") ) { 3888 this.type = "radio"; 3889 } else if ( this.element.is("input") ) { 3890 this.type = "input"; 3891 } else { 3892 this.type = "button"; 3893 } 3894 3895 if ( this.type === "checkbox" || this.type === "radio" ) { 3896 // we don't search against the document in case the element 3897 // is disconnected from the DOM 3898 ancestor = this.element.parents().last(); 3899 labelSelector = "label[for='" + this.element.attr("id") + "']"; 3900 this.buttonElement = ancestor.find( labelSelector ); 3901 if ( !this.buttonElement.length ) { 3902 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 3903 this.buttonElement = ancestor.filter( labelSelector ); 3904 if ( !this.buttonElement.length ) { 3905 this.buttonElement = ancestor.find( labelSelector ); 3906 } 3907 } 3908 this.element.addClass( "ui-helper-hidden-accessible" ); 3909 3910 checked = this.element.is( ":checked" ); 3911 if ( checked ) { 3912 this.buttonElement.addClass( "ui-state-active" ); 3913 } 3914 this.buttonElement.prop( "aria-pressed", checked ); 3915 } else { 3916 this.buttonElement = this.element; 3917 } 3918 }, 3919 3920 widget: function() { 3921 return this.buttonElement; 3922 }, 3923 3924 _destroy: function() { 3925 this.element 3926 .removeClass( "ui-helper-hidden-accessible" ); 3927 this.buttonElement 3928 .removeClass( baseClasses + " ui-state-active " + typeClasses ) 3929 .removeAttr( "role" ) 3930 .removeAttr( "aria-pressed" ) 3931 .html( this.buttonElement.find(".ui-button-text").html() ); 3932 3933 if ( !this.hasTitle ) { 3934 this.buttonElement.removeAttr( "title" ); 3935 } 3936 }, 3937 3938 _setOption: function( key, value ) { 3939 this._super( key, value ); 3940 if ( key === "disabled" ) { 3941 this.widget().toggleClass( "ui-state-disabled", !!value ); 3942 this.element.prop( "disabled", !!value ); 3943 if ( value ) { 3944 if ( this.type === "checkbox" || this.type === "radio" ) { 3945 this.buttonElement.removeClass( "ui-state-focus" ); 3946 } else { 3947 this.buttonElement.removeClass( "ui-state-focus ui-state-active" ); 3948 } 3949 } 3950 return; 3951 } 3952 this._resetButton(); 3953 }, 3954 3955 refresh: function() { 3956 //See #8237 & #8828 3957 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 3958 3959 if ( isDisabled !== this.options.disabled ) { 3960 this._setOption( "disabled", isDisabled ); 3961 } 3962 if ( this.type === "radio" ) { 3963 radioGroup( this.element[0] ).each(function() { 3964 if ( $( this ).is( ":checked" ) ) { 3965 $( this ).button( "widget" ) 3966 .addClass( "ui-state-active" ) 3967 .attr( "aria-pressed", "true" ); 3968 } else { 3969 $( this ).button( "widget" ) 3970 .removeClass( "ui-state-active" ) 3971 .attr( "aria-pressed", "false" ); 3972 } 3973 }); 3974 } else if ( this.type === "checkbox" ) { 3975 if ( this.element.is( ":checked" ) ) { 3976 this.buttonElement 3977 .addClass( "ui-state-active" ) 3978 .attr( "aria-pressed", "true" ); 3979 } else { 3980 this.buttonElement 3981 .removeClass( "ui-state-active" ) 3982 .attr( "aria-pressed", "false" ); 3983 } 3984 } 3985 }, 3986 3987 _resetButton: function() { 3988 if ( this.type === "input" ) { 3989 if ( this.options.label ) { 3990 this.element.val( this.options.label ); 3991 } 3992 return; 3993 } 3994 var buttonElement = this.buttonElement.removeClass( typeClasses ), 3995 buttonText = $( "<span></span>", this.document[0] ) 3996 .addClass( "ui-button-text" ) 3997 .html( this.options.label ) 3998 .appendTo( buttonElement.empty() ) 3999 .text(), 4000 icons = this.options.icons, 4001 multipleIcons = icons.primary && icons.secondary, 4002 buttonClasses = []; 4003 4004 if ( icons.primary || icons.secondary ) { 4005 if ( this.options.text ) { 4006 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 4007 } 4008 4009 if ( icons.primary ) { 4010 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 4011 } 4012 4013 if ( icons.secondary ) { 4014 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 4015 } 4016 4017 if ( !this.options.text ) { 4018 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 4019 4020 if ( !this.hasTitle ) { 4021 buttonElement.attr( "title", $.trim( buttonText ) ); 4022 } 4023 } 4024 } else { 4025 buttonClasses.push( "ui-button-text-only" ); 4026 } 4027 buttonElement.addClass( buttonClasses.join( " " ) ); 4028 } 4029}); 4030 4031$.widget( "ui.buttonset", { 4032 version: "1.11.1", 4033 options: { 4034 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 4035 }, 4036 4037 _create: function() { 4038 this.element.addClass( "ui-buttonset" ); 4039 }, 4040 4041 _init: function() { 4042 this.refresh(); 4043 }, 4044 4045 _setOption: function( key, value ) { 4046 if ( key === "disabled" ) { 4047 this.buttons.button( "option", key, value ); 4048 } 4049 4050 this._super( key, value ); 4051 }, 4052 4053 refresh: function() { 4054 var rtl = this.element.css( "direction" ) === "rtl", 4055 allButtons = this.element.find( this.options.items ), 4056 existingButtons = allButtons.filter( ":ui-button" ); 4057 4058 // Initialize new buttons 4059 allButtons.not( ":ui-button" ).button(); 4060 4061 // Refresh existing buttons 4062 existingButtons.button( "refresh" ); 4063 4064 this.buttons = allButtons 4065 .map(function() { 4066 return $( this ).button( "widget" )[ 0 ]; 4067 }) 4068 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 4069 .filter( ":first" ) 4070 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 4071 .end() 4072 .filter( ":last" ) 4073 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 4074 .end() 4075 .end(); 4076 }, 4077 4078 _destroy: function() { 4079 this.element.removeClass( "ui-buttonset" ); 4080 this.buttons 4081 .map(function() { 4082 return $( this ).button( "widget" )[ 0 ]; 4083 }) 4084 .removeClass( "ui-corner-left ui-corner-right" ) 4085 .end() 4086 .button( "destroy" ); 4087 } 4088}); 4089 4090var button = $.ui.button; 4091 4092 4093/*! 4094 * jQuery UI Datepicker 1.11.1 4095 * http://jqueryui.com 4096 * 4097 * Copyright 2014 jQuery Foundation and other contributors 4098 * Released under the MIT license. 4099 * http://jquery.org/license 4100 * 4101 * http://api.jqueryui.com/datepicker/ 4102 */ 4103 4104 4105$.extend($.ui, { datepicker: { version: "1.11.1" } }); 4106 4107var datepicker_instActive; 4108 4109function datepicker_getZindex( elem ) { 4110 var position, value; 4111 while ( elem.length && elem[ 0 ] !== document ) { 4112 // Ignore z-index if position is set to a value where z-index is ignored by the browser 4113 // This makes behavior of this function consistent across browsers 4114 // WebKit always returns auto if the element is positioned 4115 position = elem.css( "position" ); 4116 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 4117 // IE returns 0 when zIndex is not specified 4118 // other browsers return a string 4119 // we ignore the case of nested elements with an explicit value of 0 4120 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 4121 value = parseInt( elem.css( "zIndex" ), 10 ); 4122 if ( !isNaN( value ) && value !== 0 ) { 4123 return value; 4124 } 4125 } 4126 elem = elem.parent(); 4127 } 4128 4129 return 0; 4130} 4131/* Date picker manager. 4132 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 4133 Settings for (groups of) date pickers are maintained in an instance object, 4134 allowing multiple different settings on the same page. */ 4135 4136function Datepicker() { 4137 this._curInst = null; // The current instance in use 4138 this._keyEvent = false; // If the last event was a key event 4139 this._disabledInputs = []; // List of date picker inputs that have been disabled 4140 this._datepickerShowing = false; // True if the popup picker is showing , false if not 4141 this._inDialog = false; // True if showing within a "dialog", false if not 4142 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 4143 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 4144 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 4145 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 4146 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 4147 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 4148 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 4149 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 4150 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 4151 this.regional = []; // Available regional settings, indexed by language code 4152 this.regional[""] = { // Default regional settings 4153 closeText: "Done", // Display text for close link 4154 prevText: "Prev", // Display text for previous month link 4155 nextText: "Next", // Display text for next month link 4156 currentText: "Today", // Display text for current month link 4157 monthNames: ["January","February","March","April","May","June", 4158 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 4159 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 4160 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 4161 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 4162 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 4163 weekHeader: "Wk", // Column header for week of the year 4164 dateFormat: "mm/dd/yy", // See format options on parseDate 4165 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 4166 isRTL: false, // True if right-to-left language, false if left-to-right 4167 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 4168 yearSuffix: "" // Additional text to append to the year in the month headers 4169 }; 4170 this._defaults = { // Global defaults for all the date picker instances 4171 showOn: "focus", // "focus" for popup on focus, 4172 // "button" for trigger button, or "both" for either
vendor: 12,329 bytes, lines 4173-4460
4173 showAnim: "fadeIn", // Name of jQuery animation for popup 4174 showOptions: {}, // Options for enhanced animations 4175 defaultDate: null, // Used when field is blank: actual date, 4176 // +/-number for offset from today, null for today 4177 appendText: "", // Display text following the input box, e.g. showing the format 4178 buttonText: "...", // Text for trigger button 4179 buttonImage: "", // URL for trigger button image 4180 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 4181 hideIfNoPrevNext: false, // True to hide next/previous month links 4182 // if not applicable, false to just disable them 4183 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 4184 gotoCurrent: false, // True if today link goes back to current selection instead 4185 changeMonth: false, // True if month can be selected directly, false if only prev/next 4186 changeYear: false, // True if year can be selected directly, false if only prev/next 4187 yearRange: "c-10:c+10", // Range of years to display in drop-down, 4188 // either relative to today's year (-nn:+nn), relative to currently displayed year 4189 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 4190 showOtherMonths: false, // True to show dates in other months, false to leave blank 4191 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 4192 showWeek: false, // True to show week of the year, false to not show it 4193 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 4194 // takes a Date and returns the number of the week for it 4195 shortYearCutoff: "+10", // Short year values < this are in the current century, 4196 // > this are in the previous century, 4197 // string value starting with "+" for current year + value 4198 minDate: null, // The earliest selectable date, or null for no limit 4199 maxDate: null, // The latest selectable date, or null for no limit 4200 duration: "fast", // Duration of display/closure 4201 beforeShowDay: null, // Function that takes a date and returns an array with 4202 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 4203 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 4204 beforeShow: null, // Function that takes an input field and 4205 // returns a set of custom settings for the date picker 4206 onSelect: null, // Define a callback function when a date is selected 4207 onChangeMonthYear: null, // Define a callback function when the month or year is changed 4208 onClose: null, // Define a callback function when the datepicker is closed 4209 numberOfMonths: 1, // Number of months to show at a time 4210 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 4211 stepMonths: 1, // Number of months to step back/forward 4212 stepBigMonths: 12, // Number of months to step back/forward for the big links 4213 altField: "", // Selector for an alternate field to store selected dates into 4214 altFormat: "", // The date format to use for the alternate field 4215 constrainInput: true, // The input is constrained by the current date format 4216 showButtonPanel: false, // True to show button panel, false to not show it 4217 autoSize: false, // True to size the input for the date format, false to leave as is 4218 disabled: false // The initial disabled state 4219 }; 4220 $.extend(this._defaults, this.regional[""]); 4221 this.regional.en = $.extend( true, {}, this.regional[ "" ]); 4222 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 4223 this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 4224} 4225 4226$.extend(Datepicker.prototype, { 4227 /* Class name added to elements to indicate already configured with a date picker. */ 4228 markerClassName: "hasDatepicker", 4229 4230 //Keep track of the maximum number of rows displayed (see #7043) 4231 maxRows: 4, 4232 4233 // TODO rename to "widget" when switching to widget factory 4234 _widgetDatepicker: function() { 4235 return this.dpDiv; 4236 }, 4237 4238 /* Override the default settings for all instances of the date picker. 4239 * @param settings object - the new settings to use as defaults (anonymous object) 4240 * @return the manager object 4241 */ 4242 setDefaults: function(settings) { 4243 datepicker_extendRemove(this._defaults, settings || {}); 4244 return this; 4245 }, 4246 4247 /* Attach the date picker to a jQuery selection. 4248 * @param target element - the target input field or division or span 4249 * @param settings object - the new settings to use for this date picker instance (anonymous) 4250 */ 4251 _attachDatepicker: function(target, settings) { 4252 var nodeName, inline, inst; 4253 nodeName = target.nodeName.toLowerCase(); 4254 inline = (nodeName === "div" || nodeName === "span"); 4255 if (!target.id) { 4256 this.uuid += 1; 4257 target.id = "dp" + this.uuid; 4258 } 4259 inst = this._newInst($(target), inline); 4260 inst.settings = $.extend({}, settings || {}); 4261 if (nodeName === "input") { 4262 this._connectDatepicker(target, inst); 4263 } else if (inline) { 4264 this._inlineDatepicker(target, inst); 4265 } 4266 }, 4267 4268 /* Create a new instance object. */ 4269 _newInst: function(target, inline) { 4270 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 4271 return {id: id, input: target, // associated target 4272 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 4273 drawMonth: 0, drawYear: 0, // month being drawn 4274 inline: inline, // is datepicker inline or not 4275 dpDiv: (!inline ? this.dpDiv : // presentation div 4276 datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 4277 }, 4278 4279 /* Attach the date picker to an input field. */ 4280 _connectDatepicker: function(target, inst) { 4281 var input = $(target); 4282 inst.append = $([]); 4283 inst.trigger = $([]); 4284 if (input.hasClass(this.markerClassName)) { 4285 return; 4286 } 4287 this._attachments(input, inst); 4288 input.addClass(this.markerClassName).keydown(this._doKeyDown). 4289 keypress(this._doKeyPress).keyup(this._doKeyUp); 4290 this._autoSize(inst); 4291 $.data(target, "datepicker", inst); 4292 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 4293 if( inst.settings.disabled ) { 4294 this._disableDatepicker( target ); 4295 } 4296 }, 4297 4298 /* Make attachments based on settings. */ 4299 _attachments: function(input, inst) { 4300 var showOn, buttonText, buttonImage, 4301 appendText = this._get(inst, "appendText"), 4302 isRTL = this._get(inst, "isRTL"); 4303 4304 if (inst.append) { 4305 inst.append.remove(); 4306 } 4307 if (appendText) { 4308 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 4309 input[isRTL ? "before" : "after"](inst.append); 4310 } 4311 4312 input.unbind("focus", this._showDatepicker); 4313 4314 if (inst.trigger) { 4315 inst.trigger.remove(); 4316 } 4317 4318 showOn = this._get(inst, "showOn"); 4319 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 4320 input.focus(this._showDatepicker); 4321 } 4322 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 4323 buttonText = this._get(inst, "buttonText"); 4324 buttonImage = this._get(inst, "buttonImage"); 4325 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 4326 $("<img/>").addClass(this._triggerClass). 4327 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 4328 $("<button type='button'></button>").addClass(this._triggerClass). 4329 html(!buttonImage ? buttonText : $("<img/>").attr( 4330 { src:buttonImage, alt:buttonText, title:buttonText }))); 4331 input[isRTL ? "before" : "after"](inst.trigger); 4332 inst.trigger.click(function() { 4333 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 4334 $.datepicker._hideDatepicker(); 4335 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 4336 $.datepicker._hideDatepicker(); 4337 $.datepicker._showDatepicker(input[0]); 4338 } else { 4339 $.datepicker._showDatepicker(input[0]); 4340 } 4341 return false; 4342 }); 4343 } 4344 }, 4345 4346 /* Apply the maximum length for the date format. */ 4347 _autoSize: function(inst) { 4348 if (this._get(inst, "autoSize") && !inst.inline) { 4349 var findMax, max, maxI, i, 4350 date = new Date(2009, 12 - 1, 20), // Ensure double digits 4351 dateFormat = this._get(inst, "dateFormat"); 4352 4353 if (dateFormat.match(/[DM]/)) { 4354 findMax = function(names) { 4355 max = 0; 4356 maxI = 0; 4357 for (i = 0; i < names.length; i++) { 4358 if (names[i].length > max) { 4359 max = names[i].length; 4360 maxI = i; 4361 } 4362 } 4363 return maxI; 4364 }; 4365 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 4366 "monthNames" : "monthNamesShort")))); 4367 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 4368 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 4369 } 4370 inst.input.attr("size", this._formatDate(inst, date).length); 4371 } 4372 }, 4373 4374 /* Attach an inline date picker to a div. */ 4375 _inlineDatepicker: function(target, inst) { 4376 var divSpan = $(target); 4377 if (divSpan.hasClass(this.markerClassName)) { 4378 return; 4379 } 4380 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 4381 $.data(target, "datepicker", inst); 4382 this._setDate(inst, this._getDefaultDate(inst), true); 4383 this._updateDatepicker(inst); 4384 this._updateAlternate(inst); 4385 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 4386 if( inst.settings.disabled ) { 4387 this._disableDatepicker( target ); 4388 } 4389 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 4390 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 4391 inst.dpDiv.css( "display", "block" ); 4392 }, 4393 4394 /* Pop-up the date picker in a "dialog" box. 4395 * @param input element - ignored 4396 * @param date string or Date - the initial date to display 4397 * @param onSelect function - the function to call when a date is selected 4398 * @param settings object - update the dialog date picker instance's settings (anonymous object) 4399 * @param pos int[2] - coordinates for the dialog's position within the screen or 4400 * event - with x/y coordinates or 4401 * leave empty for default (screen centre) 4402 * @return the manager object 4403 */ 4404 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 4405 var id, browserWidth, browserHeight, scrollX, scrollY, 4406 inst = this._dialogInst; // internal instance 4407 4408 if (!inst) { 4409 this.uuid += 1; 4410 id = "dp" + this.uuid; 4411 this._dialogInput = $("<input type='text' id='" + id + 4412 "' style='position: absolute; top: -100px; width: 0px;'/>"); 4413 this._dialogInput.keydown(this._doKeyDown); 4414 $("body").append(this._dialogInput); 4415 inst = this._dialogInst = this._newInst(this._dialogInput, false); 4416 inst.settings = {}; 4417 $.data(this._dialogInput[0], "datepicker", inst); 4418 } 4419 datepicker_extendRemove(inst.settings, settings || {}); 4420 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 4421 this._dialogInput.val(date); 4422 4423 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 4424 if (!this._pos) { 4425 browserWidth = document.documentElement.clientWidth; 4426 browserHeight = document.documentElement.clientHeight; 4427 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 4428 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 4429 this._pos = // should use actual width/height below 4430 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 4431 } 4432 4433 // move input on screen for focus, but hidden behind dialog 4434 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 4435 inst.settings.onSelect = onSelect; 4436 this._inDialog = true; 4437 this.dpDiv.addClass(this._dialogClass); 4438 this._showDatepicker(this._dialogInput[0]); 4439 if ($.blockUI) { 4440 $.blockUI(this.dpDiv); 4441 } 4442 $.data(this._dialogInput[0], "datepicker", inst); 4443 return this; 4444 }, 4445 4446 /* Detach a datepicker from its control. 4447 * @param target element - the target input field or division or span 4448 */ 4449 _destroyDatepicker: function(target) { 4450 var nodeName, 4451 $target = $(target), 4452 inst = $.data(target, "datepicker"); 4453 4454 if (!$target.hasClass(this.markerClassName)) { 4455 return; 4456 } 4457 4458 nodeName = target.nodeName.toLowerCase(); 4459 $.removeData(target, "datepicker"); 4460 if (nodeName === "input") {
vendor: 6,854 bytes, lines 4461-4668
4461 inst.append.remove(); 4462 inst.trigger.remove(); 4463 $target.removeClass(this.markerClassName). 4464 unbind("focus", this._showDatepicker). 4465 unbind("keydown", this._doKeyDown). 4466 unbind("keypress", this._doKeyPress). 4467 unbind("keyup", this._doKeyUp); 4468 } else if (nodeName === "div" || nodeName === "span") { 4469 $target.removeClass(this.markerClassName).empty(); 4470 } 4471 }, 4472 4473 /* Enable the date picker to a jQuery selection. 4474 * @param target element - the target input field or division or span 4475 */ 4476 _enableDatepicker: function(target) { 4477 var nodeName, inline, 4478 $target = $(target), 4479 inst = $.data(target, "datepicker"); 4480 4481 if (!$target.hasClass(this.markerClassName)) { 4482 return; 4483 } 4484 4485 nodeName = target.nodeName.toLowerCase(); 4486 if (nodeName === "input") { 4487 target.disabled = false; 4488 inst.trigger.filter("button"). 4489 each(function() { this.disabled = false; }).end(). 4490 filter("img").css({opacity: "1.0", cursor: ""}); 4491 } else if (nodeName === "div" || nodeName === "span") { 4492 inline = $target.children("." + this._inlineClass); 4493 inline.children().removeClass("ui-state-disabled"); 4494 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 4495 prop("disabled", false); 4496 } 4497 this._disabledInputs = $.map(this._disabledInputs, 4498 function(value) { return (value === target ? null : value); }); // delete entry 4499 }, 4500 4501 /* Disable the date picker to a jQuery selection. 4502 * @param target element - the target input field or division or span 4503 */ 4504 _disableDatepicker: function(target) { 4505 var nodeName, inline, 4506 $target = $(target), 4507 inst = $.data(target, "datepicker"); 4508 4509 if (!$target.hasClass(this.markerClassName)) { 4510 return; 4511 } 4512 4513 nodeName = target.nodeName.toLowerCase(); 4514 if (nodeName === "input") { 4515 target.disabled = true; 4516 inst.trigger.filter("button"). 4517 each(function() { this.disabled = true; }).end(). 4518 filter("img").css({opacity: "0.5", cursor: "default"}); 4519 } else if (nodeName === "div" || nodeName === "span") { 4520 inline = $target.children("." + this._inlineClass); 4521 inline.children().addClass("ui-state-disabled"); 4522 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 4523 prop("disabled", true); 4524 } 4525 this._disabledInputs = $.map(this._disabledInputs, 4526 function(value) { return (value === target ? null : value); }); // delete entry 4527 this._disabledInputs[this._disabledInputs.length] = target; 4528 }, 4529 4530 /* Is the first field in a jQuery collection disabled as a datepicker? 4531 * @param target element - the target input field or division or span 4532 * @return boolean - true if disabled, false if enabled 4533 */ 4534 _isDisabledDatepicker: function(target) { 4535 if (!target) { 4536 return false; 4537 } 4538 for (var i = 0; i < this._disabledInputs.length; i++) { 4539 if (this._disabledInputs[i] === target) { 4540 return true; 4541 } 4542 } 4543 return false; 4544 }, 4545 4546 /* Retrieve the instance data for the target control. 4547 * @param target element - the target input field or division or span 4548 * @return object - the associated instance data 4549 * @throws error if a jQuery problem getting data 4550 */ 4551 _getInst: function(target) { 4552 try { 4553 return $.data(target, "datepicker"); 4554 } 4555 catch (err) { 4556 throw "Missing instance data for this datepicker"; 4557 } 4558 }, 4559 4560 /* Update or retrieve the settings for a date picker attached to an input field or division. 4561 * @param target element - the target input field or division or span 4562 * @param name object - the new settings to update or 4563 * string - the name of the setting to change or retrieve, 4564 * when retrieving also "all" for all instance settings or 4565 * "defaults" for all global defaults 4566 * @param value any - the new value for the setting 4567 * (omit if above is an object or to retrieve a value) 4568 */ 4569 _optionDatepicker: function(target, name, value) { 4570 var settings, date, minDate, maxDate, 4571 inst = this._getInst(target); 4572 4573 if (arguments.length === 2 && typeof name === "string") { 4574 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 4575 (inst ? (name === "all" ? $.extend({}, inst.settings) : 4576 this._get(inst, name)) : null)); 4577 } 4578 4579 settings = name || {}; 4580 if (typeof name === "string") { 4581 settings = {}; 4582 settings[name] = value; 4583 } 4584 4585 if (inst) { 4586 if (this._curInst === inst) { 4587 this._hideDatepicker(); 4588 } 4589 4590 date = this._getDateDatepicker(target, true); 4591 minDate = this._getMinMaxDate(inst, "min"); 4592 maxDate = this._getMinMaxDate(inst, "max"); 4593 datepicker_extendRemove(inst.settings, settings); 4594 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 4595 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 4596 inst.settings.minDate = this._formatDate(inst, minDate); 4597 } 4598 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 4599 inst.settings.maxDate = this._formatDate(inst, maxDate); 4600 } 4601 if ( "disabled" in settings ) { 4602 if ( settings.disabled ) { 4603 this._disableDatepicker(target); 4604 } else { 4605 this._enableDatepicker(target); 4606 } 4607 } 4608 this._attachments($(target), inst); 4609 this._autoSize(inst); 4610 this._setDate(inst, date); 4611 this._updateAlternate(inst); 4612 this._updateDatepicker(inst); 4613 } 4614 }, 4615 4616 // change method deprecated 4617 _changeDatepicker: function(target, name, value) { 4618 this._optionDatepicker(target, name, value); 4619 }, 4620 4621 /* Redraw the date picker attached to an input field or division. 4622 * @param target element - the target input field or division or span 4623 */ 4624 _refreshDatepicker: function(target) { 4625 var inst = this._getInst(target); 4626 if (inst) { 4627 this._updateDatepicker(inst); 4628 } 4629 }, 4630 4631 /* Set the dates for a jQuery selection. 4632 * @param target element - the target input field or division or span 4633 * @param date Date - the new date 4634 */ 4635 _setDateDatepicker: function(target, date) { 4636 var inst = this._getInst(target); 4637 if (inst) { 4638 this._setDate(inst, date); 4639 this._updateDatepicker(inst); 4640 this._updateAlternate(inst); 4641 } 4642 }, 4643 4644 /* Get the date(s) for the first entry in a jQuery selection. 4645 * @param target element - the target input field or division or span 4646 * @param noDefault boolean - true if no default date is to be used 4647 * @return Date - the current date 4648 */ 4649 _getDateDatepicker: function(target, noDefault) { 4650 var inst = this._getInst(target); 4651 if (inst && !inst.inline) { 4652 this._setDateFromField(inst, noDefault); 4653 } 4654 return (inst ? this._getDate(inst) : null); 4655 }, 4656 4657 /* Handle keystrokes. */ 4658 _doKeyDown: function(event) { 4659 var onSelect, dateStr, sel, 4660 inst = $.datepicker._getInst(event.target), 4661 handled = true, 4662 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 4663 4664 inst._keyEvent = true; 4665 if ($.datepicker._datepickerShowing) { 4666 switch (event.keyCode) { 4667 case 9: $.datepicker._hideDatepicker(); 4668 handled = false;
vendor: 4,495 bytes, lines 4669-4792
4669 break; // hide on tab out 4670 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 4671 $.datepicker._currentClass + ")", inst.dpDiv); 4672 if (sel[0]) { 4673 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 4674 } 4675 4676 onSelect = $.datepicker._get(inst, "onSelect"); 4677 if (onSelect) { 4678 dateStr = $.datepicker._formatDate(inst); 4679 4680 // trigger custom callback 4681 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 4682 } else { 4683 $.datepicker._hideDatepicker(); 4684 } 4685 4686 return false; // don't submit the form 4687 case 27: $.datepicker._hideDatepicker(); 4688 break; // hide on escape 4689 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4690 -$.datepicker._get(inst, "stepBigMonths") : 4691 -$.datepicker._get(inst, "stepMonths")), "M"); 4692 break; // previous month/year on page up/+ ctrl 4693 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4694 +$.datepicker._get(inst, "stepBigMonths") : 4695 +$.datepicker._get(inst, "stepMonths")), "M"); 4696 break; // next month/year on page down/+ ctrl 4697 case 35: if (event.ctrlKey || event.metaKey) { 4698 $.datepicker._clearDate(event.target); 4699 } 4700 handled = event.ctrlKey || event.metaKey; 4701 break; // clear on ctrl or command +end 4702 case 36: if (event.ctrlKey || event.metaKey) { 4703 $.datepicker._gotoToday(event.target); 4704 } 4705 handled = event.ctrlKey || event.metaKey; 4706 break; // current on ctrl or command +home 4707 case 37: if (event.ctrlKey || event.metaKey) { 4708 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 4709 } 4710 handled = event.ctrlKey || event.metaKey; 4711 // -1 day on ctrl or command +left 4712 if (event.originalEvent.altKey) { 4713 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4714 -$.datepicker._get(inst, "stepBigMonths") : 4715 -$.datepicker._get(inst, "stepMonths")), "M"); 4716 } 4717 // next month/year on alt +left on Mac 4718 break; 4719 case 38: if (event.ctrlKey || event.metaKey) { 4720 $.datepicker._adjustDate(event.target, -7, "D"); 4721 } 4722 handled = event.ctrlKey || event.metaKey; 4723 break; // -1 week on ctrl or command +up 4724 case 39: if (event.ctrlKey || event.metaKey) { 4725 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 4726 } 4727 handled = event.ctrlKey || event.metaKey; 4728 // +1 day on ctrl or command +right 4729 if (event.originalEvent.altKey) { 4730 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 4731 +$.datepicker._get(inst, "stepBigMonths") : 4732 +$.datepicker._get(inst, "stepMonths")), "M"); 4733 } 4734 // next month/year on alt +right 4735 break; 4736 case 40: if (event.ctrlKey || event.metaKey) { 4737 $.datepicker._adjustDate(event.target, +7, "D"); 4738 } 4739 handled = event.ctrlKey || event.metaKey; 4740 break; // +1 week on ctrl or command +down 4741 default: handled = false; 4742 } 4743 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 4744 $.datepicker._showDatepicker(this); 4745 } else { 4746 handled = false; 4747 } 4748 4749 if (handled) { 4750 event.preventDefault(); 4751 event.stopPropagation(); 4752 } 4753 }, 4754 4755 /* Filter entered characters - based on date format. */ 4756 _doKeyPress: function(event) { 4757 var chars, chr, 4758 inst = $.datepicker._getInst(event.target); 4759 4760 if ($.datepicker._get(inst, "constrainInput")) { 4761 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 4762 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 4763 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 4764 } 4765 }, 4766 4767 /* Synchronise manual entry and field/alternate field. */ 4768 _doKeyUp: function(event) { 4769 var date, 4770 inst = $.datepicker._getInst(event.target); 4771 4772 if (inst.input.val() !== inst.lastVal) { 4773 try { 4774 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 4775 (inst.input ? inst.input.val() : null), 4776 $.datepicker._getFormatConfig(inst)); 4777 4778 if (date) { // only if valid 4779 $.datepicker._setDateFromField(inst); 4780 $.datepicker._updateAlternate(inst); 4781 $.datepicker._updateDatepicker(inst); 4782 } 4783 } 4784 catch (err) { 4785 } 4786 } 4787 return true; 4788 }, 4789 4790 /* Pop-up the date picker for a given input field. 4791 * If false returned from beforeShow event handler do not show. 4792 * @param input element - the input field attached to the date picker or
vendor: 9,398 bytes, lines 4793-5067
4793 * event - if triggered by focus 4794 */ 4795 _showDatepicker: function(input) { 4796 input = input.target || input; 4797 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 4798 input = $("input", input.parentNode)[0]; 4799 } 4800 4801 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 4802 return; 4803 } 4804 4805 var inst, beforeShow, beforeShowSettings, isFixed, 4806 offset, showAnim, duration; 4807 4808 inst = $.datepicker._getInst(input); 4809 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 4810 $.datepicker._curInst.dpDiv.stop(true, true); 4811 if ( inst && $.datepicker._datepickerShowing ) { 4812 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 4813 } 4814 } 4815 4816 beforeShow = $.datepicker._get(inst, "beforeShow"); 4817 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 4818 if(beforeShowSettings === false){ 4819 return; 4820 } 4821 datepicker_extendRemove(inst.settings, beforeShowSettings); 4822 4823 inst.lastVal = null; 4824 $.datepicker._lastInput = input; 4825 $.datepicker._setDateFromField(inst); 4826 4827 if ($.datepicker._inDialog) { // hide cursor 4828 input.value = ""; 4829 } 4830 if (!$.datepicker._pos) { // position below input 4831 $.datepicker._pos = $.datepicker._findPos(input); 4832 $.datepicker._pos[1] += input.offsetHeight; // add the height 4833 } 4834 4835 isFixed = false; 4836 $(input).parents().each(function() { 4837 isFixed |= $(this).css("position") === "fixed"; 4838 return !isFixed; 4839 }); 4840 4841 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 4842 $.datepicker._pos = null; 4843 //to avoid flashes on Firefox 4844 inst.dpDiv.empty(); 4845 // determine sizing offscreen 4846 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 4847 $.datepicker._updateDatepicker(inst); 4848 // fix width for dynamic number of date pickers 4849 // and adjust position before showing 4850 offset = $.datepicker._checkOffset(inst, offset, isFixed); 4851 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 4852 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 4853 left: offset.left + "px", top: offset.top + "px"}); 4854 4855 if (!inst.inline) { 4856 showAnim = $.datepicker._get(inst, "showAnim"); 4857 duration = $.datepicker._get(inst, "duration"); 4858 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 4859 $.datepicker._datepickerShowing = true; 4860 4861 if ( $.effects && $.effects.effect[ showAnim ] ) { 4862 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 4863 } else { 4864 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 4865 } 4866 4867 if ( $.datepicker._shouldFocusInput( inst ) ) { 4868 inst.input.focus(); 4869 } 4870 4871 $.datepicker._curInst = inst; 4872 } 4873 }, 4874 4875 /* Generate the date picker content. */ 4876 _updateDatepicker: function(inst) { 4877 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 4878 datepicker_instActive = inst; // for delegate hover events 4879 inst.dpDiv.empty().append(this._generateHTML(inst)); 4880 this._attachHandlers(inst); 4881 4882 var origyearshtml, 4883 numMonths = this._getNumberOfMonths(inst), 4884 cols = numMonths[1], 4885 width = 17, 4886 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); 4887 4888 if ( activeCell.length > 0 ) { 4889 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 4890 } 4891 4892 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 4893 if (cols > 1) { 4894 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 4895 } 4896 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 4897 "Class"]("ui-datepicker-multi"); 4898 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 4899 "Class"]("ui-datepicker-rtl"); 4900 4901 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 4902 inst.input.focus(); 4903 } 4904 4905 // deffered render of the years select (to avoid flashes on Firefox) 4906 if( inst.yearshtml ){ 4907 origyearshtml = inst.yearshtml; 4908 setTimeout(function(){ 4909 //assure that inst.yearshtml didn't change. 4910 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 4911 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 4912 } 4913 origyearshtml = inst.yearshtml = null; 4914 }, 0); 4915 } 4916 }, 4917 4918 // #6694 - don't focus the input if it's already focused 4919 // this breaks the change event in IE 4920 // Support: IE and jQuery <1.9 4921 _shouldFocusInput: function( inst ) { 4922 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 4923 }, 4924 4925 /* Check positioning to remain on screen. */ 4926 _checkOffset: function(inst, offset, isFixed) { 4927 var dpWidth = inst.dpDiv.outerWidth(), 4928 dpHeight = inst.dpDiv.outerHeight(), 4929 inputWidth = inst.input ? inst.input.outerWidth() : 0, 4930 inputHeight = inst.input ? inst.input.outerHeight() : 0, 4931 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 4932 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 4933 4934 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 4935 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 4936 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 4937 4938 // now check if datepicker is showing outside window viewport - move to a better place if so. 4939 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 4940 Math.abs(offset.left + dpWidth - viewWidth) : 0); 4941 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 4942 Math.abs(dpHeight + inputHeight) : 0); 4943 4944 return offset; 4945 }, 4946 4947 /* Find an object's position on the screen. */ 4948 _findPos: function(obj) { 4949 var position, 4950 inst = this._getInst(obj), 4951 isRTL = this._get(inst, "isRTL"); 4952 4953 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 4954 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 4955 } 4956 4957 position = $(obj).offset(); 4958 return [position.left, position.top]; 4959 }, 4960 4961 /* Hide the date picker from view. 4962 * @param input element - the input field attached to the date picker 4963 */ 4964 _hideDatepicker: function(input) { 4965 var showAnim, duration, postProcess, onClose, 4966 inst = this._curInst; 4967 4968 if (!inst || (input && inst !== $.data(input, "datepicker"))) { 4969 return; 4970 } 4971 4972 if (this._datepickerShowing) { 4973 showAnim = this._get(inst, "showAnim"); 4974 duration = this._get(inst, "duration"); 4975 postProcess = function() { 4976 $.datepicker._tidyDialog(inst); 4977 }; 4978 4979 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 4980 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 4981 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 4982 } else { 4983 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 4984 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 4985 } 4986 4987 if (!showAnim) { 4988 postProcess(); 4989 } 4990 this._datepickerShowing = false; 4991 4992 onClose = this._get(inst, "onClose"); 4993 if (onClose) { 4994 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 4995 } 4996 4997 this._lastInput = null; 4998 if (this._inDialog) { 4999 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 5000 if ($.blockUI) { 5001 $.unblockUI(); 5002 $("body").append(this.dpDiv); 5003 } 5004 } 5005 this._inDialog = false; 5006 } 5007 }, 5008 5009 /* Tidy up after a dialog display. */ 5010 _tidyDialog: function(inst) { 5011 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 5012 }, 5013 5014 /* Close date picker if clicked elsewhere. */ 5015 _checkExternalClick: function(event) { 5016 if (!$.datepicker._curInst) { 5017 return; 5018 } 5019 5020 var $target = $(event.target), 5021 inst = $.datepicker._getInst($target[0]); 5022 5023 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 5024 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 5025 !$target.hasClass($.datepicker.markerClassName) && 5026 !$target.closest("." + $.datepicker._triggerClass).length && 5027 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 5028 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 5029 $.datepicker._hideDatepicker(); 5030 } 5031 }, 5032 5033 /* Adjust one of the date sub-fields. */ 5034 _adjustDate: function(id, offset, period) { 5035 var target = $(id), 5036 inst = this._getInst(target[0]); 5037 5038 if (this._isDisabledDatepicker(target[0])) { 5039 return; 5040 } 5041 this._adjustInstDate(inst, offset + 5042 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 5043 period); 5044 this._updateDatepicker(inst); 5045 }, 5046 5047 /* Action for current link. */ 5048 _gotoToday: function(id) { 5049 var date, 5050 target = $(id), 5051 inst = this._getInst(target[0]); 5052 5053 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 5054 inst.selectedDay = inst.currentDay; 5055 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 5056 inst.drawYear = inst.selectedYear = inst.currentYear; 5057 } else { 5058 date = new Date(); 5059 inst.selectedDay = date.getDate(); 5060 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5061 inst.drawYear = inst.selectedYear = date.getFullYear(); 5062 } 5063 this._notifyChange(inst); 5064 this._adjustDate(target); 5065 }, 5066 5067 /* Action for selecting a new month/year. */
vendor: 4,436 bytes, lines 5068-5199
5068 _selectMonthYear: function(id, select, period) { 5069 var target = $(id), 5070 inst = this._getInst(target[0]); 5071 5072 inst["selected" + (period === "M" ? "Month" : "Year")] = 5073 inst["draw" + (period === "M" ? "Month" : "Year")] = 5074 parseInt(select.options[select.selectedIndex].value,10); 5075 5076 this._notifyChange(inst); 5077 this._adjustDate(target); 5078 }, 5079 5080 /* Action for selecting a day. */ 5081 _selectDay: function(id, month, year, td) { 5082 var inst, 5083 target = $(id); 5084 5085 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 5086 return; 5087 } 5088 5089 inst = this._getInst(target[0]); 5090 inst.selectedDay = inst.currentDay = $("a", td).html(); 5091 inst.selectedMonth = inst.currentMonth = month; 5092 inst.selectedYear = inst.currentYear = year; 5093 this._selectDate(id, this._formatDate(inst, 5094 inst.currentDay, inst.currentMonth, inst.currentYear)); 5095 }, 5096 5097 /* Erase the input field and hide the date picker. */ 5098 _clearDate: function(id) { 5099 var target = $(id); 5100 this._selectDate(target, ""); 5101 }, 5102 5103 /* Update the input field with the selected date. */ 5104 _selectDate: function(id, dateStr) { 5105 var onSelect, 5106 target = $(id), 5107 inst = this._getInst(target[0]); 5108 5109 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 5110 if (inst.input) { 5111 inst.input.val(dateStr); 5112 } 5113 this._updateAlternate(inst); 5114 5115 onSelect = this._get(inst, "onSelect"); 5116 if (onSelect) { 5117 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 5118 } else if (inst.input) { 5119 inst.input.trigger("change"); // fire the change event 5120 } 5121 5122 if (inst.inline){ 5123 this._updateDatepicker(inst); 5124 } else { 5125 this._hideDatepicker(); 5126 this._lastInput = inst.input[0]; 5127 if (typeof(inst.input[0]) !== "object") { 5128 inst.input.focus(); // restore focus 5129 } 5130 this._lastInput = null; 5131 } 5132 }, 5133 5134 /* Update any alternate field to synchronise with the main field. */ 5135 _updateAlternate: function(inst) { 5136 var altFormat, date, dateStr, 5137 altField = this._get(inst, "altField"); 5138 5139 if (altField) { // update alternate field too 5140 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 5141 date = this._getDate(inst); 5142 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 5143 $(altField).each(function() { $(this).val(dateStr); }); 5144 } 5145 }, 5146 5147 /* Set as beforeShowDay function to prevent selection of weekends. 5148 * @param date Date - the date to customise 5149 * @return [boolean, string] - is this date selectable?, what is its CSS class? 5150 */ 5151 noWeekends: function(date) { 5152 var day = date.getDay(); 5153 return [(day > 0 && day < 6), ""]; 5154 }, 5155 5156 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 5157 * @param date Date - the date to get the week for 5158 * @return number - the number of the week within the year that contains this date 5159 */ 5160 iso8601Week: function(date) { 5161 var time, 5162 checkDate = new Date(date.getTime()); 5163 5164 // Find Thursday of this week starting on Monday 5165 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 5166 5167 time = checkDate.getTime(); 5168 checkDate.setMonth(0); // Compare with Jan 1 5169 checkDate.setDate(1); 5170 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 5171 }, 5172 5173 /* Parse a string value into a date object. 5174 * See formatDate below for the possible formats. 5175 * 5176 * @param format string - the expected format of the date 5177 * @param value string - the date in the above format 5178 * @param settings Object - attributes include: 5179 * shortYearCutoff number - the cutoff year for determining the century (optional) 5180 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 5181 * dayNames string[7] - names of the days from Sunday (optional) 5182 * monthNamesShort string[12] - abbreviated names of the months (optional) 5183 * monthNames string[12] - names of the months (optional) 5184 * @return Date - the extracted date value or null if value is blank 5185 */ 5186 parseDate: function (format, value, settings) { 5187 if (format == null || value == null) { 5188 throw "Invalid arguments"; 5189 } 5190 5191 value = (typeof value === "object" ? value.toString() : value + ""); 5192 if (value === "") { 5193 return null; 5194 } 5195 5196 var iFormat, dim, extra, 5197 iValue = 0, 5198 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 5199 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 5,261 bytes, lines 5199-5385
5199: 5200 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 5201 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 5202 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 5203 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 5204 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 5205 year = -1, 5206 month = -1, 5207 day = -1, 5208 doy = -1, 5209 literal = false, 5210 date, 5211 // Check whether a format character is doubled 5212 lookAhead = function(match) { 5213 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 5214 if (matches) { 5215 iFormat++; 5216 } 5217 return matches; 5218 }, 5219 // Extract a number from the string value 5220 getNumber = function(match) { 5221 var isDoubled = lookAhead(match), 5222 size = (match === "@" ? 14 : (match === "!" ? 20 : 5223 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 5224 minSize = (match === "y" ? size : 1), 5225 digits = new RegExp("^\\d{" + minSize + "," + size + "}"), 5226 num = value.substring(iValue).match(digits); 5227 if (!num) { 5228 throw "Missing number at position " + iValue; 5229 } 5230 iValue += num[0].length; 5231 return parseInt(num[0], 10); 5232 }, 5233 // Extract a name from the string value and convert to an index 5234 getName = function(match, shortNames, longNames) { 5235 var index = -1, 5236 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 5237 return [ [k, v] ]; 5238 }).sort(function (a, b) { 5239 return -(a[1].length - b[1].length); 5240 }); 5241 5242 $.each(names, function (i, pair) { 5243 var name = pair[1]; 5244 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 5245 index = pair[0]; 5246 iValue += name.length; 5247 return false; 5248 } 5249 }); 5250 if (index !== -1) { 5251 return index + 1; 5252 } else { 5253 throw "Unknown name at position " + iValue; 5254 } 5255 }, 5256 // Confirm that a literal character matches the string value 5257 checkLiteral = function() { 5258 if (value.charAt(iValue) !== format.charAt(iFormat)) { 5259 throw "Unexpected literal at position " + iValue; 5260 } 5261 iValue++; 5262 }; 5263 5264 for (iFormat = 0; iFormat < format.length; iFormat++) { 5265 if (literal) { 5266 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 5267 literal = false; 5268 } else { 5269 checkLiteral(); 5270 } 5271 } else { 5272 switch (format.charAt(iFormat)) { 5273 case "d": 5274 day = getNumber("d"); 5275 break; 5276 case "D": 5277 getName("D", dayNamesShort, dayNames); 5278 break; 5279 case "o": 5280 doy = getNumber("o"); 5281 break; 5282 case "m": 5283 month = getNumber("m"); 5284 break; 5285 case "M": 5286 month = getName("M", monthNamesShort, monthNames); 5287 break; 5288 case "y": 5289 year = getNumber("y"); 5290 break; 5291 case "@": 5292 date = new Date(getNumber("@")); 5293 year = date.getFullYear(); 5294 month = date.getMonth() + 1; 5295 day = date.getDate(); 5296 break; 5297 case "!": 5298 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 5299 year = date.getFullYear(); 5300 month = date.getMonth() + 1; 5301 day = date.getDate(); 5302 break; 5303 case "'": 5304 if (lookAhead("'")){ 5305 checkLiteral(); 5306 } else { 5307 literal = true; 5308 } 5309 break; 5310 default: 5311 checkLiteral(); 5312 } 5313 } 5314 } 5315 5316 if (iValue < value.length){ 5317 extra = value.substr(iValue); 5318 if (!/^\s+/.test(extra)) { 5319 throw "Extra/unparsed characters found in date: " + extra; 5320 } 5321 } 5322 5323 if (year === -1) { 5324 year = new Date().getFullYear(); 5325 } else if (year < 100) { 5326 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 5327 (year <= shortYearCutoff ? 0 : -100); 5328 } 5329 5330 if (doy > -1) { 5331 month = 1; 5332 day = doy; 5333 do { 5334 dim = this._getDaysInMonth(year, month - 1); 5335 if (day <= dim) { 5336 break; 5337 } 5338 month++; 5339 day -= dim; 5340 } while (true); 5341 } 5342 5343 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 5344 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 5345 throw "Invalid date"; // E.g. 31/02/00 5346 } 5347 return date; 5348 }, 5349 5350 /* Standard date formats. */ 5351 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 5352 COOKIE: "D, dd M yy", 5353 ISO_8601: "yy-mm-dd", 5354 RFC_822: "D, d M y", 5355 RFC_850: "DD, dd-M-y", 5356 RFC_1036: "D, d M y", 5357 RFC_1123: "D, d M yy", 5358 RFC_2822: "D, d M yy", 5359 RSS: "D, d M y", // RFC 822 5360 TICKS: "!", 5361 TIMESTAMP: "@", 5362 W3C: "yy-mm-dd", // ISO 8601 5363 5364 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 5365 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 5366 5367 /* Format a date object into a string value. 5368 * The format can be combinations of the following: 5369 * d - day of month (no leading zero) 5370 * dd - day of month (two digit) 5371 * o - day of year (no leading zeros) 5372 * oo - day of year (three digit) 5373 * D - day name short 5374 * DD - day name long 5375 * m - month of year (no leading zero) 5376 * mm - month of year (two digit) 5377 * M - month name short 5378 * MM - month name long 5379 * y - year (two digit) 5380 * yy - year (four digit) 5381 * @ - Unix timestamp (ms since 01/01/1970) 5382 * ! - Windows ticks (100ns since 01/01/0001) 5383 * "..." - literal text 5384 * '' - single quote 5385 *
vendor: 11,157 bytes, lines 5386-5719
5386 * @param format string - the desired format of the date 5387 * @param date Date - the date value to format 5388 * @param settings Object - attributes include: 5389 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 5390 * dayNames string[7] - names of the days from Sunday (optional) 5391 * monthNamesShort string[12] - abbreviated names of the months (optional) 5392 * monthNames string[12] - names of the months (optional) 5393 * @return string - the date in the above format 5394 */ 5395 formatDate: function (format, date, settings) { 5396 if (!date) { 5397 return ""; 5398 } 5399 5400 var iFormat, 5401 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 5402 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 5403 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 5404 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 5405 // Check whether a format character is doubled 5406 lookAhead = function(match) { 5407 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 5408 if (matches) { 5409 iFormat++; 5410 } 5411 return matches; 5412 }, 5413 // Format a number, with leading zero if necessary 5414 formatNumber = function(match, value, len) { 5415 var num = "" + value; 5416 if (lookAhead(match)) { 5417 while (num.length < len) { 5418 num = "0" + num; 5419 } 5420 } 5421 return num; 5422 }, 5423 // Format a name, short or long as requested 5424 formatName = function(match, value, shortNames, longNames) { 5425 return (lookAhead(match) ? longNames[value] : shortNames[value]); 5426 }, 5427 output = "", 5428 literal = false; 5429 5430 if (date) { 5431 for (iFormat = 0; iFormat < format.length; iFormat++) { 5432 if (literal) { 5433 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 5434 literal = false; 5435 } else { 5436 output += format.charAt(iFormat); 5437 } 5438 } else { 5439 switch (format.charAt(iFormat)) { 5440 case "d": 5441 output += formatNumber("d", date.getDate(), 2); 5442 break; 5443 case "D": 5444 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 5445 break; 5446 case "o": 5447 output += formatNumber("o", 5448 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 5449 break; 5450 case "m": 5451 output += formatNumber("m", date.getMonth() + 1, 2); 5452 break; 5453 case "M": 5454 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 5455 break; 5456 case "y": 5457 output += (lookAhead("y") ? date.getFullYear() : 5458 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 5459 break; 5460 case "@": 5461 output += date.getTime(); 5462 break; 5463 case "!": 5464 output += date.getTime() * 10000 + this._ticksTo1970; 5465 break; 5466 case "'": 5467 if (lookAhead("'")) { 5468 output += "'"; 5469 } else { 5470 literal = true; 5471 } 5472 break; 5473 default: 5474 output += format.charAt(iFormat); 5475 } 5476 } 5477 } 5478 } 5479 return output; 5480 }, 5481 5482 /* Extract all possible characters from the date format. */ 5483 _possibleChars: function (format) { 5484 var iFormat, 5485 chars = "", 5486 literal = false, 5487 // Check whether a format character is doubled 5488 lookAhead = function(match) { 5489 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 5490 if (matches) { 5491 iFormat++; 5492 } 5493 return matches; 5494 }; 5495 5496 for (iFormat = 0; iFormat < format.length; iFormat++) { 5497 if (literal) { 5498 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 5499 literal = false; 5500 } else { 5501 chars += format.charAt(iFormat); 5502 } 5503 } else { 5504 switch (format.charAt(iFormat)) { 5505 case "d": case "m": case "y": case "@": 5506 chars += "0123456789"; 5507 break; 5508 case "D": case "M": 5509 return null; // Accept anything 5510 case "'": 5511 if (lookAhead("'")) { 5512 chars += "'"; 5513 } else { 5514 literal = true; 5515 } 5516 break; 5517 default: 5518 chars += format.charAt(iFormat); 5519 } 5520 } 5521 } 5522 return chars; 5523 }, 5524 5525 /* Get a setting value, defaulting if necessary. */ 5526 _get: function(inst, name) { 5527 return inst.settings[name] !== undefined ? 5528 inst.settings[name] : this._defaults[name]; 5529 }, 5530 5531 /* Parse existing date and initialise date picker. */ 5532 _setDateFromField: function(inst, noDefault) { 5533 if (inst.input.val() === inst.lastVal) { 5534 return; 5535 } 5536 5537 var dateFormat = this._get(inst, "dateFormat"), 5538 dates = inst.lastVal = inst.input ? inst.input.val() : null, 5539 defaultDate = this._getDefaultDate(inst), 5540 date = defaultDate, 5541 settings = this._getFormatConfig(inst); 5542 5543 try { 5544 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 5545 } catch (event) { 5546 dates = (noDefault ? "" : dates); 5547 } 5548 inst.selectedDay = date.getDate(); 5549 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5550 inst.drawYear = inst.selectedYear = date.getFullYear(); 5551 inst.currentDay = (dates ? date.getDate() : 0); 5552 inst.currentMonth = (dates ? date.getMonth() : 0); 5553 inst.currentYear = (dates ? date.getFullYear() : 0); 5554 this._adjustInstDate(inst); 5555 }, 5556 5557 /* Retrieve the default date shown on opening. */ 5558 _getDefaultDate: function(inst) { 5559 return this._restrictMinMax(inst, 5560 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 5561 }, 5562 5563 /* A date may be specified as an exact value or a relative one. */ 5564 _determineDate: function(inst, date, defaultDate) { 5565 var offsetNumeric = function(offset) { 5566 var date = new Date(); 5567 date.setDate(date.getDate() + offset); 5568 return date; 5569 }, 5570 offsetString = function(offset) { 5571 try { 5572 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 5573 offset, $.datepicker._getFormatConfig(inst)); 5574 } 5575 catch (e) { 5576 // Ignore 5577 } 5578 5579 var date = (offset.toLowerCase().match(/^c/) ? 5580 $.datepicker._getDate(inst) : null) || new Date(), 5581 year = date.getFullYear(), 5582 month = date.getMonth(), 5583 day = date.getDate(), 5584 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 5585 matches = pattern.exec(offset); 5586 5587 while (matches) { 5588 switch (matches[2] || "d") { 5589 case "d" : case "D" : 5590 day += parseInt(matches[1],10); break; 5591 case "w" : case "W" : 5592 day += parseInt(matches[1],10) * 7; break; 5593 case "m" : case "M" : 5594 month += parseInt(matches[1],10); 5595 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 5596 break; 5597 case "y": case "Y" : 5598 year += parseInt(matches[1],10); 5599 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 5600 break; 5601 } 5602 matches = pattern.exec(offset); 5603 } 5604 return new Date(year, month, day); 5605 }, 5606 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 5607 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 5608 5609 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 5610 if (newDate) { 5611 newDate.setHours(0); 5612 newDate.setMinutes(0); 5613 newDate.setSeconds(0); 5614 newDate.setMilliseconds(0); 5615 } 5616 return this._daylightSavingAdjust(newDate); 5617 }, 5618 5619 /* Handle switch to/from daylight saving. 5620 * Hours may be non-zero on daylight saving cut-over: 5621 * > 12 when midnight changeover, but then cannot generate 5622 * midnight datetime, so jump to 1AM, otherwise reset. 5623 * @param date (Date) the date to check 5624 * @return (Date) the corrected date 5625 */ 5626 _daylightSavingAdjust: function(date) { 5627 if (!date) { 5628 return null; 5629 } 5630 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 5631 return date; 5632 }, 5633 5634 /* Set the date(s) directly. */ 5635 _setDate: function(inst, date, noChange) { 5636 var clear = !date, 5637 origMonth = inst.selectedMonth, 5638 origYear = inst.selectedYear, 5639 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 5640 5641 inst.selectedDay = inst.currentDay = newDate.getDate(); 5642 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 5643 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 5644 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 5645 this._notifyChange(inst); 5646 } 5647 this._adjustInstDate(inst); 5648 if (inst.input) { 5649 inst.input.val(clear ? "" : this._formatDate(inst)); 5650 } 5651 }, 5652 5653 /* Retrieve the date(s) directly. */ 5654 _getDate: function(inst) { 5655 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 5656 this._daylightSavingAdjust(new Date( 5657 inst.currentYear, inst.currentMonth, inst.currentDay))); 5658 return startDate; 5659 }, 5660 5661 /* Attach the onxxx handlers. These are declared statically so 5662 * they work with static code transformers like Caja. 5663 */ 5664 _attachHandlers: function(inst) { 5665 var stepMonths = this._get(inst, "stepMonths"), 5666 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 5667 inst.dpDiv.find("[data-handler]").map(function () { 5668 var handler = { 5669 prev: function () { 5670 $.datepicker._adjustDate(id, -stepMonths, "M"); 5671 }, 5672 next: function () { 5673 $.datepicker._adjustDate(id, +stepMonths, "M"); 5674 }, 5675 hide: function () { 5676 $.datepicker._hideDatepicker(); 5677 }, 5678 today: function () { 5679 $.datepicker._gotoToday(id); 5680 }, 5681 selectDay: function () { 5682 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 5683 return false; 5684 }, 5685 selectMonth: function () { 5686 $.datepicker._selectMonthYear(id, this, "M"); 5687 return false; 5688 }, 5689 selectYear: function () { 5690 $.datepicker._selectMonthYear(id, this, "Y"); 5691 return false; 5692 } 5693 }; 5694 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 5695 }); 5696 }, 5697 5698 /* Generate the HTML for the current state of the date picker. */ 5699 _generateHTML: function(inst) { 5700 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 5701 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 5702 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 5703 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 5704 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 5705 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 5706 tempDate = new Date(), 5707 today = this._daylightSavingAdjust( 5708 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 5709 isRTL = this._get(inst, "isRTL"), 5710 showButtonPanel = this._get(inst, "showButtonPanel"), 5711 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 5712 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 5713 numMonths = this._getNumberOfMonths(inst), 5714 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 5715 stepMonths = this._get(inst, "stepMonths"), 5716 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 5717 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 5718 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 5719 minDate = this._getMinMaxDate(inst, "min"),
vendor: 9,139 bytes, lines 5720-5878
5720 maxDate = this._getMinMaxDate(inst, "max"), 5721 drawMonth = inst.drawMonth - showCurrentAtPos, 5722 drawYear = inst.drawYear; 5723 5724 if (drawMonth < 0) { 5725 drawMonth += 12; 5726 drawYear--; 5727 } 5728 if (maxDate) { 5729 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 5730 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 5731 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 5732 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 5733 drawMonth--; 5734 if (drawMonth < 0) { 5735 drawMonth = 11; 5736 drawYear--; 5737 } 5738 } 5739 } 5740 inst.drawMonth = drawMonth; 5741 inst.drawYear = drawYear; 5742 5743 prevText = this._get(inst, "prevText"); 5744 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 5745 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 5746 this._getFormatConfig(inst))); 5747 5748 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 5749 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 5750 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 5751 (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); 5752 5753 nextText = this._get(inst, "nextText"); 5754 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 5755 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 5756 this._getFormatConfig(inst))); 5757 5758 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 5759 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 5760 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 5761 (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); 5762 5763 currentText = this._get(inst, "currentText"); 5764 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 5765 currentText = (!navigationAsDateFormat ? currentText : 5766 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 5767 5768 controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + 5769 this._get(inst, "closeText") + "</button>" : ""); 5770 5771 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 5772 (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + 5773 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 5774 5775 firstDay = parseInt(this._get(inst, "firstDay"),10); 5776 firstDay = (isNaN(firstDay) ? 0 : firstDay); 5777 5778 showWeek = this._get(inst, "showWeek"); 5779 dayNames = this._get(inst, "dayNames"); 5780 dayNamesMin = this._get(inst, "dayNamesMin"); 5781 monthNames = this._get(inst, "monthNames"); 5782 monthNamesShort = this._get(inst, "monthNamesShort"); 5783 beforeShowDay = this._get(inst, "beforeShowDay"); 5784 showOtherMonths = this._get(inst, "showOtherMonths"); 5785 selectOtherMonths = this._get(inst, "selectOtherMonths"); 5786 defaultDate = this._getDefaultDate(inst); 5787 html = ""; 5788 dow; 5789 for (row = 0; row < numMonths[0]; row++) { 5790 group = ""; 5791 this.maxRows = 4; 5792 for (col = 0; col < numMonths[1]; col++) { 5793 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 5794 cornerClass = " ui-corner-all"; 5795 calender = ""; 5796 if (isMultiMonth) { 5797 calender += "<div class='ui-datepicker-group"; 5798 if (numMonths[1] > 1) { 5799 switch (col) { 5800 case 0: calender += " ui-datepicker-group-first"; 5801 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 5802 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 5803 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 5804 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 5805 } 5806 } 5807 calender += "'>"; 5808 } 5809 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 5810 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 5811 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 5812 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 5813 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 5814 "</div><table class='ui-datepicker-calendar'><thead>" + 5815 "<tr>"; 5816 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 5817 for (dow = 0; dow < 7; dow++) { // days of the week 5818 day = (dow + firstDay) % 7; 5819 thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 5820 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 5821 } 5822 calender += thead + "</tr></thead><tbody>"; 5823 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 5824 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 5825 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 5826 } 5827 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 5828 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 5829 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 5830 this.maxRows = numRows; 5831 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 5832 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 5833 calender += "<tr>"; 5834 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 5835 this._get(inst, "calculateWeek")(printDate) + "</td>"); 5836 for (dow = 0; dow < 7; dow++) { // create date picker days 5837 daySettings = (beforeShowDay ? 5838 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 5839 otherMonth = (printDate.getMonth() !== drawMonth); 5840 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 5841 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 5842 tbody += "<td class='" + 5843 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 5844 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 5845 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 5846 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 5847 // or defaultDate is current printedDate and defaultDate is selectedDate 5848 " " + this._dayOverClass : "") + // highlight selected day 5849 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 5850 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 5851 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 5852 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 5853 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 5854 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 5855 (otherMonth && !showOtherMonths ? " " : // display for other months 5856 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 5857 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 5858 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 5859 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 5860 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 5861 printDate.setDate(printDate.getDate() + 1); 5862 printDate = this._daylightSavingAdjust(printDate); 5863 } 5864 calender += tbody + "</tr>"; 5865 } 5866 drawMonth++; 5867 if (drawMonth > 11) { 5868 drawMonth = 0; 5869 drawYear++; 5870 } 5871 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 5872 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 5873 group += calender; 5874 } 5875 html += group; 5876 } 5877 html += buttonPanel; 5878 inst._keyEvent = false;
vendor: 5,431 bytes, lines 5879-6022
5879 return html; 5880 }, 5881 5882 /* Generate the month and year header. */ 5883 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 5884 secondary, monthNames, monthNamesShort) { 5885 5886 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 5887 changeMonth = this._get(inst, "changeMonth"), 5888 changeYear = this._get(inst, "changeYear"), 5889 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 5890 html = "<div class='ui-datepicker-title'>", 5891 monthHtml = ""; 5892 5893 // month selection 5894 if (secondary || !changeMonth) { 5895 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 5896 } else { 5897 inMinYear = (minDate && minDate.getFullYear() === drawYear); 5898 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 5899 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 5900 for ( month = 0; month < 12; month++) { 5901 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 5902 monthHtml += "<option value='" + month + "'" + 5903 (month === drawMonth ? " selected='selected'" : "") + 5904 ">" + monthNamesShort[month] + "</option>"; 5905 } 5906 } 5907 monthHtml += "</select>"; 5908 } 5909 5910 if (!showMonthAfterYear) { 5911 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 5912 } 5913 5914 // year selection 5915 if ( !inst.yearshtml ) { 5916 inst.yearshtml = ""; 5917 if (secondary || !changeYear) { 5918 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 5919 } else { 5920 // determine range of years to display 5921 years = this._get(inst, "yearRange").split(":"); 5922 thisYear = new Date().getFullYear(); 5923 determineYear = function(value) { 5924 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 5925 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 5926 parseInt(value, 10))); 5927 return (isNaN(year) ? thisYear : year); 5928 }; 5929 year = determineYear(years[0]); 5930 endYear = Math.max(year, determineYear(years[1] || "")); 5931 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 5932 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 5933 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 5934 for (; year <= endYear; year++) { 5935 inst.yearshtml += "<option value='" + year + "'" + 5936 (year === drawYear ? " selected='selected'" : "") + 5937 ">" + year + "</option>"; 5938 } 5939 inst.yearshtml += "</select>"; 5940 5941 html += inst.yearshtml; 5942 inst.yearshtml = null; 5943 } 5944 } 5945 5946 html += this._get(inst, "yearSuffix"); 5947 if (showMonthAfterYear) { 5948 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 5949 } 5950 html += "</div>"; // Close datepicker_header 5951 return html; 5952 }, 5953 5954 /* Adjust one of the date sub-fields. */ 5955 _adjustInstDate: function(inst, offset, period) { 5956 var year = inst.drawYear + (period === "Y" ? offset : 0), 5957 month = inst.drawMonth + (period === "M" ? offset : 0), 5958 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 5959 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 5960 5961 inst.selectedDay = date.getDate(); 5962 inst.drawMonth = inst.selectedMonth = date.getMonth(); 5963 inst.drawYear = inst.selectedYear = date.getFullYear(); 5964 if (period === "M" || period === "Y") { 5965 this._notifyChange(inst); 5966 } 5967 }, 5968 5969 /* Ensure a date is within any min/max bounds. */ 5970 _restrictMinMax: function(inst, date) { 5971 var minDate = this._getMinMaxDate(inst, "min"), 5972 maxDate = this._getMinMaxDate(inst, "max"), 5973 newDate = (minDate && date < minDate ? minDate : date); 5974 return (maxDate && newDate > maxDate ? maxDate : newDate); 5975 }, 5976 5977 /* Notify change of month/year. */ 5978 _notifyChange: function(inst) { 5979 var onChange = this._get(inst, "onChangeMonthYear"); 5980 if (onChange) { 5981 onChange.apply((inst.input ? inst.input[0] : null), 5982 [inst.selectedYear, inst.selectedMonth + 1, inst]); 5983 } 5984 }, 5985 5986 /* Determine the number of months to show. */ 5987 _getNumberOfMonths: function(inst) { 5988 var numMonths = this._get(inst, "numberOfMonths"); 5989 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 5990 }, 5991 5992 /* Determine the current maximum date - ensure no time components are set. */ 5993 _getMinMaxDate: function(inst, minMax) { 5994 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 5995 }, 5996 5997 /* Find the number of days in a given month. */ 5998 _getDaysInMonth: function(year, month) { 5999 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 6000 }, 6001 6002 /* Find the day of the week of the first of a month. */ 6003 _getFirstDayOfMonth: function(year, month) { 6004 return new Date(year, month, 1).getDay(); 6005 }, 6006 6007 /* Determines if we should allow a "next/prev" month display change. */ 6008 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 6009 var numMonths = this._getNumberOfMonths(inst), 6010 date = this._daylightSavingAdjust(new Date(curYear, 6011 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 6012 6013 if (offset < 0) { 6014 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 6015 } 6016 return this._isInRange(inst, date); 6017 }, 6018 6019 /* Is the given date in the accepted range? */ 6020 _isInRange: function(inst, date) { 6021 var yearSplit, currentYear, 6022 minDate = this._getMinMaxDate(inst, "min"),
vendor: 4,850 bytes, lines 6023-6153
6023 maxDate = this._getMinMaxDate(inst, "max"), 6024 minYear = null, 6025 maxYear = null, 6026 years = this._get(inst, "yearRange"); 6027 if (years){ 6028 yearSplit = years.split(":"); 6029 currentYear = new Date().getFullYear(); 6030 minYear = parseInt(yearSplit[0], 10); 6031 maxYear = parseInt(yearSplit[1], 10); 6032 if ( yearSplit[0].match(/[+\-].*/) ) { 6033 minYear += currentYear; 6034 } 6035 if ( yearSplit[1].match(/[+\-].*/) ) { 6036 maxYear += currentYear; 6037 } 6038 } 6039 6040 return ((!minDate || date.getTime() >= minDate.getTime()) && 6041 (!maxDate || date.getTime() <= maxDate.getTime()) && 6042 (!minYear || date.getFullYear() >= minYear) && 6043 (!maxYear || date.getFullYear() <= maxYear)); 6044 }, 6045 6046 /* Provide the configuration settings for formatting/parsing. */ 6047 _getFormatConfig: function(inst) { 6048 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 6049 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 6050 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 6051 return {shortYearCutoff: shortYearCutoff, 6052 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 6053 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 6054 }, 6055 6056 /* Format the given date for display. */ 6057 _formatDate: function(inst, day, month, year) { 6058 if (!day) { 6059 inst.currentDay = inst.selectedDay; 6060 inst.currentMonth = inst.selectedMonth; 6061 inst.currentYear = inst.selectedYear; 6062 } 6063 var date = (day ? (typeof day === "object" ? day : 6064 this._daylightSavingAdjust(new Date(year, month, day))) : 6065 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 6066 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 6067 } 6068}); 6069 6070/* 6071 * Bind hover events for datepicker elements. 6072 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 6073 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 6074 */ 6075function datepicker_bindHover(dpDiv) { 6076 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 6077 return dpDiv.delegate(selector, "mouseout", function() { 6078 $(this).removeClass("ui-state-hover"); 6079 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 6080 $(this).removeClass("ui-datepicker-prev-hover"); 6081 } 6082 if (this.className.indexOf("ui-datepicker-next") !== -1) { 6083 $(this).removeClass("ui-datepicker-next-hover"); 6084 } 6085 }) 6086 .delegate( selector, "mouseover", datepicker_handleMouseover ); 6087} 6088 6089function datepicker_handleMouseover() { 6090 if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { 6091 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 6092 $(this).addClass("ui-state-hover"); 6093 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 6094 $(this).addClass("ui-datepicker-prev-hover"); 6095 } 6096 if (this.className.indexOf("ui-datepicker-next") !== -1) { 6097 $(this).addClass("ui-datepicker-next-hover"); 6098 } 6099 } 6100} 6101 6102/* jQuery extend now ignores nulls! */ 6103function datepicker_extendRemove(target, props) { 6104 $.extend(target, props); 6105 for (var name in props) { 6106 if (props[name] == null) { 6107 target[name] = props[name]; 6108 } 6109 } 6110 return target; 6111} 6112 6113/* Invoke the datepicker functionality. 6114 @param options string - a command, optionally followed by additional parameters or 6115 Object - settings for attaching new datepicker functionality 6116 @return jQuery object */ 6117$.fn.datepicker = function(options){ 6118 6119 /* Verify an empty collection wasn't passed - Fixes #6976 */ 6120 if ( !this.length ) { 6121 return this; 6122 } 6123 6124 /* Initialise the date picker. */ 6125 if (!$.datepicker.initialized) { 6126 $(document).mousedown($.datepicker._checkExternalClick); 6127 $.datepicker.initialized = true; 6128 } 6129 6130 /* Append datepicker main container to body if not exist. */ 6131 if ($("#"+$.datepicker._mainDivId).length === 0) { 6132 $("body").append($.datepicker.dpDiv); 6133 } 6134 6135 var otherArgs = Array.prototype.slice.call(arguments, 1); 6136 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 6137 return $.datepicker["_" + options + "Datepicker"]. 6138 apply($.datepicker, [this[0]].concat(otherArgs)); 6139 } 6140 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 6141 return $.datepicker["_" + options + "Datepicker"]. 6142 apply($.datepicker, [this[0]].concat(otherArgs)); 6143 } 6144 return this.each(function() { 6145 typeof options === "string" ? 6146 $.datepicker["_" + options + "Datepicker"]. 6147 apply($.datepicker, [this].concat(otherArgs)) : 6148 $.datepicker._attachDatepicker(this, options); 6149 }); 6150}; 6151 6152$.datepicker = new Datepicker(); // singleton instance 6153$.datepicker.initialized = false;
vendor: 284,398 bytes, lines 6154-16741
6154$.datepicker.uuid = new Date().getTime(); 6155$.datepicker.version = "1.11.1"; 6156 6157var datepicker = $.datepicker; 6158 6159 6160/*! 6161 * jQuery UI Draggable 1.11.1 6162 * http://jqueryui.com 6163 * 6164 * Copyright 2014 jQuery Foundation and other contributors 6165 * Released under the MIT license. 6166 * http://jquery.org/license 6167 * 6168 * http://api.jqueryui.com/draggable/ 6169 */ 6170 6171 6172$.widget("ui.draggable", $.ui.mouse, { 6173 version: "1.11.1", 6174 widgetEventPrefix: "drag", 6175 options: { 6176 addClasses: true, 6177 appendTo: "parent", 6178 axis: false, 6179 connectToSortable: false, 6180 containment: false, 6181 cursor: "auto", 6182 cursorAt: false, 6183 grid: false, 6184 handle: false, 6185 helper: "original", 6186 iframeFix: false, 6187 opacity: false, 6188 refreshPositions: false, 6189 revert: false, 6190 revertDuration: 500, 6191 scope: "default", 6192 scroll: true, 6193 scrollSensitivity: 20, 6194 scrollSpeed: 20, 6195 snap: false, 6196 snapMode: "both", 6197 snapTolerance: 20, 6198 stack: false, 6199 zIndex: false, 6200 6201 // callbacks 6202 drag: null, 6203 start: null, 6204 stop: null 6205 }, 6206 _create: function() { 6207 6208 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 6209 this.element[0].style.position = "relative"; 6210 } 6211 if (this.options.addClasses){ 6212 this.element.addClass("ui-draggable"); 6213 } 6214 if (this.options.disabled){ 6215 this.element.addClass("ui-draggable-disabled"); 6216 } 6217 this._setHandleClassName(); 6218 6219 this._mouseInit(); 6220 }, 6221 6222 _setOption: function( key, value ) { 6223 this._super( key, value ); 6224 if ( key === "handle" ) { 6225 this._removeHandleClassName(); 6226 this._setHandleClassName(); 6227 } 6228 }, 6229 6230 _destroy: function() { 6231 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 6232 this.destroyOnClear = true; 6233 return; 6234 } 6235 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 6236 this._removeHandleClassName(); 6237 this._mouseDestroy(); 6238 }, 6239 6240 _mouseCapture: function(event) { 6241 6242 var document = this.document[ 0 ], 6243 o = this.options; 6244 6245 // support: IE9 6246 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 6247 try { 6248 // Support: IE9+ 6249 // If the <body> is blurred, IE will switch windows, see #9520 6250 if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { 6251 // Blur any element that currently has focus, see #4261 6252 $( document.activeElement ).blur(); 6253 } 6254 } catch ( error ) {} 6255 6256 // among others, prevent a drag on a resizable-handle 6257 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 6258 return false; 6259 } 6260 6261 //Quit if we're not on a valid handle 6262 this.handle = this._getHandle(event); 6263 if (!this.handle) { 6264 return false; 6265 } 6266 6267 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 6268 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 6269 .css({ 6270 width: this.offsetWidth + "px", height: this.offsetHeight + "px", 6271 position: "absolute", opacity: "0.001", zIndex: 1000 6272 }) 6273 .css($(this).offset()) 6274 .appendTo("body"); 6275 }); 6276 6277 return true; 6278 6279 }, 6280 6281 _mouseStart: function(event) { 6282 6283 var o = this.options; 6284 6285 //Create and append the visible helper 6286 this.helper = this._createHelper(event); 6287 6288 this.helper.addClass("ui-draggable-dragging"); 6289 6290 //Cache the helper size 6291 this._cacheHelperProportions(); 6292 6293 //If ddmanager is used for droppables, set the global draggable 6294 if ($.ui.ddmanager) { 6295 $.ui.ddmanager.current = this; 6296 } 6297 6298 /* 6299 * - Position generation - 6300 * This block generates everything position related - it's the core of draggables. 6301 */ 6302 6303 //Cache the margins of the original element 6304 this._cacheMargins(); 6305 6306 //Store the helper's css position 6307 this.cssPosition = this.helper.css( "position" ); 6308 this.scrollParent = this.helper.scrollParent( true ); 6309 this.offsetParent = this.helper.offsetParent(); 6310 this.offsetParentCssPosition = this.offsetParent.css( "position" ); 6311 6312 //The element's absolute position on the page minus margins 6313 this.offset = this.positionAbs = this.element.offset(); 6314 this.offset = { 6315 top: this.offset.top - this.margins.top, 6316 left: this.offset.left - this.margins.left 6317 }; 6318 6319 //Reset scroll cache 6320 this.offset.scroll = false; 6321 6322 $.extend(this.offset, { 6323 click: { //Where the click happened, relative to the element 6324 left: event.pageX - this.offset.left, 6325 top: event.pageY - this.offset.top 6326 }, 6327 parent: this._getParentOffset(), 6328 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 6329 }); 6330 6331 //Generate the original position 6332 this.originalPosition = this.position = this._generatePosition( event, false ); 6333 this.originalPageX = event.pageX; 6334 this.originalPageY = event.pageY; 6335 6336 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 6337 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 6338 6339 //Set a containment if given in the options 6340 this._setContainment(); 6341 6342 //Trigger event + callbacks 6343 if (this._trigger("start", event) === false) { 6344 this._clear(); 6345 return false; 6346 } 6347 6348 //Recache the helper size 6349 this._cacheHelperProportions(); 6350 6351 //Prepare the droppable offsets 6352 if ($.ui.ddmanager && !o.dropBehaviour) { 6353 $.ui.ddmanager.prepareOffsets(this, event); 6354 } 6355 6356 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 6357 6358 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 6359 if ( $.ui.ddmanager ) { 6360 $.ui.ddmanager.dragStart(this, event); 6361 } 6362 6363 return true; 6364 }, 6365 6366 _mouseDrag: function(event, noPropagation) { 6367 // reset any necessary cached properties (see #5009) 6368 if ( this.offsetParentCssPosition === "fixed" ) { 6369 this.offset.parent = this._getParentOffset(); 6370 } 6371 6372 //Compute the helpers position 6373 this.position = this._generatePosition( event, true ); 6374 this.positionAbs = this._convertPositionTo("absolute"); 6375 6376 //Call plugins and callbacks and use the resulting position if something is returned 6377 if (!noPropagation) { 6378 var ui = this._uiHash(); 6379 if (this._trigger("drag", event, ui) === false) { 6380 this._mouseUp({}); 6381 return false; 6382 } 6383 this.position = ui.position; 6384 } 6385 6386 this.helper[ 0 ].style.left = this.position.left + "px"; 6387 this.helper[ 0 ].style.top = this.position.top + "px"; 6388 6389 if ($.ui.ddmanager) { 6390 $.ui.ddmanager.drag(this, event); 6391 } 6392 6393 return false; 6394 }, 6395 6396 _mouseStop: function(event) { 6397 6398 //If we are using droppables, inform the manager about the drop 6399 var that = this, 6400 dropped = false; 6401 if ($.ui.ddmanager && !this.options.dropBehaviour) { 6402 dropped = $.ui.ddmanager.drop(this, event); 6403 } 6404 6405 //if a drop comes from outside (a sortable) 6406 if (this.dropped) { 6407 dropped = this.dropped; 6408 this.dropped = false; 6409 } 6410 6411 if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { 6412 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 6413 if (that._trigger("stop", event) !== false) { 6414 that._clear(); 6415 } 6416 }); 6417 } else { 6418 if (this._trigger("stop", event) !== false) { 6419 this._clear(); 6420 } 6421 } 6422 6423 return false; 6424 }, 6425 6426 _mouseUp: function(event) { 6427 //Remove frame helpers 6428 $("div.ui-draggable-iframeFix").each(function() { 6429 this.parentNode.removeChild(this); 6430 }); 6431 6432 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 6433 if ( $.ui.ddmanager ) { 6434 $.ui.ddmanager.dragStop(this, event); 6435 } 6436 6437 // The interaction is over; whether or not the click resulted in a drag, focus the element 6438 this.element.focus(); 6439 6440 return $.ui.mouse.prototype._mouseUp.call(this, event); 6441 }, 6442 6443 cancel: function() { 6444 6445 if (this.helper.is(".ui-draggable-dragging")) { 6446 this._mouseUp({}); 6447 } else { 6448 this._clear(); 6449 } 6450 6451 return this; 6452 6453 }, 6454 6455 _getHandle: function(event) { 6456 return this.options.handle ? 6457 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 6458 true; 6459 }, 6460 6461 _setHandleClassName: function() { 6462 this.handleElement = this.options.handle ? 6463 this.element.find( this.options.handle ) : this.element; 6464 this.handleElement.addClass( "ui-draggable-handle" ); 6465 }, 6466 6467 _removeHandleClassName: function() { 6468 this.handleElement.removeClass( "ui-draggable-handle" ); 6469 }, 6470 6471 _createHelper: function(event) { 6472 6473 var o = this.options, 6474 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[ 0 ], [ event ])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 6475 6476 if (!helper.parents("body").length) { 6477 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 6478 } 6479 6480 if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 6481 helper.css("position", "absolute"); 6482 } 6483 6484 return helper; 6485 6486 }, 6487 6488 _adjustOffsetFromHelper: function(obj) { 6489 if (typeof obj === "string") { 6490 obj = obj.split(" "); 6491 } 6492 if ($.isArray(obj)) { 6493 obj = { left: +obj[0], top: +obj[1] || 0 }; 6494 } 6495 if ("left" in obj) { 6496 this.offset.click.left = obj.left + this.margins.left; 6497 } 6498 if ("right" in obj) { 6499 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6500 } 6501 if ("top" in obj) { 6502 this.offset.click.top = obj.top + this.margins.top; 6503 } 6504 if ("bottom" in obj) { 6505 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6506 } 6507 }, 6508 6509 _isRootNode: function( element ) { 6510 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 6511 }, 6512 6513 _getParentOffset: function() { 6514 6515 //Get the offsetParent and cache its position 6516 var po = this.offsetParent.offset(), 6517 document = this.document[ 0 ]; 6518 6519 // This is a special case where we need to modify a offset calculated on start, since the following happened: 6520 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 6521 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 6522 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 6523 if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 6524 po.left += this.scrollParent.scrollLeft(); 6525 po.top += this.scrollParent.scrollTop(); 6526 } 6527 6528 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 6529 po = { top: 0, left: 0 }; 6530 } 6531 6532 return { 6533 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), 6534 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) 6535 }; 6536 6537 }, 6538 6539 _getRelativeOffset: function() { 6540 if ( this.cssPosition !== "relative" ) { 6541 return { top: 0, left: 0 }; 6542 } 6543 6544 var p = this.element.position(), 6545 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 6546 6547 return { 6548 top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 6549 left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 6550 }; 6551 6552 }, 6553 6554 _cacheMargins: function() { 6555 this.margins = { 6556 left: (parseInt(this.element.css("marginLeft"), 10) || 0), 6557 top: (parseInt(this.element.css("marginTop"), 10) || 0), 6558 right: (parseInt(this.element.css("marginRight"), 10) || 0), 6559 bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) 6560 }; 6561 }, 6562 6563 _cacheHelperProportions: function() { 6564 this.helperProportions = { 6565 width: this.helper.outerWidth(), 6566 height: this.helper.outerHeight() 6567 }; 6568 }, 6569 6570 _setContainment: function() { 6571 6572 var over, c, ce, 6573 o = this.options, 6574 document = this.document[ 0 ]; 6575 6576 this.relativeContainer = null; 6577 6578 if ( !o.containment ) { 6579 this.containment = null; 6580 return; 6581 } 6582 6583 if ( o.containment === "window" ) { 6584 this.containment = [ 6585 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 6586 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 6587 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 6588 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6589 ]; 6590 return; 6591 } 6592 6593 if ( o.containment === "document") { 6594 this.containment = [ 6595 0, 6596 0, 6597 $( document ).width() - this.helperProportions.width - this.margins.left, 6598 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 6599 ]; 6600 return; 6601 } 6602 6603 if ( o.containment.constructor === Array ) { 6604 this.containment = o.containment; 6605 return; 6606 } 6607 6608 if ( o.containment === "parent" ) { 6609 o.containment = this.helper[ 0 ].parentNode; 6610 } 6611 6612 c = $( o.containment ); 6613 ce = c[ 0 ]; 6614 6615 if ( !ce ) { 6616 return; 6617 } 6618 6619 over = c.css( "overflow" ) !== "hidden"; 6620 6621 this.containment = [ 6622 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 6623 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 6624 ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, 6625 ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom 6626 ]; 6627 this.relativeContainer = c; 6628 }, 6629 6630 _convertPositionTo: function(d, pos) { 6631 6632 if (!pos) { 6633 pos = this.position; 6634 } 6635 6636 var mod = d === "absolute" ? 1 : -1, 6637 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 6638 6639 return { 6640 top: ( 6641 pos.top + // The absolute mouse position 6642 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6643 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 6644 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) 6645 ), 6646 left: ( 6647 pos.left + // The absolute mouse position 6648 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 6649 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 6650 ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) 6651 ) 6652 }; 6653 6654 }, 6655 6656 _generatePosition: function( event, constrainPosition ) { 6657 6658 var containment, co, top, left, 6659 o = this.options, 6660 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 6661 pageX = event.pageX, 6662 pageY = event.pageY; 6663 6664 // Cache the scroll 6665 if ( !scrollIsRootNode || !this.offset.scroll ) { 6666 this.offset.scroll = { 6667 top: this.scrollParent.scrollTop(), 6668 left: this.scrollParent.scrollLeft() 6669 }; 6670 } 6671 6672 /* 6673 * - Position constraining - 6674 * Constrain the position to a mix of grid, containment. 6675 */ 6676 6677 // If we are not dragging yet, we won't check for options 6678 if ( constrainPosition ) { 6679 if ( this.containment ) { 6680 if ( this.relativeContainer ){ 6681 co = this.relativeContainer.offset(); 6682 containment = [ 6683 this.containment[ 0 ] + co.left, 6684 this.containment[ 1 ] + co.top, 6685 this.containment[ 2 ] + co.left, 6686 this.containment[ 3 ] + co.top 6687 ]; 6688 } else { 6689 containment = this.containment; 6690 } 6691 6692 if (event.pageX - this.offset.click.left < containment[0]) { 6693 pageX = containment[0] + this.offset.click.left; 6694 } 6695 if (event.pageY - this.offset.click.top < containment[1]) { 6696 pageY = containment[1] + this.offset.click.top; 6697 } 6698 if (event.pageX - this.offset.click.left > containment[2]) { 6699 pageX = containment[2] + this.offset.click.left; 6700 } 6701 if (event.pageY - this.offset.click.top > containment[3]) { 6702 pageY = containment[3] + this.offset.click.top; 6703 } 6704 } 6705 6706 if (o.grid) { 6707 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 6708 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 6709 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 6710 6711 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 6712 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 6713 } 6714 6715 if ( o.axis === "y" ) { 6716 pageX = this.originalPageX; 6717 } 6718 6719 if ( o.axis === "x" ) { 6720 pageY = this.originalPageY; 6721 } 6722 } 6723 6724 return { 6725 top: ( 6726 pageY - // The absolute mouse position 6727 this.offset.click.top - // Click offset (relative to the element) 6728 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 6729 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 6730 ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 6731 ), 6732 left: ( 6733 pageX - // The absolute mouse position 6734 this.offset.click.left - // Click offset (relative to the element) 6735 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 6736 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 6737 ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 6738 ) 6739 }; 6740 6741 }, 6742 6743 _clear: function() { 6744 this.helper.removeClass("ui-draggable-dragging"); 6745 if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 6746 this.helper.remove(); 6747 } 6748 this.helper = null; 6749 this.cancelHelperRemoval = false; 6750 if ( this.destroyOnClear ) { 6751 this.destroy(); 6752 } 6753 }, 6754 6755 // From now on bulk stuff - mainly helpers 6756 6757 _trigger: function(type, event, ui) { 6758 ui = ui || this._uiHash(); 6759 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 6760 //The absolute position has to be recalculated after plugins 6761 if (type === "drag") { 6762 this.positionAbs = this._convertPositionTo("absolute"); 6763 } 6764 return $.Widget.prototype._trigger.call(this, type, event, ui); 6765 }, 6766 6767 plugins: {}, 6768 6769 _uiHash: function() { 6770 return { 6771 helper: this.helper, 6772 position: this.position, 6773 originalPosition: this.originalPosition, 6774 offset: this.positionAbs 6775 }; 6776 } 6777 6778}); 6779 6780$.ui.plugin.add("draggable", "connectToSortable", { 6781 start: function( event, ui, inst ) { 6782 6783 var o = inst.options, 6784 uiSortable = $.extend({}, ui, { item: inst.element }); 6785 inst.sortables = []; 6786 $(o.connectToSortable).each(function() { 6787 var sortable = $( this ).sortable( "instance" ); 6788 if (sortable && !sortable.options.disabled) { 6789 inst.sortables.push({ 6790 instance: sortable, 6791 shouldRevert: sortable.options.revert 6792 }); 6793 sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). 6794 sortable._trigger("activate", event, uiSortable); 6795 } 6796 }); 6797 6798 }, 6799 stop: function( event, ui, inst ) { 6800 6801 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 6802 var uiSortable = $.extend( {}, ui, { 6803 item: inst.element 6804 }); 6805 6806 $.each(inst.sortables, function() { 6807 if (this.instance.isOver) { 6808 6809 this.instance.isOver = 0; 6810 6811 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 6812 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 6813 6814 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 6815 if (this.shouldRevert) { 6816 this.instance.options.revert = this.shouldRevert; 6817 } 6818 6819 //Trigger the stop of the sortable 6820 this.instance._mouseStop(event); 6821 6822 this.instance.options.helper = this.instance.options._helper; 6823 6824 //If the helper has been the original item, restore properties in the sortable 6825 if (inst.options.helper === "original") { 6826 this.instance.currentItem.css({ top: "auto", left: "auto" }); 6827 } 6828 6829 } else { 6830 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 6831 this.instance._trigger("deactivate", event, uiSortable); 6832 } 6833 6834 }); 6835 6836 }, 6837 drag: function( event, ui, inst ) { 6838 6839 var that = this; 6840 6841 $.each(inst.sortables, function() { 6842 6843 var innermostIntersecting = false, 6844 thisSortable = this; 6845 6846 //Copy over some variables to allow calling the sortable's native _intersectsWith 6847 this.instance.positionAbs = inst.positionAbs; 6848 this.instance.helperProportions = inst.helperProportions; 6849 this.instance.offset.click = inst.offset.click; 6850 6851 if (this.instance._intersectsWith(this.instance.containerCache)) { 6852 innermostIntersecting = true; 6853 $.each(inst.sortables, function() { 6854 this.instance.positionAbs = inst.positionAbs; 6855 this.instance.helperProportions = inst.helperProportions; 6856 this.instance.offset.click = inst.offset.click; 6857 if (this !== thisSortable && 6858 this.instance._intersectsWith(this.instance.containerCache) && 6859 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 6860 ) { 6861 innermostIntersecting = false; 6862 } 6863 return innermostIntersecting; 6864 }); 6865 } 6866 6867 if (innermostIntersecting) { 6868 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 6869 if (!this.instance.isOver) { 6870 6871 this.instance.isOver = 1; 6872 //Now we fake the start of dragging for the sortable instance, 6873 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 6874 //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) 6875 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 6876 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 6877 this.instance.options.helper = function() { return ui.helper[0]; }; 6878 6879 event.target = this.instance.currentItem[0]; 6880 this.instance._mouseCapture(event, true); 6881 this.instance._mouseStart(event, true, true); 6882 6883 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 6884 this.instance.offset.click.top = inst.offset.click.top; 6885 this.instance.offset.click.left = inst.offset.click.left; 6886 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 6887 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 6888 6889 inst._trigger("toSortable", event); 6890 inst.dropped = this.instance.element; //draggable revert needs that 6891 //hack so receive/update callbacks work (mostly) 6892 inst.currentItem = inst.element; 6893 this.instance.fromOutside = inst; 6894 6895 } 6896 6897 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable 6898 if (this.instance.currentItem) { 6899 this.instance._mouseDrag(event); 6900 } 6901 6902 } else { 6903 6904 //If it doesn't intersect with the sortable, and it intersected before, 6905 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 6906 if (this.instance.isOver) { 6907 6908 this.instance.isOver = 0; 6909 this.instance.cancelHelperRemoval = true; 6910 6911 //Prevent reverting on this forced stop 6912 this.instance.options.revert = false; 6913 6914 // The out event needs to be triggered independently 6915 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 6916 6917 this.instance._mouseStop(event, true); 6918 this.instance.options.helper = this.instance.options._helper; 6919 6920 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 6921 this.instance.currentItem.remove(); 6922 if (this.instance.placeholder) { 6923 this.instance.placeholder.remove(); 6924 } 6925 6926 inst._trigger("fromSortable", event); 6927 inst.dropped = false; //draggable revert needs that 6928 } 6929 6930 } 6931 6932 }); 6933 6934 } 6935}); 6936 6937$.ui.plugin.add("draggable", "cursor", { 6938 start: function( event, ui, instance ) { 6939 var t = $( "body" ), 6940 o = instance.options; 6941 6942 if (t.css("cursor")) { 6943 o._cursor = t.css("cursor"); 6944 } 6945 t.css("cursor", o.cursor); 6946 }, 6947 stop: function( event, ui, instance ) { 6948 var o = instance.options; 6949 if (o._cursor) { 6950 $("body").css("cursor", o._cursor); 6951 } 6952 } 6953}); 6954 6955$.ui.plugin.add("draggable", "opacity", { 6956 start: function( event, ui, instance ) { 6957 var t = $( ui.helper ), 6958 o = instance.options; 6959 if (t.css("opacity")) { 6960 o._opacity = t.css("opacity"); 6961 } 6962 t.css("opacity", o.opacity); 6963 }, 6964 stop: function( event, ui, instance ) { 6965 var o = instance.options; 6966 if (o._opacity) { 6967 $(ui.helper).css("opacity", o._opacity); 6968 } 6969 } 6970}); 6971 6972$.ui.plugin.add("draggable", "scroll", { 6973 start: function( event, ui, i ) { 6974 if ( !i.scrollParentNotHidden ) { 6975 i.scrollParentNotHidden = i.helper.scrollParent( false ); 6976 } 6977 6978 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 6979 i.overflowOffset = i.scrollParentNotHidden.offset(); 6980 } 6981 }, 6982 drag: function( event, ui, i ) { 6983 6984 var o = i.options, 6985 scrolled = false, 6986 scrollParent = i.scrollParentNotHidden[ 0 ], 6987 document = i.document[ 0 ]; 6988 6989 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 6990 if ( !o.axis || o.axis !== "x" ) { 6991 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { 6992 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 6993 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 6994 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 6995 } 6996 } 6997 6998 if ( !o.axis || o.axis !== "y" ) { 6999 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { 7000 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 7001 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 7002 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 7003 } 7004 } 7005 7006 } else { 7007 7008 if (!o.axis || o.axis !== "x") { 7009 if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 7010 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 7011 } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 7012 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 7013 } 7014 } 7015 7016 if (!o.axis || o.axis !== "y") { 7017 if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 7018 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 7019 } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 7020 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 7021 } 7022 } 7023 7024 } 7025 7026 if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 7027 $.ui.ddmanager.prepareOffsets(i, event); 7028 } 7029 7030 } 7031}); 7032 7033$.ui.plugin.add("draggable", "snap", { 7034 start: function( event, ui, i ) { 7035 7036 var o = i.options; 7037 7038 i.snapElements = []; 7039 7040 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 7041 var $t = $(this), 7042 $o = $t.offset(); 7043 if (this !== i.element[0]) { 7044 i.snapElements.push({ 7045 item: this, 7046 width: $t.outerWidth(), height: $t.outerHeight(), 7047 top: $o.top, left: $o.left 7048 }); 7049 } 7050 }); 7051 7052 }, 7053 drag: function( event, ui, inst ) { 7054 7055 var ts, bs, ls, rs, l, r, t, b, i, first, 7056 o = inst.options, 7057 d = o.snapTolerance, 7058 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 7059 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 7060 7061 for (i = inst.snapElements.length - 1; i >= 0; i--){ 7062 7063 l = inst.snapElements[i].left; 7064 r = l + inst.snapElements[i].width; 7065 t = inst.snapElements[i].top; 7066 b = t + inst.snapElements[i].height; 7067 7068 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 7069 if (inst.snapElements[i].snapping) { 7070 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 7071 } 7072 inst.snapElements[i].snapping = false; 7073 continue; 7074 } 7075 7076 if (o.snapMode !== "inner") { 7077 ts = Math.abs(t - y2) <= d; 7078 bs = Math.abs(b - y1) <= d; 7079 ls = Math.abs(l - x2) <= d; 7080 rs = Math.abs(r - x1) <= d; 7081 if (ts) { 7082 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 7083 } 7084 if (bs) { 7085 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 7086 } 7087 if (ls) { 7088 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 7089 } 7090 if (rs) { 7091 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 7092 } 7093 } 7094 7095 first = (ts || bs || ls || rs); 7096 7097 if (o.snapMode !== "outer") { 7098 ts = Math.abs(t - y1) <= d; 7099 bs = Math.abs(b - y2) <= d; 7100 ls = Math.abs(l - x1) <= d; 7101 rs = Math.abs(r - x2) <= d; 7102 if (ts) { 7103 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 7104 } 7105 if (bs) { 7106 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 7107 } 7108 if (ls) { 7109 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 7110 } 7111 if (rs) { 7112 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 7113 } 7114 } 7115 7116 if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 7117 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 7118 } 7119 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 7120 7121 } 7122 7123 } 7124}); 7125 7126$.ui.plugin.add("draggable", "stack", { 7127 start: function( event, ui, instance ) { 7128 var min, 7129 o = instance.options, 7130 group = $.makeArray($(o.stack)).sort(function(a, b) { 7131 return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); 7132 }); 7133 7134 if (!group.length) { return; } 7135 7136 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 7137 $(group).each(function(i) { 7138 $(this).css("zIndex", min + i); 7139 }); 7140 this.css("zIndex", (min + group.length)); 7141 } 7142}); 7143 7144$.ui.plugin.add("draggable", "zIndex", { 7145 start: function( event, ui, instance ) { 7146 var t = $( ui.helper ), 7147 o = instance.options; 7148 7149 if (t.css("zIndex")) { 7150 o._zIndex = t.css("zIndex"); 7151 } 7152 t.css("zIndex", o.zIndex); 7153 }, 7154 stop: function( event, ui, instance ) { 7155 var o = instance.options; 7156 7157 if (o._zIndex) { 7158 $(ui.helper).css("zIndex", o._zIndex); 7159 } 7160 } 7161}); 7162 7163var draggable = $.ui.draggable; 7164 7165 7166/*! 7167 * jQuery UI Resizable 1.11.1 7168 * http://jqueryui.com 7169 * 7170 * Copyright 2014 jQuery Foundation and other contributors 7171 * Released under the MIT license. 7172 * http://jquery.org/license 7173 * 7174 * http://api.jqueryui.com/resizable/ 7175 */ 7176 7177 7178$.widget("ui.resizable", $.ui.mouse, { 7179 version: "1.11.1", 7180 widgetEventPrefix: "resize", 7181 options: { 7182 alsoResize: false, 7183 animate: false, 7184 animateDuration: "slow", 7185 animateEasing: "swing", 7186 aspectRatio: false, 7187 autoHide: false, 7188 containment: false, 7189 ghost: false, 7190 grid: false, 7191 handles: "e,s,se", 7192 helper: false, 7193 maxHeight: null, 7194 maxWidth: null, 7195 minHeight: 10, 7196 minWidth: 10, 7197 // See #7960 7198 zIndex: 90, 7199 7200 // callbacks 7201 resize: null, 7202 start: null, 7203 stop: null 7204 }, 7205 7206 _num: function( value ) { 7207 return parseInt( value, 10 ) || 0; 7208 }, 7209 7210 _isNumber: function( value ) { 7211 return !isNaN( parseInt( value, 10 ) ); 7212 }, 7213 7214 _hasScroll: function( el, a ) { 7215 7216 if ( $( el ).css( "overflow" ) === "hidden") { 7217 return false; 7218 } 7219 7220 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 7221 has = false; 7222 7223 if ( el[ scroll ] > 0 ) { 7224 return true; 7225 } 7226 7227 // TODO: determine which cases actually cause this to happen 7228 // if the element doesn't have the scroll set, see if it's possible to 7229 // set the scroll 7230 el[ scroll ] = 1; 7231 has = ( el[ scroll ] > 0 ); 7232 el[ scroll ] = 0; 7233 return has; 7234 }, 7235 7236 _create: function() { 7237 7238 var n, i, handle, axis, hname, 7239 that = this, 7240 o = this.options; 7241 this.element.addClass("ui-resizable"); 7242 7243 $.extend(this, { 7244 _aspectRatio: !!(o.aspectRatio), 7245 aspectRatio: o.aspectRatio, 7246 originalElement: this.element, 7247 _proportionallyResizeElements: [], 7248 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 7249 }); 7250 7251 // Wrap the element if it cannot hold child nodes 7252 if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 7253 7254 this.element.wrap( 7255 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 7256 position: this.element.css("position"), 7257 width: this.element.outerWidth(), 7258 height: this.element.outerHeight(), 7259 top: this.element.css("top"), 7260 left: this.element.css("left") 7261 }) 7262 ); 7263 7264 this.element = this.element.parent().data( 7265 "ui-resizable", this.element.resizable( "instance" ) 7266 ); 7267 7268 this.elementIsWrapper = true; 7269 7270 this.element.css({ 7271 marginLeft: this.originalElement.css("marginLeft"), 7272 marginTop: this.originalElement.css("marginTop"), 7273 marginRight: this.originalElement.css("marginRight"), 7274 marginBottom: this.originalElement.css("marginBottom") 7275 }); 7276 this.originalElement.css({ 7277 marginLeft: 0, 7278 marginTop: 0, 7279 marginRight: 0, 7280 marginBottom: 0 7281 }); 7282 // support: Safari 7283 // Prevent Safari textarea resize 7284 this.originalResizeStyle = this.originalElement.css("resize"); 7285 this.originalElement.css("resize", "none"); 7286 7287 this._proportionallyResizeElements.push( this.originalElement.css({ 7288 position: "static", 7289 zoom: 1, 7290 display: "block" 7291 }) ); 7292 7293 // support: IE9 7294 // avoid IE jump (hard set the margin) 7295 this.originalElement.css({ margin: this.originalElement.css("margin") }); 7296 7297 this._proportionallyResize(); 7298 } 7299 7300 this.handles = o.handles || 7301 ( !$(".ui-resizable-handle", this.element).length ? 7302 "e,s,se" : { 7303 n: ".ui-resizable-n", 7304 e: ".ui-resizable-e", 7305 s: ".ui-resizable-s", 7306 w: ".ui-resizable-w", 7307 se: ".ui-resizable-se", 7308 sw: ".ui-resizable-sw", 7309 ne: ".ui-resizable-ne", 7310 nw: ".ui-resizable-nw" 7311 } ); 7312 7313 if (this.handles.constructor === String) { 7314 7315 if ( this.handles === "all") { 7316 this.handles = "n,e,s,w,se,sw,ne,nw"; 7317 } 7318 7319 n = this.handles.split(","); 7320 this.handles = {}; 7321 7322 for (i = 0; i < n.length; i++) { 7323 7324 handle = $.trim(n[i]); 7325 hname = "ui-resizable-" + handle; 7326 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 7327 7328 axis.css({ zIndex: o.zIndex }); 7329 7330 // TODO : What's going on here? 7331 if ("se" === handle) { 7332 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 7333 } 7334 7335 this.handles[handle] = ".ui-resizable-" + handle; 7336 this.element.append(axis); 7337 } 7338 7339 } 7340 7341 this._renderAxis = function(target) { 7342 7343 var i, axis, padPos, padWrapper; 7344 7345 target = target || this.element; 7346 7347 for (i in this.handles) { 7348 7349 if (this.handles[i].constructor === String) { 7350 this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); 7351 } 7352 7353 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 7354 7355 axis = $(this.handles[i], this.element); 7356 7357 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 7358 7359 padPos = [ "padding", 7360 /ne|nw|n/.test(i) ? "Top" : 7361 /se|sw|s/.test(i) ? "Bottom" : 7362 /^e$/.test(i) ? "Right" : "Left" ].join(""); 7363 7364 target.css(padPos, padWrapper); 7365 7366 this._proportionallyResize(); 7367 7368 } 7369 7370 // TODO: What's that good for? There's not anything to be executed left 7371 if (!$(this.handles[i]).length) { 7372 continue; 7373 } 7374 } 7375 }; 7376 7377 // TODO: make renderAxis a prototype function 7378 this._renderAxis(this.element); 7379 7380 this._handles = $(".ui-resizable-handle", this.element) 7381 .disableSelection(); 7382 7383 this._handles.mouseover(function() { 7384 if (!that.resizing) { 7385 if (this.className) { 7386 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 7387 } 7388 that.axis = axis && axis[1] ? axis[1] : "se"; 7389 } 7390 }); 7391 7392 if (o.autoHide) { 7393 this._handles.hide(); 7394 $(this.element) 7395 .addClass("ui-resizable-autohide") 7396 .mouseenter(function() { 7397 if (o.disabled) { 7398 return; 7399 } 7400 $(this).removeClass("ui-resizable-autohide"); 7401 that._handles.show(); 7402 }) 7403 .mouseleave(function() { 7404 if (o.disabled) { 7405 return; 7406 } 7407 if (!that.resizing) { 7408 $(this).addClass("ui-resizable-autohide"); 7409 that._handles.hide(); 7410 } 7411 }); 7412 } 7413 7414 this._mouseInit(); 7415 7416 }, 7417 7418 _destroy: function() { 7419 7420 this._mouseDestroy(); 7421 7422 var wrapper, 7423 _destroy = function(exp) { 7424 $(exp) 7425 .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 7426 .removeData("resizable") 7427 .removeData("ui-resizable") 7428 .unbind(".resizable") 7429 .find(".ui-resizable-handle") 7430 .remove(); 7431 }; 7432 7433 // TODO: Unwrap at same DOM position 7434 if (this.elementIsWrapper) { 7435 _destroy(this.element); 7436 wrapper = this.element; 7437 this.originalElement.css({ 7438 position: wrapper.css("position"), 7439 width: wrapper.outerWidth(), 7440 height: wrapper.outerHeight(), 7441 top: wrapper.css("top"), 7442 left: wrapper.css("left") 7443 }).insertAfter( wrapper ); 7444 wrapper.remove(); 7445 } 7446 7447 this.originalElement.css("resize", this.originalResizeStyle); 7448 _destroy(this.originalElement); 7449 7450 return this; 7451 }, 7452 7453 _mouseCapture: function(event) { 7454 var i, handle, 7455 capture = false; 7456 7457 for (i in this.handles) { 7458 handle = $(this.handles[i])[0]; 7459 if (handle === event.target || $.contains(handle, event.target)) { 7460 capture = true; 7461 } 7462 } 7463 7464 return !this.options.disabled && capture; 7465 }, 7466 7467 _mouseStart: function(event) { 7468 7469 var curleft, curtop, cursor, 7470 o = this.options, 7471 el = this.element; 7472 7473 this.resizing = true; 7474 7475 this._renderProxy(); 7476 7477 curleft = this._num(this.helper.css("left")); 7478 curtop = this._num(this.helper.css("top")); 7479 7480 if (o.containment) { 7481 curleft += $(o.containment).scrollLeft() || 0; 7482 curtop += $(o.containment).scrollTop() || 0; 7483 } 7484 7485 this.offset = this.helper.offset(); 7486 this.position = { left: curleft, top: curtop }; 7487 7488 this.size = this._helper ? { 7489 width: this.helper.width(), 7490 height: this.helper.height() 7491 } : { 7492 width: el.width(), 7493 height: el.height() 7494 }; 7495 7496 this.originalSize = this._helper ? { 7497 width: el.outerWidth(), 7498 height: el.outerHeight() 7499 } : { 7500 width: el.width(), 7501 height: el.height() 7502 }; 7503 7504 this.sizeDiff = { 7505 width: el.outerWidth() - el.width(), 7506 height: el.outerHeight() - el.height() 7507 }; 7508 7509 this.originalPosition = { left: curleft, top: curtop }; 7510 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 7511 7512 this.aspectRatio = (typeof o.aspectRatio === "number") ? 7513 o.aspectRatio : 7514 ((this.originalSize.width / this.originalSize.height) || 1); 7515 7516 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 7517 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 7518 7519 el.addClass("ui-resizable-resizing"); 7520 this._propagate("start", event); 7521 return true; 7522 }, 7523 7524 _mouseDrag: function(event) { 7525 7526 var data, props, 7527 smp = this.originalMousePosition, 7528 a = this.axis, 7529 dx = (event.pageX - smp.left) || 0, 7530 dy = (event.pageY - smp.top) || 0, 7531 trigger = this._change[a]; 7532 7533 this._updatePrevProperties(); 7534 7535 if (!trigger) { 7536 return false; 7537 } 7538 7539 data = trigger.apply(this, [ event, dx, dy ]); 7540 7541 this._updateVirtualBoundaries(event.shiftKey); 7542 if (this._aspectRatio || event.shiftKey) { 7543 data = this._updateRatio(data, event); 7544 } 7545 7546 data = this._respectSize(data, event); 7547 7548 this._updateCache(data); 7549 7550 this._propagate("resize", event); 7551 7552 props = this._applyChanges(); 7553 7554 if ( !this._helper && this._proportionallyResizeElements.length ) { 7555 this._proportionallyResize(); 7556 } 7557 7558 if ( !$.isEmptyObject( props ) ) { 7559 this._updatePrevProperties(); 7560 this._trigger( "resize", event, this.ui() ); 7561 this._applyChanges(); 7562 } 7563 7564 return false; 7565 }, 7566 7567 _mouseStop: function(event) { 7568 7569 this.resizing = false; 7570 var pr, ista, soffseth, soffsetw, s, left, top, 7571 o = this.options, that = this; 7572 7573 if (this._helper) { 7574 7575 pr = this._proportionallyResizeElements; 7576 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 7577 soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; 7578 soffsetw = ista ? 0 : that.sizeDiff.width; 7579 7580 s = { 7581 width: (that.helper.width() - soffsetw), 7582 height: (that.helper.height() - soffseth) 7583 }; 7584 left = (parseInt(that.element.css("left"), 10) + 7585 (that.position.left - that.originalPosition.left)) || null; 7586 top = (parseInt(that.element.css("top"), 10) + 7587 (that.position.top - that.originalPosition.top)) || null; 7588 7589 if (!o.animate) { 7590 this.element.css($.extend(s, { top: top, left: left })); 7591 } 7592 7593 that.helper.height(that.size.height); 7594 that.helper.width(that.size.width); 7595 7596 if (this._helper && !o.animate) { 7597 this._proportionallyResize(); 7598 } 7599 } 7600 7601 $("body").css("cursor", "auto"); 7602 7603 this.element.removeClass("ui-resizable-resizing"); 7604 7605 this._propagate("stop", event); 7606 7607 if (this._helper) { 7608 this.helper.remove(); 7609 } 7610 7611 return false; 7612 7613 }, 7614 7615 _updatePrevProperties: function() { 7616 this.prevPosition = { 7617 top: this.position.top, 7618 left: this.position.left 7619 }; 7620 this.prevSize = { 7621 width: this.size.width, 7622 height: this.size.height 7623 }; 7624 }, 7625 7626 _applyChanges: function() { 7627 var props = {}; 7628 7629 if ( this.position.top !== this.prevPosition.top ) { 7630 props.top = this.position.top + "px"; 7631 } 7632 if ( this.position.left !== this.prevPosition.left ) { 7633 props.left = this.position.left + "px"; 7634 } 7635 if ( this.size.width !== this.prevSize.width ) { 7636 props.width = this.size.width + "px"; 7637 } 7638 if ( this.size.height !== this.prevSize.height ) { 7639 props.height = this.size.height + "px"; 7640 } 7641 7642 this.helper.css( props ); 7643 7644 return props; 7645 }, 7646 7647 _updateVirtualBoundaries: function(forceAspectRatio) { 7648 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 7649 o = this.options; 7650 7651 b = { 7652 minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, 7653 maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, 7654 minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, 7655 maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity 7656 }; 7657 7658 if (this._aspectRatio || forceAspectRatio) { 7659 pMinWidth = b.minHeight * this.aspectRatio; 7660 pMinHeight = b.minWidth / this.aspectRatio; 7661 pMaxWidth = b.maxHeight * this.aspectRatio; 7662 pMaxHeight = b.maxWidth / this.aspectRatio; 7663 7664 if (pMinWidth > b.minWidth) { 7665 b.minWidth = pMinWidth; 7666 } 7667 if (pMinHeight > b.minHeight) { 7668 b.minHeight = pMinHeight; 7669 } 7670 if (pMaxWidth < b.maxWidth) { 7671 b.maxWidth = pMaxWidth; 7672 } 7673 if (pMaxHeight < b.maxHeight) { 7674 b.maxHeight = pMaxHeight; 7675 } 7676 } 7677 this._vBoundaries = b; 7678 }, 7679 7680 _updateCache: function(data) { 7681 this.offset = this.helper.offset(); 7682 if (this._isNumber(data.left)) { 7683 this.position.left = data.left; 7684 } 7685 if (this._isNumber(data.top)) { 7686 this.position.top = data.top; 7687 } 7688 if (this._isNumber(data.height)) { 7689 this.size.height = data.height; 7690 } 7691 if (this._isNumber(data.width)) { 7692 this.size.width = data.width; 7693 } 7694 }, 7695 7696 _updateRatio: function( data ) { 7697 7698 var cpos = this.position, 7699 csize = this.size, 7700 a = this.axis; 7701 7702 if (this._isNumber(data.height)) { 7703 data.width = (data.height * this.aspectRatio); 7704 } else if (this._isNumber(data.width)) { 7705 data.height = (data.width / this.aspectRatio); 7706 } 7707 7708 if (a === "sw") { 7709 data.left = cpos.left + (csize.width - data.width); 7710 data.top = null; 7711 } 7712 if (a === "nw") { 7713 data.top = cpos.top + (csize.height - data.height); 7714 data.left = cpos.left + (csize.width - data.width); 7715 } 7716 7717 return data; 7718 }, 7719 7720 _respectSize: function( data ) { 7721 7722 var o = this._vBoundaries, 7723 a = this.axis, 7724 ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), 7725 ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 7726 isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), 7727 isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 7728 dw = this.originalPosition.left + this.originalSize.width, 7729 dh = this.position.top + this.size.height, 7730 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 7731 if (isminw) { 7732 data.width = o.minWidth; 7733 } 7734 if (isminh) { 7735 data.height = o.minHeight; 7736 } 7737 if (ismaxw) { 7738 data.width = o.maxWidth; 7739 } 7740 if (ismaxh) { 7741 data.height = o.maxHeight; 7742 } 7743 7744 if (isminw && cw) { 7745 data.left = dw - o.minWidth; 7746 } 7747 if (ismaxw && cw) { 7748 data.left = dw - o.maxWidth; 7749 } 7750 if (isminh && ch) { 7751 data.top = dh - o.minHeight; 7752 } 7753 if (ismaxh && ch) { 7754 data.top = dh - o.maxHeight; 7755 } 7756 7757 // Fixing jump error on top/left - bug #2330 7758 if (!data.width && !data.height && !data.left && data.top) { 7759 data.top = null; 7760 } else if (!data.width && !data.height && !data.top && data.left) { 7761 data.left = null; 7762 } 7763 7764 return data; 7765 }, 7766 7767 _getPaddingPlusBorderDimensions: function( element ) { 7768 var i = 0, 7769 widths = [], 7770 borders = [ 7771 element.css( "borderTopWidth" ), 7772 element.css( "borderRightWidth" ), 7773 element.css( "borderBottomWidth" ), 7774 element.css( "borderLeftWidth" ) 7775 ], 7776 paddings = [ 7777 element.css( "paddingTop" ), 7778 element.css( "paddingRight" ), 7779 element.css( "paddingBottom" ), 7780 element.css( "paddingLeft" ) 7781 ]; 7782 7783 for ( ; i < 4; i++ ) { 7784 widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); 7785 widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); 7786 } 7787 7788 return { 7789 height: widths[ 0 ] + widths[ 2 ], 7790 width: widths[ 1 ] + widths[ 3 ] 7791 }; 7792 }, 7793 7794 _proportionallyResize: function() { 7795 7796 if (!this._proportionallyResizeElements.length) { 7797 return; 7798 } 7799 7800 var prel, 7801 i = 0, 7802 element = this.helper || this.element; 7803 7804 for ( ; i < this._proportionallyResizeElements.length; i++) { 7805 7806 prel = this._proportionallyResizeElements[i]; 7807 7808 // TODO: Seems like a bug to cache this.outerDimensions 7809 // considering that we are in a loop. 7810 if (!this.outerDimensions) { 7811 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 7812 } 7813 7814 prel.css({ 7815 height: (element.height() - this.outerDimensions.height) || 0, 7816 width: (element.width() - this.outerDimensions.width) || 0 7817 }); 7818 7819 } 7820 7821 }, 7822 7823 _renderProxy: function() { 7824 7825 var el = this.element, o = this.options; 7826 this.elementOffset = el.offset(); 7827 7828 if (this._helper) { 7829 7830 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 7831 7832 this.helper.addClass(this._helper).css({ 7833 width: this.element.outerWidth() - 1, 7834 height: this.element.outerHeight() - 1, 7835 position: "absolute", 7836 left: this.elementOffset.left + "px", 7837 top: this.elementOffset.top + "px", 7838 zIndex: ++o.zIndex //TODO: Don't modify option 7839 }); 7840 7841 this.helper 7842 .appendTo("body") 7843 .disableSelection(); 7844 7845 } else { 7846 this.helper = this.element; 7847 } 7848 7849 }, 7850 7851 _change: { 7852 e: function(event, dx) { 7853 return { width: this.originalSize.width + dx }; 7854 }, 7855 w: function(event, dx) { 7856 var cs = this.originalSize, sp = this.originalPosition; 7857 return { left: sp.left + dx, width: cs.width - dx }; 7858 }, 7859 n: function(event, dx, dy) { 7860 var cs = this.originalSize, sp = this.originalPosition; 7861 return { top: sp.top + dy, height: cs.height - dy }; 7862 }, 7863 s: function(event, dx, dy) { 7864 return { height: this.originalSize.height + dy }; 7865 }, 7866 se: function(event, dx, dy) { 7867 return $.extend(this._change.s.apply(this, arguments), 7868 this._change.e.apply(this, [ event, dx, dy ])); 7869 }, 7870 sw: function(event, dx, dy) { 7871 return $.extend(this._change.s.apply(this, arguments), 7872 this._change.w.apply(this, [ event, dx, dy ])); 7873 }, 7874 ne: function(event, dx, dy) { 7875 return $.extend(this._change.n.apply(this, arguments), 7876 this._change.e.apply(this, [ event, dx, dy ])); 7877 }, 7878 nw: function(event, dx, dy) { 7879 return $.extend(this._change.n.apply(this, arguments), 7880 this._change.w.apply(this, [ event, dx, dy ])); 7881 } 7882 }, 7883 7884 _propagate: function(n, event) { 7885 $.ui.plugin.call(this, n, [ event, this.ui() ]); 7886 (n !== "resize" && this._trigger(n, event, this.ui())); 7887 }, 7888 7889 plugins: {}, 7890 7891 ui: function() { 7892 return { 7893 originalElement: this.originalElement, 7894 element: this.element, 7895 helper: this.helper, 7896 position: this.position, 7897 size: this.size, 7898 originalSize: this.originalSize, 7899 originalPosition: this.originalPosition 7900 }; 7901 } 7902 7903}); 7904 7905/* 7906 * Resizable Extensions 7907 */ 7908 7909$.ui.plugin.add("resizable", "animate", { 7910 7911 stop: function( event ) { 7912 var that = $(this).resizable( "instance" ), 7913 o = that.options, 7914 pr = that._proportionallyResizeElements, 7915 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 7916 soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, 7917 soffsetw = ista ? 0 : that.sizeDiff.width, 7918 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 7919 left = (parseInt(that.element.css("left"), 10) + 7920 (that.position.left - that.originalPosition.left)) || null, 7921 top = (parseInt(that.element.css("top"), 10) + 7922 (that.position.top - that.originalPosition.top)) || null; 7923 7924 that.element.animate( 7925 $.extend(style, top && left ? { top: top, left: left } : {}), { 7926 duration: o.animateDuration, 7927 easing: o.animateEasing, 7928 step: function() { 7929 7930 var data = { 7931 width: parseInt(that.element.css("width"), 10), 7932 height: parseInt(that.element.css("height"), 10), 7933 top: parseInt(that.element.css("top"), 10), 7934 left: parseInt(that.element.css("left"), 10) 7935 }; 7936 7937 if (pr && pr.length) { 7938 $(pr[0]).css({ width: data.width, height: data.height }); 7939 } 7940 7941 // propagating resize, and updating values for each animation step 7942 that._updateCache(data); 7943 that._propagate("resize", event); 7944 7945 } 7946 } 7947 ); 7948 } 7949 7950}); 7951 7952$.ui.plugin.add( "resizable", "containment", { 7953 7954 start: function() { 7955 var element, p, co, ch, cw, width, height, 7956 that = $( this ).resizable( "instance" ), 7957 o = that.options, 7958 el = that.element, 7959 oc = o.containment, 7960 ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 7961 7962 if ( !ce ) { 7963 return; 7964 } 7965 7966 that.containerElement = $( ce ); 7967 7968 if ( /document/.test( oc ) || oc === document ) { 7969 that.containerOffset = { 7970 left: 0, 7971 top: 0 7972 }; 7973 that.containerPosition = { 7974 left: 0, 7975 top: 0 7976 }; 7977 7978 that.parentData = { 7979 element: $( document ), 7980 left: 0, 7981 top: 0, 7982 width: $( document ).width(), 7983 height: $( document ).height() || document.body.parentNode.scrollHeight 7984 }; 7985 } else { 7986 element = $( ce ); 7987 p = []; 7988 $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { 7989 p[ i ] = that._num( element.css( "padding" + name ) ); 7990 }); 7991 7992 that.containerOffset = element.offset(); 7993 that.containerPosition = element.position(); 7994 that.containerSize = { 7995 height: ( element.innerHeight() - p[ 3 ] ), 7996 width: ( element.innerWidth() - p[ 1 ] ) 7997 }; 7998 7999 co = that.containerOffset; 8000 ch = that.containerSize.height; 8001 cw = that.containerSize.width; 8002 width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); 8003 height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; 8004 8005 that.parentData = { 8006 element: ce, 8007 left: co.left, 8008 top: co.top, 8009 width: width, 8010 height: height 8011 }; 8012 } 8013 }, 8014 8015 resize: function( event ) { 8016 var woset, hoset, isParent, isOffsetRelative, 8017 that = $( this ).resizable( "instance" ), 8018 o = that.options, 8019 co = that.containerOffset, 8020 cp = that.position, 8021 pRatio = that._aspectRatio || event.shiftKey, 8022 cop = { 8023 top: 0, 8024 left: 0 8025 }, 8026 ce = that.containerElement, 8027 continueResize = true; 8028 8029 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 8030 cop = co; 8031 } 8032 8033 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 8034 that.size.width = that.size.width + 8035 ( that._helper ? 8036 ( that.position.left - co.left ) : 8037 ( that.position.left - cop.left ) ); 8038 8039 if ( pRatio ) { 8040 that.size.height = that.size.width / that.aspectRatio; 8041 continueResize = false; 8042 } 8043 that.position.left = o.helper ? co.left : 0; 8044 } 8045 8046 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 8047 that.size.height = that.size.height + 8048 ( that._helper ? 8049 ( that.position.top - co.top ) : 8050 that.position.top ); 8051 8052 if ( pRatio ) { 8053 that.size.width = that.size.height * that.aspectRatio; 8054 continueResize = false; 8055 } 8056 that.position.top = that._helper ? co.top : 0; 8057 } 8058 8059 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 8060 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 8061 8062 if ( isParent && isOffsetRelative ) { 8063 that.offset.left = that.parentData.left + that.position.left; 8064 that.offset.top = that.parentData.top + that.position.top; 8065 } else { 8066 that.offset.left = that.element.offset().left; 8067 that.offset.top = that.element.offset().top; 8068 } 8069 8070 woset = Math.abs( that.sizeDiff.width + 8071 (that._helper ? 8072 that.offset.left - cop.left : 8073 (that.offset.left - co.left)) ); 8074 8075 hoset = Math.abs( that.sizeDiff.height + 8076 (that._helper ? 8077 that.offset.top - cop.top : 8078 (that.offset.top - co.top)) ); 8079 8080 if ( woset + that.size.width >= that.parentData.width ) { 8081 that.size.width = that.parentData.width - woset; 8082 if ( pRatio ) { 8083 that.size.height = that.size.width / that.aspectRatio; 8084 continueResize = false; 8085 } 8086 } 8087 8088 if ( hoset + that.size.height >= that.parentData.height ) { 8089 that.size.height = that.parentData.height - hoset; 8090 if ( pRatio ) { 8091 that.size.width = that.size.height * that.aspectRatio; 8092 continueResize = false; 8093 } 8094 } 8095 8096 if ( !continueResize ){ 8097 that.position.left = that.prevPosition.left; 8098 that.position.top = that.prevPosition.top; 8099 that.size.width = that.prevSize.width; 8100 that.size.height = that.prevSize.height; 8101 } 8102 }, 8103 8104 stop: function() { 8105 var that = $( this ).resizable( "instance" ), 8106 o = that.options, 8107 co = that.containerOffset, 8108 cop = that.containerPosition, 8109 ce = that.containerElement, 8110 helper = $( that.helper ), 8111 ho = helper.offset(), 8112 w = helper.outerWidth() - that.sizeDiff.width, 8113 h = helper.outerHeight() - that.sizeDiff.height; 8114 8115 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 8116 $( this ).css({ 8117 left: ho.left - cop.left - co.left, 8118 width: w, 8119 height: h 8120 }); 8121 } 8122 8123 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 8124 $( this ).css({ 8125 left: ho.left - cop.left - co.left, 8126 width: w, 8127 height: h 8128 }); 8129 } 8130 } 8131}); 8132 8133$.ui.plugin.add("resizable", "alsoResize", { 8134 8135 start: function() { 8136 var that = $(this).resizable( "instance" ), 8137 o = that.options, 8138 _store = function(exp) { 8139 $(exp).each(function() { 8140 var el = $(this); 8141 el.data("ui-resizable-alsoresize", { 8142 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 8143 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 8144 }); 8145 }); 8146 }; 8147 8148 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 8149 if (o.alsoResize.length) { 8150 o.alsoResize = o.alsoResize[0]; 8151 _store(o.alsoResize); 8152 } else { 8153 $.each(o.alsoResize, function(exp) { 8154 _store(exp); 8155 }); 8156 } 8157 } else { 8158 _store(o.alsoResize); 8159 } 8160 }, 8161 8162 resize: function(event, ui) { 8163 var that = $(this).resizable( "instance" ), 8164 o = that.options, 8165 os = that.originalSize, 8166 op = that.originalPosition, 8167 delta = { 8168 height: (that.size.height - os.height) || 0, 8169 width: (that.size.width - os.width) || 0, 8170 top: (that.position.top - op.top) || 0, 8171 left: (that.position.left - op.left) || 0 8172 }, 8173 8174 _alsoResize = function(exp, c) { 8175 $(exp).each(function() { 8176 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 8177 css = c && c.length ? 8178 c : 8179 el.parents(ui.originalElement[0]).length ? 8180 [ "width", "height" ] : 8181 [ "width", "height", "top", "left" ]; 8182 8183 $.each(css, function(i, prop) { 8184 var sum = (start[prop] || 0) + (delta[prop] || 0); 8185 if (sum && sum >= 0) { 8186 style[prop] = sum || null; 8187 } 8188 }); 8189 8190 el.css(style); 8191 }); 8192 }; 8193 8194 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 8195 $.each(o.alsoResize, function(exp, c) { 8196 _alsoResize(exp, c); 8197 }); 8198 } else { 8199 _alsoResize(o.alsoResize); 8200 } 8201 }, 8202 8203 stop: function() { 8204 $(this).removeData("resizable-alsoresize"); 8205 } 8206}); 8207 8208$.ui.plugin.add("resizable", "ghost", { 8209 8210 start: function() { 8211 8212 var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; 8213 8214 that.ghost = that.originalElement.clone(); 8215 that.ghost 8216 .css({ 8217 opacity: 0.25, 8218 display: "block", 8219 position: "relative", 8220 height: cs.height, 8221 width: cs.width, 8222 margin: 0, 8223 left: 0, 8224 top: 0 8225 }) 8226 .addClass("ui-resizable-ghost") 8227 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 8228 8229 that.ghost.appendTo(that.helper); 8230 8231 }, 8232 8233 resize: function() { 8234 var that = $(this).resizable( "instance" ); 8235 if (that.ghost) { 8236 that.ghost.css({ 8237 position: "relative", 8238 height: that.size.height, 8239 width: that.size.width 8240 }); 8241 } 8242 }, 8243 8244 stop: function() { 8245 var that = $(this).resizable( "instance" ); 8246 if (that.ghost && that.helper) { 8247 that.helper.get(0).removeChild(that.ghost.get(0)); 8248 } 8249 } 8250 8251}); 8252 8253$.ui.plugin.add("resizable", "grid", { 8254 8255 resize: function() { 8256 var outerDimensions, 8257 that = $(this).resizable( "instance" ), 8258 o = that.options, 8259 cs = that.size, 8260 os = that.originalSize, 8261 op = that.originalPosition, 8262 a = that.axis, 8263 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 8264 gridX = (grid[0] || 1), 8265 gridY = (grid[1] || 1), 8266 ox = Math.round((cs.width - os.width) / gridX) * gridX, 8267 oy = Math.round((cs.height - os.height) / gridY) * gridY, 8268 newWidth = os.width + ox, 8269 newHeight = os.height + oy, 8270 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 8271 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 8272 isMinWidth = o.minWidth && (o.minWidth > newWidth), 8273 isMinHeight = o.minHeight && (o.minHeight > newHeight); 8274 8275 o.grid = grid; 8276 8277 if (isMinWidth) { 8278 newWidth += gridX; 8279 } 8280 if (isMinHeight) { 8281 newHeight += gridY; 8282 } 8283 if (isMaxWidth) { 8284 newWidth -= gridX; 8285 } 8286 if (isMaxHeight) { 8287 newHeight -= gridY; 8288 } 8289 8290 if (/^(se|s|e)$/.test(a)) { 8291 that.size.width = newWidth; 8292 that.size.height = newHeight; 8293 } else if (/^(ne)$/.test(a)) { 8294 that.size.width = newWidth; 8295 that.size.height = newHeight; 8296 that.position.top = op.top - oy; 8297 } else if (/^(sw)$/.test(a)) { 8298 that.size.width = newWidth; 8299 that.size.height = newHeight; 8300 that.position.left = op.left - ox; 8301 } else { 8302 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { 8303 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 8304 } 8305 8306 if ( newHeight - gridY > 0 ) { 8307 that.size.height = newHeight; 8308 that.position.top = op.top - oy; 8309 } else { 8310 newHeight = gridY - outerDimensions.height; 8311 that.size.height = newHeight; 8312 that.position.top = op.top + os.height - newHeight; 8313 } 8314 if ( newWidth - gridX > 0 ) { 8315 that.size.width = newWidth; 8316 that.position.left = op.left - ox; 8317 } else { 8318 newWidth = gridY - outerDimensions.height; 8319 that.size.width = newWidth; 8320 that.position.left = op.left + os.width - newWidth; 8321 } 8322 } 8323 } 8324 8325}); 8326 8327var resizable = $.ui.resizable; 8328 8329 8330/*! 8331 * jQuery UI Dialog 1.11.1 8332 * http://jqueryui.com 8333 * 8334 * Copyright 2014 jQuery Foundation and other contributors 8335 * Released under the MIT license. 8336 * http://jquery.org/license 8337 * 8338 * http://api.jqueryui.com/dialog/ 8339 */ 8340 8341 8342var dialog = $.widget( "ui.dialog", { 8343 version: "1.11.1", 8344 options: { 8345 appendTo: "body", 8346 autoOpen: true, 8347 buttons: [], 8348 closeOnEscape: true, 8349 closeText: "Close", 8350 dialogClass: "", 8351 draggable: true, 8352 hide: null, 8353 height: "auto", 8354 maxHeight: null, 8355 maxWidth: null, 8356 minHeight: 150, 8357 minWidth: 150, 8358 modal: false, 8359 position: { 8360 my: "center", 8361 at: "center", 8362 of: window, 8363 collision: "fit", 8364 // Ensure the titlebar is always visible 8365 using: function( pos ) { 8366 var topOffset = $( this ).css( pos ).offset().top; 8367 if ( topOffset < 0 ) { 8368 $( this ).css( "top", pos.top - topOffset ); 8369 } 8370 } 8371 }, 8372 resizable: true, 8373 show: null, 8374 title: null, 8375 width: 300, 8376 8377 // callbacks 8378 beforeClose: null, 8379 close: null, 8380 drag: null, 8381 dragStart: null, 8382 dragStop: null, 8383 focus: null, 8384 open: null, 8385 resize: null, 8386 resizeStart: null, 8387 resizeStop: null 8388 }, 8389 8390 sizeRelatedOptions: { 8391 buttons: true, 8392 height: true, 8393 maxHeight: true, 8394 maxWidth: true, 8395 minHeight: true, 8396 minWidth: true, 8397 width: true 8398 }, 8399 8400 resizableRelatedOptions: { 8401 maxHeight: true, 8402 maxWidth: true, 8403 minHeight: true, 8404 minWidth: true 8405 }, 8406 8407 _create: function() { 8408 this.originalCss = { 8409 display: this.element[ 0 ].style.display, 8410 width: this.element[ 0 ].style.width, 8411 minHeight: this.element[ 0 ].style.minHeight, 8412 maxHeight: this.element[ 0 ].style.maxHeight, 8413 height: this.element[ 0 ].style.height 8414 }; 8415 this.originalPosition = { 8416 parent: this.element.parent(), 8417 index: this.element.parent().children().index( this.element ) 8418 }; 8419 this.originalTitle = this.element.attr( "title" ); 8420 this.options.title = this.options.title || this.originalTitle; 8421 8422 this._createWrapper(); 8423 8424 this.element 8425 .show() 8426 .removeAttr( "title" ) 8427 .addClass( "ui-dialog-content ui-widget-content" ) 8428 .appendTo( this.uiDialog ); 8429 8430 this._createTitlebar(); 8431 this._createButtonPane(); 8432 8433 if ( this.options.draggable && $.fn.draggable ) { 8434 this._makeDraggable(); 8435 } 8436 if ( this.options.resizable && $.fn.resizable ) { 8437 this._makeResizable(); 8438 } 8439 8440 this._isOpen = false; 8441 8442 this._trackFocus(); 8443 }, 8444 8445 _init: function() { 8446 if ( this.options.autoOpen ) { 8447 this.open(); 8448 } 8449 }, 8450 8451 _appendTo: function() { 8452 var element = this.options.appendTo; 8453 if ( element && (element.jquery || element.nodeType) ) { 8454 return $( element ); 8455 } 8456 return this.document.find( element || "body" ).eq( 0 ); 8457 }, 8458 8459 _destroy: function() { 8460 var next, 8461 originalPosition = this.originalPosition; 8462 8463 this._destroyOverlay(); 8464 8465 this.element 8466 .removeUniqueId() 8467 .removeClass( "ui-dialog-content ui-widget-content" ) 8468 .css( this.originalCss ) 8469 // Without detaching first, the following becomes really slow 8470 .detach(); 8471 8472 this.uiDialog.stop( true, true ).remove(); 8473 8474 if ( this.originalTitle ) { 8475 this.element.attr( "title", this.originalTitle ); 8476 } 8477 8478 next = originalPosition.parent.children().eq( originalPosition.index ); 8479 // Don't try to place the dialog next to itself (#8613) 8480 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 8481 next.before( this.element ); 8482 } else { 8483 originalPosition.parent.append( this.element ); 8484 } 8485 }, 8486 8487 widget: function() { 8488 return this.uiDialog; 8489 }, 8490 8491 disable: $.noop, 8492 enable: $.noop, 8493 8494 close: function( event ) { 8495 var activeElement, 8496 that = this; 8497 8498 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 8499 return; 8500 } 8501 8502 this._isOpen = false; 8503 this._focusedElement = null; 8504 this._destroyOverlay(); 8505 this._untrackInstance(); 8506 8507 if ( !this.opener.filter( ":focusable" ).focus().length ) { 8508 8509 // support: IE9 8510 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 8511 try { 8512 activeElement = this.document[ 0 ].activeElement; 8513 8514 // Support: IE9, IE10 8515 // If the <body> is blurred, IE will switch windows, see #4520 8516 if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { 8517 8518 // Hiding a focused element doesn't trigger blur in WebKit 8519 // so in case we have nothing to focus on, explicitly blur the active element 8520 // https://bugs.webkit.org/show_bug.cgi?id=47182 8521 $( activeElement ).blur(); 8522 } 8523 } catch ( error ) {} 8524 } 8525 8526 this._hide( this.uiDialog, this.options.hide, function() { 8527 that._trigger( "close", event ); 8528 }); 8529 }, 8530 8531 isOpen: function() { 8532 return this._isOpen; 8533 }, 8534 8535 moveToTop: function() { 8536 this._moveToTop(); 8537 }, 8538 8539 _moveToTop: function( event, silent ) { 8540 var moved = false, 8541 zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() { 8542 return +$( this ).css( "z-index" ); 8543 }).get(), 8544 zIndexMax = Math.max.apply( null, zIndicies ); 8545 8546 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 8547 this.uiDialog.css( "z-index", zIndexMax + 1 ); 8548 moved = true; 8549 } 8550 8551 if ( moved && !silent ) { 8552 this._trigger( "focus", event ); 8553 } 8554 return moved; 8555 }, 8556 8557 open: function() { 8558 var that = this; 8559 if ( this._isOpen ) { 8560 if ( this._moveToTop() ) { 8561 this._focusTabbable(); 8562 } 8563 return; 8564 } 8565 8566 this._isOpen = true; 8567 this.opener = $( this.document[ 0 ].activeElement ); 8568 8569 this._size(); 8570 this._position(); 8571 this._createOverlay(); 8572 this._moveToTop( null, true ); 8573 8574 // Ensure the overlay is moved to the top with the dialog, but only when 8575 // opening. The overlay shouldn't move after the dialog is open so that 8576 // modeless dialogs opened after the modal dialog stack properly. 8577 if ( this.overlay ) { 8578 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 8579 } 8580 8581 this._show( this.uiDialog, this.options.show, function() { 8582 that._focusTabbable(); 8583 that._trigger( "focus" ); 8584 }); 8585 8586 // Track the dialog immediately upon openening in case a focus event 8587 // somehow occurs outside of the dialog before an element inside the 8588 // dialog is focused (#10152) 8589 this._makeFocusTarget(); 8590 8591 this._trigger( "open" ); 8592 }, 8593 8594 _focusTabbable: function() { 8595 // Set focus to the first match: 8596 // 1. An element that was focused previously 8597 // 2. First element inside the dialog matching [autofocus] 8598 // 3. Tabbable element inside the content element 8599 // 4. Tabbable element inside the buttonpane 8600 // 5. The close button 8601 // 6. The dialog itself 8602 var hasFocus = this._focusedElement; 8603 if ( !hasFocus ) { 8604 hasFocus = this.element.find( "[autofocus]" ); 8605 } 8606 if ( !hasFocus.length ) { 8607 hasFocus = this.element.find( ":tabbable" ); 8608 } 8609 if ( !hasFocus.length ) { 8610 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 8611 } 8612 if ( !hasFocus.length ) { 8613 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 8614 } 8615 if ( !hasFocus.length ) { 8616 hasFocus = this.uiDialog; 8617 } 8618 hasFocus.eq( 0 ).focus(); 8619 }, 8620 8621 _keepFocus: function( event ) { 8622 function checkFocus() { 8623 var activeElement = this.document[0].activeElement, 8624 isActive = this.uiDialog[0] === activeElement || 8625 $.contains( this.uiDialog[0], activeElement ); 8626 if ( !isActive ) { 8627 this._focusTabbable(); 8628 } 8629 } 8630 event.preventDefault(); 8631 checkFocus.call( this ); 8632 // support: IE 8633 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 8634 // so we check again later 8635 this._delay( checkFocus ); 8636 }, 8637 8638 _createWrapper: function() { 8639 this.uiDialog = $("<div>") 8640 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + 8641 this.options.dialogClass ) 8642 .hide() 8643 .attr({ 8644 // Setting tabIndex makes the div focusable 8645 tabIndex: -1, 8646 role: "dialog" 8647 }) 8648 .appendTo( this._appendTo() ); 8649 8650 this._on( this.uiDialog, { 8651 keydown: function( event ) { 8652 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 8653 event.keyCode === $.ui.keyCode.ESCAPE ) { 8654 event.preventDefault(); 8655 this.close( event ); 8656 return; 8657 } 8658 8659 // prevent tabbing out of dialogs 8660 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 8661 return; 8662 } 8663 var tabbables = this.uiDialog.find( ":tabbable" ), 8664 first = tabbables.filter( ":first" ), 8665 last = tabbables.filter( ":last" ); 8666 8667 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { 8668 this._delay(function() { 8669 first.focus(); 8670 }); 8671 event.preventDefault(); 8672 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { 8673 this._delay(function() { 8674 last.focus(); 8675 }); 8676 event.preventDefault(); 8677 } 8678 }, 8679 mousedown: function( event ) { 8680 if ( this._moveToTop( event ) ) { 8681 this._focusTabbable(); 8682 } 8683 } 8684 }); 8685 8686 // We assume that any existing aria-describedby attribute means 8687 // that the dialog content is marked up properly 8688 // otherwise we brute force the content as the description 8689 if ( !this.element.find( "[aria-describedby]" ).length ) { 8690 this.uiDialog.attr({ 8691 "aria-describedby": this.element.uniqueId().attr( "id" ) 8692 }); 8693 } 8694 }, 8695 8696 _createTitlebar: function() { 8697 var uiDialogTitle; 8698 8699 this.uiDialogTitlebar = $( "<div>" ) 8700 .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) 8701 .prependTo( this.uiDialog ); 8702 this._on( this.uiDialogTitlebar, { 8703 mousedown: function( event ) { 8704 // Don't prevent click on close button (#8838) 8705 // Focusing a dialog that is partially scrolled out of view 8706 // causes the browser to scroll it into view, preventing the click event 8707 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 8708 // Dialog isn't getting focus when dragging (#8063) 8709 this.uiDialog.focus(); 8710 } 8711 } 8712 }); 8713 8714 // support: IE 8715 // Use type="button" to prevent enter keypresses in textboxes from closing the 8716 // dialog in IE (#9312) 8717 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 8718 .button({ 8719 label: this.options.closeText, 8720 icons: { 8721 primary: "ui-icon-closethick" 8722 }, 8723 text: false 8724 }) 8725 .addClass( "ui-dialog-titlebar-close" ) 8726 .appendTo( this.uiDialogTitlebar ); 8727 this._on( this.uiDialogTitlebarClose, { 8728 click: function( event ) { 8729 event.preventDefault(); 8730 this.close( event ); 8731 } 8732 }); 8733 8734 uiDialogTitle = $( "<span>" ) 8735 .uniqueId() 8736 .addClass( "ui-dialog-title" ) 8737 .prependTo( this.uiDialogTitlebar ); 8738 this._title( uiDialogTitle ); 8739 8740 this.uiDialog.attr({ 8741 "aria-labelledby": uiDialogTitle.attr( "id" ) 8742 }); 8743 }, 8744 8745 _title: function( title ) { 8746 if ( !this.options.title ) { 8747 title.html( " " ); 8748 } 8749 title.text( this.options.title ); 8750 }, 8751 8752 _createButtonPane: function() { 8753 this.uiDialogButtonPane = $( "<div>" ) 8754 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 8755 8756 this.uiButtonSet = $( "<div>" ) 8757 .addClass( "ui-dialog-buttonset" ) 8758 .appendTo( this.uiDialogButtonPane ); 8759 8760 this._createButtons(); 8761 }, 8762 8763 _createButtons: function() { 8764 var that = this, 8765 buttons = this.options.buttons; 8766 8767 // if we already have a button pane, remove it 8768 this.uiDialogButtonPane.remove(); 8769 this.uiButtonSet.empty(); 8770 8771 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { 8772 this.uiDialog.removeClass( "ui-dialog-buttons" ); 8773 return; 8774 } 8775 8776 $.each( buttons, function( name, props ) { 8777 var click, buttonOptions; 8778 props = $.isFunction( props ) ? 8779 { click: props, text: name } : 8780 props; 8781 // Default to a non-submitting button 8782 props = $.extend( { type: "button" }, props ); 8783 // Change the context for the click callback to be the main element 8784 click = props.click; 8785 props.click = function() { 8786 click.apply( that.element[ 0 ], arguments ); 8787 }; 8788 buttonOptions = { 8789 icons: props.icons, 8790 text: props.showText 8791 }; 8792 delete props.icons; 8793 delete props.showText; 8794 $( "<button></button>", props ) 8795 .button( buttonOptions ) 8796 .appendTo( that.uiButtonSet ); 8797 }); 8798 this.uiDialog.addClass( "ui-dialog-buttons" ); 8799 this.uiDialogButtonPane.appendTo( this.uiDialog ); 8800 }, 8801 8802 _makeDraggable: function() { 8803 var that = this, 8804 options = this.options; 8805 8806 function filteredUi( ui ) { 8807 return { 8808 position: ui.position, 8809 offset: ui.offset 8810 }; 8811 } 8812 8813 this.uiDialog.draggable({ 8814 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 8815 handle: ".ui-dialog-titlebar", 8816 containment: "document", 8817 start: function( event, ui ) { 8818 $( this ).addClass( "ui-dialog-dragging" ); 8819 that._blockFrames(); 8820 that._trigger( "dragStart", event, filteredUi( ui ) ); 8821 }, 8822 drag: function( event, ui ) { 8823 that._trigger( "drag", event, filteredUi( ui ) ); 8824 }, 8825 stop: function( event, ui ) { 8826 var left = ui.offset.left - that.document.scrollLeft(), 8827 top = ui.offset.top - that.document.scrollTop(); 8828 8829 options.position = { 8830 my: "left top", 8831 at: "left" + (left >= 0 ? "+" : "") + left + " " + 8832 "top" + (top >= 0 ? "+" : "") + top, 8833 of: that.window 8834 }; 8835 $( this ).removeClass( "ui-dialog-dragging" ); 8836 that._unblockFrames(); 8837 that._trigger( "dragStop", event, filteredUi( ui ) ); 8838 } 8839 }); 8840 }, 8841 8842 _makeResizable: function() { 8843 var that = this, 8844 options = this.options, 8845 handles = options.resizable, 8846 // .ui-resizable has position: relative defined in the stylesheet 8847 // but dialogs have to use absolute or fixed positioning 8848 position = this.uiDialog.css("position"), 8849 resizeHandles = typeof handles === "string" ? 8850 handles : 8851 "n,e,s,w,se,sw,ne,nw"; 8852 8853 function filteredUi( ui ) { 8854 return { 8855 originalPosition: ui.originalPosition, 8856 originalSize: ui.originalSize, 8857 position: ui.position, 8858 size: ui.size 8859 }; 8860 } 8861 8862 this.uiDialog.resizable({ 8863 cancel: ".ui-dialog-content", 8864 containment: "document", 8865 alsoResize: this.element, 8866 maxWidth: options.maxWidth, 8867 maxHeight: options.maxHeight, 8868 minWidth: options.minWidth, 8869 minHeight: this._minHeight(), 8870 handles: resizeHandles, 8871 start: function( event, ui ) { 8872 $( this ).addClass( "ui-dialog-resizing" ); 8873 that._blockFrames(); 8874 that._trigger( "resizeStart", event, filteredUi( ui ) ); 8875 }, 8876 resize: function( event, ui ) { 8877 that._trigger( "resize", event, filteredUi( ui ) ); 8878 }, 8879 stop: function( event, ui ) { 8880 var offset = that.uiDialog.offset(), 8881 left = offset.left - that.document.scrollLeft(), 8882 top = offset.top - that.document.scrollTop(); 8883 8884 options.height = that.uiDialog.height(); 8885 options.width = that.uiDialog.width(); 8886 options.position = { 8887 my: "left top", 8888 at: "left" + (left >= 0 ? "+" : "") + left + " " + 8889 "top" + (top >= 0 ? "+" : "") + top, 8890 of: that.window 8891 }; 8892 $( this ).removeClass( "ui-dialog-resizing" ); 8893 that._unblockFrames(); 8894 that._trigger( "resizeStop", event, filteredUi( ui ) ); 8895 } 8896 }) 8897 .css( "position", position ); 8898 }, 8899 8900 _trackFocus: function() { 8901 this._on( this.widget(), { 8902 focusin: function( event ) { 8903 this._makeFocusTarget(); 8904 this._focusedElement = $( event.target ); 8905 } 8906 }); 8907 }, 8908 8909 _makeFocusTarget: function() { 8910 this._untrackInstance(); 8911 this._trackingInstances().unshift( this ); 8912 }, 8913 8914 _untrackInstance: function() { 8915 var instances = this._trackingInstances(), 8916 exists = $.inArray( this, instances ); 8917 if ( exists !== -1 ) { 8918 instances.splice( exists, 1 ); 8919 } 8920 }, 8921 8922 _trackingInstances: function() { 8923 var instances = this.document.data( "ui-dialog-instances" ); 8924 if ( !instances ) { 8925 instances = []; 8926 this.document.data( "ui-dialog-instances", instances ); 8927 } 8928 return instances; 8929 }, 8930 8931 _minHeight: function() { 8932 var options = this.options; 8933 8934 return options.height === "auto" ? 8935 options.minHeight : 8936 Math.min( options.minHeight, options.height ); 8937 }, 8938 8939 _position: function() { 8940 // Need to show the dialog to get the actual offset in the position plugin 8941 var isVisible = this.uiDialog.is( ":visible" ); 8942 if ( !isVisible ) { 8943 this.uiDialog.show(); 8944 } 8945 this.uiDialog.position( this.options.position ); 8946 if ( !isVisible ) { 8947 this.uiDialog.hide(); 8948 } 8949 }, 8950 8951 _setOptions: function( options ) { 8952 var that = this, 8953 resize = false, 8954 resizableOptions = {}; 8955 8956 $.each( options, function( key, value ) { 8957 that._setOption( key, value ); 8958 8959 if ( key in that.sizeRelatedOptions ) { 8960 resize = true; 8961 } 8962 if ( key in that.resizableRelatedOptions ) { 8963 resizableOptions[ key ] = value; 8964 } 8965 }); 8966 8967 if ( resize ) { 8968 this._size(); 8969 this._position(); 8970 } 8971 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 8972 this.uiDialog.resizable( "option", resizableOptions ); 8973 } 8974 }, 8975 8976 _setOption: function( key, value ) { 8977 var isDraggable, isResizable, 8978 uiDialog = this.uiDialog; 8979 8980 if ( key === "dialogClass" ) { 8981 uiDialog 8982 .removeClass( this.options.dialogClass ) 8983 .addClass( value ); 8984 } 8985 8986 if ( key === "disabled" ) { 8987 return; 8988 } 8989 8990 this._super( key, value ); 8991 8992 if ( key === "appendTo" ) { 8993 this.uiDialog.appendTo( this._appendTo() ); 8994 } 8995 8996 if ( key === "buttons" ) { 8997 this._createButtons(); 8998 } 8999 9000 if ( key === "closeText" ) { 9001 this.uiDialogTitlebarClose.button({ 9002 // Ensure that we always pass a string 9003 label: "" + value 9004 }); 9005 } 9006 9007 if ( key === "draggable" ) { 9008 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 9009 if ( isDraggable && !value ) { 9010 uiDialog.draggable( "destroy" ); 9011 } 9012 9013 if ( !isDraggable && value ) { 9014 this._makeDraggable(); 9015 } 9016 } 9017 9018 if ( key === "position" ) { 9019 this._position(); 9020 } 9021 9022 if ( key === "resizable" ) { 9023 // currently resizable, becoming non-resizable 9024 isResizable = uiDialog.is( ":data(ui-resizable)" ); 9025 if ( isResizable && !value ) { 9026 uiDialog.resizable( "destroy" ); 9027 } 9028 9029 // currently resizable, changing handles 9030 if ( isResizable && typeof value === "string" ) { 9031 uiDialog.resizable( "option", "handles", value ); 9032 } 9033 9034 // currently non-resizable, becoming resizable 9035 if ( !isResizable && value !== false ) { 9036 this._makeResizable(); 9037 } 9038 } 9039 9040 if ( key === "title" ) { 9041 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 9042 } 9043 }, 9044 9045 _size: function() { 9046 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 9047 // divs will both have width and height set, so we need to reset them 9048 var nonContentHeight, minContentHeight, maxContentHeight, 9049 options = this.options; 9050 9051 // Reset content sizing 9052 this.element.show().css({ 9053 width: "auto", 9054 minHeight: 0, 9055 maxHeight: "none", 9056 height: 0 9057 }); 9058 9059 if ( options.minWidth > options.width ) { 9060 options.width = options.minWidth; 9061 } 9062 9063 // reset wrapper sizing 9064 // determine the height of all the non-content elements 9065 nonContentHeight = this.uiDialog.css({ 9066 height: "auto", 9067 width: options.width 9068 }) 9069 .outerHeight(); 9070 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 9071 maxContentHeight = typeof options.maxHeight === "number" ? 9072 Math.max( 0, options.maxHeight - nonContentHeight ) : 9073 "none"; 9074 9075 if ( options.height === "auto" ) { 9076 this.element.css({ 9077 minHeight: minContentHeight, 9078 maxHeight: maxContentHeight, 9079 height: "auto" 9080 }); 9081 } else { 9082 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 9083 } 9084 9085 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 9086 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 9087 } 9088 }, 9089 9090 _blockFrames: function() { 9091 this.iframeBlocks = this.document.find( "iframe" ).map(function() { 9092 var iframe = $( this ); 9093 9094 return $( "<div>" ) 9095 .css({ 9096 position: "absolute", 9097 width: iframe.outerWidth(), 9098 height: iframe.outerHeight() 9099 }) 9100 .appendTo( iframe.parent() ) 9101 .offset( iframe.offset() )[0]; 9102 }); 9103 }, 9104 9105 _unblockFrames: function() { 9106 if ( this.iframeBlocks ) { 9107 this.iframeBlocks.remove(); 9108 delete this.iframeBlocks; 9109 } 9110 }, 9111 9112 _allowInteraction: function( event ) { 9113 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 9114 return true; 9115 } 9116 9117 // TODO: Remove hack when datepicker implements 9118 // the .ui-front logic (#8989) 9119 return !!$( event.target ).closest( ".ui-datepicker" ).length; 9120 }, 9121 9122 _createOverlay: function() { 9123 if ( !this.options.modal ) { 9124 return; 9125 } 9126 9127 // We use a delay in case the overlay is created from an 9128 // event that we're going to be cancelling (#2804) 9129 var isOpening = true; 9130 this._delay(function() { 9131 isOpening = false; 9132 }); 9133 9134 if ( !this.document.data( "ui-dialog-overlays" ) ) { 9135 9136 // Prevent use of anchors and inputs 9137 // Using _on() for an event handler shared across many instances is 9138 // safe because the dialogs stack and must be closed in reverse order 9139 this._on( this.document, { 9140 focusin: function( event ) { 9141 if ( isOpening ) { 9142 return; 9143 } 9144 9145 if ( !this._allowInteraction( event ) ) { 9146 event.preventDefault(); 9147 this._trackingInstances()[ 0 ]._focusTabbable(); 9148 } 9149 } 9150 }); 9151 } 9152 9153 this.overlay = $( "<div>" ) 9154 .addClass( "ui-widget-overlay ui-front" ) 9155 .appendTo( this._appendTo() ); 9156 this._on( this.overlay, { 9157 mousedown: "_keepFocus" 9158 }); 9159 this.document.data( "ui-dialog-overlays", 9160 (this.document.data( "ui-dialog-overlays" ) || 0) + 1 ); 9161 }, 9162 9163 _destroyOverlay: function() { 9164 if ( !this.options.modal ) { 9165 return; 9166 } 9167 9168 if ( this.overlay ) { 9169 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 9170 9171 if ( !overlays ) { 9172 this.document 9173 .unbind( "focusin" ) 9174 .removeData( "ui-dialog-overlays" ); 9175 } else { 9176 this.document.data( "ui-dialog-overlays", overlays ); 9177 } 9178 9179 this.overlay.remove(); 9180 this.overlay = null; 9181 } 9182 } 9183}); 9184 9185 9186/*! 9187 * jQuery UI Droppable 1.11.1 9188 * http://jqueryui.com 9189 * 9190 * Copyright 2014 jQuery Foundation and other contributors 9191 * Released under the MIT license. 9192 * http://jquery.org/license 9193 * 9194 * http://api.jqueryui.com/droppable/ 9195 */ 9196 9197 9198$.widget( "ui.droppable", { 9199 version: "1.11.1", 9200 widgetEventPrefix: "drop", 9201 options: { 9202 accept: "*", 9203 activeClass: false, 9204 addClasses: true, 9205 greedy: false, 9206 hoverClass: false, 9207 scope: "default", 9208 tolerance: "intersect", 9209 9210 // callbacks 9211 activate: null, 9212 deactivate: null, 9213 drop: null, 9214 out: null, 9215 over: null 9216 }, 9217 _create: function() { 9218 9219 var proportions, 9220 o = this.options, 9221 accept = o.accept; 9222 9223 this.isover = false; 9224 this.isout = true; 9225 9226 this.accept = $.isFunction( accept ) ? accept : function( d ) { 9227 return d.is( accept ); 9228 }; 9229 9230 this.proportions = function( /* valueToWrite */ ) { 9231 if ( arguments.length ) { 9232 // Store the droppable's proportions 9233 proportions = arguments[ 0 ]; 9234 } else { 9235 // Retrieve or derive the droppable's proportions 9236 return proportions ? 9237 proportions : 9238 proportions = { 9239 width: this.element[ 0 ].offsetWidth, 9240 height: this.element[ 0 ].offsetHeight 9241 }; 9242 } 9243 }; 9244 9245 this._addToManager( o.scope ); 9246 9247 o.addClasses && this.element.addClass( "ui-droppable" ); 9248 9249 }, 9250 9251 _addToManager: function( scope ) { 9252 // Add the reference and positions to the manager 9253 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 9254 $.ui.ddmanager.droppables[ scope ].push( this ); 9255 }, 9256 9257 _splice: function( drop ) { 9258 var i = 0; 9259 for ( ; i < drop.length; i++ ) { 9260 if ( drop[ i ] === this ) { 9261 drop.splice( i, 1 ); 9262 } 9263 } 9264 }, 9265 9266 _destroy: function() { 9267 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 9268 9269 this._splice( drop ); 9270 9271 this.element.removeClass( "ui-droppable ui-droppable-disabled" ); 9272 }, 9273 9274 _setOption: function( key, value ) { 9275 9276 if ( key === "accept" ) { 9277 this.accept = $.isFunction( value ) ? value : function( d ) { 9278 return d.is( value ); 9279 }; 9280 } else if ( key === "scope" ) { 9281 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 9282 9283 this._splice( drop ); 9284 this._addToManager( value ); 9285 } 9286 9287 this._super( key, value ); 9288 }, 9289 9290 _activate: function( event ) { 9291 var draggable = $.ui.ddmanager.current; 9292 if ( this.options.activeClass ) { 9293 this.element.addClass( this.options.activeClass ); 9294 } 9295 if ( draggable ){ 9296 this._trigger( "activate", event, this.ui( draggable ) ); 9297 } 9298 }, 9299 9300 _deactivate: function( event ) { 9301 var draggable = $.ui.ddmanager.current; 9302 if ( this.options.activeClass ) { 9303 this.element.removeClass( this.options.activeClass ); 9304 } 9305 if ( draggable ){ 9306 this._trigger( "deactivate", event, this.ui( draggable ) ); 9307 } 9308 }, 9309 9310 _over: function( event ) { 9311 9312 var draggable = $.ui.ddmanager.current; 9313 9314 // Bail if draggable and droppable are same element 9315 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9316 return; 9317 } 9318 9319 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9320 if ( this.options.hoverClass ) { 9321 this.element.addClass( this.options.hoverClass ); 9322 } 9323 this._trigger( "over", event, this.ui( draggable ) ); 9324 } 9325 9326 }, 9327 9328 _out: function( event ) { 9329 9330 var draggable = $.ui.ddmanager.current; 9331 9332 // Bail if draggable and droppable are same element 9333 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9334 return; 9335 } 9336 9337 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9338 if ( this.options.hoverClass ) { 9339 this.element.removeClass( this.options.hoverClass ); 9340 } 9341 this._trigger( "out", event, this.ui( draggable ) ); 9342 } 9343 9344 }, 9345 9346 _drop: function( event, custom ) { 9347 9348 var draggable = custom || $.ui.ddmanager.current, 9349 childrenIntersection = false; 9350 9351 // Bail if draggable and droppable are same element 9352 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { 9353 return false; 9354 } 9355 9356 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() { 9357 var inst = $( this ).droppable( "instance" ); 9358 if ( 9359 inst.options.greedy && 9360 !inst.options.disabled && 9361 inst.options.scope === draggable.options.scope && 9362 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) && 9363 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event ) 9364 ) { childrenIntersection = true; return false; } 9365 }); 9366 if ( childrenIntersection ) { 9367 return false; 9368 } 9369 9370 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9371 if ( this.options.activeClass ) { 9372 this.element.removeClass( this.options.activeClass ); 9373 } 9374 if ( this.options.hoverClass ) { 9375 this.element.removeClass( this.options.hoverClass ); 9376 } 9377 this._trigger( "drop", event, this.ui( draggable ) ); 9378 return this.element; 9379 } 9380 9381 return false; 9382 9383 }, 9384 9385 ui: function( c ) { 9386 return { 9387 draggable: ( c.currentItem || c.element ), 9388 helper: c.helper, 9389 position: c.position, 9390 offset: c.positionAbs 9391 }; 9392 } 9393 9394}); 9395 9396$.ui.intersect = (function() { 9397 function isOverAxis( x, reference, size ) { 9398 return ( x >= reference ) && ( x < ( reference + size ) ); 9399 } 9400 9401 return function( draggable, droppable, toleranceMode, event ) { 9402 9403 if ( !droppable.offset ) { 9404 return false; 9405 } 9406 9407 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left, 9408 y1 = ( draggable.positionAbs || draggable.position.absolute ).top, 9409 x2 = x1 + draggable.helperProportions.width, 9410 y2 = y1 + draggable.helperProportions.height, 9411 l = droppable.offset.left, 9412 t = droppable.offset.top, 9413 r = l + droppable.proportions().width, 9414 b = t + droppable.proportions().height; 9415 9416 switch ( toleranceMode ) { 9417 case "fit": 9418 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 9419 case "intersect": 9420 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 9421 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 9422 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 9423 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 9424 case "pointer": 9425 return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); 9426 case "touch": 9427 return ( 9428 ( y1 >= t && y1 <= b ) || // Top edge touching 9429 ( y2 >= t && y2 <= b ) || // Bottom edge touching 9430 ( y1 < t && y2 > b ) // Surrounded vertically 9431 ) && ( 9432 ( x1 >= l && x1 <= r ) || // Left edge touching 9433 ( x2 >= l && x2 <= r ) || // Right edge touching 9434 ( x1 < l && x2 > r ) // Surrounded horizontally 9435 ); 9436 default: 9437 return false; 9438 } 9439 }; 9440})(); 9441 9442/* 9443 This manager tracks offsets of draggables and droppables 9444*/ 9445$.ui.ddmanager = { 9446 current: null, 9447 droppables: { "default": [] }, 9448 prepareOffsets: function( t, event ) { 9449 9450 var i, j, 9451 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 9452 type = event ? event.type : null, // workaround for #2317 9453 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 9454 9455 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 9456 9457 // No disabled and non-accepted 9458 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { 9459 continue; 9460 } 9461 9462 // Filter out elements in the current dragged item 9463 for ( j = 0; j < list.length; j++ ) { 9464 if ( list[ j ] === m[ i ].element[ 0 ] ) { 9465 m[ i ].proportions().height = 0; 9466 continue droppablesLoop; 9467 } 9468 } 9469 9470 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 9471 if ( !m[ i ].visible ) { 9472 continue; 9473 } 9474 9475 // Activate the droppable if used directly from draggables 9476 if ( type === "mousedown" ) { 9477 m[ i ]._activate.call( m[ i ], event ); 9478 } 9479 9480 m[ i ].offset = m[ i ].element.offset(); 9481 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); 9482 9483 } 9484 9485 }, 9486 drop: function( draggable, event ) { 9487 9488 var dropped = false; 9489 // Create a copy of the droppables in case the list changes during the drop (#9116) 9490 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 9491 9492 if ( !this.options ) { 9493 return; 9494 } 9495 if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 9496 dropped = this._drop.call( this, event ) || dropped; 9497 } 9498 9499 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { 9500 this.isout = true; 9501 this.isover = false; 9502 this._deactivate.call( this, event ); 9503 } 9504 9505 }); 9506 return dropped; 9507 9508 }, 9509 dragStart: function( draggable, event ) { 9510 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 9511 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 9512 if ( !draggable.options.refreshPositions ) { 9513 $.ui.ddmanager.prepareOffsets( draggable, event ); 9514 } 9515 }); 9516 }, 9517 drag: function( draggable, event ) { 9518 9519 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 9520 if ( draggable.options.refreshPositions ) { 9521 $.ui.ddmanager.prepareOffsets( draggable, event ); 9522 } 9523 9524 // Run through all droppables and check their positions based on specific tolerance options 9525 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 9526 9527 if ( this.options.disabled || this.greedyChild || !this.visible ) { 9528 return; 9529 } 9530 9531 var parentInstance, scope, parent, 9532 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 9533 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); 9534 if ( !c ) { 9535 return; 9536 } 9537 9538 if ( this.options.greedy ) { 9539 // find droppable parents with same scope 9540 scope = this.options.scope; 9541 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() { 9542 return $( this ).droppable( "instance" ).options.scope === scope; 9543 }); 9544 9545 if ( parent.length ) { 9546 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 9547 parentInstance.greedyChild = ( c === "isover" ); 9548 } 9549 } 9550 9551 // we just moved into a greedy child 9552 if ( parentInstance && c === "isover" ) { 9553 parentInstance.isover = false; 9554 parentInstance.isout = true; 9555 parentInstance._out.call( parentInstance, event ); 9556 } 9557 9558 this[ c ] = true; 9559 this[c === "isout" ? "isover" : "isout"] = false; 9560 this[c === "isover" ? "_over" : "_out"].call( this, event ); 9561 9562 // we just moved out of a greedy child 9563 if ( parentInstance && c === "isout" ) { 9564 parentInstance.isout = false; 9565 parentInstance.isover = true; 9566 parentInstance._over.call( parentInstance, event ); 9567 } 9568 }); 9569 9570 }, 9571 dragStop: function( draggable, event ) { 9572 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 9573 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 9574 if ( !draggable.options.refreshPositions ) { 9575 $.ui.ddmanager.prepareOffsets( draggable, event ); 9576 } 9577 } 9578}; 9579 9580var droppable = $.ui.droppable; 9581 9582 9583/*! 9584 * jQuery UI Effects 1.11.1 9585 * http://jqueryui.com 9586 * 9587 * Copyright 2014 jQuery Foundation and other contributors 9588 * Released under the MIT license. 9589 * http://jquery.org/license 9590 * 9591 * http://api.jqueryui.com/category/effects-core/ 9592 */ 9593 9594 9595var dataSpace = "ui-effects-", 9596 9597 // Create a local jQuery because jQuery Color relies on it and the 9598 // global may not exist with AMD and a custom build (#10199) 9599 jQuery = $; 9600 9601$.effects = { 9602 effect: {} 9603}; 9604 9605/*! 9606 * jQuery Color Animations v2.1.2 9607 * https://github.com/jquery/jquery-color 9608 * 9609 * Copyright 2014 jQuery Foundation and other contributors 9610 * Released under the MIT license. 9611 * http://jquery.org/license 9612 * 9613 * Date: Wed Jan 16 08:47:09 2013 -0600 9614 */ 9615(function( jQuery, undefined ) { 9616 9617 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 9618 9619 // plusequals test for += 100 -= 100 9620 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 9621 // a set of RE's that can match strings and generate color tuples. 9622 stringParsers = [ { 9623 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9624 parse: function( execResult ) { 9625 return [ 9626 execResult[ 1 ], 9627 execResult[ 2 ], 9628 execResult[ 3 ], 9629 execResult[ 4 ] 9630 ]; 9631 } 9632 }, { 9633 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9634 parse: function( execResult ) { 9635 return [ 9636 execResult[ 1 ] * 2.55, 9637 execResult[ 2 ] * 2.55, 9638 execResult[ 3 ] * 2.55, 9639 execResult[ 4 ] 9640 ]; 9641 } 9642 }, { 9643 // this regex ignores A-F because it's compared against an already lowercased string 9644 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 9645 parse: function( execResult ) { 9646 return [ 9647 parseInt( execResult[ 1 ], 16 ), 9648 parseInt( execResult[ 2 ], 16 ), 9649 parseInt( execResult[ 3 ], 16 ) 9650 ]; 9651 } 9652 }, { 9653 // this regex ignores A-F because it's compared against an already lowercased string 9654 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 9655 parse: function( execResult ) { 9656 return [ 9657 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 9658 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 9659 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 9660 ]; 9661 } 9662 }, { 9663 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 9664 space: "hsla", 9665 parse: function( execResult ) { 9666 return [ 9667 execResult[ 1 ], 9668 execResult[ 2 ] / 100, 9669 execResult[ 3 ] / 100, 9670 execResult[ 4 ] 9671 ]; 9672 } 9673 } ], 9674 9675 // jQuery.Color( ) 9676 color = jQuery.Color = function( color, green, blue, alpha ) { 9677 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 9678 }, 9679 spaces = { 9680 rgba: { 9681 props: { 9682 red: { 9683 idx: 0, 9684 type: "byte" 9685 }, 9686 green: { 9687 idx: 1, 9688 type: "byte" 9689 }, 9690 blue: { 9691 idx: 2, 9692 type: "byte" 9693 } 9694 } 9695 }, 9696 9697 hsla: { 9698 props: { 9699 hue: { 9700 idx: 0, 9701 type: "degrees" 9702 }, 9703 saturation: { 9704 idx: 1, 9705 type: "percent" 9706 }, 9707 lightness: { 9708 idx: 2, 9709 type: "percent" 9710 } 9711 } 9712 } 9713 }, 9714 propTypes = { 9715 "byte": { 9716 floor: true, 9717 max: 255 9718 }, 9719 "percent": { 9720 max: 1 9721 }, 9722 "degrees": { 9723 mod: 360, 9724 floor: true 9725 } 9726 }, 9727 support = color.support = {}, 9728 9729 // element for support tests 9730 supportElem = jQuery( "<p>" )[ 0 ], 9731 9732 // colors = jQuery.Color.names 9733 colors, 9734 9735 // local aliases of functions called often 9736 each = jQuery.each; 9737 9738// determine rgba support immediately 9739supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 9740support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 9741 9742// define cache name and alpha properties 9743// for rgba and hsla spaces 9744each( spaces, function( spaceName, space ) { 9745 space.cache = "_" + spaceName; 9746 space.props.alpha = { 9747 idx: 3, 9748 type: "percent", 9749 def: 1 9750 }; 9751}); 9752 9753function clamp( value, prop, allowEmpty ) { 9754 var type = propTypes[ prop.type ] || {}; 9755 9756 if ( value == null ) { 9757 return (allowEmpty || !prop.def) ? null : prop.def; 9758 } 9759 9760 // ~~ is an short way of doing floor for positive numbers 9761 value = type.floor ? ~~value : parseFloat( value ); 9762 9763 // IE will pass in empty strings as value for alpha, 9764 // which will hit this case 9765 if ( isNaN( value ) ) { 9766 return prop.def; 9767 } 9768 9769 if ( type.mod ) { 9770 // we add mod before modding to make sure that negatives values 9771 // get converted properly: -10 -> 350 9772 return (value + type.mod) % type.mod; 9773 } 9774 9775 // for now all property types without mod have min and max 9776 return 0 > value ? 0 : type.max < value ? type.max : value; 9777} 9778 9779function stringParse( string ) { 9780 var inst = color(), 9781 rgba = inst._rgba = []; 9782 9783 string = string.toLowerCase(); 9784 9785 each( stringParsers, function( i, parser ) { 9786 var parsed, 9787 match = parser.re.exec( string ), 9788 values = match && parser.parse( match ), 9789 spaceName = parser.space || "rgba"; 9790 9791 if ( values ) { 9792 parsed = inst[ spaceName ]( values ); 9793 9794 // if this was an rgba parse the assignment might happen twice 9795 // oh well.... 9796 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 9797 rgba = inst._rgba = parsed._rgba; 9798 9799 // exit each( stringParsers ) here because we matched 9800 return false; 9801 } 9802 }); 9803 9804 // Found a stringParser that handled it 9805 if ( rgba.length ) { 9806 9807 // if this came from a parsed string, force "transparent" when alpha is 0 9808 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 9809 if ( rgba.join() === "0,0,0,0" ) { 9810 jQuery.extend( rgba, colors.transparent ); 9811 } 9812 return inst; 9813 } 9814 9815 // named colors 9816 return colors[ string ]; 9817} 9818 9819color.fn = jQuery.extend( color.prototype, { 9820 parse: function( red, green, blue, alpha ) { 9821 if ( red === undefined ) { 9822 this._rgba = [ null, null, null, null ]; 9823 return this; 9824 } 9825 if ( red.jquery || red.nodeType ) { 9826 red = jQuery( red ).css( green ); 9827 green = undefined; 9828 } 9829 9830 var inst = this, 9831 type = jQuery.type( red ), 9832 rgba = this._rgba = []; 9833 9834 // more than 1 argument specified - assume ( red, green, blue, alpha ) 9835 if ( green !== undefined ) { 9836 red = [ red, green, blue, alpha ]; 9837 type = "array"; 9838 } 9839 9840 if ( type === "string" ) { 9841 return this.parse( stringParse( red ) || colors._default ); 9842 } 9843 9844 if ( type === "array" ) { 9845 each( spaces.rgba.props, function( key, prop ) { 9846 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 9847 }); 9848 return this; 9849 } 9850 9851 if ( type === "object" ) { 9852 if ( red instanceof color ) { 9853 each( spaces, function( spaceName, space ) { 9854 if ( red[ space.cache ] ) { 9855 inst[ space.cache ] = red[ space.cache ].slice(); 9856 } 9857 }); 9858 } else { 9859 each( spaces, function( spaceName, space ) { 9860 var cache = space.cache; 9861 each( space.props, function( key, prop ) { 9862 9863 // if the cache doesn't exist, and we know how to convert 9864 if ( !inst[ cache ] && space.to ) { 9865 9866 // if the value was null, we don't need to copy it 9867 // if the key was alpha, we don't need to copy it either 9868 if ( key === "alpha" || red[ key ] == null ) { 9869 return; 9870 } 9871 inst[ cache ] = space.to( inst._rgba ); 9872 } 9873 9874 // this is the only case where we allow nulls for ALL properties. 9875 // call clamp with alwaysAllowEmpty 9876 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 9877 }); 9878 9879 // everything defined but alpha? 9880 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 9881 // use the default of 1 9882 inst[ cache ][ 3 ] = 1; 9883 if ( space.from ) { 9884 inst._rgba = space.from( inst[ cache ] ); 9885 } 9886 } 9887 }); 9888 } 9889 return this; 9890 } 9891 }, 9892 is: function( compare ) { 9893 var is = color( compare ), 9894 same = true, 9895 inst = this; 9896 9897 each( spaces, function( _, space ) { 9898 var localCache, 9899 isCache = is[ space.cache ]; 9900 if (isCache) { 9901 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 9902 each( space.props, function( _, prop ) { 9903 if ( isCache[ prop.idx ] != null ) { 9904 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 9905 return same; 9906 } 9907 }); 9908 } 9909 return same; 9910 }); 9911 return same; 9912 }, 9913 _space: function() { 9914 var used = [], 9915 inst = this; 9916 each( spaces, function( spaceName, space ) { 9917 if ( inst[ space.cache ] ) { 9918 used.push( spaceName ); 9919 } 9920 }); 9921 return used.pop(); 9922 }, 9923 transition: function( other, distance ) { 9924 var end = color( other ), 9925 spaceName = end._space(), 9926 space = spaces[ spaceName ], 9927 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 9928 start = startColor[ space.cache ] || space.to( startColor._rgba ), 9929 result = start.slice(); 9930 9931 end = end[ space.cache ]; 9932 each( space.props, function( key, prop ) { 9933 var index = prop.idx, 9934 startValue = start[ index ], 9935 endValue = end[ index ], 9936 type = propTypes[ prop.type ] || {}; 9937 9938 // if null, don't override start value 9939 if ( endValue === null ) { 9940 return; 9941 } 9942 // if null - use end 9943 if ( startValue === null ) { 9944 result[ index ] = endValue; 9945 } else { 9946 if ( type.mod ) { 9947 if ( endValue - startValue > type.mod / 2 ) { 9948 startValue += type.mod; 9949 } else if ( startValue - endValue > type.mod / 2 ) { 9950 startValue -= type.mod; 9951 } 9952 } 9953 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 9954 } 9955 }); 9956 return this[ spaceName ]( result ); 9957 }, 9958 blend: function( opaque ) { 9959 // if we are already opaque - return ourself 9960 if ( this._rgba[ 3 ] === 1 ) { 9961 return this; 9962 } 9963 9964 var rgb = this._rgba.slice(), 9965 a = rgb.pop(), 9966 blend = color( opaque )._rgba; 9967 9968 return color( jQuery.map( rgb, function( v, i ) { 9969 return ( 1 - a ) * blend[ i ] + a * v; 9970 })); 9971 }, 9972 toRgbaString: function() { 9973 var prefix = "rgba(", 9974 rgba = jQuery.map( this._rgba, function( v, i ) { 9975 return v == null ? ( i > 2 ? 1 : 0 ) : v; 9976 }); 9977 9978 if ( rgba[ 3 ] === 1 ) { 9979 rgba.pop(); 9980 prefix = "rgb("; 9981 } 9982 9983 return prefix + rgba.join() + ")"; 9984 }, 9985 toHslaString: function() { 9986 var prefix = "hsla(", 9987 hsla = jQuery.map( this.hsla(), function( v, i ) { 9988 if ( v == null ) { 9989 v = i > 2 ? 1 : 0; 9990 } 9991 9992 // catch 1 and 2 9993 if ( i && i < 3 ) { 9994 v = Math.round( v * 100 ) + "%"; 9995 } 9996 return v; 9997 }); 9998 9999 if ( hsla[ 3 ] === 1 ) { 10000 hsla.pop(); 10001 prefix = "hsl("; 10002 } 10003 return prefix + hsla.join() + ")"; 10004 }, 10005 toHexString: function( includeAlpha ) { 10006 var rgba = this._rgba.slice(), 10007 alpha = rgba.pop(); 10008 10009 if ( includeAlpha ) { 10010 rgba.push( ~~( alpha * 255 ) ); 10011 } 10012 10013 return "#" + jQuery.map( rgba, function( v ) { 10014 10015 // default to 0 when nulls exist 10016 v = ( v || 0 ).toString( 16 ); 10017 return v.length === 1 ? "0" + v : v; 10018 }).join(""); 10019 }, 10020 toString: function() { 10021 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 10022 } 10023}); 10024color.fn.parse.prototype = color.fn; 10025 10026// hsla conversions adapted from: 10027// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 10028 10029function hue2rgb( p, q, h ) { 10030 h = ( h + 1 ) % 1; 10031 if ( h * 6 < 1 ) { 10032 return p + ( q - p ) * h * 6; 10033 } 10034 if ( h * 2 < 1) { 10035 return q; 10036 } 10037 if ( h * 3 < 2 ) { 10038 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 10039 } 10040 return p; 10041} 10042 10043spaces.hsla.to = function( rgba ) { 10044 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 10045 return [ null, null, null, rgba[ 3 ] ]; 10046 } 10047 var r = rgba[ 0 ] / 255, 10048 g = rgba[ 1 ] / 255, 10049 b = rgba[ 2 ] / 255, 10050 a = rgba[ 3 ], 10051 max = Math.max( r, g, b ), 10052 min = Math.min( r, g, b ), 10053 diff = max - min, 10054 add = max + min, 10055 l = add * 0.5, 10056 h, s; 10057 10058 if ( min === max ) { 10059 h = 0; 10060 } else if ( r === max ) { 10061 h = ( 60 * ( g - b ) / diff ) + 360; 10062 } else if ( g === max ) { 10063 h = ( 60 * ( b - r ) / diff ) + 120; 10064 } else { 10065 h = ( 60 * ( r - g ) / diff ) + 240; 10066 } 10067 10068 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 10069 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 10070 if ( diff === 0 ) { 10071 s = 0; 10072 } else if ( l <= 0.5 ) { 10073 s = diff / add; 10074 } else { 10075 s = diff / ( 2 - add ); 10076 } 10077 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 10078}; 10079 10080spaces.hsla.from = function( hsla ) { 10081 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 10082 return [ null, null, null, hsla[ 3 ] ]; 10083 } 10084 var h = hsla[ 0 ] / 360, 10085 s = hsla[ 1 ], 10086 l = hsla[ 2 ], 10087 a = hsla[ 3 ], 10088 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 10089 p = 2 * l - q; 10090 10091 return [ 10092 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 10093 Math.round( hue2rgb( p, q, h ) * 255 ), 10094 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 10095 a 10096 ]; 10097}; 10098 10099each( spaces, function( spaceName, space ) { 10100 var props = space.props, 10101 cache = space.cache, 10102 to = space.to, 10103 from = space.from; 10104 10105 // makes rgba() and hsla() 10106 color.fn[ spaceName ] = function( value ) { 10107 10108 // generate a cache for this space if it doesn't exist 10109 if ( to && !this[ cache ] ) { 10110 this[ cache ] = to( this._rgba ); 10111 } 10112 if ( value === undefined ) { 10113 return this[ cache ].slice(); 10114 } 10115 10116 var ret, 10117 type = jQuery.type( value ), 10118 arr = ( type === "array" || type === "object" ) ? value : arguments, 10119 local = this[ cache ].slice(); 10120 10121 each( props, function( key, prop ) { 10122 var val = arr[ type === "object" ? key : prop.idx ]; 10123 if ( val == null ) { 10124 val = local[ prop.idx ]; 10125 } 10126 local[ prop.idx ] = clamp( val, prop ); 10127 }); 10128 10129 if ( from ) { 10130 ret = color( from( local ) ); 10131 ret[ cache ] = local; 10132 return ret; 10133 } else { 10134 return color( local ); 10135 } 10136 }; 10137 10138 // makes red() green() blue() alpha() hue() saturation() lightness() 10139 each( props, function( key, prop ) { 10140 // alpha is included in more than one space 10141 if ( color.fn[ key ] ) { 10142 return; 10143 } 10144 color.fn[ key ] = function( value ) { 10145 var vtype = jQuery.type( value ), 10146 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 10147 local = this[ fn ](), 10148 cur = local[ prop.idx ], 10149 match; 10150 10151 if ( vtype === "undefined" ) { 10152 return cur; 10153 } 10154 10155 if ( vtype === "function" ) { 10156 value = value.call( this, cur ); 10157 vtype = jQuery.type( value ); 10158 } 10159 if ( value == null && prop.empty ) { 10160 return this; 10161 } 10162 if ( vtype === "string" ) { 10163 match = rplusequals.exec( value ); 10164 if ( match ) { 10165 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 10166 } 10167 } 10168 local[ prop.idx ] = value; 10169 return this[ fn ]( local ); 10170 }; 10171 }); 10172}); 10173 10174// add cssHook and .fx.step function for each named hook. 10175// accept a space separated string of properties 10176color.hook = function( hook ) { 10177 var hooks = hook.split( " " ); 10178 each( hooks, function( i, hook ) { 10179 jQuery.cssHooks[ hook ] = { 10180 set: function( elem, value ) { 10181 var parsed, curElem, 10182 backgroundColor = ""; 10183 10184 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 10185 value = color( parsed || value ); 10186 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 10187 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 10188 while ( 10189 (backgroundColor === "" || backgroundColor === "transparent") && 10190 curElem && curElem.style 10191 ) { 10192 try { 10193 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 10194 curElem = curElem.parentNode; 10195 } catch ( e ) { 10196 } 10197 } 10198 10199 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 10200 backgroundColor : 10201 "_default" ); 10202 } 10203 10204 value = value.toRgbaString(); 10205 } 10206 try { 10207 elem.style[ hook ] = value; 10208 } catch( e ) { 10209 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 10210 } 10211 } 10212 }; 10213 jQuery.fx.step[ hook ] = function( fx ) { 10214 if ( !fx.colorInit ) { 10215 fx.start = color( fx.elem, hook ); 10216 fx.end = color( fx.end ); 10217 fx.colorInit = true; 10218 } 10219 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 10220 }; 10221 }); 10222 10223}; 10224 10225color.hook( stepHooks ); 10226 10227jQuery.cssHooks.borderColor = { 10228 expand: function( value ) { 10229 var expanded = {}; 10230 10231 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 10232 expanded[ "border" + part + "Color" ] = value; 10233 }); 10234 return expanded; 10235 } 10236}; 10237 10238// Basic color names only. 10239// Usage of any of the other color names requires adding yourself or including 10240// jquery.color.svg-names.js. 10241colors = jQuery.Color.names = { 10242 // 4.1. Basic color keywords 10243 aqua: "#00ffff", 10244 black: "#000000", 10245 blue: "#0000ff", 10246 fuchsia: "#ff00ff", 10247 gray: "#808080", 10248 green: "#008000", 10249 lime: "#00ff00", 10250 maroon: "#800000", 10251 navy: "#000080", 10252 olive: "#808000", 10253 purple: "#800080", 10254 red: "#ff0000", 10255 silver: "#c0c0c0", 10256 teal: "#008080", 10257 white: "#ffffff", 10258 yellow: "#ffff00", 10259 10260 // 4.2.3. "transparent" color keyword 10261 transparent: [ null, null, null, 0 ], 10262 10263 _default: "#ffffff" 10264}; 10265 10266})( jQuery ); 10267 10268/******************************************************************************/ 10269/****************************** CLASS ANIMATIONS ******************************/ 10270/******************************************************************************/ 10271(function() { 10272 10273var classAnimationActions = [ "add", "remove", "toggle" ], 10274 shorthandStyles = { 10275 border: 1, 10276 borderBottom: 1, 10277 borderColor: 1, 10278 borderLeft: 1, 10279 borderRight: 1, 10280 borderTop: 1, 10281 borderWidth: 1, 10282 margin: 1, 10283 padding: 1 10284 }; 10285 10286$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 10287 $.fx.step[ prop ] = function( fx ) { 10288 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 10289 jQuery.style( fx.elem, prop, fx.end ); 10290 fx.setAttr = true; 10291 } 10292 }; 10293}); 10294 10295function getElementStyles( elem ) { 10296 var key, len, 10297 style = elem.ownerDocument.defaultView ? 10298 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 10299 elem.currentStyle, 10300 styles = {}; 10301 10302 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 10303 len = style.length; 10304 while ( len-- ) { 10305 key = style[ len ]; 10306 if ( typeof style[ key ] === "string" ) { 10307 styles[ $.camelCase( key ) ] = style[ key ]; 10308 } 10309 } 10310 // support: Opera, IE <9 10311 } else { 10312 for ( key in style ) { 10313 if ( typeof style[ key ] === "string" ) { 10314 styles[ key ] = style[ key ]; 10315 } 10316 } 10317 } 10318 10319 return styles; 10320} 10321 10322function styleDifference( oldStyle, newStyle ) { 10323 var diff = {}, 10324 name, value; 10325 10326 for ( name in newStyle ) { 10327 value = newStyle[ name ]; 10328 if ( oldStyle[ name ] !== value ) { 10329 if ( !shorthandStyles[ name ] ) { 10330 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 10331 diff[ name ] = value; 10332 } 10333 } 10334 } 10335 } 10336 10337 return diff; 10338} 10339 10340// support: jQuery <1.8 10341if ( !$.fn.addBack ) { 10342 $.fn.addBack = function( selector ) { 10343 return this.add( selector == null ? 10344 this.prevObject : this.prevObject.filter( selector ) 10345 ); 10346 }; 10347} 10348 10349$.effects.animateClass = function( value, duration, easing, callback ) { 10350 var o = $.speed( duration, easing, callback ); 10351 10352 return this.queue( function() { 10353 var animated = $( this ), 10354 baseClass = animated.attr( "class" ) || "", 10355 applyClassChange, 10356 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 10357 10358 // map the animated objects to store the original styles. 10359 allAnimations = allAnimations.map(function() { 10360 var el = $( this ); 10361 return { 10362 el: el, 10363 start: getElementStyles( this ) 10364 }; 10365 }); 10366 10367 // apply class change 10368 applyClassChange = function() { 10369 $.each( classAnimationActions, function(i, action) { 10370 if ( value[ action ] ) { 10371 animated[ action + "Class" ]( value[ action ] ); 10372 } 10373 }); 10374 }; 10375 applyClassChange(); 10376 10377 // map all animated objects again - calculate new styles and diff 10378 allAnimations = allAnimations.map(function() { 10379 this.end = getElementStyles( this.el[ 0 ] ); 10380 this.diff = styleDifference( this.start, this.end ); 10381 return this; 10382 }); 10383 10384 // apply original class 10385 animated.attr( "class", baseClass ); 10386 10387 // map all animated objects again - this time collecting a promise 10388 allAnimations = allAnimations.map(function() { 10389 var styleInfo = this, 10390 dfd = $.Deferred(), 10391 opts = $.extend({}, o, { 10392 queue: false, 10393 complete: function() { 10394 dfd.resolve( styleInfo ); 10395 } 10396 }); 10397 10398 this.el.animate( this.diff, opts ); 10399 return dfd.promise(); 10400 }); 10401 10402 // once all animations have completed: 10403 $.when.apply( $, allAnimations.get() ).done(function() { 10404 10405 // set the final class 10406 applyClassChange(); 10407 10408 // for each animated element, 10409 // clear all css properties that were animated 10410 $.each( arguments, function() { 10411 var el = this.el; 10412 $.each( this.diff, function(key) { 10413 el.css( key, "" ); 10414 }); 10415 }); 10416 10417 // this is guarnteed to be there if you use jQuery.speed() 10418 // it also handles dequeuing the next anim... 10419 o.complete.call( animated[ 0 ] ); 10420 }); 10421 }); 10422}; 10423 10424$.fn.extend({ 10425 addClass: (function( orig ) { 10426 return function( classNames, speed, easing, callback ) { 10427 return speed ? 10428 $.effects.animateClass.call( this, 10429 { add: classNames }, speed, easing, callback ) : 10430 orig.apply( this, arguments ); 10431 }; 10432 })( $.fn.addClass ), 10433 10434 removeClass: (function( orig ) { 10435 return function( classNames, speed, easing, callback ) { 10436 return arguments.length > 1 ? 10437 $.effects.animateClass.call( this, 10438 { remove: classNames }, speed, easing, callback ) : 10439 orig.apply( this, arguments ); 10440 }; 10441 })( $.fn.removeClass ), 10442 10443 toggleClass: (function( orig ) { 10444 return function( classNames, force, speed, easing, callback ) { 10445 if ( typeof force === "boolean" || force === undefined ) { 10446 if ( !speed ) { 10447 // without speed parameter 10448 return orig.apply( this, arguments ); 10449 } else { 10450 return $.effects.animateClass.call( this, 10451 (force ? { add: classNames } : { remove: classNames }), 10452 speed, easing, callback ); 10453 } 10454 } else { 10455 // without force parameter 10456 return $.effects.animateClass.call( this, 10457 { toggle: classNames }, force, speed, easing ); 10458 } 10459 }; 10460 })( $.fn.toggleClass ), 10461 10462 switchClass: function( remove, add, speed, easing, callback) { 10463 return $.effects.animateClass.call( this, { 10464 add: add, 10465 remove: remove 10466 }, speed, easing, callback ); 10467 } 10468}); 10469 10470})(); 10471 10472/******************************************************************************/ 10473/*********************************** EFFECTS **********************************/ 10474/******************************************************************************/ 10475 10476(function() { 10477 10478$.extend( $.effects, { 10479 version: "1.11.1", 10480 10481 // Saves a set of properties in a data storage 10482 save: function( element, set ) { 10483 for ( var i = 0; i < set.length; i++ ) { 10484 if ( set[ i ] !== null ) { 10485 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 10486 } 10487 } 10488 }, 10489 10490 // Restores a set of previously saved properties from a data storage 10491 restore: function( element, set ) { 10492 var val, i; 10493 for ( i = 0; i < set.length; i++ ) { 10494 if ( set[ i ] !== null ) { 10495 val = element.data( dataSpace + set[ i ] ); 10496 // support: jQuery 1.6.2 10497 // http://bugs.jquery.com/ticket/9917 10498 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 10499 // We can't differentiate between "" and 0 here, so we just assume 10500 // empty string since it's likely to be a more common value... 10501 if ( val === undefined ) { 10502 val = ""; 10503 } 10504 element.css( set[ i ], val ); 10505 } 10506 } 10507 }, 10508 10509 setMode: function( el, mode ) { 10510 if (mode === "toggle") { 10511 mode = el.is( ":hidden" ) ? "show" : "hide"; 10512 } 10513 return mode; 10514 }, 10515 10516 // Translates a [top,left] array into a baseline value 10517 // this should be a little more flexible in the future to handle a string & hash 10518 getBaseline: function( origin, original ) { 10519 var y, x; 10520 switch ( origin[ 0 ] ) { 10521 case "top": y = 0; break; 10522 case "middle": y = 0.5; break; 10523 case "bottom": y = 1; break; 10524 default: y = origin[ 0 ] / original.height; 10525 } 10526 switch ( origin[ 1 ] ) { 10527 case "left": x = 0; break; 10528 case "center": x = 0.5; break; 10529 case "right": x = 1; break; 10530 default: x = origin[ 1 ] / original.width; 10531 } 10532 return { 10533 x: x, 10534 y: y 10535 }; 10536 }, 10537 10538 // Wraps the element around a wrapper that copies position properties 10539 createWrapper: function( element ) { 10540 10541 // if the element is already wrapped, return it 10542 if ( element.parent().is( ".ui-effects-wrapper" )) { 10543 return element.parent(); 10544 } 10545 10546 // wrap the element 10547 var props = { 10548 width: element.outerWidth(true), 10549 height: element.outerHeight(true), 10550 "float": element.css( "float" ) 10551 }, 10552 wrapper = $( "<div></div>" ) 10553 .addClass( "ui-effects-wrapper" ) 10554 .css({ 10555 fontSize: "100%", 10556 background: "transparent", 10557 border: "none", 10558 margin: 0, 10559 padding: 0 10560 }), 10561 // Store the size in case width/height are defined in % - Fixes #5245 10562 size = { 10563 width: element.width(), 10564 height: element.height() 10565 }, 10566 active = document.activeElement; 10567 10568 // support: Firefox 10569 // Firefox incorrectly exposes anonymous content 10570 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 10571 try { 10572 active.id; 10573 } catch( e ) { 10574 active = document.body; 10575 } 10576 10577 element.wrap( wrapper ); 10578 10579 // Fixes #7595 - Elements lose focus when wrapped. 10580 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 10581 $( active ).focus(); 10582 } 10583 10584 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 10585 10586 // transfer positioning properties to the wrapper 10587 if ( element.css( "position" ) === "static" ) { 10588 wrapper.css({ position: "relative" }); 10589 element.css({ position: "relative" }); 10590 } else { 10591 $.extend( props, { 10592 position: element.css( "position" ), 10593 zIndex: element.css( "z-index" ) 10594 }); 10595 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 10596 props[ pos ] = element.css( pos ); 10597 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 10598 props[ pos ] = "auto"; 10599 } 10600 }); 10601 element.css({ 10602 position: "relative", 10603 top: 0, 10604 left: 0, 10605 right: "auto", 10606 bottom: "auto" 10607 }); 10608 } 10609 element.css(size); 10610 10611 return wrapper.css( props ).show(); 10612 }, 10613 10614 removeWrapper: function( element ) { 10615 var active = document.activeElement; 10616 10617 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 10618 element.parent().replaceWith( element ); 10619 10620 // Fixes #7595 - Elements lose focus when wrapped. 10621 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 10622 $( active ).focus(); 10623 } 10624 } 10625 10626 return element; 10627 }, 10628 10629 setTransition: function( element, list, factor, value ) { 10630 value = value || {}; 10631 $.each( list, function( i, x ) { 10632 var unit = element.cssUnit( x ); 10633 if ( unit[ 0 ] > 0 ) { 10634 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 10635 } 10636 }); 10637 return value; 10638 } 10639}); 10640 10641// return an effect options object for the given parameters: 10642function _normalizeArguments( effect, options, speed, callback ) { 10643 10644 // allow passing all options as the first parameter 10645 if ( $.isPlainObject( effect ) ) { 10646 options = effect; 10647 effect = effect.effect; 10648 } 10649 10650 // convert to an object 10651 effect = { effect: effect }; 10652 10653 // catch (effect, null, ...) 10654 if ( options == null ) { 10655 options = {}; 10656 } 10657 10658 // catch (effect, callback) 10659 if ( $.isFunction( options ) ) { 10660 callback = options; 10661 speed = null; 10662 options = {}; 10663 } 10664 10665 // catch (effect, speed, ?) 10666 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 10667 callback = speed; 10668 speed = options; 10669 options = {}; 10670 } 10671 10672 // catch (effect, options, callback) 10673 if ( $.isFunction( speed ) ) { 10674 callback = speed; 10675 speed = null; 10676 } 10677 10678 // add options to effect 10679 if ( options ) { 10680 $.extend( effect, options ); 10681 } 10682 10683 speed = speed || options.duration; 10684 effect.duration = $.fx.off ? 0 : 10685 typeof speed === "number" ? speed : 10686 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 10687 $.fx.speeds._default; 10688 10689 effect.complete = callback || options.complete; 10690 10691 return effect; 10692} 10693 10694function standardAnimationOption( option ) { 10695 // Valid standard speeds (nothing, number, named speed) 10696 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 10697 return true; 10698 } 10699 10700 // Invalid strings - treat as "normal" speed 10701 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 10702 return true; 10703 } 10704 10705 // Complete callback 10706 if ( $.isFunction( option ) ) { 10707 return true; 10708 } 10709 10710 // Options hash (but not naming an effect) 10711 if ( typeof option === "object" && !option.effect ) { 10712 return true; 10713 } 10714 10715 // Didn't match any standard API 10716 return false; 10717} 10718 10719$.fn.extend({ 10720 effect: function( /* effect, options, speed, callback */ ) { 10721 var args = _normalizeArguments.apply( this, arguments ), 10722 mode = args.mode, 10723 queue = args.queue, 10724 effectMethod = $.effects.effect[ args.effect ]; 10725 10726 if ( $.fx.off || !effectMethod ) { 10727 // delegate to the original method (e.g., .show()) if possible 10728 if ( mode ) { 10729 return this[ mode ]( args.duration, args.complete ); 10730 } else { 10731 return this.each( function() { 10732 if ( args.complete ) { 10733 args.complete.call( this ); 10734 } 10735 }); 10736 } 10737 } 10738 10739 function run( next ) { 10740 var elem = $( this ), 10741 complete = args.complete, 10742 mode = args.mode; 10743 10744 function done() { 10745 if ( $.isFunction( complete ) ) { 10746 complete.call( elem[0] ); 10747 } 10748 if ( $.isFunction( next ) ) { 10749 next(); 10750 } 10751 } 10752 10753 // If the element already has the correct final state, delegate to 10754 // the core methods so the internal tracking of "olddisplay" works. 10755 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 10756 elem[ mode ](); 10757 done(); 10758 } else { 10759 effectMethod.call( elem[0], args, done ); 10760 } 10761 } 10762 10763 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 10764 }, 10765 10766 show: (function( orig ) { 10767 return function( option ) { 10768 if ( standardAnimationOption( option ) ) { 10769 return orig.apply( this, arguments ); 10770 } else { 10771 var args = _normalizeArguments.apply( this, arguments ); 10772 args.mode = "show"; 10773 return this.effect.call( this, args ); 10774 } 10775 }; 10776 })( $.fn.show ), 10777 10778 hide: (function( orig ) { 10779 return function( option ) { 10780 if ( standardAnimationOption( option ) ) { 10781 return orig.apply( this, arguments ); 10782 } else { 10783 var args = _normalizeArguments.apply( this, arguments ); 10784 args.mode = "hide"; 10785 return this.effect.call( this, args ); 10786 } 10787 }; 10788 })( $.fn.hide ), 10789 10790 toggle: (function( orig ) { 10791 return function( option ) { 10792 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 10793 return orig.apply( this, arguments ); 10794 } else { 10795 var args = _normalizeArguments.apply( this, arguments ); 10796 args.mode = "toggle"; 10797 return this.effect.call( this, args ); 10798 } 10799 }; 10800 })( $.fn.toggle ), 10801 10802 // helper functions 10803 cssUnit: function(key) { 10804 var style = this.css( key ), 10805 val = []; 10806 10807 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 10808 if ( style.indexOf( unit ) > 0 ) { 10809 val = [ parseFloat( style ), unit ]; 10810 } 10811 }); 10812 return val; 10813 } 10814}); 10815 10816})(); 10817 10818/******************************************************************************/ 10819/*********************************** EASING ***********************************/ 10820/******************************************************************************/ 10821 10822(function() { 10823 10824// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 10825 10826var baseEasings = {}; 10827 10828$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 10829 baseEasings[ name ] = function( p ) { 10830 return Math.pow( p, i + 2 ); 10831 }; 10832}); 10833 10834$.extend( baseEasings, { 10835 Sine: function( p ) { 10836 return 1 - Math.cos( p * Math.PI / 2 ); 10837 }, 10838 Circ: function( p ) { 10839 return 1 - Math.sqrt( 1 - p * p ); 10840 }, 10841 Elastic: function( p ) { 10842 return p === 0 || p === 1 ? p : 10843 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 10844 }, 10845 Back: function( p ) { 10846 return p * p * ( 3 * p - 2 ); 10847 }, 10848 Bounce: function( p ) { 10849 var pow2, 10850 bounce = 4; 10851 10852 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 10853 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 10854 } 10855}); 10856 10857$.each( baseEasings, function( name, easeIn ) { 10858 $.easing[ "easeIn" + name ] = easeIn; 10859 $.easing[ "easeOut" + name ] = function( p ) { 10860 return 1 - easeIn( 1 - p ); 10861 }; 10862 $.easing[ "easeInOut" + name ] = function( p ) { 10863 return p < 0.5 ? 10864 easeIn( p * 2 ) / 2 : 10865 1 - easeIn( p * -2 + 2 ) / 2; 10866 }; 10867}); 10868 10869})(); 10870 10871var effect = $.effects; 10872 10873 10874/*! 10875 * jQuery UI Effects Blind 1.11.1 10876 * http://jqueryui.com 10877 * 10878 * Copyright 2014 jQuery Foundation and other contributors 10879 * Released under the MIT license. 10880 * http://jquery.org/license 10881 * 10882 * http://api.jqueryui.com/blind-effect/ 10883 */ 10884 10885 10886var effectBlind = $.effects.effect.blind = function( o, done ) { 10887 // Create element 10888 var el = $( this ), 10889 rvertical = /up|down|vertical/, 10890 rpositivemotion = /up|left|vertical|horizontal/, 10891 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10892 mode = $.effects.setMode( el, o.mode || "hide" ), 10893 direction = o.direction || "up", 10894 vertical = rvertical.test( direction ), 10895 ref = vertical ? "height" : "width", 10896 ref2 = vertical ? "top" : "left", 10897 motion = rpositivemotion.test( direction ), 10898 animation = {}, 10899 show = mode === "show", 10900 wrapper, distance, margin; 10901 10902 // if already wrapped, the wrapper's properties are my property. #6245 10903 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 10904 $.effects.save( el.parent(), props ); 10905 } else { 10906 $.effects.save( el, props ); 10907 } 10908 el.show(); 10909 wrapper = $.effects.createWrapper( el ).css({ 10910 overflow: "hidden" 10911 }); 10912 10913 distance = wrapper[ ref ](); 10914 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 10915 10916 animation[ ref ] = show ? distance : 0; 10917 if ( !motion ) { 10918 el 10919 .css( vertical ? "bottom" : "right", 0 ) 10920 .css( vertical ? "top" : "left", "auto" ) 10921 .css({ position: "absolute" }); 10922 10923 animation[ ref2 ] = show ? margin : distance + margin; 10924 } 10925 10926 // start at 0 if we are showing 10927 if ( show ) { 10928 wrapper.css( ref, 0 ); 10929 if ( !motion ) { 10930 wrapper.css( ref2, margin + distance ); 10931 } 10932 } 10933 10934 // Animate 10935 wrapper.animate( animation, { 10936 duration: o.duration, 10937 easing: o.easing, 10938 queue: false, 10939 complete: function() { 10940 if ( mode === "hide" ) { 10941 el.hide(); 10942 } 10943 $.effects.restore( el, props ); 10944 $.effects.removeWrapper( el ); 10945 done(); 10946 } 10947 }); 10948}; 10949 10950 10951/*! 10952 * jQuery UI Effects Bounce 1.11.1 10953 * http://jqueryui.com 10954 * 10955 * Copyright 2014 jQuery Foundation and other contributors 10956 * Released under the MIT license. 10957 * http://jquery.org/license 10958 * 10959 * http://api.jqueryui.com/bounce-effect/ 10960 */ 10961 10962 10963var effectBounce = $.effects.effect.bounce = function( o, done ) { 10964 var el = $( this ), 10965 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 10966 10967 // defaults: 10968 mode = $.effects.setMode( el, o.mode || "effect" ), 10969 hide = mode === "hide", 10970 show = mode === "show", 10971 direction = o.direction || "up", 10972 distance = o.distance, 10973 times = o.times || 5, 10974 10975 // number of internal animations 10976 anims = times * 2 + ( show || hide ? 1 : 0 ), 10977 speed = o.duration / anims, 10978 easing = o.easing, 10979 10980 // utility: 10981 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 10982 motion = ( direction === "up" || direction === "left" ), 10983 i, 10984 upAnim, 10985 downAnim, 10986 10987 // we will need to re-assemble the queue to stack our animations in place 10988 queue = el.queue(), 10989 queuelen = queue.length; 10990 10991 // Avoid touching opacity to prevent clearType and PNG issues in IE 10992 if ( show || hide ) { 10993 props.push( "opacity" ); 10994 } 10995 10996 $.effects.save( el, props ); 10997 el.show(); 10998 $.effects.createWrapper( el ); // Create Wrapper 10999 11000 // default distance for the BIGGEST bounce is the outer Distance / 3 11001 if ( !distance ) { 11002 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 11003 } 11004 11005 if ( show ) { 11006 downAnim = { opacity: 1 }; 11007 downAnim[ ref ] = 0; 11008 11009 // if we are showing, force opacity 0 and set the initial position 11010 // then do the "first" animation 11011 el.css( "opacity", 0 ) 11012 .css( ref, motion ? -distance * 2 : distance * 2 ) 11013 .animate( downAnim, speed, easing ); 11014 } 11015 11016 // start at the smallest distance if we are hiding 11017 if ( hide ) { 11018 distance = distance / Math.pow( 2, times - 1 ); 11019 } 11020 11021 downAnim = {}; 11022 downAnim[ ref ] = 0; 11023 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 11024 for ( i = 0; i < times; i++ ) { 11025 upAnim = {}; 11026 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 11027 11028 el.animate( upAnim, speed, easing ) 11029 .animate( downAnim, speed, easing ); 11030 11031 distance = hide ? distance * 2 : distance / 2; 11032 } 11033 11034 // Last Bounce when Hiding 11035 if ( hide ) { 11036 upAnim = { opacity: 0 }; 11037 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 11038 11039 el.animate( upAnim, speed, easing ); 11040 } 11041 11042 el.queue(function() { 11043 if ( hide ) { 11044 el.hide(); 11045 } 11046 $.effects.restore( el, props ); 11047 $.effects.removeWrapper( el ); 11048 done(); 11049 }); 11050 11051 // inject all the animations we just queued to be first in line (after "inprogress") 11052 if ( queuelen > 1) { 11053 queue.splice.apply( queue, 11054 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11055 } 11056 el.dequeue(); 11057 11058}; 11059 11060 11061/*! 11062 * jQuery UI Effects Clip 1.11.1 11063 * http://jqueryui.com 11064 * 11065 * Copyright 2014 jQuery Foundation and other contributors 11066 * Released under the MIT license. 11067 * http://jquery.org/license 11068 * 11069 * http://api.jqueryui.com/clip-effect/ 11070 */ 11071 11072 11073var effectClip = $.effects.effect.clip = function( o, done ) { 11074 // Create element 11075 var el = $( this ), 11076 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11077 mode = $.effects.setMode( el, o.mode || "hide" ), 11078 show = mode === "show", 11079 direction = o.direction || "vertical", 11080 vert = direction === "vertical", 11081 size = vert ? "height" : "width", 11082 position = vert ? "top" : "left", 11083 animation = {}, 11084 wrapper, animate, distance; 11085 11086 // Save & Show 11087 $.effects.save( el, props ); 11088 el.show(); 11089 11090 // Create Wrapper 11091 wrapper = $.effects.createWrapper( el ).css({ 11092 overflow: "hidden" 11093 }); 11094 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 11095 distance = animate[ size ](); 11096 11097 // Shift 11098 if ( show ) { 11099 animate.css( size, 0 ); 11100 animate.css( position, distance / 2 ); 11101 } 11102 11103 // Create Animation Object: 11104 animation[ size ] = show ? distance : 0; 11105 animation[ position ] = show ? 0 : distance / 2; 11106 11107 // Animate 11108 animate.animate( animation, { 11109 queue: false, 11110 duration: o.duration, 11111 easing: o.easing, 11112 complete: function() { 11113 if ( !show ) { 11114 el.hide(); 11115 } 11116 $.effects.restore( el, props ); 11117 $.effects.removeWrapper( el ); 11118 done(); 11119 } 11120 }); 11121 11122}; 11123 11124 11125/*! 11126 * jQuery UI Effects Drop 1.11.1 11127 * http://jqueryui.com 11128 * 11129 * Copyright 2014 jQuery Foundation and other contributors 11130 * Released under the MIT license. 11131 * http://jquery.org/license 11132 * 11133 * http://api.jqueryui.com/drop-effect/ 11134 */ 11135 11136 11137var effectDrop = $.effects.effect.drop = function( o, done ) { 11138 11139 var el = $( this ), 11140 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 11141 mode = $.effects.setMode( el, o.mode || "hide" ), 11142 show = mode === "show", 11143 direction = o.direction || "left", 11144 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 11145 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 11146 animation = { 11147 opacity: show ? 1 : 0 11148 }, 11149 distance; 11150 11151 // Adjust 11152 $.effects.save( el, props ); 11153 el.show(); 11154 $.effects.createWrapper( el ); 11155 11156 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 11157 11158 if ( show ) { 11159 el 11160 .css( "opacity", 0 ) 11161 .css( ref, motion === "pos" ? -distance : distance ); 11162 } 11163 11164 // Animation 11165 animation[ ref ] = ( show ? 11166 ( motion === "pos" ? "+=" : "-=" ) : 11167 ( motion === "pos" ? "-=" : "+=" ) ) + 11168 distance; 11169 11170 // Animate 11171 el.animate( animation, { 11172 queue: false, 11173 duration: o.duration, 11174 easing: o.easing, 11175 complete: function() { 11176 if ( mode === "hide" ) { 11177 el.hide(); 11178 } 11179 $.effects.restore( el, props ); 11180 $.effects.removeWrapper( el ); 11181 done(); 11182 } 11183 }); 11184}; 11185 11186 11187/*! 11188 * jQuery UI Effects Explode 1.11.1 11189 * http://jqueryui.com 11190 * 11191 * Copyright 2014 jQuery Foundation and other contributors 11192 * Released under the MIT license. 11193 * http://jquery.org/license 11194 * 11195 * http://api.jqueryui.com/explode-effect/ 11196 */ 11197 11198 11199var effectExplode = $.effects.effect.explode = function( o, done ) { 11200 11201 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 11202 cells = rows, 11203 el = $( this ), 11204 mode = $.effects.setMode( el, o.mode || "hide" ), 11205 show = mode === "show", 11206 11207 // show and then visibility:hidden the element before calculating offset 11208 offset = el.show().css( "visibility", "hidden" ).offset(), 11209 11210 // width and height of a piece 11211 width = Math.ceil( el.outerWidth() / cells ), 11212 height = Math.ceil( el.outerHeight() / rows ), 11213 pieces = [], 11214 11215 // loop 11216 i, j, left, top, mx, my; 11217 11218 // children animate complete: 11219 function childComplete() { 11220 pieces.push( this ); 11221 if ( pieces.length === rows * cells ) { 11222 animComplete(); 11223 } 11224 } 11225 11226 // clone the element for each row and cell. 11227 for ( i = 0; i < rows ; i++ ) { // ===> 11228 top = offset.top + i * height; 11229 my = i - ( rows - 1 ) / 2 ; 11230 11231 for ( j = 0; j < cells ; j++ ) { // ||| 11232 left = offset.left + j * width; 11233 mx = j - ( cells - 1 ) / 2 ; 11234 11235 // Create a clone of the now hidden main element that will be absolute positioned 11236 // within a wrapper div off the -left and -top equal to size of our pieces 11237 el 11238 .clone() 11239 .appendTo( "body" ) 11240 .wrap( "<div></div>" ) 11241 .css({ 11242 position: "absolute", 11243 visibility: "visible", 11244 left: -j * width, 11245 top: -i * height 11246 }) 11247 11248 // select the wrapper - make it overflow: hidden and absolute positioned based on 11249 // where the original was located +left and +top equal to the size of pieces 11250 .parent() 11251 .addClass( "ui-effects-explode" ) 11252 .css({ 11253 position: "absolute", 11254 overflow: "hidden", 11255 width: width, 11256 height: height, 11257 left: left + ( show ? mx * width : 0 ), 11258 top: top + ( show ? my * height : 0 ), 11259 opacity: show ? 0 : 1 11260 }).animate({ 11261 left: left + ( show ? 0 : mx * width ), 11262 top: top + ( show ? 0 : my * height ), 11263 opacity: show ? 1 : 0 11264 }, o.duration || 500, o.easing, childComplete ); 11265 } 11266 } 11267 11268 function animComplete() { 11269 el.css({ 11270 visibility: "visible" 11271 }); 11272 $( pieces ).remove(); 11273 if ( !show ) { 11274 el.hide(); 11275 } 11276 done(); 11277 } 11278}; 11279 11280 11281/*! 11282 * jQuery UI Effects Fade 1.11.1 11283 * http://jqueryui.com 11284 * 11285 * Copyright 2014 jQuery Foundation and other contributors 11286 * Released under the MIT license. 11287 * http://jquery.org/license 11288 * 11289 * http://api.jqueryui.com/fade-effect/ 11290 */ 11291 11292 11293var effectFade = $.effects.effect.fade = function( o, done ) { 11294 var el = $( this ), 11295 mode = $.effects.setMode( el, o.mode || "toggle" ); 11296 11297 el.animate({ 11298 opacity: mode 11299 }, { 11300 queue: false, 11301 duration: o.duration, 11302 easing: o.easing, 11303 complete: done 11304 }); 11305}; 11306 11307 11308/*! 11309 * jQuery UI Effects Fold 1.11.1 11310 * http://jqueryui.com 11311 * 11312 * Copyright 2014 jQuery Foundation and other contributors 11313 * Released under the MIT license. 11314 * http://jquery.org/license 11315 * 11316 * http://api.jqueryui.com/fold-effect/ 11317 */ 11318 11319 11320var effectFold = $.effects.effect.fold = function( o, done ) { 11321 11322 // Create element 11323 var el = $( this ), 11324 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11325 mode = $.effects.setMode( el, o.mode || "hide" ), 11326 show = mode === "show", 11327 hide = mode === "hide", 11328 size = o.size || 15, 11329 percent = /([0-9]+)%/.exec( size ), 11330 horizFirst = !!o.horizFirst, 11331 widthFirst = show !== horizFirst, 11332 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 11333 duration = o.duration / 2, 11334 wrapper, distance, 11335 animation1 = {}, 11336 animation2 = {}; 11337 11338 $.effects.save( el, props ); 11339 el.show(); 11340 11341 // Create Wrapper 11342 wrapper = $.effects.createWrapper( el ).css({ 11343 overflow: "hidden" 11344 }); 11345 distance = widthFirst ? 11346 [ wrapper.width(), wrapper.height() ] : 11347 [ wrapper.height(), wrapper.width() ]; 11348 11349 if ( percent ) { 11350 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 11351 } 11352 if ( show ) { 11353 wrapper.css( horizFirst ? { 11354 height: 0, 11355 width: size 11356 } : { 11357 height: size, 11358 width: 0 11359 }); 11360 } 11361 11362 // Animation 11363 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 11364 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 11365 11366 // Animate 11367 wrapper 11368 .animate( animation1, duration, o.easing ) 11369 .animate( animation2, duration, o.easing, function() { 11370 if ( hide ) { 11371 el.hide(); 11372 } 11373 $.effects.restore( el, props ); 11374 $.effects.removeWrapper( el ); 11375 done(); 11376 }); 11377 11378}; 11379 11380 11381/*! 11382 * jQuery UI Effects Highlight 1.11.1 11383 * http://jqueryui.com 11384 * 11385 * Copyright 2014 jQuery Foundation and other contributors 11386 * Released under the MIT license. 11387 * http://jquery.org/license 11388 * 11389 * http://api.jqueryui.com/highlight-effect/ 11390 */ 11391 11392 11393var effectHighlight = $.effects.effect.highlight = function( o, done ) { 11394 var elem = $( this ), 11395 props = [ "backgroundImage", "backgroundColor", "opacity" ], 11396 mode = $.effects.setMode( elem, o.mode || "show" ), 11397 animation = { 11398 backgroundColor: elem.css( "backgroundColor" ) 11399 }; 11400 11401 if (mode === "hide") { 11402 animation.opacity = 0; 11403 } 11404 11405 $.effects.save( elem, props ); 11406 11407 elem 11408 .show() 11409 .css({ 11410 backgroundImage: "none", 11411 backgroundColor: o.color || "#ffff99" 11412 }) 11413 .animate( animation, { 11414 queue: false, 11415 duration: o.duration, 11416 easing: o.easing, 11417 complete: function() { 11418 if ( mode === "hide" ) { 11419 elem.hide(); 11420 } 11421 $.effects.restore( elem, props ); 11422 done(); 11423 } 11424 }); 11425}; 11426 11427 11428/*! 11429 * jQuery UI Effects Size 1.11.1 11430 * http://jqueryui.com 11431 * 11432 * Copyright 2014 jQuery Foundation and other contributors 11433 * Released under the MIT license. 11434 * http://jquery.org/license 11435 * 11436 * http://api.jqueryui.com/size-effect/ 11437 */ 11438 11439 11440var effectSize = $.effects.effect.size = function( o, done ) { 11441 11442 // Create element 11443 var original, baseline, factor, 11444 el = $( this ), 11445 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 11446 11447 // Always restore 11448 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 11449 11450 // Copy for children 11451 props2 = [ "width", "height", "overflow" ], 11452 cProps = [ "fontSize" ], 11453 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 11454 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 11455 11456 // Set options 11457 mode = $.effects.setMode( el, o.mode || "effect" ), 11458 restore = o.restore || mode !== "effect", 11459 scale = o.scale || "both", 11460 origin = o.origin || [ "middle", "center" ], 11461 position = el.css( "position" ), 11462 props = restore ? props0 : props1, 11463 zero = { 11464 height: 0, 11465 width: 0, 11466 outerHeight: 0, 11467 outerWidth: 0 11468 }; 11469 11470 if ( mode === "show" ) { 11471 el.show(); 11472 } 11473 original = { 11474 height: el.height(), 11475 width: el.width(), 11476 outerHeight: el.outerHeight(), 11477 outerWidth: el.outerWidth() 11478 }; 11479 11480 if ( o.mode === "toggle" && mode === "show" ) { 11481 el.from = o.to || zero; 11482 el.to = o.from || original; 11483 } else { 11484 el.from = o.from || ( mode === "show" ? zero : original ); 11485 el.to = o.to || ( mode === "hide" ? zero : original ); 11486 } 11487 11488 // Set scaling factor 11489 factor = { 11490 from: { 11491 y: el.from.height / original.height, 11492 x: el.from.width / original.width 11493 }, 11494 to: { 11495 y: el.to.height / original.height, 11496 x: el.to.width / original.width 11497 } 11498 }; 11499 11500 // Scale the css box 11501 if ( scale === "box" || scale === "both" ) { 11502 11503 // Vertical props scaling 11504 if ( factor.from.y !== factor.to.y ) { 11505 props = props.concat( vProps ); 11506 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 11507 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 11508 } 11509 11510 // Horizontal props scaling 11511 if ( factor.from.x !== factor.to.x ) { 11512 props = props.concat( hProps ); 11513 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 11514 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 11515 } 11516 } 11517 11518 // Scale the content 11519 if ( scale === "content" || scale === "both" ) { 11520 11521 // Vertical props scaling 11522 if ( factor.from.y !== factor.to.y ) { 11523 props = props.concat( cProps ).concat( props2 ); 11524 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 11525 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 11526 } 11527 } 11528 11529 $.effects.save( el, props ); 11530 el.show(); 11531 $.effects.createWrapper( el ); 11532 el.css( "overflow", "hidden" ).css( el.from ); 11533 11534 // Adjust 11535 if (origin) { // Calculate baseline shifts 11536 baseline = $.effects.getBaseline( origin, original ); 11537 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 11538 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 11539 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 11540 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 11541 } 11542 el.css( el.from ); // set top & left 11543 11544 // Animate 11545 if ( scale === "content" || scale === "both" ) { // Scale the children 11546 11547 // Add margins/font-size 11548 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 11549 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 11550 props2 = props0.concat(vProps).concat(hProps); 11551 11552 el.find( "*[width]" ).each( function() { 11553 var child = $( this ), 11554 c_original = { 11555 height: child.height(), 11556 width: child.width(), 11557 outerHeight: child.outerHeight(), 11558 outerWidth: child.outerWidth() 11559 }; 11560 if (restore) { 11561 $.effects.save(child, props2); 11562 } 11563 11564 child.from = { 11565 height: c_original.height * factor.from.y, 11566 width: c_original.width * factor.from.x, 11567 outerHeight: c_original.outerHeight * factor.from.y, 11568 outerWidth: c_original.outerWidth * factor.from.x 11569 }; 11570 child.to = { 11571 height: c_original.height * factor.to.y, 11572 width: c_original.width * factor.to.x, 11573 outerHeight: c_original.height * factor.to.y, 11574 outerWidth: c_original.width * factor.to.x 11575 }; 11576 11577 // Vertical props scaling 11578 if ( factor.from.y !== factor.to.y ) { 11579 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 11580 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 11581 } 11582 11583 // Horizontal props scaling 11584 if ( factor.from.x !== factor.to.x ) { 11585 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 11586 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 11587 } 11588 11589 // Animate children 11590 child.css( child.from ); 11591 child.animate( child.to, o.duration, o.easing, function() { 11592 11593 // Restore children 11594 if ( restore ) { 11595 $.effects.restore( child, props2 ); 11596 } 11597 }); 11598 }); 11599 } 11600 11601 // Animate 11602 el.animate( el.to, { 11603 queue: false, 11604 duration: o.duration, 11605 easing: o.easing, 11606 complete: function() { 11607 if ( el.to.opacity === 0 ) { 11608 el.css( "opacity", el.from.opacity ); 11609 } 11610 if ( mode === "hide" ) { 11611 el.hide(); 11612 } 11613 $.effects.restore( el, props ); 11614 if ( !restore ) { 11615 11616 // we need to calculate our new positioning based on the scaling 11617 if ( position === "static" ) { 11618 el.css({ 11619 position: "relative", 11620 top: el.to.top, 11621 left: el.to.left 11622 }); 11623 } else { 11624 $.each([ "top", "left" ], function( idx, pos ) { 11625 el.css( pos, function( _, str ) { 11626 var val = parseInt( str, 10 ), 11627 toRef = idx ? el.to.left : el.to.top; 11628 11629 // if original was "auto", recalculate the new value from wrapper 11630 if ( str === "auto" ) { 11631 return toRef + "px"; 11632 } 11633 11634 return val + toRef + "px"; 11635 }); 11636 }); 11637 } 11638 } 11639 11640 $.effects.removeWrapper( el ); 11641 done(); 11642 } 11643 }); 11644 11645}; 11646 11647 11648/*! 11649 * jQuery UI Effects Scale 1.11.1 11650 * http://jqueryui.com 11651 * 11652 * Copyright 2014 jQuery Foundation and other contributors 11653 * Released under the MIT license. 11654 * http://jquery.org/license 11655 * 11656 * http://api.jqueryui.com/scale-effect/ 11657 */ 11658 11659 11660var effectScale = $.effects.effect.scale = function( o, done ) { 11661 11662 // Create element 11663 var el = $( this ), 11664 options = $.extend( true, {}, o ), 11665 mode = $.effects.setMode( el, o.mode || "effect" ), 11666 percent = parseInt( o.percent, 10 ) || 11667 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 11668 direction = o.direction || "both", 11669 origin = o.origin, 11670 original = { 11671 height: el.height(), 11672 width: el.width(), 11673 outerHeight: el.outerHeight(), 11674 outerWidth: el.outerWidth() 11675 }, 11676 factor = { 11677 y: direction !== "horizontal" ? (percent / 100) : 1, 11678 x: direction !== "vertical" ? (percent / 100) : 1 11679 }; 11680 11681 // We are going to pass this effect to the size effect: 11682 options.effect = "size"; 11683 options.queue = false; 11684 options.complete = done; 11685 11686 // Set default origin and restore for show/hide 11687 if ( mode !== "effect" ) { 11688 options.origin = origin || [ "middle", "center" ]; 11689 options.restore = true; 11690 } 11691 11692 options.from = o.from || ( mode === "show" ? { 11693 height: 0, 11694 width: 0, 11695 outerHeight: 0, 11696 outerWidth: 0 11697 } : original ); 11698 options.to = { 11699 height: original.height * factor.y, 11700 width: original.width * factor.x, 11701 outerHeight: original.outerHeight * factor.y, 11702 outerWidth: original.outerWidth * factor.x 11703 }; 11704 11705 // Fade option to support puff 11706 if ( options.fade ) { 11707 if ( mode === "show" ) { 11708 options.from.opacity = 0; 11709 options.to.opacity = 1; 11710 } 11711 if ( mode === "hide" ) { 11712 options.from.opacity = 1; 11713 options.to.opacity = 0; 11714 } 11715 } 11716 11717 // Animate 11718 el.effect( options ); 11719 11720}; 11721 11722 11723/*! 11724 * jQuery UI Effects Puff 1.11.1 11725 * http://jqueryui.com 11726 * 11727 * Copyright 2014 jQuery Foundation and other contributors 11728 * Released under the MIT license. 11729 * http://jquery.org/license 11730 * 11731 * http://api.jqueryui.com/puff-effect/ 11732 */ 11733 11734 11735var effectPuff = $.effects.effect.puff = function( o, done ) { 11736 var elem = $( this ), 11737 mode = $.effects.setMode( elem, o.mode || "hide" ), 11738 hide = mode === "hide", 11739 percent = parseInt( o.percent, 10 ) || 150, 11740 factor = percent / 100, 11741 original = { 11742 height: elem.height(), 11743 width: elem.width(), 11744 outerHeight: elem.outerHeight(), 11745 outerWidth: elem.outerWidth() 11746 }; 11747 11748 $.extend( o, { 11749 effect: "scale", 11750 queue: false, 11751 fade: true, 11752 mode: mode, 11753 complete: done, 11754 percent: hide ? percent : 100, 11755 from: hide ? 11756 original : 11757 { 11758 height: original.height * factor, 11759 width: original.width * factor, 11760 outerHeight: original.outerHeight * factor, 11761 outerWidth: original.outerWidth * factor 11762 } 11763 }); 11764 11765 elem.effect( o ); 11766}; 11767 11768 11769/*! 11770 * jQuery UI Effects Pulsate 1.11.1 11771 * http://jqueryui.com 11772 * 11773 * Copyright 2014 jQuery Foundation and other contributors 11774 * Released under the MIT license. 11775 * http://jquery.org/license 11776 * 11777 * http://api.jqueryui.com/pulsate-effect/ 11778 */ 11779 11780 11781var effectPulsate = $.effects.effect.pulsate = function( o, done ) { 11782 var elem = $( this ), 11783 mode = $.effects.setMode( elem, o.mode || "show" ), 11784 show = mode === "show", 11785 hide = mode === "hide", 11786 showhide = ( show || mode === "hide" ), 11787 11788 // showing or hiding leaves of the "last" animation 11789 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 11790 duration = o.duration / anims, 11791 animateTo = 0, 11792 queue = elem.queue(), 11793 queuelen = queue.length, 11794 i; 11795 11796 if ( show || !elem.is(":visible")) { 11797 elem.css( "opacity", 0 ).show(); 11798 animateTo = 1; 11799 } 11800 11801 // anims - 1 opacity "toggles" 11802 for ( i = 1; i < anims; i++ ) { 11803 elem.animate({ 11804 opacity: animateTo 11805 }, duration, o.easing ); 11806 animateTo = 1 - animateTo; 11807 } 11808 11809 elem.animate({ 11810 opacity: animateTo 11811 }, duration, o.easing); 11812 11813 elem.queue(function() { 11814 if ( hide ) { 11815 elem.hide(); 11816 } 11817 done(); 11818 }); 11819 11820 // We just queued up "anims" animations, we need to put them next in the queue 11821 if ( queuelen > 1 ) { 11822 queue.splice.apply( queue, 11823 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11824 } 11825 elem.dequeue(); 11826}; 11827 11828 11829/*! 11830 * jQuery UI Effects Shake 1.11.1 11831 * http://jqueryui.com 11832 * 11833 * Copyright 2014 jQuery Foundation and other contributors 11834 * Released under the MIT license. 11835 * http://jquery.org/license 11836 * 11837 * http://api.jqueryui.com/shake-effect/ 11838 */ 11839 11840 11841var effectShake = $.effects.effect.shake = function( o, done ) { 11842 11843 var el = $( this ), 11844 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 11845 mode = $.effects.setMode( el, o.mode || "effect" ), 11846 direction = o.direction || "left", 11847 distance = o.distance || 20, 11848 times = o.times || 3, 11849 anims = times * 2 + 1, 11850 speed = Math.round( o.duration / anims ), 11851 ref = (direction === "up" || direction === "down") ? "top" : "left", 11852 positiveMotion = (direction === "up" || direction === "left"), 11853 animation = {}, 11854 animation1 = {}, 11855 animation2 = {}, 11856 i, 11857 11858 // we will need to re-assemble the queue to stack our animations in place 11859 queue = el.queue(), 11860 queuelen = queue.length; 11861 11862 $.effects.save( el, props ); 11863 el.show(); 11864 $.effects.createWrapper( el ); 11865 11866 // Animation 11867 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 11868 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 11869 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 11870 11871 // Animate 11872 el.animate( animation, speed, o.easing ); 11873 11874 // Shakes 11875 for ( i = 1; i < times; i++ ) { 11876 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 11877 } 11878 el 11879 .animate( animation1, speed, o.easing ) 11880 .animate( animation, speed / 2, o.easing ) 11881 .queue(function() { 11882 if ( mode === "hide" ) { 11883 el.hide(); 11884 } 11885 $.effects.restore( el, props ); 11886 $.effects.removeWrapper( el ); 11887 done(); 11888 }); 11889 11890 // inject all the animations we just queued to be first in line (after "inprogress") 11891 if ( queuelen > 1) { 11892 queue.splice.apply( queue, 11893 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 11894 } 11895 el.dequeue(); 11896 11897}; 11898 11899 11900/*! 11901 * jQuery UI Effects Slide 1.11.1 11902 * http://jqueryui.com 11903 * 11904 * Copyright 2014 jQuery Foundation and other contributors 11905 * Released under the MIT license. 11906 * http://jquery.org/license 11907 * 11908 * http://api.jqueryui.com/slide-effect/ 11909 */ 11910 11911 11912var effectSlide = $.effects.effect.slide = function( o, done ) { 11913 11914 // Create element 11915 var el = $( this ), 11916 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 11917 mode = $.effects.setMode( el, o.mode || "show" ), 11918 show = mode === "show", 11919 direction = o.direction || "left", 11920 ref = (direction === "up" || direction === "down") ? "top" : "left", 11921 positiveMotion = (direction === "up" || direction === "left"), 11922 distance, 11923 animation = {}; 11924 11925 // Adjust 11926 $.effects.save( el, props ); 11927 el.show(); 11928 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 11929 11930 $.effects.createWrapper( el ).css({ 11931 overflow: "hidden" 11932 }); 11933 11934 if ( show ) { 11935 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 11936 } 11937 11938 // Animation 11939 animation[ ref ] = ( show ? 11940 ( positiveMotion ? "+=" : "-=") : 11941 ( positiveMotion ? "-=" : "+=")) + 11942 distance; 11943 11944 // Animate 11945 el.animate( animation, { 11946 queue: false, 11947 duration: o.duration, 11948 easing: o.easing, 11949 complete: function() { 11950 if ( mode === "hide" ) { 11951 el.hide(); 11952 } 11953 $.effects.restore( el, props ); 11954 $.effects.removeWrapper( el ); 11955 done(); 11956 } 11957 }); 11958}; 11959 11960 11961/*! 11962 * jQuery UI Effects Transfer 1.11.1 11963 * http://jqueryui.com 11964 * 11965 * Copyright 2014 jQuery Foundation and other contributors 11966 * Released under the MIT license. 11967 * http://jquery.org/license 11968 * 11969 * http://api.jqueryui.com/transfer-effect/ 11970 */ 11971 11972 11973var effectTransfer = $.effects.effect.transfer = function( o, done ) { 11974 var elem = $( this ), 11975 target = $( o.to ), 11976 targetFixed = target.css( "position" ) === "fixed", 11977 body = $("body"), 11978 fixTop = targetFixed ? body.scrollTop() : 0, 11979 fixLeft = targetFixed ? body.scrollLeft() : 0, 11980 endPosition = target.offset(), 11981 animation = { 11982 top: endPosition.top - fixTop, 11983 left: endPosition.left - fixLeft, 11984 height: target.innerHeight(), 11985 width: target.innerWidth() 11986 }, 11987 startPosition = elem.offset(), 11988 transfer = $( "<div class='ui-effects-transfer'></div>" ) 11989 .appendTo( document.body ) 11990 .addClass( o.className ) 11991 .css({ 11992 top: startPosition.top - fixTop, 11993 left: startPosition.left - fixLeft, 11994 height: elem.innerHeight(), 11995 width: elem.innerWidth(), 11996 position: targetFixed ? "fixed" : "absolute" 11997 }) 11998 .animate( animation, o.duration, o.easing, function() { 11999 transfer.remove(); 12000 done(); 12001 }); 12002}; 12003 12004 12005/*! 12006 * jQuery UI Progressbar 1.11.1 12007 * http://jqueryui.com 12008 * 12009 * Copyright 2014 jQuery Foundation and other contributors 12010 * Released under the MIT license. 12011 * http://jquery.org/license 12012 * 12013 * http://api.jqueryui.com/progressbar/ 12014 */ 12015 12016 12017var progressbar = $.widget( "ui.progressbar", { 12018 version: "1.11.1", 12019 options: { 12020 max: 100, 12021 value: 0, 12022 12023 change: null, 12024 complete: null 12025 }, 12026 12027 min: 0, 12028 12029 _create: function() { 12030 // Constrain initial value 12031 this.oldValue = this.options.value = this._constrainedValue(); 12032 12033 this.element 12034 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12035 .attr({ 12036 // Only set static values, aria-valuenow and aria-valuemax are 12037 // set inside _refreshValue() 12038 role: "progressbar", 12039 "aria-valuemin": this.min 12040 }); 12041 12042 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12043 .appendTo( this.element ); 12044 12045 this._refreshValue(); 12046 }, 12047 12048 _destroy: function() { 12049 this.element 12050 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12051 .removeAttr( "role" ) 12052 .removeAttr( "aria-valuemin" ) 12053 .removeAttr( "aria-valuemax" ) 12054 .removeAttr( "aria-valuenow" ); 12055 12056 this.valueDiv.remove(); 12057 }, 12058 12059 value: function( newValue ) { 12060 if ( newValue === undefined ) { 12061 return this.options.value; 12062 } 12063 12064 this.options.value = this._constrainedValue( newValue ); 12065 this._refreshValue(); 12066 }, 12067 12068 _constrainedValue: function( newValue ) { 12069 if ( newValue === undefined ) { 12070 newValue = this.options.value; 12071 } 12072 12073 this.indeterminate = newValue === false; 12074 12075 // sanitize value 12076 if ( typeof newValue !== "number" ) { 12077 newValue = 0; 12078 } 12079 12080 return this.indeterminate ? false : 12081 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12082 }, 12083 12084 _setOptions: function( options ) { 12085 // Ensure "value" option is set after other values (like max) 12086 var value = options.value; 12087 delete options.value; 12088 12089 this._super( options ); 12090 12091 this.options.value = this._constrainedValue( value ); 12092 this._refreshValue(); 12093 }, 12094 12095 _setOption: function( key, value ) { 12096 if ( key === "max" ) { 12097 // Don't allow a max less than min 12098 value = Math.max( this.min, value ); 12099 } 12100 if ( key === "disabled" ) { 12101 this.element 12102 .toggleClass( "ui-state-disabled", !!value ) 12103 .attr( "aria-disabled", value ); 12104 } 12105 this._super( key, value ); 12106 }, 12107 12108 _percentage: function() { 12109 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 12110 }, 12111 12112 _refreshValue: function() { 12113 var value = this.options.value, 12114 percentage = this._percentage(); 12115 12116 this.valueDiv 12117 .toggle( this.indeterminate || value > this.min ) 12118 .toggleClass( "ui-corner-right", value === this.options.max ) 12119 .width( percentage.toFixed(0) + "%" ); 12120 12121 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 12122 12123 if ( this.indeterminate ) { 12124 this.element.removeAttr( "aria-valuenow" ); 12125 if ( !this.overlayDiv ) { 12126 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 12127 } 12128 } else { 12129 this.element.attr({ 12130 "aria-valuemax": this.options.max, 12131 "aria-valuenow": value 12132 }); 12133 if ( this.overlayDiv ) { 12134 this.overlayDiv.remove(); 12135 this.overlayDiv = null; 12136 } 12137 } 12138 12139 if ( this.oldValue !== value ) { 12140 this.oldValue = value; 12141 this._trigger( "change" ); 12142 } 12143 if ( value === this.options.max ) { 12144 this._trigger( "complete" ); 12145 } 12146 } 12147}); 12148 12149 12150/*! 12151 * jQuery UI Selectable 1.11.1 12152 * http://jqueryui.com 12153 * 12154 * Copyright 2014 jQuery Foundation and other contributors 12155 * Released under the MIT license. 12156 * http://jquery.org/license 12157 * 12158 * http://api.jqueryui.com/selectable/ 12159 */ 12160 12161 12162var selectable = $.widget("ui.selectable", $.ui.mouse, { 12163 version: "1.11.1", 12164 options: { 12165 appendTo: "body", 12166 autoRefresh: true, 12167 distance: 0, 12168 filter: "*", 12169 tolerance: "touch", 12170 12171 // callbacks 12172 selected: null, 12173 selecting: null, 12174 start: null, 12175 stop: null, 12176 unselected: null, 12177 unselecting: null 12178 }, 12179 _create: function() { 12180 var selectees, 12181 that = this; 12182 12183 this.element.addClass("ui-selectable"); 12184 12185 this.dragged = false; 12186 12187 // cache selectee children based on filter 12188 this.refresh = function() { 12189 selectees = $(that.options.filter, that.element[0]); 12190 selectees.addClass("ui-selectee"); 12191 selectees.each(function() { 12192 var $this = $(this), 12193 pos = $this.offset(); 12194 $.data(this, "selectable-item", { 12195 element: this, 12196 $element: $this, 12197 left: pos.left, 12198 top: pos.top, 12199 right: pos.left + $this.outerWidth(), 12200 bottom: pos.top + $this.outerHeight(), 12201 startselected: false, 12202 selected: $this.hasClass("ui-selected"), 12203 selecting: $this.hasClass("ui-selecting"), 12204 unselecting: $this.hasClass("ui-unselecting") 12205 }); 12206 }); 12207 }; 12208 this.refresh(); 12209 12210 this.selectees = selectees.addClass("ui-selectee"); 12211 12212 this._mouseInit(); 12213 12214 this.helper = $("<div class='ui-selectable-helper'></div>"); 12215 }, 12216 12217 _destroy: function() { 12218 this.selectees 12219 .removeClass("ui-selectee") 12220 .removeData("selectable-item"); 12221 this.element 12222 .removeClass("ui-selectable ui-selectable-disabled"); 12223 this._mouseDestroy(); 12224 }, 12225 12226 _mouseStart: function(event) { 12227 var that = this, 12228 options = this.options; 12229 12230 this.opos = [ event.pageX, event.pageY ]; 12231 12232 if (this.options.disabled) { 12233 return; 12234 } 12235 12236 this.selectees = $(options.filter, this.element[0]); 12237 12238 this._trigger("start", event); 12239 12240 $(options.appendTo).append(this.helper); 12241 // position helper (lasso) 12242 this.helper.css({ 12243 "left": event.pageX, 12244 "top": event.pageY, 12245 "width": 0, 12246 "height": 0 12247 }); 12248 12249 if (options.autoRefresh) { 12250 this.refresh(); 12251 } 12252 12253 this.selectees.filter(".ui-selected").each(function() { 12254 var selectee = $.data(this, "selectable-item"); 12255 selectee.startselected = true; 12256 if (!event.metaKey && !event.ctrlKey) { 12257 selectee.$element.removeClass("ui-selected"); 12258 selectee.selected = false; 12259 selectee.$element.addClass("ui-unselecting"); 12260 selectee.unselecting = true; 12261 // selectable UNSELECTING callback 12262 that._trigger("unselecting", event, { 12263 unselecting: selectee.element 12264 }); 12265 } 12266 }); 12267 12268 $(event.target).parents().addBack().each(function() { 12269 var doSelect, 12270 selectee = $.data(this, "selectable-item"); 12271 if (selectee) { 12272 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 12273 selectee.$element 12274 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 12275 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 12276 selectee.unselecting = !doSelect; 12277 selectee.selecting = doSelect; 12278 selectee.selected = doSelect; 12279 // selectable (UN)SELECTING callback 12280 if (doSelect) { 12281 that._trigger("selecting", event, { 12282 selecting: selectee.element 12283 }); 12284 } else { 12285 that._trigger("unselecting", event, { 12286 unselecting: selectee.element 12287 }); 12288 } 12289 return false; 12290 } 12291 }); 12292 12293 }, 12294 12295 _mouseDrag: function(event) { 12296 12297 this.dragged = true; 12298 12299 if (this.options.disabled) { 12300 return; 12301 } 12302 12303 var tmp, 12304 that = this, 12305 options = this.options, 12306 x1 = this.opos[0], 12307 y1 = this.opos[1], 12308 x2 = event.pageX, 12309 y2 = event.pageY; 12310 12311 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 12312 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 12313 this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); 12314 12315 this.selectees.each(function() { 12316 var selectee = $.data(this, "selectable-item"), 12317 hit = false; 12318 12319 //prevent helper from being selected if appendTo: selectable 12320 if (!selectee || selectee.element === that.element[0]) { 12321 return; 12322 } 12323 12324 if (options.tolerance === "touch") { 12325 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 12326 } else if (options.tolerance === "fit") { 12327 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 12328 } 12329 12330 if (hit) { 12331 // SELECT 12332 if (selectee.selected) { 12333 selectee.$element.removeClass("ui-selected"); 12334 selectee.selected = false; 12335 } 12336 if (selectee.unselecting) { 12337 selectee.$element.removeClass("ui-unselecting"); 12338 selectee.unselecting = false; 12339 } 12340 if (!selectee.selecting) { 12341 selectee.$element.addClass("ui-selecting"); 12342 selectee.selecting = true; 12343 // selectable SELECTING callback 12344 that._trigger("selecting", event, { 12345 selecting: selectee.element 12346 }); 12347 } 12348 } else { 12349 // UNSELECT 12350 if (selectee.selecting) { 12351 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 12352 selectee.$element.removeClass("ui-selecting"); 12353 selectee.selecting = false; 12354 selectee.$element.addClass("ui-selected"); 12355 selectee.selected = true; 12356 } else { 12357 selectee.$element.removeClass("ui-selecting"); 12358 selectee.selecting = false; 12359 if (selectee.startselected) { 12360 selectee.$element.addClass("ui-unselecting"); 12361 selectee.unselecting = true; 12362 } 12363 // selectable UNSELECTING callback 12364 that._trigger("unselecting", event, { 12365 unselecting: selectee.element 12366 }); 12367 } 12368 } 12369 if (selectee.selected) { 12370 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 12371 selectee.$element.removeClass("ui-selected"); 12372 selectee.selected = false; 12373 12374 selectee.$element.addClass("ui-unselecting"); 12375 selectee.unselecting = true; 12376 // selectable UNSELECTING callback 12377 that._trigger("unselecting", event, { 12378 unselecting: selectee.element 12379 }); 12380 } 12381 } 12382 } 12383 }); 12384 12385 return false; 12386 }, 12387 12388 _mouseStop: function(event) { 12389 var that = this; 12390 12391 this.dragged = false; 12392 12393 $(".ui-unselecting", this.element[0]).each(function() { 12394 var selectee = $.data(this, "selectable-item"); 12395 selectee.$element.removeClass("ui-unselecting"); 12396 selectee.unselecting = false; 12397 selectee.startselected = false; 12398 that._trigger("unselected", event, { 12399 unselected: selectee.element 12400 }); 12401 }); 12402 $(".ui-selecting", this.element[0]).each(function() { 12403 var selectee = $.data(this, "selectable-item"); 12404 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 12405 selectee.selecting = false; 12406 selectee.selected = true; 12407 selectee.startselected = true; 12408 that._trigger("selected", event, { 12409 selected: selectee.element 12410 }); 12411 }); 12412 this._trigger("stop", event); 12413 12414 this.helper.remove(); 12415 12416 return false; 12417 } 12418 12419}); 12420 12421 12422/*! 12423 * jQuery UI Selectmenu 1.11.1 12424 * http://jqueryui.com 12425 * 12426 * Copyright 2014 jQuery Foundation and other contributors 12427 * Released under the MIT license. 12428 * http://jquery.org/license 12429 * 12430 * http://api.jqueryui.com/selectmenu 12431 */ 12432 12433 12434var selectmenu = $.widget( "ui.selectmenu", { 12435 version: "1.11.1", 12436 defaultElement: "<select>", 12437 options: { 12438 appendTo: null, 12439 disabled: null, 12440 icons: { 12441 button: "ui-icon-triangle-1-s" 12442 }, 12443 position: { 12444 my: "left top", 12445 at: "left bottom", 12446 collision: "none" 12447 }, 12448 width: null, 12449 12450 // callbacks 12451 change: null, 12452 close: null, 12453 focus: null, 12454 open: null, 12455 select: null 12456 }, 12457 12458 _create: function() { 12459 var selectmenuId = this.element.uniqueId().attr( "id" ); 12460 this.ids = { 12461 element: selectmenuId, 12462 button: selectmenuId + "-button", 12463 menu: selectmenuId + "-menu" 12464 }; 12465 12466 this._drawButton(); 12467 this._drawMenu(); 12468 12469 if ( this.options.disabled ) { 12470 this.disable(); 12471 } 12472 }, 12473 12474 _drawButton: function() { 12475 var that = this, 12476 tabindex = this.element.attr( "tabindex" ); 12477 12478 // Associate existing label with the new button 12479 this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button ); 12480 this._on( this.label, { 12481 click: function( event ) { 12482 this.button.focus(); 12483 event.preventDefault(); 12484 } 12485 }); 12486 12487 // Hide original select element 12488 this.element.hide(); 12489 12490 // Create button 12491 this.button = $( "<span>", { 12492 "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all", 12493 tabindex: tabindex || this.options.disabled ? -1 : 0, 12494 id: this.ids.button, 12495 role: "combobox", 12496 "aria-expanded": "false", 12497 "aria-autocomplete": "list", 12498 "aria-owns": this.ids.menu, 12499 "aria-haspopup": "true" 12500 }) 12501 .insertAfter( this.element ); 12502 12503 $( "<span>", { 12504 "class": "ui-icon " + this.options.icons.button 12505 }) 12506 .prependTo( this.button ); 12507 12508 this.buttonText = $( "<span>", { 12509 "class": "ui-selectmenu-text" 12510 }) 12511 .appendTo( this.button ); 12512 12513 this._setText( this.buttonText, this.element.find( "option:selected" ).text() ); 12514 this._resizeButton(); 12515 12516 this._on( this.button, this._buttonEvents ); 12517 this.button.one( "focusin", function() { 12518 12519 // Delay rendering the menu items until the button receives focus. 12520 // The menu may have already been rendered via a programmatic open. 12521 if ( !that.menuItems ) { 12522 that._refreshMenu(); 12523 } 12524 }); 12525 this._hoverable( this.button ); 12526 this._focusable( this.button ); 12527 }, 12528 12529 _drawMenu: function() { 12530 var that = this; 12531 12532 // Create menu 12533 this.menu = $( "<ul>", { 12534 "aria-hidden": "true", 12535 "aria-labelledby": this.ids.button, 12536 id: this.ids.menu 12537 }); 12538 12539 // Wrap menu 12540 this.menuWrap = $( "<div>", { 12541 "class": "ui-selectmenu-menu ui-front" 12542 }) 12543 .append( this.menu ) 12544 .appendTo( this._appendTo() ); 12545 12546 // Initialize menu widget 12547 this.menuInstance = this.menu 12548 .menu({ 12549 role: "listbox", 12550 select: function( event, ui ) { 12551 event.preventDefault(); 12552 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 12553 }, 12554 focus: function( event, ui ) { 12555 var item = ui.item.data( "ui-selectmenu-item" ); 12556 12557 // Prevent inital focus from firing and check if its a newly focused item 12558 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 12559 that._trigger( "focus", event, { item: item } ); 12560 if ( !that.isOpen ) { 12561 that._select( item, event ); 12562 } 12563 } 12564 that.focusIndex = item.index; 12565 12566 that.button.attr( "aria-activedescendant", 12567 that.menuItems.eq( item.index ).attr( "id" ) ); 12568 } 12569 }) 12570 .menu( "instance" ); 12571 12572 // Adjust menu styles to dropdown 12573 this.menu 12574 .addClass( "ui-corner-bottom" ) 12575 .removeClass( "ui-corner-all" ); 12576 12577 // Don't close the menu on mouseleave 12578 this.menuInstance._off( this.menu, "mouseleave" ); 12579 12580 // Cancel the menu's collapseAll on document click 12581 this.menuInstance._closeOnDocumentClick = function() { 12582 return false; 12583 }; 12584 12585 // Selects often contain empty items, but never contain dividers 12586 this.menuInstance._isDivider = function() { 12587 return false; 12588 }; 12589 }, 12590 12591 refresh: function() { 12592 this._refreshMenu(); 12593 this._setText( this.buttonText, this._getSelectedItem().text() ); 12594 if ( !this.options.width ) { 12595 this._resizeButton(); 12596 } 12597 }, 12598 12599 _refreshMenu: function() { 12600 this.menu.empty(); 12601 12602 var item, 12603 options = this.element.find( "option" ); 12604 12605 if ( !options.length ) { 12606 return; 12607 } 12608 12609 this._parseOptions( options ); 12610 this._renderMenu( this.menu, this.items ); 12611 12612 this.menuInstance.refresh(); 12613 this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" ); 12614 12615 item = this._getSelectedItem(); 12616 12617 // Update the menu to have the correct item focused 12618 this.menuInstance.focus( null, item ); 12619 this._setAria( item.data( "ui-selectmenu-item" ) ); 12620 12621 // Set disabled state 12622 this._setOption( "disabled", this.element.prop( "disabled" ) ); 12623 }, 12624 12625 open: function( event ) { 12626 if ( this.options.disabled ) { 12627 return; 12628 } 12629 12630 // If this is the first time the menu is being opened, render the items 12631 if ( !this.menuItems ) { 12632 this._refreshMenu(); 12633 } else { 12634 12635 // Menu clears focus on close, reset focus to selected item 12636 this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); 12637 this.menuInstance.focus( null, this._getSelectedItem() ); 12638 } 12639 12640 this.isOpen = true; 12641 this._toggleAttr(); 12642 this._resizeMenu(); 12643 this._position(); 12644 12645 this._on( this.document, this._documentClick ); 12646 12647 this._trigger( "open", event ); 12648 }, 12649 12650 _position: function() { 12651 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 12652 }, 12653 12654 close: function( event ) { 12655 if ( !this.isOpen ) { 12656 return; 12657 } 12658 12659 this.isOpen = false; 12660 this._toggleAttr(); 12661 12662 this._off( this.document ); 12663 12664 this._trigger( "close", event ); 12665 }, 12666 12667 widget: function() { 12668 return this.button; 12669 }, 12670 12671 menuWidget: function() { 12672 return this.menu; 12673 }, 12674 12675 _renderMenu: function( ul, items ) { 12676 var that = this, 12677 currentOptgroup = ""; 12678 12679 $.each( items, function( index, item ) { 12680 if ( item.optgroup !== currentOptgroup ) { 12681 $( "<li>", { 12682 "class": "ui-selectmenu-optgroup ui-menu-divider" + 12683 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 12684 " ui-state-disabled" : 12685 "" ), 12686 text: item.optgroup 12687 }) 12688 .appendTo( ul ); 12689 12690 currentOptgroup = item.optgroup; 12691 } 12692 12693 that._renderItemData( ul, item ); 12694 }); 12695 }, 12696 12697 _renderItemData: function( ul, item ) { 12698 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 12699 }, 12700 12701 _renderItem: function( ul, item ) { 12702 var li = $( "<li>" ); 12703 12704 if ( item.disabled ) { 12705 li.addClass( "ui-state-disabled" ); 12706 } 12707 this._setText( li, item.label ); 12708 12709 return li.appendTo( ul ); 12710 }, 12711 12712 _setText: function( element, value ) { 12713 if ( value ) { 12714 element.text( value ); 12715 } else { 12716 element.html( " " ); 12717 } 12718 }, 12719 12720 _move: function( direction, event ) { 12721 var item, next, 12722 filter = ".ui-menu-item"; 12723 12724 if ( this.isOpen ) { 12725 item = this.menuItems.eq( this.focusIndex ); 12726 } else { 12727 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ); 12728 filter += ":not(.ui-state-disabled)"; 12729 } 12730 12731 if ( direction === "first" || direction === "last" ) { 12732 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 12733 } else { 12734 next = item[ direction + "All" ]( filter ).eq( 0 ); 12735 } 12736 12737 if ( next.length ) { 12738 this.menuInstance.focus( event, next ); 12739 } 12740 }, 12741 12742 _getSelectedItem: function() { 12743 return this.menuItems.eq( this.element[ 0 ].selectedIndex ); 12744 }, 12745 12746 _toggle: function( event ) { 12747 this[ this.isOpen ? "close" : "open" ]( event ); 12748 }, 12749 12750 _documentClick: { 12751 mousedown: function( event ) { 12752 if ( !this.isOpen ) { 12753 return; 12754 } 12755 12756 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) { 12757 this.close( event ); 12758 } 12759 } 12760 }, 12761 12762 _buttonEvents: { 12763 12764 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 12765 mousedown: function( event ) { 12766 event.preventDefault(); 12767 }, 12768 12769 click: "_toggle", 12770 12771 keydown: function( event ) { 12772 var preventDefault = true; 12773 switch ( event.keyCode ) { 12774 case $.ui.keyCode.TAB: 12775 case $.ui.keyCode.ESCAPE: 12776 this.close( event ); 12777 preventDefault = false; 12778 break; 12779 case $.ui.keyCode.ENTER: 12780 if ( this.isOpen ) { 12781 this._selectFocusedItem( event ); 12782 } 12783 break; 12784 case $.ui.keyCode.UP: 12785 if ( event.altKey ) { 12786 this._toggle( event ); 12787 } else { 12788 this._move( "prev", event ); 12789 } 12790 break; 12791 case $.ui.keyCode.DOWN: 12792 if ( event.altKey ) { 12793 this._toggle( event ); 12794 } else { 12795 this._move( "next", event ); 12796 } 12797 break; 12798 case $.ui.keyCode.SPACE: 12799 if ( this.isOpen ) { 12800 this._selectFocusedItem( event ); 12801 } else { 12802 this._toggle( event ); 12803 } 12804 break; 12805 case $.ui.keyCode.LEFT: 12806 this._move( "prev", event ); 12807 break; 12808 case $.ui.keyCode.RIGHT: 12809 this._move( "next", event ); 12810 break; 12811 case $.ui.keyCode.HOME: 12812 case $.ui.keyCode.PAGE_UP: 12813 this._move( "first", event ); 12814 break; 12815 case $.ui.keyCode.END: 12816 case $.ui.keyCode.PAGE_DOWN: 12817 this._move( "last", event ); 12818 break; 12819 default: 12820 this.menu.trigger( event ); 12821 preventDefault = false; 12822 } 12823 12824 if ( preventDefault ) { 12825 event.preventDefault(); 12826 } 12827 } 12828 }, 12829 12830 _selectFocusedItem: function( event ) { 12831 var item = this.menuItems.eq( this.focusIndex ); 12832 if ( !item.hasClass( "ui-state-disabled" ) ) { 12833 this._select( item.data( "ui-selectmenu-item" ), event ); 12834 } 12835 }, 12836 12837 _select: function( item, event ) { 12838 var oldIndex = this.element[ 0 ].selectedIndex; 12839 12840 // Change native select element 12841 this.element[ 0 ].selectedIndex = item.index; 12842 this._setText( this.buttonText, item.label ); 12843 this._setAria( item ); 12844 this._trigger( "select", event, { item: item } ); 12845 12846 if ( item.index !== oldIndex ) { 12847 this._trigger( "change", event, { item: item } ); 12848 } 12849 12850 this.close( event ); 12851 }, 12852 12853 _setAria: function( item ) { 12854 var id = this.menuItems.eq( item.index ).attr( "id" ); 12855 12856 this.button.attr({ 12857 "aria-labelledby": id, 12858 "aria-activedescendant": id 12859 }); 12860 this.menu.attr( "aria-activedescendant", id ); 12861 }, 12862 12863 _setOption: function( key, value ) { 12864 if ( key === "icons" ) { 12865 this.button.find( "span.ui-icon" ) 12866 .removeClass( this.options.icons.button ) 12867 .addClass( value.button ); 12868 } 12869 12870 this._super( key, value ); 12871 12872 if ( key === "appendTo" ) { 12873 this.menuWrap.appendTo( this._appendTo() ); 12874 } 12875 12876 if ( key === "disabled" ) { 12877 this.menuInstance.option( "disabled", value ); 12878 this.button 12879 .toggleClass( "ui-state-disabled", value ) 12880 .attr( "aria-disabled", value ); 12881 12882 this.element.prop( "disabled", value ); 12883 if ( value ) { 12884 this.button.attr( "tabindex", -1 ); 12885 this.close(); 12886 } else { 12887 this.button.attr( "tabindex", 0 ); 12888 } 12889 } 12890 12891 if ( key === "width" ) { 12892 this._resizeButton(); 12893 } 12894 }, 12895 12896 _appendTo: function() { 12897 var element = this.options.appendTo; 12898 12899 if ( element ) { 12900 element = element.jquery || element.nodeType ? 12901 $( element ) : 12902 this.document.find( element ).eq( 0 ); 12903 } 12904 12905 if ( !element || !element[ 0 ] ) { 12906 element = this.element.closest( ".ui-front" ); 12907 } 12908 12909 if ( !element.length ) { 12910 element = this.document[ 0 ].body; 12911 } 12912 12913 return element; 12914 }, 12915 12916 _toggleAttr: function() { 12917 this.button 12918 .toggleClass( "ui-corner-top", this.isOpen ) 12919 .toggleClass( "ui-corner-all", !this.isOpen ) 12920 .attr( "aria-expanded", this.isOpen ); 12921 this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen ); 12922 this.menu.attr( "aria-hidden", !this.isOpen ); 12923 }, 12924 12925 _resizeButton: function() { 12926 var width = this.options.width; 12927 12928 if ( !width ) { 12929 width = this.element.show().outerWidth(); 12930 this.element.hide(); 12931 } 12932 12933 this.button.outerWidth( width ); 12934 }, 12935 12936 _resizeMenu: function() { 12937 this.menu.outerWidth( Math.max( 12938 this.button.outerWidth(), 12939 12940 // support: IE10 12941 // IE10 wraps long text (possibly a rounding bug) 12942 // so we add 1px to avoid the wrapping 12943 this.menu.width( "" ).outerWidth() + 1 12944 ) ); 12945 }, 12946 12947 _getCreateOptions: function() { 12948 return { disabled: this.element.prop( "disabled" ) }; 12949 }, 12950 12951 _parseOptions: function( options ) { 12952 var data = []; 12953 options.each(function( index, item ) { 12954 var option = $( item ), 12955 optgroup = option.parent( "optgroup" ); 12956 data.push({ 12957 element: option, 12958 index: index, 12959 value: option.attr( "value" ), 12960 label: option.text(), 12961 optgroup: optgroup.attr( "label" ) || "", 12962 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 12963 }); 12964 }); 12965 this.items = data; 12966 }, 12967 12968 _destroy: function() { 12969 this.menuWrap.remove(); 12970 this.button.remove(); 12971 this.element.show(); 12972 this.element.removeUniqueId(); 12973 this.label.attr( "for", this.ids.element ); 12974 } 12975}); 12976 12977 12978/*! 12979 * jQuery UI Slider 1.11.1 12980 * http://jqueryui.com 12981 * 12982 * Copyright 2014 jQuery Foundation and other contributors 12983 * Released under the MIT license. 12984 * http://jquery.org/license 12985 * 12986 * http://api.jqueryui.com/slider/ 12987 */ 12988 12989 12990var slider = $.widget( "ui.slider", $.ui.mouse, { 12991 version: "1.11.1", 12992 widgetEventPrefix: "slide", 12993 12994 options: { 12995 animate: false, 12996 distance: 0, 12997 max: 100, 12998 min: 0, 12999 orientation: "horizontal", 13000 range: false, 13001 step: 1, 13002 value: 0, 13003 values: null, 13004 13005 // callbacks 13006 change: null, 13007 slide: null, 13008 start: null, 13009 stop: null 13010 }, 13011 13012 // number of pages in a slider 13013 // (how many times can you page up/down to go through the whole range) 13014 numPages: 5, 13015 13016 _create: function() { 13017 this._keySliding = false; 13018 this._mouseSliding = false; 13019 this._animateOff = true; 13020 this._handleIndex = null; 13021 this._detectOrientation(); 13022 this._mouseInit(); 13023 13024 this.element 13025 .addClass( "ui-slider" + 13026 " ui-slider-" + this.orientation + 13027 " ui-widget" + 13028 " ui-widget-content" + 13029 " ui-corner-all"); 13030 13031 this._refresh(); 13032 this._setOption( "disabled", this.options.disabled ); 13033 13034 this._animateOff = false; 13035 }, 13036 13037 _refresh: function() { 13038 this._createRange(); 13039 this._createHandles(); 13040 this._setupEvents(); 13041 this._refreshValue(); 13042 }, 13043 13044 _createHandles: function() { 13045 var i, handleCount, 13046 options = this.options, 13047 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 13048 handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>", 13049 handles = []; 13050 13051 handleCount = ( options.values && options.values.length ) || 1; 13052 13053 if ( existingHandles.length > handleCount ) { 13054 existingHandles.slice( handleCount ).remove(); 13055 existingHandles = existingHandles.slice( 0, handleCount ); 13056 } 13057 13058 for ( i = existingHandles.length; i < handleCount; i++ ) { 13059 handles.push( handle ); 13060 } 13061 13062 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 13063 13064 this.handle = this.handles.eq( 0 ); 13065 13066 this.handles.each(function( i ) { 13067 $( this ).data( "ui-slider-handle-index", i ); 13068 }); 13069 }, 13070 13071 _createRange: function() { 13072 var options = this.options, 13073 classes = ""; 13074 13075 if ( options.range ) { 13076 if ( options.range === true ) { 13077 if ( !options.values ) { 13078 options.values = [ this._valueMin(), this._valueMin() ]; 13079 } else if ( options.values.length && options.values.length !== 2 ) { 13080 options.values = [ options.values[0], options.values[0] ]; 13081 } else if ( $.isArray( options.values ) ) { 13082 options.values = options.values.slice(0); 13083 } 13084 } 13085 13086 if ( !this.range || !this.range.length ) { 13087 this.range = $( "<div></div>" ) 13088 .appendTo( this.element ); 13089 13090 classes = "ui-slider-range" + 13091 // note: this isn't the most fittingly semantic framework class for this element, 13092 // but worked best visually with a variety of themes 13093 " ui-widget-header ui-corner-all"; 13094 } else { 13095 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 13096 // Handle range switching from true to min/max 13097 .css({ 13098 "left": "", 13099 "bottom": "" 13100 }); 13101 } 13102 13103 this.range.addClass( classes + 13104 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 13105 } else { 13106 if ( this.range ) { 13107 this.range.remove(); 13108 } 13109 this.range = null; 13110 } 13111 }, 13112 13113 _setupEvents: function() { 13114 this._off( this.handles ); 13115 this._on( this.handles, this._handleEvents ); 13116 this._hoverable( this.handles ); 13117 this._focusable( this.handles ); 13118 }, 13119 13120 _destroy: function() { 13121 this.handles.remove(); 13122 if ( this.range ) { 13123 this.range.remove(); 13124 } 13125 13126 this.element 13127 .removeClass( "ui-slider" + 13128 " ui-slider-horizontal" + 13129 " ui-slider-vertical" + 13130 " ui-widget" + 13131 " ui-widget-content" + 13132 " ui-corner-all" ); 13133 13134 this._mouseDestroy(); 13135 }, 13136 13137 _mouseCapture: function( event ) { 13138 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 13139 that = this, 13140 o = this.options; 13141 13142 if ( o.disabled ) { 13143 return false; 13144 } 13145 13146 this.elementSize = { 13147 width: this.element.outerWidth(), 13148 height: this.element.outerHeight() 13149 }; 13150 this.elementOffset = this.element.offset(); 13151 13152 position = { x: event.pageX, y: event.pageY }; 13153 normValue = this._normValueFromMouse( position ); 13154 distance = this._valueMax() - this._valueMin() + 1; 13155 this.handles.each(function( i ) { 13156 var thisDistance = Math.abs( normValue - that.values(i) ); 13157 if (( distance > thisDistance ) || 13158 ( distance === thisDistance && 13159 (i === that._lastChangedValue || that.values(i) === o.min ))) { 13160 distance = thisDistance; 13161 closestHandle = $( this ); 13162 index = i; 13163 } 13164 }); 13165 13166 allowed = this._start( event, index ); 13167 if ( allowed === false ) { 13168 return false; 13169 } 13170 this._mouseSliding = true; 13171 13172 this._handleIndex = index; 13173 13174 closestHandle 13175 .addClass( "ui-state-active" ) 13176 .focus(); 13177 13178 offset = closestHandle.offset(); 13179 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 13180 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 13181 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 13182 top: event.pageY - offset.top - 13183 ( closestHandle.height() / 2 ) - 13184 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 13185 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 13186 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 13187 }; 13188 13189 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13190 this._slide( event, index, normValue ); 13191 } 13192 this._animateOff = true; 13193 return true; 13194 }, 13195 13196 _mouseStart: function() { 13197 return true; 13198 }, 13199 13200 _mouseDrag: function( event ) { 13201 var position = { x: event.pageX, y: event.pageY }, 13202 normValue = this._normValueFromMouse( position ); 13203 13204 this._slide( event, this._handleIndex, normValue ); 13205 13206 return false; 13207 }, 13208 13209 _mouseStop: function( event ) { 13210 this.handles.removeClass( "ui-state-active" ); 13211 this._mouseSliding = false; 13212 13213 this._stop( event, this._handleIndex ); 13214 this._change( event, this._handleIndex ); 13215 13216 this._handleIndex = null; 13217 this._clickOffset = null; 13218 this._animateOff = false; 13219 13220 return false; 13221 }, 13222 13223 _detectOrientation: function() { 13224 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13225 }, 13226 13227 _normValueFromMouse: function( position ) { 13228 var pixelTotal, 13229 pixelMouse, 13230 percentMouse, 13231 valueTotal, 13232 valueMouse; 13233 13234 if ( this.orientation === "horizontal" ) { 13235 pixelTotal = this.elementSize.width; 13236 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 13237 } else { 13238 pixelTotal = this.elementSize.height; 13239 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 13240 } 13241 13242 percentMouse = ( pixelMouse / pixelTotal ); 13243 if ( percentMouse > 1 ) { 13244 percentMouse = 1; 13245 } 13246 if ( percentMouse < 0 ) { 13247 percentMouse = 0; 13248 } 13249 if ( this.orientation === "vertical" ) { 13250 percentMouse = 1 - percentMouse; 13251 } 13252 13253 valueTotal = this._valueMax() - this._valueMin(); 13254 valueMouse = this._valueMin() + percentMouse * valueTotal; 13255 13256 return this._trimAlignValue( valueMouse ); 13257 }, 13258 13259 _start: function( event, index ) { 13260 var uiHash = { 13261 handle: this.handles[ index ], 13262 value: this.value() 13263 }; 13264 if ( this.options.values && this.options.values.length ) { 13265 uiHash.value = this.values( index ); 13266 uiHash.values = this.values(); 13267 } 13268 return this._trigger( "start", event, uiHash ); 13269 }, 13270 13271 _slide: function( event, index, newVal ) { 13272 var otherVal, 13273 newValues, 13274 allowed; 13275 13276 if ( this.options.values && this.options.values.length ) { 13277 otherVal = this.values( index ? 0 : 1 ); 13278 13279 if ( ( this.options.values.length === 2 && this.options.range === true ) && 13280 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 13281 ) { 13282 newVal = otherVal; 13283 } 13284 13285 if ( newVal !== this.values( index ) ) { 13286 newValues = this.values(); 13287 newValues[ index ] = newVal; 13288 // A slide can be canceled by returning false from the slide callback 13289 allowed = this._trigger( "slide", event, { 13290 handle: this.handles[ index ], 13291 value: newVal, 13292 values: newValues 13293 } ); 13294 otherVal = this.values( index ? 0 : 1 ); 13295 if ( allowed !== false ) { 13296 this.values( index, newVal ); 13297 } 13298 } 13299 } else { 13300 if ( newVal !== this.value() ) { 13301 // A slide can be canceled by returning false from the slide callback 13302 allowed = this._trigger( "slide", event, { 13303 handle: this.handles[ index ], 13304 value: newVal 13305 } ); 13306 if ( allowed !== false ) { 13307 this.value( newVal ); 13308 } 13309 } 13310 } 13311 }, 13312 13313 _stop: function( event, index ) { 13314 var uiHash = { 13315 handle: this.handles[ index ], 13316 value: this.value() 13317 }; 13318 if ( this.options.values && this.options.values.length ) { 13319 uiHash.value = this.values( index ); 13320 uiHash.values = this.values(); 13321 } 13322 13323 this._trigger( "stop", event, uiHash ); 13324 }, 13325 13326 _change: function( event, index ) { 13327 if ( !this._keySliding && !this._mouseSliding ) { 13328 var uiHash = { 13329 handle: this.handles[ index ], 13330 value: this.value() 13331 }; 13332 if ( this.options.values && this.options.values.length ) { 13333 uiHash.value = this.values( index ); 13334 uiHash.values = this.values(); 13335 } 13336 13337 //store the last changed value index for reference when handles overlap 13338 this._lastChangedValue = index; 13339 13340 this._trigger( "change", event, uiHash ); 13341 } 13342 }, 13343 13344 value: function( newValue ) { 13345 if ( arguments.length ) { 13346 this.options.value = this._trimAlignValue( newValue ); 13347 this._refreshValue(); 13348 this._change( null, 0 ); 13349 return; 13350 } 13351 13352 return this._value(); 13353 }, 13354 13355 values: function( index, newValue ) { 13356 var vals, 13357 newValues, 13358 i; 13359 13360 if ( arguments.length > 1 ) { 13361 this.options.values[ index ] = this._trimAlignValue( newValue ); 13362 this._refreshValue(); 13363 this._change( null, index ); 13364 return; 13365 } 13366 13367 if ( arguments.length ) { 13368 if ( $.isArray( arguments[ 0 ] ) ) { 13369 vals = this.options.values; 13370 newValues = arguments[ 0 ]; 13371 for ( i = 0; i < vals.length; i += 1 ) { 13372 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13373 this._change( null, i ); 13374 } 13375 this._refreshValue(); 13376 } else { 13377 if ( this.options.values && this.options.values.length ) { 13378 return this._values( index ); 13379 } else { 13380 return this.value(); 13381 } 13382 } 13383 } else { 13384 return this._values(); 13385 } 13386 }, 13387 13388 _setOption: function( key, value ) { 13389 var i, 13390 valsLength = 0; 13391 13392 if ( key === "range" && this.options.range === true ) { 13393 if ( value === "min" ) { 13394 this.options.value = this._values( 0 ); 13395 this.options.values = null; 13396 } else if ( value === "max" ) { 13397 this.options.value = this._values( this.options.values.length - 1 ); 13398 this.options.values = null; 13399 } 13400 } 13401 13402 if ( $.isArray( this.options.values ) ) { 13403 valsLength = this.options.values.length; 13404 } 13405 13406 if ( key === "disabled" ) { 13407 this.element.toggleClass( "ui-state-disabled", !!value ); 13408 } 13409 13410 this._super( key, value ); 13411 13412 switch ( key ) { 13413 case "orientation": 13414 this._detectOrientation(); 13415 this.element 13416 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13417 .addClass( "ui-slider-" + this.orientation ); 13418 this._refreshValue(); 13419 13420 // Reset positioning from previous orientation 13421 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 13422 break; 13423 case "value": 13424 this._animateOff = true; 13425 this._refreshValue(); 13426 this._change( null, 0 ); 13427 this._animateOff = false; 13428 break; 13429 case "values": 13430 this._animateOff = true; 13431 this._refreshValue(); 13432 for ( i = 0; i < valsLength; i += 1 ) { 13433 this._change( null, i ); 13434 } 13435 this._animateOff = false; 13436 break; 13437 case "min": 13438 case "max": 13439 this._animateOff = true; 13440 this._refreshValue(); 13441 this._animateOff = false; 13442 break; 13443 case "range": 13444 this._animateOff = true; 13445 this._refresh(); 13446 this._animateOff = false; 13447 break; 13448 } 13449 }, 13450 13451 //internal value getter 13452 // _value() returns value trimmed by min and max, aligned by step 13453 _value: function() { 13454 var val = this.options.value; 13455 val = this._trimAlignValue( val ); 13456 13457 return val; 13458 }, 13459 13460 //internal values getter 13461 // _values() returns array of values trimmed by min and max, aligned by step 13462 // _values( index ) returns single value trimmed by min and max, aligned by step 13463 _values: function( index ) { 13464 var val, 13465 vals, 13466 i; 13467 13468 if ( arguments.length ) { 13469 val = this.options.values[ index ]; 13470 val = this._trimAlignValue( val ); 13471 13472 return val; 13473 } else if ( this.options.values && this.options.values.length ) { 13474 // .slice() creates a copy of the array 13475 // this copy gets trimmed by min and max and then returned 13476 vals = this.options.values.slice(); 13477 for ( i = 0; i < vals.length; i+= 1) { 13478 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13479 } 13480 13481 return vals; 13482 } else { 13483 return []; 13484 } 13485 }, 13486 13487 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13488 _trimAlignValue: function( val ) { 13489 if ( val <= this._valueMin() ) { 13490 return this._valueMin(); 13491 } 13492 if ( val >= this._valueMax() ) { 13493 return this._valueMax(); 13494 } 13495 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13496 valModStep = (val - this._valueMin()) % step, 13497 alignValue = val - valModStep; 13498 13499 if ( Math.abs(valModStep) * 2 >= step ) { 13500 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13501 } 13502 13503 // Since JavaScript has problems with large floats, round 13504 // the final value to 5 digits after the decimal point (see #4124) 13505 return parseFloat( alignValue.toFixed(5) ); 13506 }, 13507 13508 _valueMin: function() { 13509 return this.options.min; 13510 }, 13511 13512 _valueMax: function() { 13513 return this.options.max; 13514 }, 13515 13516 _refreshValue: function() { 13517 var lastValPercent, valPercent, value, valueMin, valueMax, 13518 oRange = this.options.range, 13519 o = this.options, 13520 that = this, 13521 animate = ( !this._animateOff ) ? o.animate : false, 13522 _set = {}; 13523 13524 if ( this.options.values && this.options.values.length ) { 13525 this.handles.each(function( i ) { 13526 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13527 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13528 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13529 if ( that.options.range === true ) { 13530 if ( that.orientation === "horizontal" ) { 13531 if ( i === 0 ) { 13532 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13533 } 13534 if ( i === 1 ) { 13535 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13536 } 13537 } else { 13538 if ( i === 0 ) { 13539 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13540 } 13541 if ( i === 1 ) { 13542 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13543 } 13544 } 13545 } 13546 lastValPercent = valPercent; 13547 }); 13548 } else { 13549 value = this.value(); 13550 valueMin = this._valueMin(); 13551 valueMax = this._valueMax(); 13552 valPercent = ( valueMax !== valueMin ) ? 13553 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13554 0; 13555 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13556 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13557 13558 if ( oRange === "min" && this.orientation === "horizontal" ) { 13559 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13560 } 13561 if ( oRange === "max" && this.orientation === "horizontal" ) { 13562 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13563 } 13564 if ( oRange === "min" && this.orientation === "vertical" ) { 13565 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13566 } 13567 if ( oRange === "max" && this.orientation === "vertical" ) { 13568 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13569 } 13570 } 13571 }, 13572 13573 _handleEvents: { 13574 keydown: function( event ) { 13575 var allowed, curVal, newVal, step, 13576 index = $( event.target ).data( "ui-slider-handle-index" ); 13577 13578 switch ( event.keyCode ) { 13579 case $.ui.keyCode.HOME: 13580 case $.ui.keyCode.END: 13581 case $.ui.keyCode.PAGE_UP: 13582 case $.ui.keyCode.PAGE_DOWN: 13583 case $.ui.keyCode.UP: 13584 case $.ui.keyCode.RIGHT: 13585 case $.ui.keyCode.DOWN: 13586 case $.ui.keyCode.LEFT: 13587 event.preventDefault(); 13588 if ( !this._keySliding ) { 13589 this._keySliding = true; 13590 $( event.target ).addClass( "ui-state-active" ); 13591 allowed = this._start( event, index ); 13592 if ( allowed === false ) { 13593 return; 13594 } 13595 } 13596 break; 13597 } 13598 13599 step = this.options.step; 13600 if ( this.options.values && this.options.values.length ) { 13601 curVal = newVal = this.values( index ); 13602 } else { 13603 curVal = newVal = this.value(); 13604 } 13605 13606 switch ( event.keyCode ) { 13607 case $.ui.keyCode.HOME: 13608 newVal = this._valueMin(); 13609 break; 13610 case $.ui.keyCode.END: 13611 newVal = this._valueMax(); 13612 break; 13613 case $.ui.keyCode.PAGE_UP: 13614 newVal = this._trimAlignValue( 13615 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 13616 ); 13617 break; 13618 case $.ui.keyCode.PAGE_DOWN: 13619 newVal = this._trimAlignValue( 13620 curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); 13621 break; 13622 case $.ui.keyCode.UP: 13623 case $.ui.keyCode.RIGHT: 13624 if ( curVal === this._valueMax() ) { 13625 return; 13626 } 13627 newVal = this._trimAlignValue( curVal + step ); 13628 break; 13629 case $.ui.keyCode.DOWN: 13630 case $.ui.keyCode.LEFT: 13631 if ( curVal === this._valueMin() ) { 13632 return; 13633 } 13634 newVal = this._trimAlignValue( curVal - step ); 13635 break; 13636 } 13637 13638 this._slide( event, index, newVal ); 13639 }, 13640 keyup: function( event ) { 13641 var index = $( event.target ).data( "ui-slider-handle-index" ); 13642 13643 if ( this._keySliding ) { 13644 this._keySliding = false; 13645 this._stop( event, index ); 13646 this._change( event, index ); 13647 $( event.target ).removeClass( "ui-state-active" ); 13648 } 13649 } 13650 } 13651}); 13652 13653 13654/*! 13655 * jQuery UI Sortable 1.11.1 13656 * http://jqueryui.com 13657 * 13658 * Copyright 2014 jQuery Foundation and other contributors 13659 * Released under the MIT license. 13660 * http://jquery.org/license 13661 * 13662 * http://api.jqueryui.com/sortable/ 13663 */ 13664 13665 13666var sortable = $.widget("ui.sortable", $.ui.mouse, { 13667 version: "1.11.1", 13668 widgetEventPrefix: "sort", 13669 ready: false, 13670 options: { 13671 appendTo: "parent", 13672 axis: false, 13673 connectWith: false, 13674 containment: false, 13675 cursor: "auto", 13676 cursorAt: false, 13677 dropOnEmpty: true, 13678 forcePlaceholderSize: false, 13679 forceHelperSize: false, 13680 grid: false, 13681 handle: false, 13682 helper: "original", 13683 items: "> *", 13684 opacity: false, 13685 placeholder: false, 13686 revert: false, 13687 scroll: true, 13688 scrollSensitivity: 20, 13689 scrollSpeed: 20, 13690 scope: "default", 13691 tolerance: "intersect", 13692 zIndex: 1000, 13693 13694 // callbacks 13695 activate: null, 13696 beforeStop: null, 13697 change: null, 13698 deactivate: null, 13699 out: null, 13700 over: null, 13701 receive: null, 13702 remove: null, 13703 sort: null, 13704 start: null, 13705 stop: null, 13706 update: null 13707 }, 13708 13709 _isOverAxis: function( x, reference, size ) { 13710 return ( x >= reference ) && ( x < ( reference + size ) ); 13711 }, 13712 13713 _isFloating: function( item ) { 13714 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 13715 }, 13716 13717 _create: function() { 13718 13719 var o = this.options; 13720 this.containerCache = {}; 13721 this.element.addClass("ui-sortable"); 13722 13723 //Get the items 13724 this.refresh(); 13725 13726 //Let's determine if the items are being displayed horizontally 13727 this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false; 13728 13729 //Let's determine the parent's offset 13730 this.offset = this.element.offset(); 13731 13732 //Initialize mouse events for interaction 13733 this._mouseInit(); 13734 13735 this._setHandleClassName(); 13736 13737 //We're ready to go 13738 this.ready = true; 13739 13740 }, 13741 13742 _setOption: function( key, value ) { 13743 this._super( key, value ); 13744 13745 if ( key === "handle" ) { 13746 this._setHandleClassName(); 13747 } 13748 }, 13749 13750 _setHandleClassName: function() { 13751 this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" ); 13752 $.each( this.items, function() { 13753 ( this.instance.options.handle ? 13754 this.item.find( this.instance.options.handle ) : this.item ) 13755 .addClass( "ui-sortable-handle" ); 13756 }); 13757 }, 13758 13759 _destroy: function() { 13760 this.element 13761 .removeClass( "ui-sortable ui-sortable-disabled" ) 13762 .find( ".ui-sortable-handle" ) 13763 .removeClass( "ui-sortable-handle" ); 13764 this._mouseDestroy(); 13765 13766 for ( var i = this.items.length - 1; i >= 0; i-- ) { 13767 this.items[i].item.removeData(this.widgetName + "-item"); 13768 } 13769 13770 return this; 13771 }, 13772 13773 _mouseCapture: function(event, overrideHandle) { 13774 var currentItem = null, 13775 validHandle = false, 13776 that = this; 13777 13778 if (this.reverting) { 13779 return false; 13780 } 13781 13782 if(this.options.disabled || this.options.type === "static") { 13783 return false; 13784 } 13785 13786 //We have to refresh the items data once first 13787 this._refreshItems(event); 13788 13789 //Find out if the clicked node (or one of its parents) is a actual item in this.items 13790 $(event.target).parents().each(function() { 13791 if($.data(this, that.widgetName + "-item") === that) { 13792 currentItem = $(this); 13793 return false; 13794 } 13795 }); 13796 if($.data(event.target, that.widgetName + "-item") === that) { 13797 currentItem = $(event.target); 13798 } 13799 13800 if(!currentItem) { 13801 return false; 13802 } 13803 if(this.options.handle && !overrideHandle) { 13804 $(this.options.handle, currentItem).find("*").addBack().each(function() { 13805 if(this === event.target) { 13806 validHandle = true; 13807 } 13808 }); 13809 if(!validHandle) { 13810 return false; 13811 } 13812 } 13813 13814 this.currentItem = currentItem; 13815 this._removeCurrentsFromItems(); 13816 return true; 13817 13818 }, 13819 13820 _mouseStart: function(event, overrideHandle, noActivation) { 13821 13822 var i, body, 13823 o = this.options; 13824 13825 this.currentContainer = this; 13826 13827 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 13828 this.refreshPositions(); 13829 13830 //Create and append the visible helper 13831 this.helper = this._createHelper(event); 13832 13833 //Cache the helper size 13834 this._cacheHelperProportions(); 13835 13836 /* 13837 * - Position generation - 13838 * This block generates everything position related - it's the core of draggables. 13839 */ 13840 13841 //Cache the margins of the original element 13842 this._cacheMargins(); 13843 13844 //Get the next scrolling parent 13845 this.scrollParent = this.helper.scrollParent(); 13846 13847 //The element's absolute position on the page minus margins 13848 this.offset = this.currentItem.offset(); 13849 this.offset = { 13850 top: this.offset.top - this.margins.top, 13851 left: this.offset.left - this.margins.left 13852 }; 13853 13854 $.extend(this.offset, { 13855 click: { //Where the click happened, relative to the element 13856 left: event.pageX - this.offset.left, 13857 top: event.pageY - this.offset.top 13858 }, 13859 parent: this._getParentOffset(), 13860 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 13861 }); 13862 13863 // Only after we got the offset, we can change the helper's position to absolute 13864 // TODO: Still need to figure out a way to make relative sorting possible 13865 this.helper.css("position", "absolute"); 13866 this.cssPosition = this.helper.css("position"); 13867 13868 //Generate the original position 13869 this.originalPosition = this._generatePosition(event); 13870 this.originalPageX = event.pageX; 13871 this.originalPageY = event.pageY; 13872 13873 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 13874 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 13875 13876 //Cache the former DOM position 13877 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 13878 13879 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way 13880 if(this.helper[0] !== this.currentItem[0]) { 13881 this.currentItem.hide(); 13882 } 13883 13884 //Create the placeholder 13885 this._createPlaceholder(); 13886 13887 //Set a containment if given in the options 13888 if(o.containment) { 13889 this._setContainment(); 13890 } 13891 13892 if( o.cursor && o.cursor !== "auto" ) { // cursor option 13893 body = this.document.find( "body" ); 13894 13895 // support: IE 13896 this.storedCursor = body.css( "cursor" ); 13897 body.css( "cursor", o.cursor ); 13898 13899 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 13900 } 13901 13902 if(o.opacity) { // opacity option 13903 if (this.helper.css("opacity")) { 13904 this._storedOpacity = this.helper.css("opacity"); 13905 } 13906 this.helper.css("opacity", o.opacity); 13907 } 13908 13909 if(o.zIndex) { // zIndex option 13910 if (this.helper.css("zIndex")) { 13911 this._storedZIndex = this.helper.css("zIndex"); 13912 } 13913 this.helper.css("zIndex", o.zIndex); 13914 } 13915 13916 //Prepare scrolling 13917 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 13918 this.overflowOffset = this.scrollParent.offset(); 13919 } 13920 13921 //Call callbacks 13922 this._trigger("start", event, this._uiHash()); 13923 13924 //Recache the helper size 13925 if(!this._preserveHelperProportions) { 13926 this._cacheHelperProportions(); 13927 } 13928 13929 13930 //Post "activate" events to possible containers 13931 if( !noActivation ) { 13932 for ( i = this.containers.length - 1; i >= 0; i-- ) { 13933 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 13934 } 13935 } 13936 13937 //Prepare possible droppables 13938 if($.ui.ddmanager) { 13939 $.ui.ddmanager.current = this; 13940 } 13941 13942 if ($.ui.ddmanager && !o.dropBehaviour) { 13943 $.ui.ddmanager.prepareOffsets(this, event); 13944 } 13945 13946 this.dragging = true; 13947 13948 this.helper.addClass("ui-sortable-helper"); 13949 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 13950 return true; 13951 13952 }, 13953 13954 _mouseDrag: function(event) { 13955 var i, item, itemElement, intersection, 13956 o = this.options, 13957 scrolled = false; 13958 13959 //Compute the helpers position 13960 this.position = this._generatePosition(event); 13961 this.positionAbs = this._convertPositionTo("absolute"); 13962 13963 if (!this.lastPositionAbs) { 13964 this.lastPositionAbs = this.positionAbs; 13965 } 13966 13967 //Do scrolling 13968 if(this.options.scroll) { 13969 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 13970 13971 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 13972 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 13973 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 13974 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 13975 } 13976 13977 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 13978 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 13979 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 13980 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 13981 } 13982 13983 } else { 13984 13985 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 13986 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 13987 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 13988 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 13989 } 13990 13991 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 13992 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 13993 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 13994 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 13995 } 13996 13997 } 13998 13999 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 14000 $.ui.ddmanager.prepareOffsets(this, event); 14001 } 14002 } 14003 14004 //Regenerate the absolute position used for position checks 14005 this.positionAbs = this._convertPositionTo("absolute"); 14006 14007 //Set the helper position 14008 if(!this.options.axis || this.options.axis !== "y") { 14009 this.helper[0].style.left = this.position.left+"px"; 14010 } 14011 if(!this.options.axis || this.options.axis !== "x") { 14012 this.helper[0].style.top = this.position.top+"px"; 14013 } 14014 14015 //Rearrange 14016 for (i = this.items.length - 1; i >= 0; i--) { 14017 14018 //Cache variables and intersection, continue if no intersection 14019 item = this.items[i]; 14020 itemElement = item.item[0]; 14021 intersection = this._intersectsWithPointer(item); 14022 if (!intersection) { 14023 continue; 14024 } 14025 14026 // Only put the placeholder inside the current Container, skip all 14027 // items from other containers. This works because when moving 14028 // an item from one container to another the 14029 // currentContainer is switched before the placeholder is moved. 14030 // 14031 // Without this, moving items in "sub-sortables" can cause 14032 // the placeholder to jitter between the outer and inner container. 14033 if (item.instance !== this.currentContainer) { 14034 continue; 14035 } 14036 14037 // cannot intersect with itself 14038 // no useless actions that have been done before 14039 // no action if the item moved is the parent of the item checked 14040 if (itemElement !== this.currentItem[0] && 14041 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 14042 !$.contains(this.placeholder[0], itemElement) && 14043 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 14044 ) { 14045 14046 this.direction = intersection === 1 ? "down" : "up"; 14047 14048 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 14049 this._rearrange(event, item); 14050 } else { 14051 break; 14052 } 14053 14054 this._trigger("change", event, this._uiHash()); 14055 break; 14056 } 14057 } 14058 14059 //Post events to containers 14060 this._contactContainers(event); 14061 14062 //Interconnect with droppables 14063 if($.ui.ddmanager) { 14064 $.ui.ddmanager.drag(this, event); 14065 } 14066 14067 //Call callbacks 14068 this._trigger("sort", event, this._uiHash()); 14069 14070 this.lastPositionAbs = this.positionAbs; 14071 return false; 14072 14073 }, 14074 14075 _mouseStop: function(event, noPropagation) { 14076 14077 if(!event) { 14078 return; 14079 } 14080 14081 //If we are using droppables, inform the manager about the drop 14082 if ($.ui.ddmanager && !this.options.dropBehaviour) { 14083 $.ui.ddmanager.drop(this, event); 14084 } 14085 14086 if(this.options.revert) { 14087 var that = this, 14088 cur = this.placeholder.offset(), 14089 axis = this.options.axis, 14090 animation = {}; 14091 14092 if ( !axis || axis === "x" ) { 14093 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 14094 } 14095 if ( !axis || axis === "y" ) { 14096 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 14097 } 14098 this.reverting = true; 14099 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 14100 that._clear(event); 14101 }); 14102 } else { 14103 this._clear(event, noPropagation); 14104 } 14105 14106 return false; 14107 14108 }, 14109 14110 cancel: function() { 14111 14112 if(this.dragging) { 14113 14114 this._mouseUp({ target: null }); 14115 14116 if(this.options.helper === "original") { 14117 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 14118 } else { 14119 this.currentItem.show(); 14120 } 14121 14122 //Post deactivating events to containers 14123 for (var i = this.containers.length - 1; i >= 0; i--){ 14124 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 14125 if(this.containers[i].containerCache.over) { 14126 this.containers[i]._trigger("out", null, this._uiHash(this)); 14127 this.containers[i].containerCache.over = 0; 14128 } 14129 } 14130 14131 } 14132 14133 if (this.placeholder) { 14134 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 14135 if(this.placeholder[0].parentNode) { 14136 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 14137 } 14138 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 14139 this.helper.remove(); 14140 } 14141 14142 $.extend(this, { 14143 helper: null, 14144 dragging: false, 14145 reverting: false, 14146 _noFinalSort: null 14147 }); 14148 14149 if(this.domPosition.prev) { 14150 $(this.domPosition.prev).after(this.currentItem); 14151 } else { 14152 $(this.domPosition.parent).prepend(this.currentItem); 14153 } 14154 } 14155 14156 return this; 14157 14158 }, 14159 14160 serialize: function(o) { 14161 14162 var items = this._getItemsAsjQuery(o && o.connected), 14163 str = []; 14164 o = o || {}; 14165 14166 $(items).each(function() { 14167 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 14168 if (res) { 14169 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 14170 } 14171 }); 14172 14173 if(!str.length && o.key) { 14174 str.push(o.key + "="); 14175 } 14176 14177 return str.join("&"); 14178 14179 }, 14180 14181 toArray: function(o) { 14182 14183 var items = this._getItemsAsjQuery(o && o.connected), 14184 ret = []; 14185 14186 o = o || {}; 14187 14188 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 14189 return ret; 14190 14191 }, 14192 14193 /* Be careful with the following core functions */ 14194 _intersectsWith: function(item) { 14195 14196 var x1 = this.positionAbs.left, 14197 x2 = x1 + this.helperProportions.width, 14198 y1 = this.positionAbs.top, 14199 y2 = y1 + this.helperProportions.height, 14200 l = item.left, 14201 r = l + item.width, 14202 t = item.top, 14203 b = t + item.height, 14204 dyClick = this.offset.click.top, 14205 dxClick = this.offset.click.left, 14206 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 14207 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 14208 isOverElement = isOverElementHeight && isOverElementWidth; 14209 14210 if ( this.options.tolerance === "pointer" || 14211 this.options.forcePointerForContainers || 14212 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 14213 ) { 14214 return isOverElement; 14215 } else { 14216 14217 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 14218 x2 - (this.helperProportions.width / 2) < r && // Left Half 14219 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 14220 y2 - (this.helperProportions.height / 2) < b ); // Top Half 14221 14222 } 14223 }, 14224 14225 _intersectsWithPointer: function(item) { 14226 14227 var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 14228 isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 14229 isOverElement = isOverElementHeight && isOverElementWidth, 14230 verticalDirection = this._getDragVerticalDirection(), 14231 horizontalDirection = this._getDragHorizontalDirection(); 14232 14233 if (!isOverElement) { 14234 return false; 14235 } 14236 14237 return this.floating ? 14238 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 14239 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 14240 14241 }, 14242 14243 _intersectsWithSides: function(item) { 14244 14245 var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 14246 isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 14247 verticalDirection = this._getDragVerticalDirection(), 14248 horizontalDirection = this._getDragHorizontalDirection(); 14249 14250 if (this.floating && horizontalDirection) { 14251 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 14252 } else { 14253 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 14254 } 14255 14256 }, 14257 14258 _getDragVerticalDirection: function() { 14259 var delta = this.positionAbs.top - this.lastPositionAbs.top; 14260 return delta !== 0 && (delta > 0 ? "down" : "up"); 14261 }, 14262 14263 _getDragHorizontalDirection: function() { 14264 var delta = this.positionAbs.left - this.lastPositionAbs.left; 14265 return delta !== 0 && (delta > 0 ? "right" : "left"); 14266 }, 14267 14268 refresh: function(event) { 14269 this._refreshItems(event); 14270 this._setHandleClassName(); 14271 this.refreshPositions(); 14272 return this; 14273 }, 14274 14275 _connectWith: function() { 14276 var options = this.options; 14277 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 14278 }, 14279 14280 _getItemsAsjQuery: function(connected) { 14281 14282 var i, j, cur, inst, 14283 items = [], 14284 queries = [], 14285 connectWith = this._connectWith(); 14286 14287 if(connectWith && connected) { 14288 for (i = connectWith.length - 1; i >= 0; i--){ 14289 cur = $(connectWith[i]); 14290 for ( j = cur.length - 1; j >= 0; j--){ 14291 inst = $.data(cur[j], this.widgetFullName); 14292 if(inst && inst !== this && !inst.options.disabled) { 14293 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); 14294 } 14295 } 14296 } 14297 } 14298 14299 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); 14300 14301 function addItems() { 14302 items.push( this ); 14303 } 14304 for (i = queries.length - 1; i >= 0; i--){ 14305 queries[i][0].each( addItems ); 14306 } 14307 14308 return $(items); 14309 14310 }, 14311 14312 _removeCurrentsFromItems: function() { 14313 14314 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 14315 14316 this.items = $.grep(this.items, function (item) { 14317 for (var j=0; j < list.length; j++) { 14318 if(list[j] === item.item[0]) { 14319 return false; 14320 } 14321 } 14322 return true; 14323 }); 14324 14325 }, 14326 14327 _refreshItems: function(event) { 14328 14329 this.items = []; 14330 this.containers = [this]; 14331 14332 var i, j, cur, inst, targetData, _queries, item, queriesLength, 14333 items = this.items, 14334 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 14335 connectWith = this._connectWith(); 14336 14337 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 14338 for (i = connectWith.length - 1; i >= 0; i--){ 14339 cur = $(connectWith[i]); 14340 for (j = cur.length - 1; j >= 0; j--){ 14341 inst = $.data(cur[j], this.widgetFullName); 14342 if(inst && inst !== this && !inst.options.disabled) { 14343 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 14344 this.containers.push(inst); 14345 } 14346 } 14347 } 14348 } 14349 14350 for (i = queries.length - 1; i >= 0; i--) { 14351 targetData = queries[i][1]; 14352 _queries = queries[i][0]; 14353 14354 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 14355 item = $(_queries[j]); 14356 14357 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 14358 14359 items.push({ 14360 item: item, 14361 instance: targetData, 14362 width: 0, height: 0, 14363 left: 0, top: 0 14364 }); 14365 } 14366 } 14367 14368 }, 14369 14370 refreshPositions: function(fast) { 14371 14372 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 14373 if(this.offsetParent && this.helper) { 14374 this.offset.parent = this._getParentOffset(); 14375 } 14376 14377 var i, item, t, p; 14378 14379 for (i = this.items.length - 1; i >= 0; i--){ 14380 item = this.items[i]; 14381 14382 //We ignore calculating positions of all connected containers when we're not over them 14383 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 14384 continue; 14385 } 14386 14387 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 14388 14389 if (!fast) { 14390 item.width = t.outerWidth(); 14391 item.height = t.outerHeight(); 14392 } 14393 14394 p = t.offset(); 14395 item.left = p.left; 14396 item.top = p.top; 14397 } 14398 14399 if(this.options.custom && this.options.custom.refreshContainers) { 14400 this.options.custom.refreshContainers.call(this); 14401 } else { 14402 for (i = this.containers.length - 1; i >= 0; i--){ 14403 p = this.containers[i].element.offset(); 14404 this.containers[i].containerCache.left = p.left; 14405 this.containers[i].containerCache.top = p.top; 14406 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 14407 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 14408 } 14409 } 14410 14411 return this; 14412 }, 14413 14414 _createPlaceholder: function(that) { 14415 that = that || this; 14416 var className, 14417 o = that.options; 14418 14419 if(!o.placeholder || o.placeholder.constructor === String) { 14420 className = o.placeholder; 14421 o.placeholder = { 14422 element: function() { 14423 14424 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 14425 element = $( "<" + nodeName + ">", that.document[0] ) 14426 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 14427 .removeClass("ui-sortable-helper"); 14428 14429 if ( nodeName === "tr" ) { 14430 that.currentItem.children().each(function() { 14431 $( "<td> </td>", that.document[0] ) 14432 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 14433 .appendTo( element ); 14434 }); 14435 } else if ( nodeName === "img" ) { 14436 element.attr( "src", that.currentItem.attr( "src" ) ); 14437 } 14438 14439 if ( !className ) { 14440 element.css( "visibility", "hidden" ); 14441 } 14442 14443 return element; 14444 }, 14445 update: function(container, p) { 14446 14447 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 14448 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 14449 if(className && !o.forcePlaceholderSize) { 14450 return; 14451 } 14452 14453 //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item 14454 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 14455 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 14456 } 14457 }; 14458 } 14459 14460 //Create the placeholder 14461 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 14462 14463 //Append it after the actual current item 14464 that.currentItem.after(that.placeholder); 14465 14466 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 14467 o.placeholder.update(that, that.placeholder); 14468 14469 }, 14470 14471 _contactContainers: function(event) { 14472 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, 14473 innermostContainer = null, 14474 innermostIndex = null; 14475 14476 // get innermost container that intersects with item 14477 for (i = this.containers.length - 1; i >= 0; i--) { 14478 14479 // never consider a container that's located within the item itself 14480 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 14481 continue; 14482 } 14483 14484 if(this._intersectsWith(this.containers[i].containerCache)) { 14485 14486 // if we've already found a container and it's more "inner" than this, then continue 14487 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 14488 continue; 14489 } 14490 14491 innermostContainer = this.containers[i]; 14492 innermostIndex = i; 14493 14494 } else { 14495 // container doesn't intersect. trigger "out" event if necessary 14496 if(this.containers[i].containerCache.over) { 14497 this.containers[i]._trigger("out", event, this._uiHash(this)); 14498 this.containers[i].containerCache.over = 0; 14499 } 14500 } 14501 14502 } 14503 14504 // if no intersecting containers found, return 14505 if(!innermostContainer) { 14506 return; 14507 } 14508 14509 // move the item into the container if it's not there already 14510 if(this.containers.length === 1) { 14511 if (!this.containers[innermostIndex].containerCache.over) { 14512 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 14513 this.containers[innermostIndex].containerCache.over = 1; 14514 } 14515 } else { 14516 14517 //When entering a new container, we will find the item with the least distance and append our item near it 14518 dist = 10000; 14519 itemWithLeastDistance = null; 14520 floating = innermostContainer.floating || this._isFloating(this.currentItem); 14521 posProperty = floating ? "left" : "top"; 14522 sizeProperty = floating ? "width" : "height"; 14523 axis = floating ? "clientX" : "clientY"; 14524 14525 for (j = this.items.length - 1; j >= 0; j--) { 14526 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 14527 continue; 14528 } 14529 if(this.items[j].item[0] === this.currentItem[0]) { 14530 continue; 14531 } 14532 14533 cur = this.items[j].item.offset()[posProperty]; 14534 nearBottom = false; 14535 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 14536 nearBottom = true; 14537 } 14538 14539 if ( Math.abs( event[ axis ] - cur ) < dist ) { 14540 dist = Math.abs( event[ axis ] - cur ); 14541 itemWithLeastDistance = this.items[ j ]; 14542 this.direction = nearBottom ? "up": "down"; 14543 } 14544 } 14545 14546 //Check if dropOnEmpty is enabled 14547 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 14548 return; 14549 } 14550 14551 if(this.currentContainer === this.containers[innermostIndex]) { 14552 return; 14553 } 14554 14555 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 14556 this._trigger("change", event, this._uiHash()); 14557 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 14558 this.currentContainer = this.containers[innermostIndex]; 14559 14560 //Update the placeholder 14561 this.options.placeholder.update(this.currentContainer, this.placeholder); 14562 14563 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 14564 this.containers[innermostIndex].containerCache.over = 1; 14565 } 14566 14567 14568 }, 14569 14570 _createHelper: function(event) { 14571 14572 var o = this.options, 14573 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 14574 14575 //Add the helper to the DOM if that didn't happen already 14576 if(!helper.parents("body").length) { 14577 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 14578 } 14579 14580 if(helper[0] === this.currentItem[0]) { 14581 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; 14582 } 14583 14584 if(!helper[0].style.width || o.forceHelperSize) { 14585 helper.width(this.currentItem.width()); 14586 } 14587 if(!helper[0].style.height || o.forceHelperSize) { 14588 helper.height(this.currentItem.height()); 14589 } 14590 14591 return helper; 14592 14593 }, 14594 14595 _adjustOffsetFromHelper: function(obj) { 14596 if (typeof obj === "string") { 14597 obj = obj.split(" "); 14598 } 14599 if ($.isArray(obj)) { 14600 obj = {left: +obj[0], top: +obj[1] || 0}; 14601 } 14602 if ("left" in obj) { 14603 this.offset.click.left = obj.left + this.margins.left; 14604 } 14605 if ("right" in obj) { 14606 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 14607 } 14608 if ("top" in obj) { 14609 this.offset.click.top = obj.top + this.margins.top; 14610 } 14611 if ("bottom" in obj) { 14612 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 14613 } 14614 }, 14615 14616 _getParentOffset: function() { 14617 14618 14619 //Get the offsetParent and cache its position 14620 this.offsetParent = this.helper.offsetParent(); 14621 var po = this.offsetParent.offset(); 14622 14623 // This is a special case where we need to modify a offset calculated on start, since the following happened: 14624 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 14625 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 14626 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 14627 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 14628 po.left += this.scrollParent.scrollLeft(); 14629 po.top += this.scrollParent.scrollTop(); 14630 } 14631 14632 // This needs to be actually done for all browsers, since pageX/pageY includes this information 14633 // with an ugly IE fix 14634 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 14635 po = { top: 0, left: 0 }; 14636 } 14637 14638 return { 14639 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 14640 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 14641 }; 14642 14643 }, 14644 14645 _getRelativeOffset: function() { 14646 14647 if(this.cssPosition === "relative") { 14648 var p = this.currentItem.position(); 14649 return { 14650 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 14651 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 14652 }; 14653 } else { 14654 return { top: 0, left: 0 }; 14655 } 14656 14657 }, 14658 14659 _cacheMargins: function() { 14660 this.margins = { 14661 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 14662 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 14663 }; 14664 }, 14665 14666 _cacheHelperProportions: function() { 14667 this.helperProportions = { 14668 width: this.helper.outerWidth(), 14669 height: this.helper.outerHeight() 14670 }; 14671 }, 14672 14673 _setContainment: function() { 14674 14675 var ce, co, over, 14676 o = this.options; 14677 if(o.containment === "parent") { 14678 o.containment = this.helper[0].parentNode; 14679 } 14680 if(o.containment === "document" || o.containment === "window") { 14681 this.containment = [ 14682 0 - this.offset.relative.left - this.offset.parent.left, 14683 0 - this.offset.relative.top - this.offset.parent.top, 14684 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 14685 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 14686 ]; 14687 } 14688 14689 if(!(/^(document|window|parent)$/).test(o.containment)) { 14690 ce = $(o.containment)[0]; 14691 co = $(o.containment).offset(); 14692 over = ($(ce).css("overflow") !== "hidden"); 14693 14694 this.containment = [ 14695 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 14696 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 14697 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, 14698 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 14699 ]; 14700 } 14701 14702 }, 14703 14704 _convertPositionTo: function(d, pos) { 14705 14706 if(!pos) { 14707 pos = this.position; 14708 } 14709 var mod = d === "absolute" ? 1 : -1, 14710 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 14711 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 14712 14713 return { 14714 top: ( 14715 pos.top + // The absolute mouse position 14716 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 14717 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 14718 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 14719 ), 14720 left: ( 14721 pos.left + // The absolute mouse position 14722 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 14723 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 14724 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 14725 ) 14726 }; 14727 14728 }, 14729 14730 _generatePosition: function(event) { 14731 14732 var top, left, 14733 o = this.options, 14734 pageX = event.pageX, 14735 pageY = event.pageY, 14736 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 14737 14738 // This is another very weird special case that only happens for relative elements: 14739 // 1. If the css position is relative 14740 // 2. and the scroll parent is the document or similar to the offset parent 14741 // we have to refresh the relative offset during the scroll so there are no jumps 14742 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 14743 this.offset.relative = this._getRelativeOffset(); 14744 } 14745 14746 /* 14747 * - Position constraining - 14748 * Constrain the position to a mix of grid, containment. 14749 */ 14750 14751 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 14752 14753 if(this.containment) { 14754 if(event.pageX - this.offset.click.left < this.containment[0]) { 14755 pageX = this.containment[0] + this.offset.click.left; 14756 } 14757 if(event.pageY - this.offset.click.top < this.containment[1]) { 14758 pageY = this.containment[1] + this.offset.click.top; 14759 } 14760 if(event.pageX - this.offset.click.left > this.containment[2]) { 14761 pageX = this.containment[2] + this.offset.click.left; 14762 } 14763 if(event.pageY - this.offset.click.top > this.containment[3]) { 14764 pageY = this.containment[3] + this.offset.click.top; 14765 } 14766 } 14767 14768 if(o.grid) { 14769 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 14770 pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; 14771 14772 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 14773 pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; 14774 } 14775 14776 } 14777 14778 return { 14779 top: ( 14780 pageY - // The absolute mouse position 14781 this.offset.click.top - // Click offset (relative to the element) 14782 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 14783 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 14784 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 14785 ), 14786 left: ( 14787 pageX - // The absolute mouse position 14788 this.offset.click.left - // Click offset (relative to the element) 14789 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 14790 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 14791 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 14792 ) 14793 }; 14794 14795 }, 14796 14797 _rearrange: function(event, i, a, hardRefresh) { 14798 14799 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); 14800 14801 //Various things done here to improve the performance: 14802 // 1. we create a setTimeout, that calls refreshPositions 14803 // 2. on the instance, we have a counter variable, that get's higher after every append 14804 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 14805 // 4. this lets only the last addition to the timeout stack through 14806 this.counter = this.counter ? ++this.counter : 1; 14807 var counter = this.counter; 14808 14809 this._delay(function() { 14810 if(counter === this.counter) { 14811 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 14812 } 14813 }); 14814 14815 }, 14816 14817 _clear: function(event, noPropagation) { 14818 14819 this.reverting = false; 14820 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 14821 // everything else normalized again 14822 var i, 14823 delayedTriggers = []; 14824 14825 // We first have to update the dom position of the actual currentItem 14826 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 14827 if(!this._noFinalSort && this.currentItem.parent().length) { 14828 this.placeholder.before(this.currentItem); 14829 } 14830 this._noFinalSort = null; 14831 14832 if(this.helper[0] === this.currentItem[0]) { 14833 for(i in this._storedCSS) { 14834 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 14835 this._storedCSS[i] = ""; 14836 } 14837 } 14838 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 14839 } else { 14840 this.currentItem.show(); 14841 } 14842 14843 if(this.fromOutside && !noPropagation) { 14844 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 14845 } 14846 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 14847 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 14848 } 14849 14850 // Check if the items Container has Changed and trigger appropriate 14851 // events. 14852 if (this !== this.currentContainer) { 14853 if(!noPropagation) { 14854 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 14855 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 14856 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 14857 } 14858 } 14859 14860 14861 //Post events to containers 14862 function delayEvent( type, instance, container ) { 14863 return function( event ) { 14864 container._trigger( type, event, instance._uiHash( instance ) ); 14865 }; 14866 } 14867 for (i = this.containers.length - 1; i >= 0; i--){ 14868 if (!noPropagation) { 14869 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 14870 } 14871 if(this.containers[i].containerCache.over) { 14872 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 14873 this.containers[i].containerCache.over = 0; 14874 } 14875 } 14876 14877 //Do what was originally in plugins 14878 if ( this.storedCursor ) { 14879 this.document.find( "body" ).css( "cursor", this.storedCursor ); 14880 this.storedStylesheet.remove(); 14881 } 14882 if(this._storedOpacity) { 14883 this.helper.css("opacity", this._storedOpacity); 14884 } 14885 if(this._storedZIndex) { 14886 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 14887 } 14888 14889 this.dragging = false; 14890 if(this.cancelHelperRemoval) { 14891 if(!noPropagation) { 14892 this._trigger("beforeStop", event, this._uiHash()); 14893 for (i=0; i < delayedTriggers.length; i++) { 14894 delayedTriggers[i].call(this, event); 14895 } //Trigger all delayed events 14896 this._trigger("stop", event, this._uiHash()); 14897 } 14898 14899 this.fromOutside = false; 14900 return false; 14901 } 14902 14903 if(!noPropagation) { 14904 this._trigger("beforeStop", event, this._uiHash()); 14905 } 14906 14907 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 14908 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 14909 14910 if(this.helper[0] !== this.currentItem[0]) { 14911 this.helper.remove(); 14912 } 14913 this.helper = null; 14914 14915 if(!noPropagation) { 14916 for (i=0; i < delayedTriggers.length; i++) { 14917 delayedTriggers[i].call(this, event); 14918 } //Trigger all delayed events 14919 this._trigger("stop", event, this._uiHash()); 14920 } 14921 14922 this.fromOutside = false; 14923 return true; 14924 14925 }, 14926 14927 _trigger: function() { 14928 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 14929 this.cancel(); 14930 } 14931 }, 14932 14933 _uiHash: function(_inst) { 14934 var inst = _inst || this; 14935 return { 14936 helper: inst.helper, 14937 placeholder: inst.placeholder || $([]), 14938 position: inst.position, 14939 originalPosition: inst.originalPosition, 14940 offset: inst.positionAbs, 14941 item: inst.currentItem, 14942 sender: _inst ? _inst.element : null 14943 }; 14944 } 14945 14946}); 14947 14948 14949/*! 14950 * jQuery UI Spinner 1.11.1 14951 * http://jqueryui.com 14952 * 14953 * Copyright 2014 jQuery Foundation and other contributors 14954 * Released under the MIT license. 14955 * http://jquery.org/license 14956 * 14957 * http://api.jqueryui.com/spinner/ 14958 */ 14959 14960 14961function spinner_modifier( fn ) { 14962 return function() { 14963 var previous = this.element.val(); 14964 fn.apply( this, arguments ); 14965 this._refresh(); 14966 if ( previous !== this.element.val() ) { 14967 this._trigger( "change" ); 14968 } 14969 }; 14970} 14971 14972var spinner = $.widget( "ui.spinner", { 14973 version: "1.11.1", 14974 defaultElement: "<input>", 14975 widgetEventPrefix: "spin", 14976 options: { 14977 culture: null, 14978 icons: { 14979 down: "ui-icon-triangle-1-s", 14980 up: "ui-icon-triangle-1-n" 14981 }, 14982 incremental: true, 14983 max: null, 14984 min: null, 14985 numberFormat: null, 14986 page: 10, 14987 step: 1, 14988 14989 change: null, 14990 spin: null, 14991 start: null, 14992 stop: null 14993 }, 14994 14995 _create: function() { 14996 // handle string values that need to be parsed 14997 this._setOption( "max", this.options.max ); 14998 this._setOption( "min", this.options.min ); 14999 this._setOption( "step", this.options.step ); 15000 15001 // Only format if there is a value, prevents the field from being marked 15002 // as invalid in Firefox, see #9573. 15003 if ( this.value() !== "" ) { 15004 // Format the value, but don't constrain. 15005 this._value( this.element.val(), true ); 15006 } 15007 15008 this._draw(); 15009 this._on( this._events ); 15010 this._refresh(); 15011 15012 // turning off autocomplete prevents the browser from remembering the 15013 // value when navigating through history, so we re-enable autocomplete 15014 // if the page is unloaded before the widget is destroyed. #7790 15015 this._on( this.window, { 15016 beforeunload: function() { 15017 this.element.removeAttr( "autocomplete" ); 15018 } 15019 }); 15020 }, 15021 15022 _getCreateOptions: function() { 15023 var options = {}, 15024 element = this.element; 15025 15026 $.each( [ "min", "max", "step" ], function( i, option ) { 15027 var value = element.attr( option ); 15028 if ( value !== undefined && value.length ) { 15029 options[ option ] = value; 15030 } 15031 }); 15032 15033 return options; 15034 }, 15035 15036 _events: { 15037 keydown: function( event ) { 15038 if ( this._start( event ) && this._keydown( event ) ) { 15039 event.preventDefault(); 15040 } 15041 }, 15042 keyup: "_stop", 15043 focus: function() { 15044 this.previous = this.element.val(); 15045 }, 15046 blur: function( event ) { 15047 if ( this.cancelBlur ) { 15048 delete this.cancelBlur; 15049 return; 15050 } 15051 15052 this._stop(); 15053 this._refresh(); 15054 if ( this.previous !== this.element.val() ) { 15055 this._trigger( "change", event ); 15056 } 15057 }, 15058 mousewheel: function( event, delta ) { 15059 if ( !delta ) { 15060 return; 15061 } 15062 if ( !this.spinning && !this._start( event ) ) { 15063 return false; 15064 } 15065 15066 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 15067 clearTimeout( this.mousewheelTimer ); 15068 this.mousewheelTimer = this._delay(function() { 15069 if ( this.spinning ) { 15070 this._stop( event ); 15071 } 15072 }, 100 ); 15073 event.preventDefault(); 15074 }, 15075 "mousedown .ui-spinner-button": function( event ) { 15076 var previous; 15077 15078 // We never want the buttons to have focus; whenever the user is 15079 // interacting with the spinner, the focus should be on the input. 15080 // If the input is focused then this.previous is properly set from 15081 // when the input first received focus. If the input is not focused 15082 // then we need to set this.previous based on the value before spinning. 15083 previous = this.element[0] === this.document[0].activeElement ? 15084 this.previous : this.element.val(); 15085 function checkFocus() { 15086 var isActive = this.element[0] === this.document[0].activeElement; 15087 if ( !isActive ) { 15088 this.element.focus(); 15089 this.previous = previous; 15090 // support: IE 15091 // IE sets focus asynchronously, so we need to check if focus 15092 // moved off of the input because the user clicked on the button. 15093 this._delay(function() { 15094 this.previous = previous; 15095 }); 15096 } 15097 } 15098 15099 // ensure focus is on (or stays on) the text field 15100 event.preventDefault(); 15101 checkFocus.call( this ); 15102 15103 // support: IE 15104 // IE doesn't prevent moving focus even with event.preventDefault() 15105 // so we set a flag to know when we should ignore the blur event 15106 // and check (again) if focus moved off of the input. 15107 this.cancelBlur = true; 15108 this._delay(function() { 15109 delete this.cancelBlur; 15110 checkFocus.call( this ); 15111 }); 15112 15113 if ( this._start( event ) === false ) { 15114 return; 15115 } 15116 15117 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 15118 }, 15119 "mouseup .ui-spinner-button": "_stop", 15120 "mouseenter .ui-spinner-button": function( event ) { 15121 // button will add ui-state-active if mouse was down while mouseleave and kept down 15122 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 15123 return; 15124 } 15125 15126 if ( this._start( event ) === false ) { 15127 return false; 15128 } 15129 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 15130 }, 15131 // TODO: do we really want to consider this a stop? 15132 // shouldn't we just stop the repeater and wait until mouseup before 15133 // we trigger the stop event? 15134 "mouseleave .ui-spinner-button": "_stop" 15135 }, 15136 15137 _draw: function() { 15138 var uiSpinner = this.uiSpinner = this.element 15139 .addClass( "ui-spinner-input" ) 15140 .attr( "autocomplete", "off" ) 15141 .wrap( this._uiSpinnerHtml() ) 15142 .parent() 15143 // add buttons 15144 .append( this._buttonHtml() ); 15145 15146 this.element.attr( "role", "spinbutton" ); 15147 15148 // button bindings 15149 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 15150 .attr( "tabIndex", -1 ) 15151 .button() 15152 .removeClass( "ui-corner-all" ); 15153 15154 // IE 6 doesn't understand height: 50% for the buttons 15155 // unless the wrapper has an explicit height 15156 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 15157 uiSpinner.height() > 0 ) { 15158 uiSpinner.height( uiSpinner.height() ); 15159 } 15160 15161 // disable spinner if element was already disabled 15162 if ( this.options.disabled ) { 15163 this.disable(); 15164 } 15165 }, 15166 15167 _keydown: function( event ) { 15168 var options = this.options, 15169 keyCode = $.ui.keyCode; 15170 15171 switch ( event.keyCode ) { 15172 case keyCode.UP: 15173 this._repeat( null, 1, event ); 15174 return true; 15175 case keyCode.DOWN: 15176 this._repeat( null, -1, event ); 15177 return true; 15178 case keyCode.PAGE_UP: 15179 this._repeat( null, options.page, event ); 15180 return true; 15181 case keyCode.PAGE_DOWN: 15182 this._repeat( null, -options.page, event ); 15183 return true; 15184 } 15185 15186 return false; 15187 }, 15188 15189 _uiSpinnerHtml: function() { 15190 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 15191 }, 15192 15193 _buttonHtml: function() { 15194 return "" + 15195 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 15196 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 15197 "</a>" + 15198 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 15199 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 15200 "</a>"; 15201 }, 15202 15203 _start: function( event ) { 15204 if ( !this.spinning && this._trigger( "start", event ) === false ) { 15205 return false; 15206 } 15207 15208 if ( !this.counter ) { 15209 this.counter = 1; 15210 } 15211 this.spinning = true; 15212 return true; 15213 }, 15214 15215 _repeat: function( i, steps, event ) { 15216 i = i || 500; 15217 15218 clearTimeout( this.timer ); 15219 this.timer = this._delay(function() { 15220 this._repeat( 40, steps, event ); 15221 }, i ); 15222 15223 this._spin( steps * this.options.step, event ); 15224 }, 15225 15226 _spin: function( step, event ) { 15227 var value = this.value() || 0; 15228 15229 if ( !this.counter ) { 15230 this.counter = 1; 15231 } 15232 15233 value = this._adjustValue( value + step * this._increment( this.counter ) ); 15234 15235 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 15236 this._value( value ); 15237 this.counter++; 15238 } 15239 }, 15240 15241 _increment: function( i ) { 15242 var incremental = this.options.incremental; 15243 15244 if ( incremental ) { 15245 return $.isFunction( incremental ) ? 15246 incremental( i ) : 15247 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 15248 } 15249 15250 return 1; 15251 }, 15252 15253 _precision: function() { 15254 var precision = this._precisionOf( this.options.step ); 15255 if ( this.options.min !== null ) { 15256 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 15257 } 15258 return precision; 15259 }, 15260 15261 _precisionOf: function( num ) { 15262 var str = num.toString(), 15263 decimal = str.indexOf( "." ); 15264 return decimal === -1 ? 0 : str.length - decimal - 1; 15265 }, 15266 15267 _adjustValue: function( value ) { 15268 var base, aboveMin, 15269 options = this.options; 15270 15271 // make sure we're at a valid step 15272 // - find out where we are relative to the base (min or 0) 15273 base = options.min !== null ? options.min : 0; 15274 aboveMin = value - base; 15275 // - round to the nearest step 15276 aboveMin = Math.round(aboveMin / options.step) * options.step; 15277 // - rounding is based on 0, so adjust back to our base 15278 value = base + aboveMin; 15279 15280 // fix precision from bad JS floating point math 15281 value = parseFloat( value.toFixed( this._precision() ) ); 15282 15283 // clamp the value 15284 if ( options.max !== null && value > options.max) { 15285 return options.max; 15286 } 15287 if ( options.min !== null && value < options.min ) { 15288 return options.min; 15289 } 15290 15291 return value; 15292 }, 15293 15294 _stop: function( event ) { 15295 if ( !this.spinning ) { 15296 return; 15297 } 15298 15299 clearTimeout( this.timer ); 15300 clearTimeout( this.mousewheelTimer ); 15301 this.counter = 0; 15302 this.spinning = false; 15303 this._trigger( "stop", event ); 15304 }, 15305 15306 _setOption: function( key, value ) { 15307 if ( key === "culture" || key === "numberFormat" ) { 15308 var prevValue = this._parse( this.element.val() ); 15309 this.options[ key ] = value; 15310 this.element.val( this._format( prevValue ) ); 15311 return; 15312 } 15313 15314 if ( key === "max" || key === "min" || key === "step" ) { 15315 if ( typeof value === "string" ) { 15316 value = this._parse( value ); 15317 } 15318 } 15319 if ( key === "icons" ) { 15320 this.buttons.first().find( ".ui-icon" ) 15321 .removeClass( this.options.icons.up ) 15322 .addClass( value.up ); 15323 this.buttons.last().find( ".ui-icon" ) 15324 .removeClass( this.options.icons.down ) 15325 .addClass( value.down ); 15326 } 15327 15328 this._super( key, value ); 15329 15330 if ( key === "disabled" ) { 15331 this.widget().toggleClass( "ui-state-disabled", !!value ); 15332 this.element.prop( "disabled", !!value ); 15333 this.buttons.button( value ? "disable" : "enable" ); 15334 } 15335 }, 15336 15337 _setOptions: spinner_modifier(function( options ) { 15338 this._super( options ); 15339 }), 15340 15341 _parse: function( val ) { 15342 if ( typeof val === "string" && val !== "" ) { 15343 val = window.Globalize && this.options.numberFormat ? 15344 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 15345 } 15346 return val === "" || isNaN( val ) ? null : val; 15347 }, 15348 15349 _format: function( value ) { 15350 if ( value === "" ) { 15351 return ""; 15352 } 15353 return window.Globalize && this.options.numberFormat ? 15354 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 15355 value; 15356 }, 15357 15358 _refresh: function() { 15359 this.element.attr({ 15360 "aria-valuemin": this.options.min, 15361 "aria-valuemax": this.options.max, 15362 // TODO: what should we do with values that can't be parsed? 15363 "aria-valuenow": this._parse( this.element.val() ) 15364 }); 15365 }, 15366 15367 isValid: function() { 15368 var value = this.value(); 15369 15370 // null is invalid 15371 if ( value === null ) { 15372 return false; 15373 } 15374 15375 // if value gets adjusted, it's invalid 15376 return value === this._adjustValue( value ); 15377 }, 15378 15379 // update the value without triggering change 15380 _value: function( value, allowAny ) { 15381 var parsed; 15382 if ( value !== "" ) { 15383 parsed = this._parse( value ); 15384 if ( parsed !== null ) { 15385 if ( !allowAny ) { 15386 parsed = this._adjustValue( parsed ); 15387 } 15388 value = this._format( parsed ); 15389 } 15390 } 15391 this.element.val( value ); 15392 this._refresh(); 15393 }, 15394 15395 _destroy: function() { 15396 this.element 15397 .removeClass( "ui-spinner-input" ) 15398 .prop( "disabled", false ) 15399 .removeAttr( "autocomplete" ) 15400 .removeAttr( "role" ) 15401 .removeAttr( "aria-valuemin" ) 15402 .removeAttr( "aria-valuemax" ) 15403 .removeAttr( "aria-valuenow" ); 15404 this.uiSpinner.replaceWith( this.element ); 15405 }, 15406 15407 stepUp: spinner_modifier(function( steps ) { 15408 this._stepUp( steps ); 15409 }), 15410 _stepUp: function( steps ) { 15411 if ( this._start() ) { 15412 this._spin( (steps || 1) * this.options.step ); 15413 this._stop(); 15414 } 15415 }, 15416 15417 stepDown: spinner_modifier(function( steps ) { 15418 this._stepDown( steps ); 15419 }), 15420 _stepDown: function( steps ) { 15421 if ( this._start() ) { 15422 this._spin( (steps || 1) * -this.options.step ); 15423 this._stop(); 15424 } 15425 }, 15426 15427 pageUp: spinner_modifier(function( pages ) { 15428 this._stepUp( (pages || 1) * this.options.page ); 15429 }), 15430 15431 pageDown: spinner_modifier(function( pages ) { 15432 this._stepDown( (pages || 1) * this.options.page ); 15433 }), 15434 15435 value: function( newVal ) { 15436 if ( !arguments.length ) { 15437 return this._parse( this.element.val() ); 15438 } 15439 spinner_modifier( this._value ).call( this, newVal ); 15440 }, 15441 15442 widget: function() { 15443 return this.uiSpinner; 15444 } 15445}); 15446 15447 15448/*! 15449 * jQuery UI Tabs 1.11.1 15450 * http://jqueryui.com 15451 * 15452 * Copyright 2014 jQuery Foundation and other contributors 15453 * Released under the MIT license. 15454 * http://jquery.org/license 15455 * 15456 * http://api.jqueryui.com/tabs/ 15457 */ 15458 15459 15460var tabs = $.widget( "ui.tabs", { 15461 version: "1.11.1", 15462 delay: 300, 15463 options: { 15464 active: null, 15465 collapsible: false, 15466 event: "click", 15467 heightStyle: "content", 15468 hide: null, 15469 show: null, 15470 15471 // callbacks 15472 activate: null, 15473 beforeActivate: null, 15474 beforeLoad: null, 15475 load: null 15476 }, 15477 15478 _isLocal: (function() { 15479 var rhash = /#.*$/; 15480 15481 return function( anchor ) { 15482 var anchorUrl, locationUrl; 15483 15484 // support: IE7 15485 // IE7 doesn't normalize the href property when set via script (#9317) 15486 anchor = anchor.cloneNode( false ); 15487 15488 anchorUrl = anchor.href.replace( rhash, "" ); 15489 locationUrl = location.href.replace( rhash, "" ); 15490 15491 // decoding may throw an error if the URL isn't UTF-8 (#9518) 15492 try { 15493 anchorUrl = decodeURIComponent( anchorUrl ); 15494 } catch ( error ) {} 15495 try { 15496 locationUrl = decodeURIComponent( locationUrl ); 15497 } catch ( error ) {} 15498 15499 return anchor.hash.length > 1 && anchorUrl === locationUrl; 15500 }; 15501 })(), 15502 15503 _create: function() { 15504 var that = this, 15505 options = this.options; 15506 15507 this.running = false; 15508 15509 this.element 15510 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 15511 .toggleClass( "ui-tabs-collapsible", options.collapsible ); 15512 15513 this._processTabs(); 15514 options.active = this._initialActive(); 15515 15516 // Take disabling tabs via class attribute from HTML 15517 // into account and update option properly. 15518 if ( $.isArray( options.disabled ) ) { 15519 options.disabled = $.unique( options.disabled.concat( 15520 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 15521 return that.tabs.index( li ); 15522 }) 15523 ) ).sort(); 15524 } 15525 15526 // check for length avoids error when initializing empty list 15527 if ( this.options.active !== false && this.anchors.length ) { 15528 this.active = this._findActive( options.active ); 15529 } else { 15530 this.active = $(); 15531 } 15532 15533 this._refresh(); 15534 15535 if ( this.active.length ) { 15536 this.load( options.active ); 15537 } 15538 }, 15539 15540 _initialActive: function() { 15541 var active = this.options.active, 15542 collapsible = this.options.collapsible, 15543 locationHash = location.hash.substring( 1 ); 15544 15545 if ( active === null ) { 15546 // check the fragment identifier in the URL 15547 if ( locationHash ) { 15548 this.tabs.each(function( i, tab ) { 15549 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 15550 active = i; 15551 return false; 15552 } 15553 }); 15554 } 15555 15556 // check for a tab marked active via a class 15557 if ( active === null ) { 15558 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 15559 } 15560 15561 // no active tab, set to false 15562 if ( active === null || active === -1 ) { 15563 active = this.tabs.length ? 0 : false; 15564 } 15565 } 15566 15567 // handle numbers: negative, out of range 15568 if ( active !== false ) { 15569 active = this.tabs.index( this.tabs.eq( active ) ); 15570 if ( active === -1 ) { 15571 active = collapsible ? false : 0; 15572 } 15573 } 15574 15575 // don't allow collapsible: false and active: false 15576 if ( !collapsible && active === false && this.anchors.length ) { 15577 active = 0; 15578 } 15579 15580 return active; 15581 }, 15582 15583 _getCreateEventData: function() { 15584 return { 15585 tab: this.active, 15586 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 15587 }; 15588 }, 15589 15590 _tabKeydown: function( event ) { 15591 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 15592 selectedIndex = this.tabs.index( focusedTab ), 15593 goingForward = true; 15594 15595 if ( this._handlePageNav( event ) ) { 15596 return; 15597 } 15598 15599 switch ( event.keyCode ) { 15600 case $.ui.keyCode.RIGHT: 15601 case $.ui.keyCode.DOWN: 15602 selectedIndex++; 15603 break; 15604 case $.ui.keyCode.UP: 15605 case $.ui.keyCode.LEFT: 15606 goingForward = false; 15607 selectedIndex--; 15608 break; 15609 case $.ui.keyCode.END: 15610 selectedIndex = this.anchors.length - 1; 15611 break; 15612 case $.ui.keyCode.HOME: 15613 selectedIndex = 0; 15614 break; 15615 case $.ui.keyCode.SPACE: 15616 // Activate only, no collapsing 15617 event.preventDefault(); 15618 clearTimeout( this.activating ); 15619 this._activate( selectedIndex ); 15620 return; 15621 case $.ui.keyCode.ENTER: 15622 // Toggle (cancel delayed activation, allow collapsing) 15623 event.preventDefault(); 15624 clearTimeout( this.activating ); 15625 // Determine if we should collapse or activate 15626 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 15627 return; 15628 default: 15629 return; 15630 } 15631 15632 // Focus the appropriate tab, based on which key was pressed 15633 event.preventDefault(); 15634 clearTimeout( this.activating ); 15635 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 15636 15637 // Navigating with control key will prevent automatic activation 15638 if ( !event.ctrlKey ) { 15639 // Update aria-selected immediately so that AT think the tab is already selected. 15640 // Otherwise AT may confuse the user by stating that they need to activate the tab, 15641 // but the tab will already be activated by the time the announcement finishes. 15642 focusedTab.attr( "aria-selected", "false" ); 15643 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 15644 15645 this.activating = this._delay(function() { 15646 this.option( "active", selectedIndex ); 15647 }, this.delay ); 15648 } 15649 }, 15650 15651 _panelKeydown: function( event ) { 15652 if ( this._handlePageNav( event ) ) { 15653 return; 15654 } 15655 15656 // Ctrl+up moves focus to the current tab 15657 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 15658 event.preventDefault(); 15659 this.active.focus(); 15660 } 15661 }, 15662 15663 // Alt+page up/down moves focus to the previous/next tab (and activates) 15664 _handlePageNav: function( event ) { 15665 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 15666 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 15667 return true; 15668 } 15669 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 15670 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 15671 return true; 15672 } 15673 }, 15674 15675 _findNextTab: function( index, goingForward ) { 15676 var lastTabIndex = this.tabs.length - 1; 15677 15678 function constrain() { 15679 if ( index > lastTabIndex ) { 15680 index = 0; 15681 } 15682 if ( index < 0 ) { 15683 index = lastTabIndex; 15684 } 15685 return index; 15686 } 15687 15688 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 15689 index = goingForward ? index + 1 : index - 1; 15690 } 15691 15692 return index; 15693 }, 15694 15695 _focusNextTab: function( index, goingForward ) { 15696 index = this._findNextTab( index, goingForward ); 15697 this.tabs.eq( index ).focus(); 15698 return index; 15699 }, 15700 15701 _setOption: function( key, value ) { 15702 if ( key === "active" ) { 15703 // _activate() will handle invalid values and update this.options 15704 this._activate( value ); 15705 return; 15706 } 15707 15708 if ( key === "disabled" ) { 15709 // don't use the widget factory's disabled handling 15710 this._setupDisabled( value ); 15711 return; 15712 } 15713 15714 this._super( key, value); 15715 15716 if ( key === "collapsible" ) { 15717 this.element.toggleClass( "ui-tabs-collapsible", value ); 15718 // Setting collapsible: false while collapsed; open first panel 15719 if ( !value && this.options.active === false ) { 15720 this._activate( 0 ); 15721 } 15722 } 15723 15724 if ( key === "event" ) { 15725 this._setupEvents( value ); 15726 } 15727 15728 if ( key === "heightStyle" ) { 15729 this._setupHeightStyle( value ); 15730 } 15731 }, 15732 15733 _sanitizeSelector: function( hash ) { 15734 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 15735 }, 15736 15737 refresh: function() { 15738 var options = this.options, 15739 lis = this.tablist.children( ":has(a[href])" ); 15740 15741 // get disabled tabs from class attribute from HTML 15742 // this will get converted to a boolean if needed in _refresh() 15743 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 15744 return lis.index( tab ); 15745 }); 15746 15747 this._processTabs(); 15748 15749 // was collapsed or no tabs 15750 if ( options.active === false || !this.anchors.length ) { 15751 options.active = false; 15752 this.active = $(); 15753 // was active, but active tab is gone 15754 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 15755 // all remaining tabs are disabled 15756 if ( this.tabs.length === options.disabled.length ) { 15757 options.active = false; 15758 this.active = $(); 15759 // activate previous tab 15760 } else { 15761 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 15762 } 15763 // was active, active tab still exists 15764 } else { 15765 // make sure active index is correct 15766 options.active = this.tabs.index( this.active ); 15767 } 15768 15769 this._refresh(); 15770 }, 15771 15772 _refresh: function() { 15773 this._setupDisabled( this.options.disabled ); 15774 this._setupEvents( this.options.event ); 15775 this._setupHeightStyle( this.options.heightStyle ); 15776 15777 this.tabs.not( this.active ).attr({ 15778 "aria-selected": "false", 15779 "aria-expanded": "false", 15780 tabIndex: -1 15781 }); 15782 this.panels.not( this._getPanelForTab( this.active ) ) 15783 .hide() 15784 .attr({ 15785 "aria-hidden": "true" 15786 }); 15787 15788 // Make sure one tab is in the tab order 15789 if ( !this.active.length ) { 15790 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 15791 } else { 15792 this.active 15793 .addClass( "ui-tabs-active ui-state-active" ) 15794 .attr({ 15795 "aria-selected": "true", 15796 "aria-expanded": "true", 15797 tabIndex: 0 15798 }); 15799 this._getPanelForTab( this.active ) 15800 .show() 15801 .attr({ 15802 "aria-hidden": "false" 15803 }); 15804 } 15805 }, 15806 15807 _processTabs: function() { 15808 var that = this; 15809 15810 this.tablist = this._getList() 15811 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 15812 .attr( "role", "tablist" ) 15813 15814 // Prevent users from focusing disabled tabs via click 15815 .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { 15816 if ( $( this ).is( ".ui-state-disabled" ) ) { 15817 event.preventDefault(); 15818 } 15819 }) 15820 15821 // support: IE <9 15822 // Preventing the default action in mousedown doesn't prevent IE 15823 // from focusing the element, so if the anchor gets focused, blur. 15824 // We don't have to worry about focusing the previously focused 15825 // element since clicking on a non-focusable element should focus 15826 // the body anyway. 15827 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 15828 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 15829 this.blur(); 15830 } 15831 }); 15832 15833 this.tabs = this.tablist.find( "> li:has(a[href])" ) 15834 .addClass( "ui-state-default ui-corner-top" ) 15835 .attr({ 15836 role: "tab", 15837 tabIndex: -1 15838 }); 15839 15840 this.anchors = this.tabs.map(function() { 15841 return $( "a", this )[ 0 ]; 15842 }) 15843 .addClass( "ui-tabs-anchor" ) 15844 .attr({ 15845 role: "presentation", 15846 tabIndex: -1 15847 }); 15848 15849 this.panels = $(); 15850 15851 this.anchors.each(function( i, anchor ) { 15852 var selector, panel, panelId, 15853 anchorId = $( anchor ).uniqueId().attr( "id" ), 15854 tab = $( anchor ).closest( "li" ), 15855 originalAriaControls = tab.attr( "aria-controls" ); 15856 15857 // inline tab 15858 if ( that._isLocal( anchor ) ) { 15859 selector = anchor.hash; 15860 panelId = selector.substring( 1 ); 15861 panel = that.element.find( that._sanitizeSelector( selector ) ); 15862 // remote tab 15863 } else { 15864 // If the tab doesn't already have aria-controls, 15865 // generate an id by using a throw-away element 15866 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 15867 selector = "#" + panelId; 15868 panel = that.element.find( selector ); 15869 if ( !panel.length ) { 15870 panel = that._createPanel( panelId ); 15871 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 15872 } 15873 panel.attr( "aria-live", "polite" ); 15874 } 15875 15876 if ( panel.length) { 15877 that.panels = that.panels.add( panel ); 15878 } 15879 if ( originalAriaControls ) { 15880 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 15881 } 15882 tab.attr({ 15883 "aria-controls": panelId, 15884 "aria-labelledby": anchorId 15885 }); 15886 panel.attr( "aria-labelledby", anchorId ); 15887 }); 15888 15889 this.panels 15890 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 15891 .attr( "role", "tabpanel" ); 15892 }, 15893 15894 // allow overriding how to find the list for rare usage scenarios (#7715) 15895 _getList: function() { 15896 return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); 15897 }, 15898 15899 _createPanel: function( id ) { 15900 return $( "<div>" ) 15901 .attr( "id", id ) 15902 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 15903 .data( "ui-tabs-destroy", true ); 15904 }, 15905 15906 _setupDisabled: function( disabled ) { 15907 if ( $.isArray( disabled ) ) { 15908 if ( !disabled.length ) { 15909 disabled = false; 15910 } else if ( disabled.length === this.anchors.length ) { 15911 disabled = true; 15912 } 15913 } 15914 15915 // disable tabs 15916 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 15917 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 15918 $( li ) 15919 .addClass( "ui-state-disabled" ) 15920 .attr( "aria-disabled", "true" ); 15921 } else { 15922 $( li ) 15923 .removeClass( "ui-state-disabled" ) 15924 .removeAttr( "aria-disabled" ); 15925 } 15926 } 15927 15928 this.options.disabled = disabled; 15929 }, 15930 15931 _setupEvents: function( event ) { 15932 var events = {}; 15933 if ( event ) { 15934 $.each( event.split(" "), function( index, eventName ) { 15935 events[ eventName ] = "_eventHandler"; 15936 }); 15937 } 15938 15939 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 15940 // Always prevent the default action, even when disabled 15941 this._on( true, this.anchors, { 15942 click: function( event ) { 15943 event.preventDefault(); 15944 } 15945 }); 15946 this._on( this.anchors, events ); 15947 this._on( this.tabs, { keydown: "_tabKeydown" } ); 15948 this._on( this.panels, { keydown: "_panelKeydown" } ); 15949 15950 this._focusable( this.tabs ); 15951 this._hoverable( this.tabs ); 15952 }, 15953 15954 _setupHeightStyle: function( heightStyle ) { 15955 var maxHeight, 15956 parent = this.element.parent(); 15957 15958 if ( heightStyle === "fill" ) { 15959 maxHeight = parent.height(); 15960 maxHeight -= this.element.outerHeight() - this.element.height(); 15961 15962 this.element.siblings( ":visible" ).each(function() { 15963 var elem = $( this ), 15964 position = elem.css( "position" ); 15965 15966 if ( position === "absolute" || position === "fixed" ) { 15967 return; 15968 } 15969 maxHeight -= elem.outerHeight( true ); 15970 }); 15971 15972 this.element.children().not( this.panels ).each(function() { 15973 maxHeight -= $( this ).outerHeight( true ); 15974 }); 15975 15976 this.panels.each(function() { 15977 $( this ).height( Math.max( 0, maxHeight - 15978 $( this ).innerHeight() + $( this ).height() ) ); 15979 }) 15980 .css( "overflow", "auto" ); 15981 } else if ( heightStyle === "auto" ) { 15982 maxHeight = 0; 15983 this.panels.each(function() { 15984 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 15985 }).height( maxHeight ); 15986 } 15987 }, 15988 15989 _eventHandler: function( event ) { 15990 var options = this.options, 15991 active = this.active, 15992 anchor = $( event.currentTarget ), 15993 tab = anchor.closest( "li" ), 15994 clickedIsActive = tab[ 0 ] === active[ 0 ], 15995 collapsing = clickedIsActive && options.collapsible, 15996 toShow = collapsing ? $() : this._getPanelForTab( tab ), 15997 toHide = !active.length ? $() : this._getPanelForTab( active ), 15998 eventData = { 15999 oldTab: active, 16000 oldPanel: toHide, 16001 newTab: collapsing ? $() : tab, 16002 newPanel: toShow 16003 }; 16004 16005 event.preventDefault(); 16006 16007 if ( tab.hasClass( "ui-state-disabled" ) || 16008 // tab is already loading 16009 tab.hasClass( "ui-tabs-loading" ) || 16010 // can't switch durning an animation 16011 this.running || 16012 // click on active header, but not collapsible 16013 ( clickedIsActive && !options.collapsible ) || 16014 // allow canceling activation 16015 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 16016 return; 16017 } 16018 16019 options.active = collapsing ? false : this.tabs.index( tab ); 16020 16021 this.active = clickedIsActive ? $() : tab; 16022 if ( this.xhr ) { 16023 this.xhr.abort(); 16024 } 16025 16026 if ( !toHide.length && !toShow.length ) { 16027 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 16028 } 16029 16030 if ( toShow.length ) { 16031 this.load( this.tabs.index( tab ), event ); 16032 } 16033 this._toggle( event, eventData ); 16034 }, 16035 16036 // handles show/hide for selecting tabs 16037 _toggle: function( event, eventData ) { 16038 var that = this, 16039 toShow = eventData.newPanel, 16040 toHide = eventData.oldPanel; 16041 16042 this.running = true; 16043 16044 function complete() { 16045 that.running = false; 16046 that._trigger( "activate", event, eventData ); 16047 } 16048 16049 function show() { 16050 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 16051 16052 if ( toShow.length && that.options.show ) { 16053 that._show( toShow, that.options.show, complete ); 16054 } else { 16055 toShow.show(); 16056 complete(); 16057 } 16058 } 16059 16060 // start out by hiding, then showing, then completing 16061 if ( toHide.length && this.options.hide ) { 16062 this._hide( toHide, this.options.hide, function() { 16063 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 16064 show(); 16065 }); 16066 } else { 16067 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 16068 toHide.hide(); 16069 show(); 16070 } 16071 16072 toHide.attr( "aria-hidden", "true" ); 16073 eventData.oldTab.attr({ 16074 "aria-selected": "false", 16075 "aria-expanded": "false" 16076 }); 16077 // If we're switching tabs, remove the old tab from the tab order. 16078 // If we're opening from collapsed state, remove the previous tab from the tab order. 16079 // If we're collapsing, then keep the collapsing tab in the tab order. 16080 if ( toShow.length && toHide.length ) { 16081 eventData.oldTab.attr( "tabIndex", -1 ); 16082 } else if ( toShow.length ) { 16083 this.tabs.filter(function() { 16084 return $( this ).attr( "tabIndex" ) === 0; 16085 }) 16086 .attr( "tabIndex", -1 ); 16087 } 16088 16089 toShow.attr( "aria-hidden", "false" ); 16090 eventData.newTab.attr({ 16091 "aria-selected": "true", 16092 "aria-expanded": "true", 16093 tabIndex: 0 16094 }); 16095 }, 16096 16097 _activate: function( index ) { 16098 var anchor, 16099 active = this._findActive( index ); 16100 16101 // trying to activate the already active panel 16102 if ( active[ 0 ] === this.active[ 0 ] ) { 16103 return; 16104 } 16105 16106 // trying to collapse, simulate a click on the current active header 16107 if ( !active.length ) { 16108 active = this.active; 16109 } 16110 16111 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 16112 this._eventHandler({ 16113 target: anchor, 16114 currentTarget: anchor, 16115 preventDefault: $.noop 16116 }); 16117 }, 16118 16119 _findActive: function( index ) { 16120 return index === false ? $() : this.tabs.eq( index ); 16121 }, 16122 16123 _getIndex: function( index ) { 16124 // meta-function to give users option to provide a href string instead of a numerical index. 16125 if ( typeof index === "string" ) { 16126 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 16127 } 16128 16129 return index; 16130 }, 16131 16132 _destroy: function() { 16133 if ( this.xhr ) { 16134 this.xhr.abort(); 16135 } 16136 16137 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 16138 16139 this.tablist 16140 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 16141 .removeAttr( "role" ); 16142 16143 this.anchors 16144 .removeClass( "ui-tabs-anchor" ) 16145 .removeAttr( "role" ) 16146 .removeAttr( "tabIndex" ) 16147 .removeUniqueId(); 16148 16149 this.tablist.unbind( this.eventNamespace ); 16150 16151 this.tabs.add( this.panels ).each(function() { 16152 if ( $.data( this, "ui-tabs-destroy" ) ) { 16153 $( this ).remove(); 16154 } else { 16155 $( this ) 16156 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 16157 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 16158 .removeAttr( "tabIndex" ) 16159 .removeAttr( "aria-live" ) 16160 .removeAttr( "aria-busy" ) 16161 .removeAttr( "aria-selected" ) 16162 .removeAttr( "aria-labelledby" ) 16163 .removeAttr( "aria-hidden" ) 16164 .removeAttr( "aria-expanded" ) 16165 .removeAttr( "role" ); 16166 } 16167 }); 16168 16169 this.tabs.each(function() { 16170 var li = $( this ), 16171 prev = li.data( "ui-tabs-aria-controls" ); 16172 if ( prev ) { 16173 li 16174 .attr( "aria-controls", prev ) 16175 .removeData( "ui-tabs-aria-controls" ); 16176 } else { 16177 li.removeAttr( "aria-controls" ); 16178 } 16179 }); 16180 16181 this.panels.show(); 16182 16183 if ( this.options.heightStyle !== "content" ) { 16184 this.panels.css( "height", "" ); 16185 } 16186 }, 16187 16188 enable: function( index ) { 16189 var disabled = this.options.disabled; 16190 if ( disabled === false ) { 16191 return; 16192 } 16193 16194 if ( index === undefined ) { 16195 disabled = false; 16196 } else { 16197 index = this._getIndex( index ); 16198 if ( $.isArray( disabled ) ) { 16199 disabled = $.map( disabled, function( num ) { 16200 return num !== index ? num : null; 16201 }); 16202 } else { 16203 disabled = $.map( this.tabs, function( li, num ) { 16204 return num !== index ? num : null; 16205 }); 16206 } 16207 } 16208 this._setupDisabled( disabled ); 16209 }, 16210 16211 disable: function( index ) { 16212 var disabled = this.options.disabled; 16213 if ( disabled === true ) { 16214 return; 16215 } 16216 16217 if ( index === undefined ) { 16218 disabled = true; 16219 } else { 16220 index = this._getIndex( index ); 16221 if ( $.inArray( index, disabled ) !== -1 ) { 16222 return; 16223 } 16224 if ( $.isArray( disabled ) ) { 16225 disabled = $.merge( [ index ], disabled ).sort(); 16226 } else { 16227 disabled = [ index ]; 16228 } 16229 } 16230 this._setupDisabled( disabled ); 16231 }, 16232 16233 load: function( index, event ) { 16234 index = this._getIndex( index ); 16235 var that = this, 16236 tab = this.tabs.eq( index ), 16237 anchor = tab.find( ".ui-tabs-anchor" ), 16238 panel = this._getPanelForTab( tab ), 16239 eventData = { 16240 tab: tab, 16241 panel: panel 16242 }; 16243 16244 // not remote 16245 if ( this._isLocal( anchor[ 0 ] ) ) { 16246 return; 16247 } 16248 16249 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 16250 16251 // support: jQuery <1.8 16252 // jQuery <1.8 returns false if the request is canceled in beforeSend, 16253 // but as of 1.8, $.ajax() always returns a jqXHR object. 16254 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 16255 tab.addClass( "ui-tabs-loading" ); 16256 panel.attr( "aria-busy", "true" ); 16257 16258 this.xhr 16259 .success(function( response ) { 16260 // support: jQuery <1.8 16261 // http://bugs.jquery.com/ticket/11778 16262 setTimeout(function() { 16263 panel.html( response ); 16264 that._trigger( "load", event, eventData ); 16265 }, 1 ); 16266 }) 16267 .complete(function( jqXHR, status ) { 16268 // support: jQuery <1.8 16269 // http://bugs.jquery.com/ticket/11778 16270 setTimeout(function() { 16271 if ( status === "abort" ) { 16272 that.panels.stop( false, true ); 16273 } 16274 16275 tab.removeClass( "ui-tabs-loading" ); 16276 panel.removeAttr( "aria-busy" ); 16277 16278 if ( jqXHR === that.xhr ) { 16279 delete that.xhr; 16280 } 16281 }, 1 ); 16282 }); 16283 } 16284 }, 16285 16286 _ajaxSettings: function( anchor, event, eventData ) { 16287 var that = this; 16288 return { 16289 url: anchor.attr( "href" ), 16290 beforeSend: function( jqXHR, settings ) { 16291 return that._trigger( "beforeLoad", event, 16292 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 16293 } 16294 }; 16295 }, 16296 16297 _getPanelForTab: function( tab ) { 16298 var id = $( tab ).attr( "aria-controls" ); 16299 return this.element.find( this._sanitizeSelector( "#" + id ) ); 16300 } 16301}); 16302 16303 16304/*! 16305 * jQuery UI Tooltip 1.11.1 16306 * http://jqueryui.com 16307 * 16308 * Copyright 2014 jQuery Foundation and other contributors 16309 * Released under the MIT license. 16310 * http://jquery.org/license 16311 * 16312 * http://api.jqueryui.com/tooltip/ 16313 */ 16314 16315 16316var tooltip = $.widget( "ui.tooltip", { 16317 version: "1.11.1", 16318 options: { 16319 content: function() { 16320 // support: IE<9, Opera in jQuery <1.7 16321 // .text() can't accept undefined, so coerce to a string 16322 var title = $( this ).attr( "title" ) || ""; 16323 // Escape title, since we're going from an attribute to raw HTML 16324 return $( "<a>" ).text( title ).html(); 16325 }, 16326 hide: true, 16327 // Disabled elements have inconsistent behavior across browsers (#8661) 16328 items: "[title]:not([disabled])", 16329 position: { 16330 my: "left top+15", 16331 at: "left bottom", 16332 collision: "flipfit flip" 16333 }, 16334 show: true, 16335 tooltipClass: null, 16336 track: false, 16337 16338 // callbacks 16339 close: null, 16340 open: null 16341 }, 16342 16343 _addDescribedBy: function( elem, id ) { 16344 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 16345 describedby.push( id ); 16346 elem 16347 .data( "ui-tooltip-id", id ) 16348 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 16349 }, 16350 16351 _removeDescribedBy: function( elem ) { 16352 var id = elem.data( "ui-tooltip-id" ), 16353 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 16354 index = $.inArray( id, describedby ); 16355 16356 if ( index !== -1 ) { 16357 describedby.splice( index, 1 ); 16358 } 16359 16360 elem.removeData( "ui-tooltip-id" ); 16361 describedby = $.trim( describedby.join( " " ) ); 16362 if ( describedby ) { 16363 elem.attr( "aria-describedby", describedby ); 16364 } else { 16365 elem.removeAttr( "aria-describedby" ); 16366 } 16367 }, 16368 16369 _create: function() { 16370 this._on({ 16371 mouseover: "open", 16372 focusin: "open" 16373 }); 16374 16375 // IDs of generated tooltips, needed for destroy 16376 this.tooltips = {}; 16377 // IDs of parent tooltips where we removed the title attribute 16378 this.parents = {}; 16379 16380 if ( this.options.disabled ) { 16381 this._disable(); 16382 } 16383 16384 // Append the aria-live region so tooltips announce correctly 16385 this.liveRegion = $( "<div>" ) 16386 .attr({ 16387 role: "log", 16388 "aria-live": "assertive", 16389 "aria-relevant": "additions" 16390 }) 16391 .addClass( "ui-helper-hidden-accessible" ) 16392 .appendTo( this.document[ 0 ].body ); 16393 }, 16394 16395 _setOption: function( key, value ) { 16396 var that = this; 16397 16398 if ( key === "disabled" ) { 16399 this[ value ? "_disable" : "_enable" ](); 16400 this.options[ key ] = value; 16401 // disable element style changes 16402 return; 16403 } 16404 16405 this._super( key, value ); 16406 16407 if ( key === "content" ) { 16408 $.each( this.tooltips, function( id, element ) { 16409 that._updateContent( element ); 16410 }); 16411 } 16412 }, 16413 16414 _disable: function() { 16415 var that = this; 16416 16417 // close open tooltips 16418 $.each( this.tooltips, function( id, element ) { 16419 var event = $.Event( "blur" ); 16420 event.target = event.currentTarget = element[0]; 16421 that.close( event, true ); 16422 }); 16423 16424 // remove title attributes to prevent native tooltips 16425 this.element.find( this.options.items ).addBack().each(function() { 16426 var element = $( this ); 16427 if ( element.is( "[title]" ) ) { 16428 element 16429 .data( "ui-tooltip-title", element.attr( "title" ) ) 16430 .removeAttr( "title" ); 16431 } 16432 }); 16433 }, 16434 16435 _enable: function() { 16436 // restore title attributes 16437 this.element.find( this.options.items ).addBack().each(function() { 16438 var element = $( this ); 16439 if ( element.data( "ui-tooltip-title" ) ) { 16440 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16441 } 16442 }); 16443 }, 16444 16445 open: function( event ) { 16446 var that = this, 16447 target = $( event ? event.target : this.element ) 16448 // we need closest here due to mouseover bubbling, 16449 // but always pointing at the same event target 16450 .closest( this.options.items ); 16451 16452 // No element to show a tooltip for or the tooltip is already open 16453 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 16454 return; 16455 } 16456 16457 if ( target.attr( "title" ) ) { 16458 target.data( "ui-tooltip-title", target.attr( "title" ) ); 16459 } 16460 16461 target.data( "ui-tooltip-open", true ); 16462 16463 // kill parent tooltips, custom or native, for hover 16464 if ( event && event.type === "mouseover" ) { 16465 target.parents().each(function() { 16466 var parent = $( this ), 16467 blurEvent; 16468 if ( parent.data( "ui-tooltip-open" ) ) { 16469 blurEvent = $.Event( "blur" ); 16470 blurEvent.target = blurEvent.currentTarget = this; 16471 that.close( blurEvent, true ); 16472 } 16473 if ( parent.attr( "title" ) ) { 16474 parent.uniqueId(); 16475 that.parents[ this.id ] = { 16476 element: this, 16477 title: parent.attr( "title" ) 16478 }; 16479 parent.attr( "title", "" ); 16480 } 16481 }); 16482 } 16483 16484 this._updateContent( target, event ); 16485 }, 16486 16487 _updateContent: function( target, event ) { 16488 var content, 16489 contentOption = this.options.content, 16490 that = this, 16491 eventType = event ? event.type : null; 16492 16493 if ( typeof contentOption === "string" ) { 16494 return this._open( event, target, contentOption ); 16495 } 16496 16497 content = contentOption.call( target[0], function( response ) { 16498 // ignore async response if tooltip was closed already 16499 if ( !target.data( "ui-tooltip-open" ) ) { 16500 return; 16501 } 16502 // IE may instantly serve a cached response for ajax requests 16503 // delay this call to _open so the other call to _open runs first 16504 that._delay(function() { 16505 // jQuery creates a special event for focusin when it doesn't 16506 // exist natively. To improve performance, the native event 16507 // object is reused and the type is changed. Therefore, we can't 16508 // rely on the type being correct after the event finished 16509 // bubbling, so we set it back to the previous value. (#8740) 16510 if ( event ) { 16511 event.type = eventType; 16512 } 16513 this._open( event, target, response ); 16514 }); 16515 }); 16516 if ( content ) { 16517 this._open( event, target, content ); 16518 } 16519 }, 16520 16521 _open: function( event, target, content ) { 16522 var tooltip, events, delayedShow, a11yContent, 16523 positionOption = $.extend( {}, this.options.position ); 16524 16525 if ( !content ) { 16526 return; 16527 } 16528 16529 // Content can be updated multiple times. If the tooltip already 16530 // exists, then just update the content and bail. 16531 tooltip = this._find( target ); 16532 if ( tooltip.length ) { 16533 tooltip.find( ".ui-tooltip-content" ).html( content ); 16534 return; 16535 } 16536 16537 // if we have a title, clear it to prevent the native tooltip 16538 // we have to check first to avoid defining a title if none exists 16539 // (we don't want to cause an element to start matching [title]) 16540 // 16541 // We use removeAttr only for key events, to allow IE to export the correct 16542 // accessible attributes. For mouse events, set to empty string to avoid 16543 // native tooltip showing up (happens only when removing inside mouseover). 16544 if ( target.is( "[title]" ) ) { 16545 if ( event && event.type === "mouseover" ) { 16546 target.attr( "title", "" ); 16547 } else { 16548 target.removeAttr( "title" ); 16549 } 16550 } 16551 16552 tooltip = this._tooltip( target ); 16553 this._addDescribedBy( target, tooltip.attr( "id" ) ); 16554 tooltip.find( ".ui-tooltip-content" ).html( content ); 16555 16556 // Support: Voiceover on OS X, JAWS on IE <= 9 16557 // JAWS announces deletions even when aria-relevant="additions" 16558 // Voiceover will sometimes re-read the entire log region's contents from the beginning 16559 this.liveRegion.children().hide(); 16560 if ( content.clone ) { 16561 a11yContent = content.clone(); 16562 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 16563 } else { 16564 a11yContent = content; 16565 } 16566 $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion ); 16567 16568 function position( event ) { 16569 positionOption.of = event; 16570 if ( tooltip.is( ":hidden" ) ) { 16571 return; 16572 } 16573 tooltip.position( positionOption ); 16574 } 16575 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 16576 this._on( this.document, { 16577 mousemove: position 16578 }); 16579 // trigger once to override element-relative positioning 16580 position( event ); 16581 } else { 16582 tooltip.position( $.extend({ 16583 of: target 16584 }, this.options.position ) ); 16585 } 16586 16587 this.hiding = false; 16588 this.closing = false; 16589 tooltip.hide(); 16590 16591 this._show( tooltip, this.options.show ); 16592 // Handle tracking tooltips that are shown with a delay (#8644). As soon 16593 // as the tooltip is visible, position the tooltip using the most recent 16594 // event. 16595 if ( this.options.show && this.options.show.delay ) { 16596 delayedShow = this.delayedShow = setInterval(function() { 16597 if ( tooltip.is( ":visible" ) ) { 16598 position( positionOption.of ); 16599 clearInterval( delayedShow ); 16600 } 16601 }, $.fx.interval ); 16602 } 16603 16604 this._trigger( "open", event, { tooltip: tooltip } ); 16605 16606 events = { 16607 keyup: function( event ) { 16608 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 16609 var fakeEvent = $.Event(event); 16610 fakeEvent.currentTarget = target[0]; 16611 this.close( fakeEvent, true ); 16612 } 16613 } 16614 }; 16615 16616 // Only bind remove handler for delegated targets. Non-delegated 16617 // tooltips will handle this in destroy. 16618 if ( target[ 0 ] !== this.element[ 0 ] ) { 16619 events.remove = function() { 16620 this._removeTooltip( tooltip ); 16621 }; 16622 } 16623 16624 if ( !event || event.type === "mouseover" ) { 16625 events.mouseleave = "close"; 16626 } 16627 if ( !event || event.type === "focusin" ) { 16628 events.focusout = "close"; 16629 } 16630 this._on( true, target, events ); 16631 }, 16632 16633 close: function( event ) { 16634 var that = this, 16635 target = $( event ? event.currentTarget : this.element ), 16636 tooltip = this._find( target ); 16637 16638 // disabling closes the tooltip, so we need to track when we're closing 16639 // to avoid an infinite loop in case the tooltip becomes disabled on close 16640 if ( this.closing ) { 16641 return; 16642 } 16643 16644 // Clear the interval for delayed tracking tooltips 16645 clearInterval( this.delayedShow ); 16646 16647 // only set title if we had one before (see comment in _open()) 16648 // If the title attribute has changed since open(), don't restore 16649 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 16650 target.attr( "title", target.data( "ui-tooltip-title" ) ); 16651 } 16652 16653 this._removeDescribedBy( target ); 16654 16655 this.hiding = true; 16656 tooltip.stop( true ); 16657 this._hide( tooltip, this.options.hide, function() { 16658 that._removeTooltip( $( this ) ); 16659 this.hiding = false; 16660 this.closing = false; 16661 }); 16662 16663 target.removeData( "ui-tooltip-open" ); 16664 this._off( target, "mouseleave focusout keyup" ); 16665 16666 // Remove 'remove' binding only on delegated targets 16667 if ( target[ 0 ] !== this.element[ 0 ] ) { 16668 this._off( target, "remove" ); 16669 } 16670 this._off( this.document, "mousemove" ); 16671 16672 if ( event && event.type === "mouseleave" ) { 16673 $.each( this.parents, function( id, parent ) { 16674 $( parent.element ).attr( "title", parent.title ); 16675 delete that.parents[ id ]; 16676 }); 16677 } 16678 16679 this.closing = true; 16680 this._trigger( "close", event, { tooltip: tooltip } ); 16681 if ( !this.hiding ) { 16682 this.closing = false; 16683 } 16684 }, 16685 16686 _tooltip: function( element ) { 16687 var tooltip = $( "<div>" ) 16688 .attr( "role", "tooltip" ) 16689 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 16690 ( this.options.tooltipClass || "" ) ), 16691 id = tooltip.uniqueId().attr( "id" ); 16692 16693 $( "<div>" ) 16694 .addClass( "ui-tooltip-content" ) 16695 .appendTo( tooltip ); 16696 16697 tooltip.appendTo( this.document[0].body ); 16698 this.tooltips[ id ] = element; 16699 return tooltip; 16700 }, 16701 16702 _find: function( target ) { 16703 var id = target.data( "ui-tooltip-id" ); 16704 return id ? $( "#" + id ) : $(); 16705 }, 16706 16707 _removeTooltip: function( tooltip ) { 16708 tooltip.remove(); 16709 delete this.tooltips[ tooltip.attr( "id" ) ]; 16710 }, 16711 16712 _destroy: function() { 16713 var that = this; 16714 16715 // close open tooltips 16716 $.each( this.tooltips, function( id, element ) { 16717 // Delegate to close method to handle common cleanup 16718 var event = $.Event( "blur" ); 16719 event.target = event.currentTarget = element[0]; 16720 that.close( event, true ); 16721 16722 // Remove immediately; destroying an open tooltip doesn't use the 16723 // hide animation 16724 $( "#" + id ).remove(); 16725 16726 // Restore the title 16727 if ( element.data( "ui-tooltip-title" ) ) { 16728 // If the title attribute has changed since open(), don't restore 16729 if ( !element.attr( "title" ) ) { 16730 element.attr( "title", element.data( "ui-tooltip-title" ) ); 16731 } 16732 element.removeData( "ui-tooltip-title" ); 16733 } 16734 }); 16735 this.liveRegion.remove(); 16736 } 16737}); 16738 16739 16740 16741}));
16741; 16742/* English/UK initialisation for the jQuery UI date picker plugin. */ 16743/* Written by Stuart. */ 16744jQuery(function($){ 16745 $.datepicker.regional['en-GB'] = { 16746 closeText: 'Done', 16747 prevText: 'Prev', 16748 nextText: 'Next', 16749 currentText: 'Today', 16750 monthNames: ['January','February','March','April','May','June', 16751 'July','August','September','October','November','December'], 16752 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 16753 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 16754 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 16755 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 16756 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], 16757 weekHeader: 'Wk', 16758 dateFormat: 'dd/mm/yy', 16759 firstDay: 1, 16760 isRTL: false, 16761 showMonthAfterYear: false, 16762 yearSuffix: ''}; 16763 $.datepicker.setDefaults($.datepicker.regional['en-GB']); 16764}); 16765; 16766/** 16767 * Owl carousel 16768 * @version 2.0.0 16769 * @author Bartosz Wojciechowski 16770 * @license The MIT License (MIT) 16771 * @todo Lazy Load Icon 16772 * @todo prevent animationend bubling 16773 * @todo itemsScaleUp 16774 * @todo Test Zepto 16775 * @todo stagePadding calculate wrong active classes 16776 */ 16777;(function($, window, document, undefined) { 16778 16779 var drag, state, e; 16780 16781 /** 16782 * Template for status information about drag and touch events. 16783 * @private 16784 */ 16785 drag = { 16786 start: 0, 16787 startX: 0, 16788 startY: 0, 16789 current: 0, 16790 currentX: 0, 16791 currentY: 0, 16792 offsetX: 0, 16793 offsetY: 0, 16794 distance: null, 16795 startTime: 0, 16796 endTime: 0, 16797 updatedX: 0, 16798 targetEl: null 16799 }; 16800 16801 /** 16802 * Template for some status informations. 16803 * @private 16804 */ 16805 state = { 16806 isTouch: false, 16807 isScrolling: false, 16808 isSwiping: false, 16809 direction: false, 16810 inMotion: false 16811 }; 16812 16813 /** 16814 * Event functions references. 16815 * @private 16816 */ 16817 e = { 16818 _onDragStart: null, 16819 _onDragMove: null, 16820 _onDragEnd: null, 16821 _transitionEnd: null, 16822 _resizer: null, 16823 _responsiveCall: null, 16824 _goToLoop: null, 16825 _checkVisibile: null 16826 }; 16827 16828 /** 16829 * Creates a carousel. 16830 * @class The Owl Carousel. 16831 * @public 16832 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 16833 * @param {Object} [options] - The options 16834 */ 16835 function Owl(element, options) { 16836 16837 /** 16838 * Current settings for the carousel. 16839 * @public 16840 */ 16841 this.settings = null; 16842 16843 /** 16844 * Current options set by the caller including defaults. 16845 * @public 16846 */ 16847 this.options = $.extend({}, Owl.Defaults, options); 16848 16849 /** 16850 * Plugin element. 16851 * @public 16852 */ 16853 this.$element = $(element); 16854 16855 /** 16856 * Caches informations about drag and touch events. 16857 */ 16858 this.drag = $.extend({}, drag); 16859 16860 /** 16861 * Caches some status informations. 16862 * @protected 16863 */ 16864 this.state = $.extend({}, state); 16865 16866 /** 16867 * @protected 16868 * @todo Must be documented 16869 */ 16870 this.e = $.extend({}, e); 16871 16872 /** 16873 * References to the running plugins of this carousel. 16874 * @protected 16875 */ 16876 this._plugins = {}; 16877 16878 /** 16879 * Currently suppressed events to prevent them from beeing retriggered. 16880 * @protected 16881 */ 16882 this._supress = {}; 16883 16884 /** 16885 * Absolute current position. 16886 * @protected 16887 */ 16888 this._current = null; 16889 16890 /** 16891 * Animation speed in milliseconds. 16892 * @protected 16893 */ 16894 this._speed = null; 16895 16896 /** 16897 * Coordinates of all items in pixel. 16898 * @todo The name of this member is missleading. 16899 * @protected 16900 */ 16901 this._coordinates = []; 16902 16903 /** 16904 * Current breakpoint. 16905 * @todo Real media queries would be nice. 16906 * @protected 16907 */ 16908 this._breakpoint = null; 16909 16910 /** 16911 * Current width of the plugin element. 16912 */ 16913 this._width = null; 16914 16915 /** 16916 * All real items. 16917 * @protected 16918 */ 16919 this._items = []; 16920 16921 /** 16922 * All cloned items. 16923 * @protected 16924 */ 16925 this._clones = []; 16926 16927 /** 16928 * Merge values of all items. 16929 * @todo Maybe this could be part of a plugin. 16930 * @protected 16931 */ 16932 this._mergers = []; 16933 16934 /** 16935 * Invalidated parts within the update process. 16936 * @protected 16937 */ 16938 this._invalidated = {}; 16939 16940 /** 16941 * Ordered list of workers for the update process. 16942 * @protected 16943 */ 16944 this._pipe = []; 16945 16946 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 16947 this._plugins[key[0].toLowerCase() + key.slice(1)] 16948 = new plugin(this); 16949 }, this)); 16950 16951 $.each(Owl.Pipe, $.proxy(function(priority, worker) { 16952 this._pipe.push({ 16953 'filter': worker.filter, 16954 'run': $.proxy(worker.run, this) 16955 }); 16956 }, this)); 16957 16958 this.setup(); 16959 this.initialize(); 16960 } 16961 16962 /** 16963 * Default options for the carousel. 16964 * @public 16965 */ 16966 Owl.Defaults = { 16967 items: 3, 16968 loop: false, 16969 center: false, 16970
16971 mouseDrag: true, 16972 touchDrag: true, 16973 pullDrag: true, 16974 freeDrag: false, 16975 16976 margin: 0, 16977 stagePadding: 0, 16978 16979 merge: false, 16980 mergeFit: true, 16981 autoWidth: false, 16982 16983 startPosition: 0, 16984 rtl: false, 16985 16986 smartSpeed: 250, 16987 fluidSpeed: false, 16988 dragEndSpeed: false, 16989 16990 responsive: {}, 16991 responsiveRefreshRate: 200, 16992 responsiveBaseElement: window, 16993 responsiveClass: false, 16994 16995 fallbackEasing: 'swing', 16996 16997 info: false, 16998 16999 nestedItemSelector: false, 17000 itemElement: 'div', 17001 stageElement: 'div', 17002 17003 // Classes and Names 17004 themeClass: 'owl-theme', 17005 baseClass: 'owl-carousel', 17006 itemClass: 'owl-item', 17007 centerClass: 'center', 17008 activeClass: 'active' 17009 }; 17010 17011 /** 17012 * Enumeration for width. 17013 * @public 17014 * @readonly 17015 * @enum {String} 17016 */ 17017 Owl.Width = { 17018 Default: 'default', 17019 Inner: 'inner', 17020 Outer: 'outer' 17021 }; 17022 17023 /** 17024 * Contains all registered plugins. 17025 * @public 17026 */ 17027 Owl.Plugins = {}; 17028 17029 /** 17030 * Update pipe. 17031 */ 17032 Owl.Pipe = [ { 17033 filter: [ 'width', 'items', 'settings' ], 17034 run: function(cache) { 17035 cache.current = this._items && this._items[this.relative(this._current)]; 17036 } 17037 }, { 17038 filter: [ 'items', 'settings' ], 17039 run: function() { 17040 var cached = this._clones, 17041 clones = this.$stage.children('.cloned'); 17042 17043 if (clones.length !== cached.length || (!this.settings.loop && cached.length > 0)) { 17044 this.$stage.children('.cloned').remove(); 17045 this._clones = []; 17046 } 17047 } 17048 }, { 17049 filter: [ 'items', 'settings' ], 17050 run: function() { 17051 var i, n, 17052 clones = this._clones, 17053 items = this._items, 17054 delta = this.settings.loop ? clones.length - Math.max(this.settings.items * 2, 4) : 0; 17055 17056 for (i = 0, n = Math.abs(delta / 2); i < n; i++) { 17057 if (delta > 0) { 17058 this.$stage.children().eq(items.length + clones.length - 1).remove(); 17059 clones.pop(); 17060 this.$stage.children().eq(0).remove(); 17061 clones.pop(); 17062 } else { 17063 clones.push(clones.length / 2); 17064 this.$stage.append(items[clones[clones.length - 1]].clone().addClass('cloned')); 17065 clones.push(items.length - 1 - (clones.length - 1) / 2); 17066 this.$stage.prepend(items[clones[clones.length - 1]].clone().addClass('cloned')); 17067 } 17068 } 17069 } 17070 }, { 17071 filter: [ 'width', 'items', 'settings' ], 17072 run: function() { 17073 var rtl = (this.settings.rtl ? 1 : -1), 17074 width = (this.width() / this.settings.items).toFixed(3), 17075 coordinate = 0, merge, i, n; 17076 17077 this._coordinates = []; 17078 for (i = 0, n = this._clones.length + this._items.length; i < n; i++) { 17079 merge = this._mergers[this.relative(i)]; 17080 merge = (this.settings.mergeFit && Math.min(merge, this.settings.items)) || merge; 17081 coordinate += (this.settings.autoWidth ? this._items[this.relative(i)].width() + this.settings.margin : width * merge) * rtl; 17082 17083 this._coordinates.push(coordinate); 17084 } 17085 } 17086 }, { 17087 filter: [ 'width', 'items', 'settings' ], 17088 run: function() { 17089 var i, n, width = (this.width() / this.settings.items).toFixed(3), css = { 17090 'width': Math.abs(this._coordinates[this._coordinates.length - 1]) + this.settings.stagePadding * 2, 17091 'padding-left': this.settings.stagePadding || '', 17092 'padding-right': this.settings.stagePadding || '' 17093 }; 17094 17095 this.$stage.css(css); 17096 17097 css = { 'width': this.settings.autoWidth ? 'auto' : width - this.settings.margin }; 17098 css[this.settings.rtl ? 'margin-left' : 'margin-right'] = this.settings.margin; 17099 17100 if (!this.settings.autoWidth && $.grep(this._mergers, function(v) { return v > 1 }).length > 0) { 17101 for (i = 0, n = this._coordinates.length; i < n; i++) { 17102 css.width = Math.abs(this._coordinates[i]) - Math.abs(this._coordinates[i - 1] || 0) - this.settings.margin; 17103 this.$stage.children().eq(i).css(css); 17104 } 17105 } else { 17106 this.$stage.children().css(css); 17107 } 17108 } 17109 }, { 17110 filter: [ 'width', 'items', 'settings' ], 17111 run: function(cache) { 17112 cache.current && this.reset(this.$stage.children().index(cache.current)); 17113 } 17114 }, { 17115 filter: [ 'position' ], 17116 run: function() { 17117 this.animate(this.coordinates(this._current)); 17118 } 17119 }, { 17120 filter: [ 'width', 'position', 'items', 'settings' ], 17121 run: function() { 17122 var rtl = this.settings.rtl ? 1 : -1, 17123 padding = this.settings.stagePadding * 2, 17124 begin = this.coordinates(this.current()) + padding, 17125 end = begin + this.width() * rtl, 17126 inner, outer, matches = [], i, n; 17127 17128 for (i = 0, n = this._coordinates.length; i < n; i++) { 17129 inner = this._coordinates[i - 1] || 0; 17130 outer = Math.abs(this._coordinates[i]) + padding * rtl; 17131 17132 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 17133 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 17134 matches.push(i); 17135 } 17136 } 17137 17138 this.$stage.children('.' + this.settings.activeClass).removeClass(this.settings.activeClass); 17139 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass(this.settings.activeClass); 17140 17141 if (this.settings.center) { 17142 this.$stage.children('.' + this.settings.centerClass).removeClass(this.settings.centerClass); 17143 this.$stage.children().eq(this.current()).addClass(this.settings.centerClass); 17144 } 17145 } 17146 } ]; 17147 17148 /** 17149 * Initializes the carousel. 17150 * @protected 17151 */ 17152 Owl.prototype.initialize = function() { 17153 this.trigger('initialize'); 17154 17155 this.$element 17156 .addClass(this.settings.baseClass) 17157 .addClass(this.settings.themeClass) 17158 .toggleClass('owl-rtl', this.settings.rtl); 17159 17160 // check support 17161 this.browserSupport(); 17162 17163 if (this.settings.autoWidth && this.state.imagesLoaded !== true) { 17164 var imgs, nestedSelector, width; 17165 imgs = this.$element.find('img'); 17166 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 17167 width = this.$element.children(nestedSelector).width(); 17168 17169 if (imgs.length && width <= 0) { 17170 this.preloadAutoWidthImages(imgs); 17171 return false; 17172 } 17173 } 17174 17175 this.$element.addClass('owl-loading'); 17176 17177 // create stage 17178 this.$stage = $('<' + this.settings.stageElement + ' class="owl-stage"/>') 17179 .wrap('<div class="owl-stage-outer">'); 17180 17181 // append stage 17182 this.$element.append(this.$stage.parent()); 17183 17184 // append content 17185 this.replace(this.$element.children().not(this.$stage.parent())); 17186 17187 // set view width 17188 this._width = this.$element.width(); 17189 17190 // update view 17191 this.refresh();
17192 17193 this.$element.removeClass('owl-loading').addClass('owl-loaded'); 17194 17195 // attach generic events 17196 this.eventsCall(); 17197 17198 // attach generic events 17199 this.internalEvents(); 17200 17201 // attach custom control events 17202 this.addTriggerableEvents(); 17203 17204 this.trigger('initialized'); 17205 }; 17206 17207 /** 17208 * Setups the current settings. 17209 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 17210 * @todo Support for media queries by using `matchMedia` would be nice. 17211 * @public 17212 */ 17213 Owl.prototype.setup = function() { 17214 var viewport = this.viewport(), 17215 overwrites = this.options.responsive, 17216 match = -1, 17217 settings = null; 17218 17219 if (!overwrites) { 17220 settings = $.extend({}, this.options); 17221 } else { 17222 $.each(overwrites, function(breakpoint) { 17223 if (breakpoint <= viewport && breakpoint > match) { 17224 match = Number(breakpoint); 17225 } 17226 }); 17227 17228 settings = $.extend({}, this.options, overwrites[match]); 17229 delete settings.responsive; 17230 17231 // responsive class 17232 if (settings.responsiveClass) { 17233 this.$element.attr('class', function(i, c) { 17234 return c.replace(/\b owl-responsive-\S+/g, ''); 17235 }).addClass('owl-responsive-' + match); 17236 } 17237 } 17238 17239 if (this.settings === null || this._breakpoint !== match) { 17240 this.trigger('change', { property: { name: 'settings', value: settings } }); 17241 this._breakpoint = match; 17242 this.settings = settings; 17243 this.invalidate('settings'); 17244 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 17245 } 17246 }; 17247 17248 /** 17249 * Updates option logic if necessery. 17250 * @protected 17251 */ 17252 Owl.prototype.optionsLogic = function() { 17253 // Toggle Center class 17254 this.$element.toggleClass('owl-center', this.settings.center); 17255 17256 // if items number is less than in body 17257 if (this.settings.loop && this._items.length < this.settings.items) { 17258 this.settings.loop = false; 17259 } 17260 17261 if (this.settings.autoWidth) { 17262 this.settings.stagePadding = false; 17263 this.settings.merge = false; 17264 } 17265 }; 17266 17267 /** 17268 * Prepares an item before add. 17269 * @todo Rename event parameter `content` to `item`. 17270 * @protected 17271 * @returns {jQuery|HTMLElement} - The item container. 17272 */ 17273 Owl.prototype.prepare = function(item) { 17274 var event = this.trigger('prepare', { content: item }); 17275 17276 if (!event.data) { 17277 event.data = $('<' + this.settings.itemElement + '/>') 17278 .addClass(this.settings.itemClass).append(item) 17279 } 17280 17281 this.trigger('prepared', { content: event.data }); 17282 17283 return event.data; 17284 }; 17285 17286 /** 17287 * Updates the view. 17288 * @public 17289 */ 17290 Owl.prototype.update = function() { 17291 var i = 0, 17292 n = this._pipe.length, 17293 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 17294 cache = {}; 17295 17296 while (i < n) { 17297 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 17298 this._pipe[i].run(cache); 17299 } 17300 i++; 17301 } 17302 17303 this._invalidated = {}; 17304 }; 17305 17306 /** 17307 * Gets the width of the view. 17308 * @public 17309 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 17310 * @returns {Number} - The width of the view in pixel. 17311 */ 17312 Owl.prototype.width = function(dimension) { 17313 dimension = dimension || Owl.Width.Default; 17314 switch (dimension) { 17315 case Owl.Width.Inner: 17316 case Owl.Width.Outer: 17317 return this._width; 17318 default: 17319 return this._width - this.settings.stagePadding * 2 + this.settings.margin; 17320 } 17321 }; 17322 17323 /** 17324 * Refreshes the carousel primarily for adaptive purposes. 17325 * @public 17326 */ 17327 Owl.prototype.refresh = function() { 17328 if (this._items.length === 0) { 17329 return false; 17330 } 17331 17332 var start = new Date().getTime(); 17333 17334 this.trigger('refresh'); 17335 17336 this.setup(); 17337 17338 this.optionsLogic(); 17339 17340 // hide and show methods helps here to set a proper widths, 17341 // this prevents scrollbar to be calculated in stage width 17342 this.$stage.addClass('owl-refresh'); 17343 17344 this.update(); 17345 17346 this.$stage.removeClass('owl-refresh'); 17347 17348 this.state.orientation = window.orientation; 17349 17350 this.watchVisibility(); 17351 17352 this.trigger('refreshed'); 17353 }; 17354 17355 /** 17356 * Save internal event references and add event based functions. 17357 * @protected 17358 */ 17359 Owl.prototype.eventsCall = function() { 17360 // Save events references 17361 this.e._onDragStart = $.proxy(function(e) { 17362 this.onDragStart(e); 17363 }, this); 17364 this.e._onDragMove = $.proxy(function(e) { 17365 this.onDragMove(e); 17366 }, this); 17367 this.e._onDragEnd = $.proxy(function(e) { 17368 this.onDragEnd(e); 17369 }, this); 17370 this.e._onResize = $.proxy(function(e) { 17371 this.onResize(e); 17372 }, this); 17373 this.e._transitionEnd = $.proxy(function(e) { 17374 this.transitionEnd(e); 17375 }, this); 17376 this.e._preventClick = $.proxy(function(e) { 17377 this.preventClick(e); 17378 }, this); 17379 }; 17380 17381 /** 17382 * Checks window `resize` event. 17383 * @protected 17384 */ 17385 Owl.prototype.onThrottledResize = function() { 17386 window.clearTimeout(this.resizeTimer); 17387 this.resizeTimer = window.setTimeout(this.e._onResize, this.settings.responsiveRefreshRate); 17388 }; 17389 17390 /** 17391 * Checks window `resize` event. 17392 * @protected 17393 */ 17394 Owl.prototype.onResize = function() { 17395 if (!this._items.length) { 17396 return false; 17397 } 17398 17399 if (this._width === this.$element.width()) { 17400 return false; 17401 } 17402 17403 if (this.trigger('resize').isDefaultPrevented()) { 17404 return false; 17405 } 17406 17407 this._width = this.$element.width(); 17408 17409 this.invalidate('width'); 17410 17411 this.refresh();
17412 17413 this.trigger('resized'); 17414 }; 17415 17416 /** 17417 * Checks for touch/mouse drag event type and add run event handlers. 17418 * @protected 17419 */ 17420 Owl.prototype.eventsRouter = function(event) { 17421 var type = event.type; 17422 17423 if (type === "mousedown" || type === "touchstart") { 17424 this.onDragStart(event); 17425 } else if (type === "mousemove" || type === "touchmove") { 17426 this.onDragMove(event); 17427 } else if (type === "mouseup" || type === "touchend") { 17428 this.onDragEnd(event); 17429 } else if (type === "touchcancel") { 17430 this.onDragEnd(event); 17431 } 17432 }; 17433 17434 /** 17435 * Checks for touch/mouse drag options and add necessery event handlers. 17436 * @protected 17437 */ 17438 Owl.prototype.internalEvents = function() { 17439 var isTouch = isTouchSupport(), 17440 isTouchIE = isTouchSupportIE(); 17441 17442 if (this.settings.mouseDrag){ 17443 this.$stage.on('mousedown', $.proxy(function(event) { this.eventsRouter(event) }, this)); 17444 this.$stage.on('dragstart', function() { return false }); 17445 this.$stage.get(0).onselectstart = function() { return false }; 17446 } else { 17447 this.$element.addClass('owl-text-select-on'); 17448 } 17449 17450 if (this.settings.touchDrag && !isTouchIE){ 17451 this.$stage.on('touchstart touchcancel', $.proxy(function(event) { this.eventsRouter(event) }, this)); 17452 } 17453 17454 // catch transitionEnd event 17455 if (this.transitionEndVendor) { 17456 this.on(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd, false); 17457 } 17458 17459 // responsive 17460 if (this.settings.responsive !== false) { 17461 this.on(window, 'resize', $.proxy(this.onThrottledResize, this)); 17462 } 17463 }; 17464 17465 /** 17466 * Handles touchstart/mousedown event. 17467 * @protected 17468 * @param {Event} event - The event arguments. 17469 */ 17470 Owl.prototype.onDragStart = function(event) { 17471 var ev, isTouchEvent, pageX, pageY, animatedPos; 17472 17473 ev = event.originalEvent || event || window.event; 17474 17475 // prevent right click 17476 if (ev.which === 3 || this.state.isTouch) { 17477 return false; 17478 } 17479 17480 if (ev.type === 'mousedown') { 17481 this.$stage.addClass('owl-grab'); 17482 } 17483 17484 this.trigger('drag'); 17485 this.drag.startTime = new Date().getTime(); 17486 this.speed(0); 17487 this.state.isTouch = true; 17488 this.state.isScrolling = false; 17489 this.state.isSwiping = false; 17490 this.drag.distance = 0; 17491 17492 pageX = getTouches(ev).x; 17493 pageY = getTouches(ev).y; 17494 17495 // get stage position left 17496 this.drag.offsetX = this.$stage.position().left; 17497 this.drag.offsetY = this.$stage.position().top; 17498 17499 if (this.settings.rtl) { 17500 this.drag.offsetX = this.$stage.position().left + this.$stage.width() - this.width() 17501 + this.settings.margin; 17502 } 17503 17504 // catch position // ie to fix 17505 if (this.state.inMotion && this.support3d) { 17506 animatedPos = this.getTransformProperty(); 17507 this.drag.offsetX = animatedPos; 17508 this.animate(animatedPos); 17509 this.state.inMotion = true; 17510 } else if (this.state.inMotion && !this.support3d) { 17511 this.state.inMotion = false; 17512 return false; 17513 } 17514 17515 this.drag.startX = pageX - this.drag.offsetX; 17516 this.drag.startY = pageY - this.drag.offsetY; 17517 17518 this.drag.start = pageX - this.drag.startX; 17519 this.drag.targetEl = ev.target || ev.srcElement; 17520 this.drag.updatedX = this.drag.start; 17521 17522 // to do/check 17523 // prevent links and images dragging; 17524 if (this.drag.targetEl.tagName === "IMG" || this.drag.targetEl.tagName === "A") { 17525 this.drag.targetEl.draggable = false; 17526 } 17527 17528 $(document).on('mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents', $.proxy(function(event) {this.eventsRouter(event)},this)); 17529 }; 17530 17531 /** 17532 * Handles the touchmove/mousemove events. 17533 * @todo Simplify 17534 * @protected 17535 * @param {Event} event - The event arguments. 17536 */ 17537 Owl.prototype.onDragMove = function(event) { 17538 var ev, isTouchEvent, pageX, pageY, minValue, maxValue, pull; 17539 17540 if (!this.state.isTouch) { 17541 return; 17542 } 17543 17544 if (this.state.isScrolling) { 17545 return; 17546 } 17547 17548 ev = event.originalEvent || event || window.event; 17549 17550 pageX = getTouches(ev).x; 17551 pageY = getTouches(ev).y; 17552 17553 // Drag Direction 17554 this.drag.currentX = pageX - this.drag.startX; 17555 this.drag.currentY = pageY - this.drag.startY; 17556 this.drag.distance = this.drag.currentX - this.drag.offsetX; 17557 17558 // Check move direction 17559 if (this.drag.distance < 0) { 17560 this.state.direction = this.settings.rtl ? 'right' : 'left'; 17561 } else if (this.drag.distance > 0) { 17562 this.state.direction = this.settings.rtl ? 'left' : 'right'; 17563 } 17564 // Loop 17565 if (this.settings.loop) { 17566 if (this.op(this.drag.currentX, '>', this.coordinates(this.minimum())) && this.state.direction === 'right') { 17567 this.drag.currentX -= (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length); 17568 } else if (this.op(this.drag.currentX, '<', this.coordinates(this.maximum())) && this.state.direction === 'left') { 17569 this.drag.currentX += (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length); 17570 } 17571 } else { 17572 // pull 17573 minValue = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 17574 maxValue = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 17575 pull = this.settings.pullDrag ? this.drag.distance / 5 : 0; 17576 this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull); 17577 } 17578 17579 // Lock browser if swiping horizontal 17580 17581 if ((this.drag.distance > 8 || this.drag.distance < -8)) { 17582 if (ev.preventDefault !== undefined) { 17583 ev.preventDefault(); 17584 } else { 17585 ev.returnValue = false; 17586 } 17587 this.state.isSwiping = true; 17588 } 17589 17590 this.drag.updatedX = this.drag.currentX; 17591 17592 // Lock Owl if scrolling 17593 if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) { 17594 this.state.isScrolling = true; 17595 this.drag.updatedX = this.drag.start; 17596 } 17597 17598 this.animate(this.drag.updatedX); 17599 }; 17600 17601 /** 17602 * Handles the touchend/mouseup events. 17603 * @protected 17604 */ 17605 Owl.prototype.onDragEnd = function(event) { 17606 var compareTimes, distanceAbs, closest; 17607 17608 if (!this.state.isTouch) { 17609 return; 17610 } 17611 17612 if (event.type === 'mouseup') { 17613 this.$stage.removeClass('owl-grab'); 17614 } 17615 17616 this.trigger('dragged'); 17617 17618 // prevent links and images dragging; 17619 this.drag.targetEl.removeAttribute("draggable"); 17620 17621 // remove drag event listeners 17622 17623 this.state.isTouch = false; 17624 this.state.isScrolling = false; 17625 this.state.isSwiping = false; 17626 17627 // to check 17628 if (this.drag.distance === 0 && this.state.inMotion !== true) { 17629 this.state.inMotion = false; 17630 return false; 17631 } 17632 17633 // prevent clicks while scrolling 17634 17635 this.drag.endTime = new Date().getTime(); 17636 compareTimes = this.drag.endTime - this.drag.startTime; 17637 distanceAbs = Math.abs(this.drag.distance); 17638 17639 // to test 17640 if (distanceAbs > 3 || compareTimes > 300) { 17641 this.removeClick(this.drag.targetEl); 17642 } 17643 17644 closest = this.closest(this.drag.updatedX); 17645 17646 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 17647 this.current(closest); 17648 this.invalidate('position'); 17649 this.update(); 17650 17651 // if pullDrag is off then fire transitionEnd event manually when stick 17652 // to border 17653 if (!this.settings.pullDrag && this.drag.updatedX === this.coordinates(closest)) { 17654 this.transitionEnd(); 17655 } 17656 17657 this.drag.distance = 0; 17658 17659 $(document).off('.owl.dragEvents'); 17660 }; 17661 17662 /** 17663 * Attaches `preventClick` to disable link while swipping. 17664 * @protected 17665 * @param {HTMLElement} [target] - The target of the `click` event. 17666 */ 17667 Owl.prototype.removeClick = function(target) { 17668 this.drag.targetEl = target; 17669 $(target).on('click.preventClick', this.e._preventClick); 17670 // to make sure click is removed: 17671 window.setTimeout(function() { 17672 $(target).off('click.preventClick'); 17673 }, 300); 17674 }; 17675 17676 /** 17677 * Suppresses click event. 17678 * @protected 17679 * @param {Event} ev - The event arguments. 17680 */ 17681 Owl.prototype.preventClick = function(ev) { 17682 if (ev.preventDefault) { 17683 ev.preventDefault(); 17684 } else { 17685 ev.returnValue = false; 17686 } 17687 if (ev.stopPropagation) { 17688 ev.stopPropagation(); 17689 } 17690 $(ev.target).off('click.preventClick'); 17691 }; 17692 17693 /** 17694 * Catches stage position while animate (only CSS3). 17695 * @protected 17696 * @returns 17697 */ 17698 Owl.prototype.getTransformProperty = function() { 17699 var transform, matrix3d; 17700 17701 transform = window.getComputedStyle(this.$stage.get(0), null).getPropertyValue(this.vendorName + 'transform'); 17702 // var transform = this.$stage.css(this.vendorName + 'transform') 17703 transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(','); 17704 matrix3d = transform.length === 16; 17705 17706 return matrix3d !== true ? transform[4] : transform[12]; 17707 }; 17708 17709 /** 17710 * Gets absolute position of the closest item for a coordinate. 17711 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 17712 * @protected 17713 * @param {Number} coordinate - The coordinate in pixel. 17714 * @return {Number} - The absolute position of the closest item. 17715 */ 17716 Owl.prototype.closest = function(coordinate) { 17717 var position = -1, pull = 30, width = this.width(), coordinates = this.coordinates();
17718 17719 if (!this.settings.freeDrag) { 17720 // check closest item 17721 $.each(coordinates, $.proxy(function(index, value) { 17722 if (coordinate > value - pull && coordinate < value + pull) { 17723 position = index; 17724 } else if (this.op(coordinate, '<', value) 17725 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 17726 position = this.state.direction === 'left' ? index + 1 : index; 17727 } 17728 return position === -1; 17729 }, this)); 17730 } 17731 17732 if (!this.settings.loop) { 17733 // non loop boundries 17734 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 17735 position = coordinate = this.minimum(); 17736 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 17737 position = coordinate = this.maximum(); 17738 } 17739 } 17740 17741 return position; 17742 }; 17743 17744 /** 17745 * Animates the stage. 17746 * @public 17747 * @param {Number} coordinate - The coordinate in pixels. 17748 */ 17749 Owl.prototype.animate = function(coordinate) { 17750 this.trigger('translate'); 17751 this.state.inMotion = this.speed() > 0; 17752 17753 if (this.support3d) { 17754 this.$stage.css({ 17755 transform: 'translate3d(' + coordinate + 'px' + ',0px, 0px)', 17756 transition: (this.speed() / 1000) + 's' 17757 }); 17758 } else if (this.state.isTouch) { 17759 this.$stage.css({ 17760 left: coordinate + 'px' 17761 }); 17762 } else { 17763 this.$stage.animate({ 17764 left: coordinate 17765 }, this.speed() / 1000, this.settings.fallbackEasing, $.proxy(function() { 17766 if (this.state.inMotion) { 17767 this.transitionEnd(); 17768 } 17769 }, this)); 17770 } 17771 }; 17772 17773 /** 17774 * Sets the absolute position of the current item. 17775 * @public 17776 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 17777 * @returns {Number} - The absolute position of the current item. 17778 */ 17779 Owl.prototype.current = function(position) { 17780 if (position === undefined) { 17781 return this._current; 17782 } 17783 17784 if (this._items.length === 0) { 17785 return undefined; 17786 } 17787 17788 position = this.normalize(position); 17789 17790 if (this._current !== position) { 17791 var event = this.trigger('change', { property: { name: 'position', value: position } }); 17792 17793 if (event.data !== undefined) { 17794 position = this.normalize(event.data); 17795 } 17796 17797 this._current = position; 17798 17799 this.invalidate('position'); 17800 17801 this.trigger('changed', { property: { name: 'position', value: this._current } }); 17802 } 17803 17804 return this._current; 17805 }; 17806 17807 /** 17808 * Invalidates the given part of the update routine. 17809 * @param {String} part - The part to invalidate. 17810 */ 17811 Owl.prototype.invalidate = function(part) { 17812 this._invalidated[part] = true; 17813 } 17814 17815 /** 17816 * Resets the absolute position of the current item. 17817 * @public 17818 * @param {Number} position - The absolute position of the new item. 17819 */ 17820 Owl.prototype.reset = function(position) { 17821 position = this.normalize(position); 17822 17823 if (position === undefined) { 17824 return; 17825 } 17826 17827 this._speed = 0; 17828 this._current = position; 17829 17830 this.suppress([ 'translate', 'translated' ]); 17831 17832 this.animate(this.coordinates(position)); 17833 17834 this.release([ 'translate', 'translated' ]); 17835 }; 17836 17837 /** 17838 * Normalizes an absolute or a relative position for an item. 17839 * @public 17840 * @param {Number} position - The absolute or relative position to normalize. 17841 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 17842 * @returns {Number} - The normalized position. 17843 */ 17844 Owl.prototype.normalize = function(position, relative) { 17845 var n = (relative ? this._items.length : this._items.length + this._clones.length); 17846 17847 if (!$.isNumeric(position) || n < 1) { 17848 return undefined; 17849 } 17850 17851 if (this._clones.length) { 17852 position = ((position % n) + n) % n; 17853 } else { 17854 position = Math.max(this.minimum(relative), Math.min(this.maximum(relative), position)); 17855 } 17856 17857 return position; 17858 17859 17860 17861 }; 17862 17863 /** 17864 * Converts an absolute position for an item into a relative position. 17865 * @public 17866 * @param {Number} position - The absolute position to convert. 17867 * @returns {Number} - The converted position. 17868 */ 17869 Owl.prototype.relative = function(position) { 17870 position = this.normalize(position); 17871 position = position - this._clones.length / 2; 17872 return this.normalize(position, true); 17873 }; 17874 17875 /** 17876 * Gets the maximum position for an item. 17877 * @public 17878 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 17879 * @returns {Number} 17880 */ 17881 Owl.prototype.maximum = function(relative) { 17882 var maximum, width, i = 0, coordinate, 17883 settings = this.settings; 17884 17885 if (relative) { 17886 return this._items.length - 1; 17887 } 17888 17889 if (!settings.loop && settings.center) { 17890 maximum = this._items.length - 1; 17891 }
17891 else if (!settings.loop && !settings.center) { 17892 maximum = this._items.length - settings.items; 17893 } else if (settings.loop || settings.center) { 17894 maximum = this._items.length + settings.items; 17895 } else if (settings.autoWidth || settings.merge) { 17896 revert = settings.rtl ? 1 : -1; 17897 width = this.$stage.width() - this.$element.width(); 17898 while (coordinate = this.coordinates(i)) { 17899 if (coordinate * revert >= width) { 17900 break; 17901 } 17902 maximum = ++i; 17903 } 17904 } else { 17905 throw 'Can not detect maximum absolute position.' 17906 } 17907 17908 return maximum; 17909 }; 17910 17911 /** 17912 * Gets the minimum position for an item. 17913 * @public 17914 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 17915 * @returns {Number} 17916 */ 17917 Owl.prototype.minimum = function(relative) { 17918 if (relative) { 17919 return 0; 17920 } 17921 17922 return this._clones.length / 2; 17923 }; 17924 17925 /** 17926 * Gets an item at the specified relative position. 17927 * @public 17928 * @param {Number} [position] - The relative position of the item. 17929 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 17930 */ 17931 Owl.prototype.items = function(position) { 17932 if (position === undefined) { 17933 return this._items.slice(); 17934 } 17935 17936 position = this.normalize(position, true); 17937 return this._items[position]; 17938 }; 17939 17940 /** 17941 * Gets an item at the specified relative position. 17942 * @public 17943 * @param {Number} [position] - The relative position of the item. 17944 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 17945 */ 17946 Owl.prototype.mergers = function(position) { 17947 if (position === undefined) { 17948 return this._mergers.slice(); 17949 } 17950 17951 position = this.normalize(position, true); 17952 return this._mergers[position]; 17953 }; 17954 17955 /** 17956 * Gets the absolute positions of clones for an item. 17957 * @public 17958 * @param {Number} [position] - The relative position of the item. 17959 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 17960 */ 17961 Owl.prototype.clones = function(position) { 17962 var odd = this._clones.length / 2, 17963 even = odd + this._items.length, 17964 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 17965 17966 if (position === undefined) { 17967 return $.map(this._clones, function(v, i) { return map(i) }); 17968 } 17969 17970 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 17971 }; 17972 17973 /** 17974 * Sets the current animation speed. 17975 * @public 17976 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 17977 * @returns {Number} - The current animation speed in milliseconds. 17978 */ 17979 Owl.prototype.speed = function(speed) { 17980 if (speed !== undefined) { 17981 this._speed = speed; 17982 } 17983 17984 return this._speed; 17985 }; 17986 17987 /** 17988 * Gets the coordinate of an item. 17989 * @todo The name of this method is missleanding. 17990 * @public 17991 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 17992 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 17993 */ 17994 Owl.prototype.coordinates = function(position) { 17995 var coordinate = null; 17996 17997 if (position === undefined) { 17998 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 17999 return this.coordinates(index); 18000 }, this)); 18001 } 18002 18003 if (this.settings.center) { 18004 coordinate = this._coordinates[position]; 18005 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 18006 } else { 18007 coordinate = this._coordinates[position - 1] || 0; 18008 } 18009 18010 return coordinate; 18011 }; 18012 18013 /** 18014 * Calculates the speed for a translation. 18015 * @protected 18016 * @param {Number} from - The absolute position of the start item. 18017 * @param {Number} to - The absolute position of the target item. 18018 * @param {Number} [factor=undefined] - The time factor in milliseconds. 18019 * @returns {Number} - The time in milliseconds for the translation. 18020 */ 18021 Owl.prototype.duration = function(from, to, factor) { 18022 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 18023 }; 18024 18025 /** 18026 * Slides to the specified item. 18027 * @public 18028 * @param {Number} position - The position of the item. 18029 * @param {Number}
18029 [speed] - The time in milliseconds for the transition. 18030 */ 18031 Owl.prototype.to = function(position, speed) { 18032 if (this.settings.loop) { 18033 var distance = position - this.relative(this.current()), 18034 revert = this.current(), 18035 before = this.current(), 18036 after = this.current() + distance, 18037 direction = before - after < 0 ? true : false, 18038 items = this._clones.length + this._items.length; 18039 18040 if (after < this.settings.items && direction === false) { 18041 revert = before + this._items.length; 18042 this.reset(revert); 18043 } else if (after >= items - this.settings.items && direction === true) { 18044 revert = before - this._items.length; 18045 this.reset(revert); 18046 } 18047 window.clearTimeout(this.e._goToLoop); 18048 this.e._goToLoop = window.setTimeout($.proxy(function() { 18049 this.speed(this.duration(this.current(), revert + distance, speed)); 18050 this.current(revert + distance); 18051 this.update(); 18052 }, this), 30); 18053 } else { 18054 this.speed(this.duration(this.current(), position, speed)); 18055 this.current(position); 18056 this.update(); 18057 } 18058 }; 18059 18060 /** 18061 * Slides to the next item. 18062 * @public 18063 * @param {Number} [speed] - The time in milliseconds for the transition. 18064 */ 18065 Owl.prototype.next = function(speed) { 18066 speed = speed || false; 18067 this.to(this.relative(this.current()) + 1, speed); 18068 }; 18069 18070 /** 18071 * Slides to the previous item. 18072 * @public 18073 * @param {Number} [speed] - The time in milliseconds for the transition. 18074 */ 18075 Owl.prototype.prev = function(speed) { 18076 speed = speed || false; 18077 this.to(this.relative(this.current()) - 1, speed); 18078 }; 18079 18080 /** 18081 * Handles the end of an animation. 18082 * @protected 18083 * @param {Event} event - The event arguments. 18084 */ 18085 Owl.prototype.transitionEnd = function(event) { 18086 18087 // if css2 animation then event object is undefined 18088 if (event !== undefined) { 18089 event.stopPropagation(); 18090 18091 // Catch only owl-stage transitionEnd event 18092 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 18093 return false; 18094 } 18095 } 18096 18097 this.state.inMotion = false; 18098 this.trigger('translated'); 18099 }; 18100 18101 /** 18102 * Gets viewport width. 18103 * @protected 18104 * @return {Number} - The width in pixel. 18105 */ 18106 Owl.prototype.viewport = function() { 18107 var width; 18108 if (this.options.responsiveBaseElement !== window) { 18109 width = $(this.options.responsiveBaseElement).width(); 18110 } else if (window.innerWidth) { 18111 width = window.innerWidth; 18112 } else if (document.documentElement && document.documentElement.clientWidth) { 18113 width = document.documentElement.clientWidth; 18114 } else { 18115 throw 'Can not detect viewport width.'; 18116 } 18117 return width; 18118 }; 18119 18120 /** 18121 * Replaces the current content. 18122 * @public 18123 * @param {HTMLElement|jQuery|String} content - The new content. 18124 */ 18125 Owl.prototype.replace = function(content) { 18126 this.$stage.empty(); 18127 this._items = []; 18128 18129 if (content) { 18130 content = (content instanceof jQuery) ? content : $(content); 18131 } 18132 18133 if (this.settings.nestedItemSelector) { 18134 content = content.find('.' + this.settings.nestedItemSelector); 18135 } 18136 18137 content.filter(function() { 18138 return this.nodeType === 1; 18139 }).each($.proxy(function(index, item) { 18140 item = this.prepare(item); 18141 this.$stage.append(item); 18142 this._items.push(item); 18143 this._mergers.push(item.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 18144 }, this)); 18145 18146 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 18147 18148 this.invalidate('items'); 18149 }; 18150 18151 /** 18152 * Adds an item. 18153 * @todo Use `item` instead of `content` for the event arguments. 18154 * @public 18155 * @param {HTMLElement|jQuery|String} content - The item content to add. 18156 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 18157 */ 18158 Owl.prototype.add = function(content, position) { 18159 position = position === undefined ? this._items.length : this.normalize(position, true); 18160 18161 this.trigger('add', { content: content, position: position }); 18162 18163 if (this._items.length === 0 || position === this._items.length) { 18164 this.$stage.append(content); 18165 this._items.push(content); 18166 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 18167 } else { 18168 this._items[position].before(content); 18169 this._items.splice(position, 0, content); 18170 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 18171 } 18172 18173 this.invalidate('items'); 18174 18175 this.trigger('added', { content: content, position: position }); 18176 }; 18177 18178 /** 18179 * Removes an item by its position. 18180 * @todo Use `item` instead of `content` for the event arguments. 18181 * @public 18182 * @param {Number} position - The relative position of the item to remove. 18183 */ 18184 Owl.prototype.remove = function(position) { 18185 position = this.normalize(position, true); 18186 18187 if (position === undefined) { 18188 return; 18189 } 18190
18191 this.trigger('remove', { content: this._items[position], position: position }); 18192 18193 this._items[position].remove(); 18194 this._items.splice(position, 1); 18195 this._mergers.splice(position, 1); 18196 18197 this.invalidate('items'); 18198 18199 this.trigger('removed', { content: null, position: position }); 18200 }; 18201 18202 /** 18203 * Adds triggerable events. 18204 * @protected 18205 */ 18206 Owl.prototype.addTriggerableEvents = function() { 18207 var handler = $.proxy(function(callback, event) { 18208 return $.proxy(function(e) { 18209 if (e.relatedTarget !== this) { 18210 this.suppress([ event ]); 18211 callback.apply(this, [].slice.call(arguments, 1)); 18212 this.release([ event ]); 18213 } 18214 }, this); 18215 }, this); 18216 18217 $.each({ 18218 'next': this.next, 18219 'prev': this.prev, 18220 'to': this.to, 18221 'destroy': this.destroy, 18222 'refresh': this.refresh, 18223 'replace': this.replace, 18224 'add': this.add, 18225 'remove': this.remove 18226 }, $.proxy(function(event, callback) { 18227 this.register(event); 18228 this.$element.on(event + '.owl.carousel', handler(callback, event + '.owl.carousel')); 18229 }, this)); 18230 18231 }; 18232 18233 /** 18234 * Watches the visibility of the carousel element. 18235 * @protected 18236 */ 18237 Owl.prototype.watchVisibility = function() { 18238 18239 // test on zepto 18240 if (!isElVisible(this.$element.get(0))) { 18241 this.$element.addClass('owl-hidden'); 18242 window.clearInterval(this.e._checkVisibile); 18243 this.e._checkVisibile = window.setInterval($.proxy(checkVisible, this), 500); 18244 } 18245 18246 function isElVisible(el) { 18247 return el.offsetWidth > 0 && el.offsetHeight > 0; 18248 } 18249 18250 function checkVisible() { 18251 if (isElVisible(this.$element.get(0))) { 18252 this.$element.removeClass('owl-hidden'); 18253 this.refresh(); 18254 window.clearInterval(this.e._checkVisibile); 18255 } 18256 } 18257 }; 18258 18259 /** 18260 * Preloads images with auto width. 18261 * @protected 18262 * @todo Still to test 18263 */ 18264 Owl.prototype.preloadAutoWidthImages = function(imgs) { 18265 var loaded, that, $el, img; 18266 18267 loaded = 0; 18268 that = this; 18269 imgs.each(function(i, el) { 18270 $el = $(el); 18271 img = new Image(); 18272 18273 img.onload = function() { 18274 loaded++; 18275 $el.attr('src', img.src); 18276 $el.css('opacity', 1); 18277 if (loaded >= imgs.length) { 18278 that.state.imagesLoaded = true; 18279 that.initialize(); 18280 } 18281 }; 18282 18283 img.src = $el.attr('src') || $el.attr('data-src') || $el.attr('data-src-retina'); 18284 }); 18285 }; 18286 18287 /** 18288 * Destroys the carousel. 18289 * @public 18290 */ 18291 Owl.prototype.destroy = function() { 18292 18293 if (this.$element.hasClass(this.settings.themeClass)) { 18294 this.$element.removeClass(this.settings.themeClass); 18295 } 18296 18297 if (this.settings.responsive !== false) { 18298 $(window).off('resize.owl.carousel'); 18299 } 18300 18301 if (this.transitionEndVendor) { 18302 this.off(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd); 18303 } 18304 18305 for ( var i in this._plugins) { 18306 this._plugins[i].destroy(); 18307 } 18308 18309 if (this.settings.mouseDrag || this.settings.touchDrag) { 18310 this.$stage.off('mousedown touchstart touchcancel'); 18311 $(document).off('.owl.dragEvents'); 18312 this.$stage.get(0).onselectstart = function() {}; 18313 this.$stage.off('dragstart', function() { return false }); 18314 } 18315 18316 // remove event handlers in the ".owl.carousel" namespace 18317 this.$element.off('.owl'); 18318 18319 this.$stage.children('.cloned').remove(); 18320 this.e = null; 18321 this.$element.removeData('owlCarouselAsia'); 18322 18323 this.$stage.children().contents().unwrap(); 18324 this.$stage.children().unwrap(); 18325 this.$stage.unwrap(); 18326 }; 18327 18328 /** 18329 * Operators to calculate right-to-left and left-to-right. 18330 * @protected 18331 * @param {Number} [a] - The left side operand. 18332 * @param {String} [o] - The operator. 18333 * @param {Number} [b] - The right side operand. 18334 */ 18335 Owl.prototype.op = function(a, o, b) { 18336 var rtl = this.settings.rtl; 18337 switch (o) { 18338 case '<': 18339 return rtl ? a > b : a < b; 18340 case '>': 18341 return rtl ? a < b : a > b; 18342 case '>=': 18343 return rtl ? a <= b : a >= b; 18344 case '<=': 18345 return rtl ? a >= b : a <= b; 18346 default: 18347 break; 18348 } 18349 }; 18350 18351 /** 18352 * Attaches to an internal event. 18353 * @protected 18354 * @param {HTMLElement} element - The event source. 18355 * @param {String} event - The event name. 18356 * @param {Function} listener - The event handler to attach. 18357 * @param {Boolean} capture - Wether the event should be handled at the capturing p
18357hase or not. 18358 */ 18359 Owl.prototype.on = function(element, event, listener, capture) { 18360 if (element.addEventListener) { 18361 element.addEventListener(event, listener, capture); 18362 } else if (element.attachEvent) { 18363 element.attachEvent('on' + event, listener); 18364 } 18365 }; 18366 18367 /** 18368 * Detaches from an internal event. 18369 * @protected 18370 * @param {HTMLElement} element - The event source. 18371 * @param {String} event - The event name. 18372 * @param {Function} listener - The attached event handler to detach. 18373 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 18374 */ 18375 Owl.prototype.off = function(element, event, listener, capture) { 18376 if (element.removeEventListener) { 18377 element.removeEventListener(event, listener, capture); 18378 } else if (element.detachEvent) { 18379 element.detachEvent('on' + event, listener); 18380 } 18381 }; 18382 18383 /** 18384 * Triggers a public event. 18385 * @protected 18386 * @param {String} name - The event name. 18387 * @param {*} [data=null] - The event data. 18388 * @param {String} [namespace=carousel] - The event namespace. 18389 * @returns {Event} - The event arguments. 18390 */ 18391 Owl.prototype.trigger = function(name, data, namespace) { 18392 var status = { 18393 item: { count: this._items.length, index: this.current() } 18394 }, handler = $.camelCase( 18395 $.grep([ 'on', name, namespace ], function(v) { return v }) 18396 .join('-').toLowerCase() 18397 ), event = $.Event( 18398 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 18399 $.extend({ relatedTarget: this }, status, data) 18400 ); 18401 18402 if (!this._supress[name]) { 18403 $.each(this._plugins, function(name, plugin) { 18404 if (plugin.onTrigger) { 18405 plugin.onTrigger(event); 18406 } 18407 }); 18408 this.register(name); 18409 this.$element.trigger(event); 18410 18411 if (this.settings && typeof this.settings[handler] === 'function') { 18412 this.settings[handler].apply(this, event); 18413 } 18414 } 18415 18416 return event; 18417 }; 18418 /** 18419 * Registers a public event. 18420 * @public 18421 * @param {String} name - The event name to register. 18422 */ 18423 Owl.prototype.register = function(name) { 18424 if (!$.event.special[name]) { 18425 $.event.special[name] = {}; 18426 } 18427 18428 if (!$.event.special[name].owl) { 18429 var _default = $.event.special[name]._default; 18430 $.event.special[name]._default = function(e) { 18431 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 18432 return _default.apply(this, arguments); 18433 } 18434 return e.namespace && e.namespace.indexOf('owl') > -1; 18435 }; 18436 $.event.special[name].owl = true; 18437 } 18438 }; 18439 18440 /** 18441 * Suppresses events. 18442 * @protected 18443 * @param {Array.<String>} events - The events to suppress. 18444 */ 18445 Owl.prototype.suppress = function(events) { 18446 $.each(events, $.proxy(function(index, event) { 18447 this._supress[event] = true; 18448 }, this)); 18449 } 18450 18451 /** 18452 * Releases suppressed events. 18453 * @protected 18454 * @param {Array.<String>} events - The events to release. 18455 */ 18456 Owl.prototype.release = function(events) { 18457 $.each(events, $.proxy(function(index, event) { 18458 delete this._supress[event]; 18459 }, this)); 18460 } 18461 18462 /** 18463 * Checks the availability of some browser features. 18464 * @protected 18465 */ 18466 Owl.prototype.browserSupport = function() { 18467 this.support3d = isPerspective(); 18468 18469 if (this.support3d) { 18470 this.transformVendor = isTransform(); 18471 18472 // take transitionend event name by detecting transition 18473 var endVendors = [ 'transitionend', 'webkitTransitionEnd', 'transitionend', 'oTransitionEnd' ]; 18474 this.transitionEndVendor = endVendors[isTransition()]; 18475 18476 // take vendor name from transform name 18477 this.vendorName = this.transformVendor.replace(/Transform/i, ''); 18478 this.vendorName = this.vendorName !== '' ? '-' + this.vendorName.toLowerCase() + '-' : ''; 18479 } 18480 18481 this.state.orientation = window.orientation; 18482 }; 18483 18484 /** 18485 * Get touch/drag coordinats. 18486 * @private 18487 * @param {event} - mousedown/touchstart event 18488 * @returns {object} - Contains X and Y of current mouse/touch position 18489 */ 18490 18491 function getTouches(event) { 18492 if (event.touches !== undefined) { 18493 return { 18494 x: event.touches[0].pageX, 18495 y: event.touches[0].pageY 18496 }; 18497 } 18498 18499 if (event.touches === undefined) { 18500 if (event.pageX !== undefined) { 18501 return { 18502 x: event.pageX, 18503 y: event.pageY 18504 }; 18505 } 18506 18507 if (event.pageX === undefined) { 18508 return { 18509 x: event.clientX, 18510 y: event.clientY 18511 }; 18512 } 18513 } 18514 } 18515 18516 /** 18517 * Checks for CSS support. 18518 * @private 18519 * @param {Array} array - The CSS properties to check for. 18520 * @returns {Array} - Contains the supported CSS property name and its index or `false`. 18521 */ 18522 function isStyleSupported(array) { 18523 var p, s, fake = document.createElement('div'), list = array; 18524 for (p in list) { 18525 s = list[p]; 18526 if (typeof fake.style[s] !== 'undefined') { 18527 fake = null; 18528 return [ s, p ]; 18529 } 18530 } 18531 return [ false ]; 18532 } 18533 18534 /** 18535 * Checks for CSS transition support. 18536 * @private 18537 * @todo Realy bad design 18538 * @returns {Number} 18539 */ 18540 function isTransition() { 18541 return isStyleSupported([ 'transition', 'WebkitTransition', 'MozTransition', 'OTransition' ])[1]; 18542 } 18543 18544 /** 18545 * Checks for CSS transform support. 18546 * @private 18547 * @returns {String} The supported property name or false. 18548 */ 18549 function isTransform() { 18550 return isStyleSupported([ 'transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ])[0]; 18551 } 18552 18553 /** 18554 * Checks for CSS perspective support. 18555 * @private 18556 * @returns {String} The supported property name or false. 18557 */ 18558 function isPerspective() { 18559 return isStyleSupported([ 'perspective', 'webkitPerspective', 'MozPerspective', 'OPerspective', 'MsPerspective' ])[0]; 18560 } 18561 18562 /** 18563 * Checks wether touch is supported or not. 18564 * @private 18565 * @returns {Boolean} 18566 */ 18567 function isTouchSupport() { 18568 return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints); 18569 } 18570 18571 /** 18572 * Checks wether touch is supported or not for IE. 18573 * @private 18574 * @returns {Boolean} 18575 */ 18576 function isTouchSupportIE() { 18577 return window.navigator.msPointerEnabled; 18578 } 18579 18580 /** 18581 * The jQuery Plugin for the Owl Carousel 18582 * @public 18583 */ 18584 $.fn.owlCarouselAsia = function(options) { 18585 return this.each(function() { 18586 if (!$(this).data('owlCarouselAsia')) { 18587 $(this).data('owlCarouselAsia', new Owl(this, options)); 18588 } 18589 }); 18590 }; 18591 18592 /** 18593 * The constructor for the jQuery Plugin 18594 * @public 18595 */ 18596 $.fn.owlCarouselAsia.Constructor = Owl; 18597 18598})(window.Zepto || window.jQuery, window, document); 18599 18600/** 18601 * Lazy Plugin 18602 * @version 2.0.0 18603 * @author Bartosz Wojciechowski 18604 * @license The MIT License (MIT) 18605 */ 18606;(function($, window, document, undefined) { 18607 18608 /** 18609 * Creates the lazy plugin. 18610 * @class The Lazy Plugin 18611 * @param {Owl} carousel - The Owl Carousel 18612 */ 18613 var Lazy = function(carousel) { 18614 18615 /** 18616 * Reference to the core. 18617 * @protected 18618 * @type {Owl} 18619 */ 18620 this._core = carousel; 18621 18622 /** 18623 * Already loaded items. 18624 * @protected 18625 * @type {Array.<jQuery>} 18626 */ 18627 this._loaded = []; 18628 18629 /** 18630 * Event handlers. 18631 * @protected 18632 * @type {Object} 18633 */ 18634 this._handlers = { 18635 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 18636 if (!e.namespace) { 18637 return; 18638 } 18639 18640 if (!this._core.settings || !this._core.settings.lazyLoad) { 18641 return; 18642 } 18643 18644 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 18645 var settings = this._core.settings, 18646 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 18647 i = ((settings.center && n * -1) || 0), 18648 position = ((e.property && e.property.value) || this._core.current()) + i, 18649 clones = this._core.clones().length, 18650 load = $.proxy(function(i, v) { this.load(v) }, this); 18651 18652 while (i++ < n) { 18653 this.load(clones / 2 + this._core.relative(position)); 18654 clones && $.each(this._core.clones(this._core.relative(position++)), load
vendor: 7,234 bytes, lines 18654-18945
18654); 18655 } 18656 } 18657 }, this) 18658 }; 18659 18660 // set the default options 18661 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 18662 18663 // register event handler 18664 this._core.$element.on(this._handlers); 18665 } 18666 18667 /** 18668 * Default options. 18669 * @public 18670 */ 18671 Lazy.Defaults = { 18672 lazyLoad: false 18673 } 18674 18675 /** 18676 * Loads all resources of an item at the specified position. 18677 * @param {Number} position - The absolute position of the item. 18678 * @protected 18679 */ 18680 Lazy.prototype.load = function(position) { 18681 var $item = this._core.$stage.children().eq(position), 18682 $elements = $item && $item.find('.owl-lazy'); 18683 18684 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 18685 return; 18686 } 18687 18688 $elements.each($.proxy(function(index, element) { 18689 var $element = $(element), image, 18690 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 18691 18692 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 18693 18694 if ($element.is('img')) { 18695 $element.one('load.owl.lazy', $.proxy(function() { 18696 $element.css('opacity', 1); 18697 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 18698 }, this)).attr('src', url); 18699 } else { 18700 image = new Image(); 18701 image.onload = $.proxy(function() { 18702 $element.css({ 18703 'background-image': 'url(' + url + ')', 18704 'opacity': '1' 18705 }); 18706 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 18707 }, this); 18708 image.src = url; 18709 } 18710 }, this)); 18711 18712 this._loaded.push($item.get(0)); 18713 } 18714 18715 /** 18716 * Destroys the plugin. 18717 * @public 18718 */ 18719 Lazy.prototype.destroy = function() { 18720 var handler, property; 18721 18722 for (handler in this.handlers) { 18723 this._core.$element.off(handler, this.handlers[handler]); 18724 } 18725 for (property in Object.getOwnPropertyNames(this)) { 18726 typeof this[property] != 'function' && (this[property] = null); 18727 } 18728 } 18729 18730 $.fn.owlCarouselAsia.Constructor.Plugins.Lazy = Lazy; 18731 18732})(window.Zepto || window.jQuery, window, document); 18733 18734/** 18735 * AutoHeight Plugin 18736 * @version 2.0.0 18737 * @author Bartosz Wojciechowski 18738 * @license The MIT License (MIT) 18739 */ 18740;(function($, window, document, undefined) { 18741 18742 /** 18743 * Creates the auto height plugin. 18744 * @class The Auto Height Plugin 18745 * @param {Owl} carousel - The Owl Carousel 18746 */ 18747 var AutoHeight = function(carousel) { 18748 /** 18749 * Reference to the core. 18750 * @protected 18751 * @type {Owl} 18752 */ 18753 this._core = carousel; 18754 18755 /** 18756 * All event handlers. 18757 * @protected 18758 * @type {Object} 18759 */ 18760 this._handlers = { 18761 'initialized.owl.carousel': $.proxy(function() { 18762 if (this._core.settings.autoHeight) { 18763 this.update(); 18764 } 18765 }, this), 18766 'changed.owl.carousel': $.proxy(function(e) { 18767 if (this._core.settings.autoHeight && e.property.name == 'position'){ 18768 this.update(); 18769 } 18770 }, this), 18771 'loaded.owl.lazy': $.proxy(function(e) { 18772 if (this._core.settings.autoHeight && e.element.closest('.' + this._core.settings.itemClass) 18773 === this._core.$stage.children().eq(this._core.current())) { 18774 this.update(); 18775 } 18776 }, this) 18777 }; 18778 18779 // set default options 18780 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 18781 18782 // register event handlers 18783 this._core.$element.on(this._handlers); 18784 }; 18785 18786 /** 18787 * Default options. 18788 * @public 18789 */ 18790 AutoHeight.Defaults = { 18791 autoHeight: false, 18792 autoHeightClass: 'owl-height' 18793 }; 18794 18795 /** 18796 * Updates the view. 18797 */ 18798 AutoHeight.prototype.update = function() { 18799 this._core.$stage.parent() 18800 .height(this._core.$stage.children().eq(this._core.current()).height()) 18801 .addClass(this._core.settings.autoHeightClass); 18802 }; 18803 18804 AutoHeight.prototype.destroy = function() { 18805 var handler, property; 18806 18807 for (handler in this._handlers) { 18808 this._core.$element.off(handler, this._handlers[handler]); 18809 } 18810 for (property in Object.getOwnPropertyNames(this)) { 18811 typeof this[property] != 'function' && (this[property] = null); 18812 } 18813 }; 18814 18815 $.fn.owlCarouselAsia.Constructor.Plugins.AutoHeight = AutoHeight; 18816 18817})(window.Zepto || window.jQuery, window, document); 18818 18819/** 18820 * Video Plugin 18821 * @version 2.0.0 18822 * @author Bartosz Wojciechowski 18823 * @license The MIT License (MIT) 18824 */ 18825;(function($, window, document, undefined) { 18826 18827 /** 18828 * Creates the video plugin. 18829 * @class The Video Plugin 18830 * @param {Owl} carousel - The Owl Carousel 18831 */ 18832 var Video = function(carousel) { 18833 /** 18834 * Reference to the core. 18835 * @protected 18836 * @type {Owl} 18837 */ 18838 this._core = carousel; 18839 18840 /** 18841 * Cache all video URLs. 18842 * @protected 18843 * @type {Object} 18844 */ 18845 this._videos = {}; 18846 18847 /** 18848 * Current playing item. 18849 * @protected 18850 * @type {jQuery} 18851 */ 18852 this._playing = null; 18853 18854 /** 18855 * Whether this is in fullscreen or not. 18856 * @protected 18857 * @type {Boolean} 18858 */ 18859 this._fullscreen = false; 18860 18861 /** 18862 * All event handlers. 18863 * @protected 18864 * @type {Object} 18865 */ 18866 this._handlers = { 18867 'resize.owl.carousel': $.proxy(function(e) { 18868 if (this._core.settings.video && !this.isInFullScreen()) { 18869 e.preventDefault(); 18870 } 18871 }, this), 18872 'refresh.owl.carousel changed.owl.carousel': $.proxy(function(e) { 18873 if (this._playing) { 18874 this.stop(); 18875 } 18876 }, this), 18877 'prepared.owl.carousel': $.proxy(function(e) { 18878 var $element = $(e.content).find('.owl-video'); 18879 if ($element.length) { 18880 $element.css('display', 'none'); 18881 this.fetch($element, $(e.content)); 18882 } 18883 }, this) 18884 }; 18885 18886 // set default options 18887 this._core.options = $.extend({}, Video.Defaults, this._core.options); 18888 18889 // register event handlers 18890 this._core.$element.on(this._handlers); 18891 18892 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 18893 this.play(e); 18894 }, this)); 18895 }; 18896 18897 /** 18898 * Default options. 18899 * @public 18900 */ 18901 Video.Defaults = { 18902 video: false, 18903 videoHeight: false, 18904 videoWidth: false 18905 }; 18906 18907 /** 18908 * Gets the video ID and the type (YouTube/Vimeo only). 18909 * @protected 18910 * @param {jQuery} target - The target containing the video data. 18911 * @param {jQuery} item - The item containing the video. 18912 */ 18913 Video.prototype.fetch = function(target, item) { 18914 18915 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 18916 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 18917 width = target.attr('data-width') || this._core.settings.videoWidth, 18918 height = target.attr('data-height') || this._core.settings.videoHeight, 18919 url = target.attr('href'); 18920 18921 if (url) { 18922 id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/); 18923 18924 if (id[3].indexOf('youtu') > -1) { 18925 type = 'youtube'; 18926 } else if (id[3].indexOf('vimeo') > -1) { 18927 type = 'vimeo'; 18928 } else { 18929 throw new Error('Video URL not supported.'); 18930 } 18931 id = id[6]; 18932 } else { 18933 throw new Error('Missing video URL.'); 18934 } 18935 18936 this._videos[url] = { 18937 type: type, 18938 id: id, 18939 width: width, 18940 height: height 18941 }; 18942 18943 item.attr('data-video', url); 18944 18945 this.thumbnail(target, this._videos[url]);
18946 }; 18947 18948 /** 18949 * Creates video thumbnail. 18950 * @protected 18951 * @param {jQuery} target - The target containing the video data. 18952 * @param {Object} info - The video info object. 18953 * @see `fetch` 18954 */ 18955 Video.prototype.thumbnail = function(target, video) { 18956 18957 var tnLink, 18958 icon, 18959 path, 18960 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 18961 customTn = target.find('img'), 18962 srcType = 'src', 18963 lazyClass = '', 18964 settings = this._core.settings, 18965 create = function(path) { 18966 icon = '<div class="owl-video-play-icon"></div>'; 18967 18968 if (settings.lazyLoad) { 18969 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 18970 } else { 18971 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 18972 } 18973 target.after(tnLink); 18974 target.after(icon); 18975 }; 18976 18977 // wrap video content into owl-video-wrapper div 18978 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 18979 18980 if (this._core.settings.lazyLoad) { 18981 srcType = 'data-src'; 18982 lazyClass = 'owl-lazy'; 18983 } 18984 18985 // custom thumbnail 18986 if (customTn.length) { 18987 create(customTn.attr(srcType)); 18988 customTn.remove(); 18989 return false; 18990 } 18991 18992 if (video.type === 'youtube') { 18993 path = "http://img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 18994 create(path); 18995 } else if (video.type === 'vimeo') { 18996 $.ajax({ 18997 type: 'GET', 18998 url: 'http://vimeo.com/api/v2/video/' + video.id + '.json', 18999 jsonp: 'callback', 19000 dataType: 'jsonp', 19001 success: function(data) { 19002 path = data[0].thumbnail_large; 19003 create(path); 19004 } 19005 }); 19006 } 19007 }; 19008 19009 /** 19010 * Stops the current video. 19011 * @public 19012 */ 19013 Video.prototype.stop = function() { 19014 this._core.trigger('stop', null, 'video'); 19015 this._playing.find('.owl-video-frame').remove(); 19016 this._playing.removeClass('owl-video-playing'); 19017 this._playing = null; 19018 }; 19019 19020 /** 19021 * Starts the current video. 19022 * @public 19023 * @param {Event} ev - The event arguments. 19024 */ 19025 Video.prototype.play = function(ev) { 19026 this._core.trigger('play', null, 'video'); 19027 19028 if (this._playing) { 19029 this.stop(); 19030 } 19031 19032 var target = $(ev.target || ev.srcElement), 19033 item = target.closest('.' + this._core.settings.itemClass), 19034 video = this._videos[item.attr('data-video')], 19035 width = video.width || '100%', 19036 height = video.height || this._core.$stage.height(), 19037 html, wrap; 19038 19039 if (video.type === 'youtube') { 19040 html = '<iframe width="' + width + '" height="' + height + '" src="http://www.youtube.com/embed/' 19041 + video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 19042 } else if (video.type === 'vimeo') { 19043 html = '<iframe src="http://player.vimeo.com/video/' + video.id + '?autoplay=1" width="' + width 19044 + '" height="' + height 19045 + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 19046 } 19047 19048 item.addClass('owl-video-playing'); 19049 this._playing = item; 19050 19051 wrap = $('<div style="height:' + height + 'px; width:' + width + 'px" class="owl-video-frame">' 19052 + html + '</div>'); 19053 target.after(wrap); 19054 }; 19055 19056 /** 19057 * Checks whether an video is currently in full screen mode or not. 19058 * @todo Bad style because looks like a readonly method but changes members. 19059 * @protected 19060 * @returns {Boolean} 19061 */ 19062 Video.prototype.isInFullScreen = function() { 19063 19064 // if Vimeo Fullscreen mode 19065 var element = document.fullscreenElement || document.mozFullScreenElement 19066 || document.webkitFullscreenElement; 19067 19068 if (element && $(element).parent().hasClass('owl-video-frame')) { 19069 this._core.speed(0); 19070 this._fullscreen = true; 19071 } 19072 19073 if (element && this._fullscreen && this._playing) { 19074 return false; 19075 } 19076 19077 // comming back from fullscreen 19078 if (this._fullscreen) { 19079 this._fullscreen = false; 19080 return false; 19081 } 19082 19083 // check full screen mode and window orientation 19084 if (this._playing) { 19085 if (this._core.state.orientation !== window.orientation) { 19086 this._core.state.orientation = window.orientation; 19087 return false; 19088 } 19089 } 19090 19091 return true; 19092 }; 19093 19094 /** 19095 * Destroys the plugin. 19096 */ 19097 Video.prototype.destroy = function() { 19098 var handler, property; 19099 19100 this._core.$element.off('click.owl.video'); 19101 19102 for (handler in this._handlers) { 19103 this._core.$element.off(handler, this._handlers[handler]); 19104 } 19105 for (property in Object.getOwnPropertyNames(this)) { 19106 typeof this[property] != 'function' && (this[property] = null); 19107 } 19108 }; 19109 19110 $.fn.owlCarouselAsia.Constructor.Plugins.Video = Video; 19111 19112})(window.Zepto || window.jQuery, window, document); 19113 19114/** 19115 * Animate Plugin 19116 * @version 2.0.0 19117 * @author Bartosz Wojciechowski 19118 * @license The MIT License (MIT) 19119 */ 19120;(function($, window, document, undefined) { 19121 19122 /** 19123 * Creates the animate plugin. 19124 * @class The Navigation Plugin 19125 * @param {Owl} scope - The Owl Carousel 19126 */ 19127 var Animate = function(scope) { 19128 this.core = scope; 19129 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 19130 this.swapping = true; 19131 this.previous = undefined; 19132 this.next = undefined; 19133 19134 this.handlers = { 19135 'change.owl.carousel': $.proxy(function(e) { 19136 if (e.property.name == 'position') { 19137 this.previous = this.core.current(); 19138 this.next = e.property.value; 19139 } 19140 }, this), 19141 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 19142 this.swapping = e.type == 'translated'; 19143 }, this), 19144 'translate.owl.carousel': $.proxy(function(e) { 19145 if (this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 19146 this.swap();
19147 } 19148 }, this) 19149 }; 19150 19151 this.core.$element.on(this.handlers); 19152 }; 19153 19154 /** 19155 * Default options. 19156 * @public 19157 */ 19158 Animate.Defaults = { 19159 animateOut: false, 19160 animateIn: false 19161 }; 19162 19163 /** 19164 * Toggles the animation classes whenever an translations starts. 19165 * @protected 19166 * @returns {Boolean|undefined} 19167 */ 19168 Animate.prototype.swap = function() { 19169 19170 if (this.core.settings.items !== 1 || !this.core.support3d) { 19171 return; 19172 } 19173 19174 this.core.speed(0); 19175 19176 var left, 19177 clear = $.proxy(this.clear, this), 19178 previous = this.core.$stage.children().eq(this.previous), 19179 next = this.core.$stage.children().eq(this.next), 19180 incoming = this.core.settings.animateIn, 19181 outgoing = this.core.settings.animateOut; 19182 19183 if (this.core.current() === this.previous) { 19184 return; 19185 } 19186 19187 if (outgoing) { 19188 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 19189 previous.css( { 'left': left + 'px' } ) 19190 .addClass('animated owl-animated-out') 19191 .addClass(outgoing) 19192 .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); 19193 } 19194 19195 if (incoming) { 19196 next.addClass('animated owl-animated-in') 19197 .addClass(incoming) 19198 .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); 19199 } 19200 }; 19201 19202 Animate.prototype.clear = function(e) { 19203 $(e.target).css( { 'left': '' } ) 19204 .removeClass('animated owl-animated-out owl-animated-in') 19205 .removeClass(this.core.settings.animateIn) 19206 .removeClass(this.core.settings.animateOut); 19207 this.core.transitionEnd(); 19208 } 19209 19210 /** 19211 * Destroys the plugin. 19212 * @public 19213 */ 19214 Animate.prototype.destroy = function() { 19215 var handler, property; 19216 19217 for (handler in this.handlers) { 19218 this.core.$element.off(handler, this.handlers[handler]); 19219 } 19220 for (property in Object.getOwnPropertyNames(this)) { 19221 typeof this[property] != 'function' && (this[property] = null); 19222 } 19223 }; 19224 19225 $.fn.owlCarouselAsia.Constructor.Plugins.Animate = Animate; 19226 19227})(window.Zepto || window.jQuery, window, document); 19228 19229/** 19230 * Autoplay Plugin 19231 * @version 2.0.0 19232 * @author Bartosz Wojciechowski 19233 * @license The MIT License (MIT) 19234 */ 19235;(function($, window, document, undefined) { 19236 19237 /** 19238 * Creates the autoplay plugin. 19239 * @class The Autoplay Plugin 19240 * @param {Owl} scope - The Owl Carousel 19241 */ 19242 var Autoplay = function(scope) { 19243 this.core = scope; 19244 this.core.options = $.extend({}, Autoplay.Defaults, this.core.options); 19245 19246 this.handlers = { 19247 'translated.owl.carousel refreshed.owl.carousel': $.proxy(function() { 19248 this.autoplay(); 19249 }, this), 19250 'play.owl.autoplay': $.proxy(function(e, t, s) { 19251 this.play(t, s); 19252 }, this), 19253 'stop.owl.autoplay': $.proxy(function() { 19254 this.stop(); 19255 }, this), 19256 'mouseover.owl.autoplay': $.proxy(function() { 19257 if (this.core.settings.autoplayHoverPause) { 19258 this.pause(); 19259 } 19260 }, this), 19261 'mouseleave.owl.autoplay': $.proxy(function() { 19262 if (this.core.settings.autoplayHoverPause) { 19263 this.autoplay(); 19264 } 19265 }, this) 19266 }; 19267 19268 this.core.$element.on(this.handlers); 19269 }; 19270 19271 /** 19272 * Default options. 19273 * @public 19274 */ 19275 Autoplay.Defaults = { 19276 autoplay: false, 19277 autoplayTimeout: 5000, 19278 autoplayHoverPause: false, 19279 autoplaySpeed: false 19280 }; 19281 19282 /** 19283 * @protected 19284 * @todo Must be documented. 19285 */ 19286 Autoplay.prototype.autoplay = function() { 19287 if (this.core.settings.autoplay && !this.core.state.videoPlay) { 19288 window.clearInterval(this.interval); 19289 19290 this.interval = window.setInterval($.proxy(function() { 19291 this.play(); 19292 }, this), this.core.settings.autoplayTimeout); 19293 } else { 19294 window.clearInterval(this.interval); 19295 } 19296 }; 19297 19298 /** 19299 * Starts the autoplay. 19300 * @public 19301 * @param {Number} [timeout] - ... 19302 * @param {Number} [speed] - ... 19303 * @returns {Boolean|undefined} - ... 19304 * @todo Must be documented. 19305 */ 19306 Autoplay.prototype.play = function(timeout, speed) { 19307 // if tab is inactive - doesnt work in <IE10 19308 if (document.hidden === true) { 19309 return; 19310 } 19311 19312 if (this.core.state.isTouch || this.core.state.isScrolling 19313 || this.core.state.isSwiping || this.core.state.inMotion) { 19314 return; 19315 } 19316 19317 if (this.core.settings.autoplay === false) { 19318 window.clearInterval(this.interval); 19319 return; 19320 } 19321 19322 this.core.next(this.core.settings.autoplaySpeed); 19323 }; 19324 19325 /** 19326 * Stops the autoplay. 19327 * @public 19328 */ 19329 Autoplay.prototype.stop = function() { 19330 window.clearInterval(this.interval); 19331 }; 19332 19333 /** 19334 * Pauses the autoplay. 19335 * @public 19336 */ 19337 Autoplay.prototype.pause = function() { 19338 window.clearInterval(this.interval); 19339 }; 19340 19341 /** 19342 * Destroys the plugin. 19343 */ 19344 Autoplay.prototype.destroy = function() { 19345 var handler, property; 19346 19347 window.clearInterval(this.interval); 19348 19349 for (handler in this.handlers) { 19350 this.core.$element.off(handler, this.handlers[handler]); 19351 } 19352 for (property in Object.getOwnPropertyNames(this)) { 19353 typeof this[property] != 'function' && (this[property] = null); 19354 } 19355 }; 19356 19357 $.fn.owlCarouselAsia.Constructor.Plugins.autoplay = Autoplay; 19358 19359})(window.Zepto || window.jQuery, window, document); 19360 19361/** 19362 * Navigation Plugin 19363 * @version 2.0.0 19364 * @author Artus Kolanowski 19365 * @license The MIT License (MIT) 19366 */ 19367;(function($, window, document, undefined) { 19368 'use strict'; 19369 19370 /** 19371 * Creates the navigation plugin. 19372 * @class The Navigation Plugin 19373 * @param {Owl} carousel - The Owl Carousel. 19374 */ 19375 var Navigation = function(carousel) { 19376 /** 19377 * Reference to the core. 19378 * @protected 19379 * @type {Owl} 19380 */ 19381 this._core = carousel; 19382 19383 /** 19384 * Indicates whether the plugin is initialized or not. 19385 * @protected 19386 * @type {Boolean} 19387 */ 19388 this._initialized = false; 19389 19390 /** 19391 * The current paging indexes. 19392 * @protected 19393 * @type {Array} 19394 */ 19395 this._pages = []; 19396 19397 /** 19398 * All DOM elements of the user interface. 19399 * @protected 19400 * @type {Object} 19401 */ 19402 this._controls = {}; 19403 19404 /** 19405 * Markup for an indicator. 19406 * @protected 19407 * @type {Array.<String>} 19408 */ 19409 this._templates = []; 19410 19411 /** 19412 * The carousel element. 19413 * @type {jQuery} 19414 */ 19415 this.$element = this._core.$element; 19416 19417 /** 19418 * Overridden methods of the carousel. 19419 * @protected 19420 * @type {Object} 19421 */ 19422 this._overrides = { 19423 next: this._core.next, 19424 prev: this._core.prev, 19425 to: this._core.to 19426 }; 19427 19428 /** 19429 * All event handlers. 19430 * @protected 19431 * @type {Object} 19432 */ 19433 this._handlers = { 19434 'prepared.owl.carousel': $.proxy(function(e) { 19435 if (this._core.settings.dotsData) { 19436 this._templates.push($(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot')); 19437 } 19438 }, this), 19439 'add.owl.carousel': $.proxy(function(e) { 19440 if (this._core.settings.dotsData) { 19441 this._templates.splice(e.position, 0, $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot')); 19442 } 19443 }, this), 19444 'remove.owl.carousel prepared.owl.carousel': $.proxy(function(e) { 19445 if (this._core.settings.dotsData) { 19446 this._templates.splice(e.position, 1); 19447 } 19448 }, this), 19449 'change.owl.carousel': $.proxy(function(e) { 19450 if (e.property.name == 'position') { 19451 if (!this._core.state.revert && !this._core.settings.loop && this._core.settings.navRewind) { 19452 var current = this._core.current(), 19453 maximum = this._core.maximum(), 19454 minimum = this._core.minimum(); 19455 e.data = e.property.value > maximum 19456 ? current >= maximum ? minimum : maximum 19457 : e.property.value < minimum ? maximum : e.property.value; 19458 } 19459 } 19460 }, this), 19461 'changed.owl.carousel': $.proxy(function(e) { 19462 if (e.property.name == 'position') { 19463 this.draw(); 19464 } 19465 }, this), 19466 'refreshed.owl.carousel': $.proxy(function() { 19467 if (!this._initialized) { 19468 this.initialize(); 19469 this._initialized = true; 19470 } 19471 this._core.trigger('refresh', null, 'navigation'); 19472 this.update(); 19473 this.draw(); 19474 this._core.trigger('refreshed', null, 'navigation'); 19475 }, this) 19476 }; 19477 19478 // set default options 19479 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 19480 19481 // register event handlers 19482 this.$element.on(this._handlers); 19483 } 19484 19485 /** 19486 * Default options. 19487 * @public 19488 * @todo Rename `slideBy` to `navBy` 19489 */ 19490 Navigation.Defaults = { 19491 nav: false, 19492 navRewind: true, 19493 navText: [ 'prev', 'next' ], 19494 navSpeed: false, 19495 navElement: 'div', 19496 navContainer: false, 19497 navContainerClass: 'owl-nav', 19498 navClass: [ 'owl-prev', 'owl-next' ], 19499 slideBy: 1, 19500 dotClass: 'owl-dot', 19501 dotsClass: 'owl-dots', 19502 dots: true, 19503 dotsEach: false, 19504 dotData: false, 19505 dotsSpeed: false, 19506 dotsContainer: false,
19507 controlsClass: 'owl-controls' 19508 } 19509 19510 /** 19511 * Initializes the layout of the plugin and extends the carousel. 19512 * @protected 19513 */ 19514 Navigation.prototype.initialize = function() { 19515 var $container, override, 19516 options = this._core.settings; 19517 19518 // create the indicator template 19519 if (!options.dotsData) { 19520 this._templates = [ $('<div>') 19521 .addClass(options.dotClass) 19522 .append($('<span>')) 19523 .prop('outerHTML') ]; 19524 } 19525 19526 // create controls container if needed 19527 if (!options.navContainer || !options.dotsContainer) { 19528 this._controls.$container = $('<div>') 19529 .addClass(options.controlsClass) 19530 .appendTo(this.$element); 19531 } 19532 19533 // create DOM structure for absolute navigation 19534 this._controls.$indicators = options.dotsContainer ? $(options.dotsContainer) 19535 : $('<div>').hide().addClass(options.dotsClass).appendTo(this._controls.$container); 19536 19537 this._controls.$indicators.on('click', 'div', $.proxy(function(e) { 19538 var index = $(e.target).parent().is(this._controls.$indicators) 19539 ? $(e.target).index() : $(e.target).parent().index(); 19540 19541 e.preventDefault(); 19542 19543 this.to(index, options.dotsSpeed); 19544 }, this)); 19545 19546 // create DOM structure for relative navigation 19547 $container = options.navContainer ? $(options.navContainer) 19548 : $('<div>').addClass(options.navContainerClass).prependTo(this._controls.$container); 19549 19550 this._controls.$next = $('<' + options.navElement + '>'); 19551 this._controls.$previous = this._controls.$next.clone(); 19552 19553 this._controls.$previous 19554 .addClass(options.navClass[0]) 19555 .html(options.navText[0]) 19556 .hide() 19557 .prependTo($container) 19558 .on('click', $.proxy(function(e) { 19559 this.prev(options.navSpeed); 19560 }, this)); 19561 this._controls.$next 19562 .addClass(options.navClass[1]) 19563 .html(options.navText[1]) 19564 .hide() 19565 .appendTo($container) 19566 .on('click', $.proxy(function(e) { 19567 this.next(options.navSpeed); 19568 }, this)); 19569 19570 // override public methods of the carousel 19571 for (override in this._overrides) { 19572 this._core[override] = $.proxy(this[override], this); 19573 } 19574 } 19575 19576 /** 19577 * Destroys the plugin. 19578 * @protected 19579 */ 19580 Navigation.prototype.destroy = function() { 19581 var handler, control, property, override; 19582 19583 for (handler in this._handlers) { 19584 this.$element.off(handler, this._handlers[handler]); 19585 } 19586 for (control in this._controls) { 19587 this._controls[control].remove(); 19588 } 19589 for (override in this.overides) { 19590 this._core[override] = this._overrides[override]; 19591 } 19592 for (property in Object.getOwnPropertyNames(this)) { 19593 typeof this[property] != 'function' && (this[property] = null); 19594 } 19595 } 19596 19597 /** 19598 * Updates the internal state. 19599 * @protected 19600 */ 19601 Navigation.prototype.update = function() { 19602 var i, j, k, 19603 //options = this._core.settings, 19604 lower = this._core.clones().length / 2, 19605 upper = lower + this._core.items().length, 19606 maximum = this._core.maximum(true), 19607 options = this._core.settings, 19608 size = options.center || options.autoWidth || options.dotData 19609 ? 1 : options.dotsEach || options.items; 19610 19611 if (options.slideBy !== 'page') { 19612 options.slideBy = Math.min(options.slideBy, options.items); 19613 } 19614 19615 if (options.dots || options.slideBy == 'page') { 19616 this._pages = []; 19617 19618 for (i = lower, j = 0, k = 0; i < upper; i++) { 19619 if (j >= size || j === 0) { 19620 this._pages.push({ 19621 //start: i - lower, 19622 start: Math.min(maximum, i - lower), 19623 end: i - lower + size - 1 19624 }); 19625 if (Math.min(maximum, i - lower) === maximum) { 19626 break; 19627 } 19628 j = 0, ++k; 19629 } 19630 j += this._core.mergers(this._core.relative(i)); 19631 } 19632 } 19633 } 19634 19635 /** 19636 * Draws the user interface. 19637 * @todo The option `dotData` wont work. 19638 * @protected 19639 */ 19640 Navigation.prototype.draw = function() { 19641 var difference, i, html = '', 19642 options = this._core.settings, 19643 $items = this._core.$stage.children(), 19644 index = this._core.relative(this._core.current()); 19645 19646 if (options.nav && !options.loop && !options.navRewind) { 19647 this._controls.$previous.toggleClass('disabled', index <= 0); 19648 this._controls.$next.toggleClass('disabled', index >= this._core.maximum()); 19649 } 19650 19651 this._controls.$previous.toggle(options.nav); 19652 this._controls.$next.toggle(options.nav); 19653 19654 if (options.dots) { 19655 difference = this._pages.length - this._controls.$indicators.children().length; 19656 19657 if (options.dotData && difference !== 0) { 19658 for (i = 0; i < this._controls.$indicators.children().length; i++) { 19659 html += this._templates[this._core.relative(i)]; 19660 } 19661 this._controls.$indicators.html(html); 19662 } else if (difference > 0) { 19663 html = new Array(difference + 1).join(this._templates[0]); 19664 this._controls.$indicators.append(html); 19665 } else if (difference < 0) { 19666 this._controls.$indicators.children().slice(difference).remove(); 19667 } 19668 19669 //this._controls.$indicators.find('.active').removeClass('active'); 19670 //this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 19671 this._controls.$indicators.find('.active').removeClass('active'); 19672 if(!options.loop && options.items + index == $items.length){
19673 this._controls.$indicators.children().last().addClass('active'); 19674 }else{ 19675 this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 19676 } 19677 } 19678 19679 this._controls.$indicators.toggle(options.dots); 19680 } 19681 19682 /** 19683 * Extends event data. 19684 * @protected 19685 * @param {Event} event - The event object which gets thrown. 19686 */ 19687 Navigation.prototype.onTrigger = function(event) { 19688 var settings = this._core.settings; 19689 19690 event.page = { 19691 index: $.inArray(this.current(), this._pages), 19692 count: this._pages.length, 19693 size: settings && (settings.center || settings.autoWidth || settings.dotData 19694 ? 1 : settings.dotsEach || settings.items) 19695 }; 19696 } 19697 19698 /** 19699 * Gets the current page position of the carousel. 19700 * @protected 19701 * @returns {Number} 19702 */ 19703 /*Navigation.prototype.current = function() { 19704 var index = this._core.relative(this._core.current()); 19705 return $.grep(this._pages, function(o) { 19706 return o.start <= index && o.end >= index; 19707 }).pop(); 19708 }*/ 19709 19710 Navigation.prototype.current = function() { 19711 var current = this._core.relative(this._core.current()); 19712 return $.grep(this._pages, $.proxy(function(page, index) { 19713 19714 return page.start <= current && page.end >= current; 19715 }, this)).pop(); 19716 } 19717 19718 /** 19719 * Gets the current succesor/predecessor position. 19720 * @protected 19721 * @returns {Number} 19722 */ 19723 Navigation.prototype.getPosition = function(successor) { 19724 var position, length, 19725 options = this._core.settings; 19726 19727 if (options.slideBy == 'page') { 19728 position = $.inArray(this.current(), this._pages); 19729 length = this._pages.length; 19730 successor ? ++position : --position; 19731 position = this._pages[((position % length) + length) % length].start; 19732 } else { 19733 position = this._core.relative(this._core.current()); 19734 length = this._core.items().length; 19735 successor ? position += options.slideBy : position -= options.slideBy; 19736 } 19737 return position; 19738 } 19739 19740 /** 19741 * Slides to the next item or page. 19742 * @public 19743 * @param {Number} [speed=false] - The time in milliseconds for the transition. 19744 */ 19745 Navigation.prototype.next = function(speed) { 19746 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 19747 } 19748 19749 /** 19750 * Slides to the previous item or page. 19751 * @public 19752 * @param {Number} [speed=false] - The time in milliseconds for the transition. 19753 */ 19754 Navigation.prototype.prev = function(speed) { 19755 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 19756 } 19757 19758 /** 19759 * Slides to the specified item or page. 19760 * @public 19761 * @param {Number} position - The position of the item or page. 19762 * @param {Number} [speed] - The time in milliseconds for the transition. 19763 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 19764 */ 19765 Navigation.prototype.to = function(position, speed, standard) { 19766 var length; 19767 19768 if (!standard) { 19769 length = this._pages.length; 19770 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 19771 } else { 19772 $.proxy(this._overrides.to, this._core)(position, speed); 19773 } 19774 } 19775 19776 $.fn.owlCarouselAsia.Constructor.Plugins.Navigation = Navigation; 19777 19778})(window.Zepto || window.jQuery, window, document); 19779 19780/** 19781 * Hash Plugin 19782 * @version 2.0.0 19783 * @author Artus Kolanowski 19784 * @license The MIT License (MIT) 19785 */ 19786;(function($, window, document, undefined) { 19787 'use strict'; 19788 19789 /** 19790 * Creates the hash plugin. 19791 * @class The Hash Plugin 19792 * @param {Owl} carousel - The Owl Carousel 19793 */ 19794 var Hash = function(carousel) { 19795 /** 19796 * Reference to the core. 19797 * @protected 19798 * @type {Owl} 19799 */ 19800 this._core = carousel; 19801 19802 /** 19803 * Hash table for the hashes. 19804 * @protected 19805 * @type {Object} 19806 */ 19807 this._hashes = {}; 19808 19809 /** 19810 * The carousel element. 19811 * @type {jQuery} 19812 */ 19813 this.$element = this._core.$element; 19814 19815 /** 19816 * All event handlers. 19817 * @protected 19818 * @type {Object} 19819 */ 19820 this._handlers = { 19821 'initialized.owl.carousel': $.proxy(function() { 19822 if (this._core.settings.startPosition == 'URLHash') { 19823 $(window).trigger('hashchange.owl.navigation'); 19824 } 19825 }, this), 19826 'prepared.owl.carousel': $.proxy(function(e) { 19827 var hash = $(e.content).find('[data-hash]').andSelf('[data-hash]').attr('data-hash'); 19828 this._hashes[hash] = e.content; 19829 }, this) 19830 }; 19831 19832 // set default options 19833 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 19834 19835 // register the event handlers 19836 this.$element.on(this._handlers); 19837 19838 // register event listener for hash navigation 19839 $(window).on('hashchange.owl.navigation', $.proxy(function() { 19840 var hash = window.location.hash.substring(1), 19841 items = this._core.$stage.children(), 19842 position = this._hashes[hash] && items.index(this._hashes[hash]) || 0; 19843 19844 if (!hash) { 19845 return false; 19846 } 19847 19848 this._core.to(position, false, true); 19849 }, this)); 19850 } 19851 19852 /** 19853 * Default options. 19854 * @public 19855 */ 19856 Hash.Defaults = { 19857 URLhashListener: false 19858 } 19859 19860 /** 19861 * Destroys the plugin. 19862 * @public 19863 */ 19864 Hash.prototype.destroy = function() { 19865 var handler, property; 19866 19867 $(window).off('hashchange.owl.navigation'); 19868 19869 for (handler in this._handlers) { 19870 this._core.$element.off(handler, this._handlers[handler]); 19871 } 19872 for (property in Object.getOwnPropertyNames(this)) { 19873 typeof this[property] != 'function' && (this[property] = null); 19874 } 19875 } 19876 19877 $.fn.owlCarouselAsia.Constructor.Plugins.Hash = Hash; 19878 19879})(window.Zepto || window.jQuery, window, document); 19880;
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.