1 2; /* Start:"a:4:{s:4:"full";s:29:"/js/script.js?172122556711515";s:6:"source";s:13:"/js/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 3$(function() { 4 var thisTex; 5 var regionSelectTex; 6 var regionName; 7 8 $('.vibor select ').change(function(){ 9 window.location.href = $(this).find('option:selected').val(); 10 }); 11 12 /****************************************************** 13 CITY CHANGE 14 *********************************************************/ 15 $(document).on('click', '.select span', function(){ 16 17 //показÑаеÑ/ÑбиÑаем панелÑÐºÑ Ð¿ÐµÑеклÑÑÐµÐ½Ð¸Ñ ÑзÑка на УÐÐ 18 if ( $(this).html() == "Ðиев" ) $('#lang').addClass('active'); 19 if ( $(this).html() != "Ðиев" ) $('#lang').removeClass('active'); 20 21 thisTex = $(this).closest('.select').html(); 22 regionSelectTex = $('.region-select').clone().removeClass('region-select').addClass('select'); 23 regionName = $(this).closest('.select').text(); 24 $(this).closest('.select').detach(); 25 $('.region-select').html(thisTex); 26 $('.point .hidden').prepend(regionSelectTex); 27 28 29 $.ajax({ 30 type: 'POST', 31 url: '/include/phone-ajax.php', 32 data: { name: regionName }, 33 cache: false, 34 dataType: 'json', 35 success: function(data) { 36 $('.phone-block .phone, .bottom-block .phone').html(data[0]); 37 $('.bottom-block .adress').html(data[1]); 38 $('a.contacts').attr('href',data[2]); 39 $('.icon-item .number').html(data[3]); 40 //new 41 $('.phoneNumber .number').html(data[3]); 42 $('.footer-form-office-mail').html(data[8]); 43 $(".footer-form-office-mail").attr("href", "mailto:"+data[8]); 44 45 if(data[4]){ 46 $('.review-block .name-block').html(data[4]); 47 $('.motivation-block .form-name').val(data[5]); 48 $('.motivation-block .form-address').val(data[6]); 49 $('#publicid').val(data[7]); 50 51 } 52 }, 53 }); 54 55 56 }); 57 58 /****************************************************** 59 LEFT MENU 60 *********************************************************/ 61 62 $('.menu-sidebar a, .sidebar-title a').each(function(){ 63 if ($(this).attr('href')==window.location.pathname + window.location.search) 64 { 65 $(this).closest('li').addClass('parent'); 66 $(this).before('<span>' + $(this).html() +'</span>'); 67 $(this).detach(); 68 } 69 }); 70 71 /*********************************************************** 72 SLIDER 73 ***********************************************************/ 74 function mycarousel_initCallback(carousel) 75 { 76 // Disable autoscrolling if the user clicks the prev or next button. 77 carousel.buttonNext.bind('click', function() { 78 carousel.startAuto(0); 79 }); 80 81 carousel.buttonPrev.bind('click', function() { 82 carousel.startAuto(0); 83 }); 84 85 // Pause autoscrolling if the user moves with the cursor over the clip. 86 carousel.clip.hover(function() { 87 carousel.stopAuto(); 88 }, function() { 89 carousel.startAuto(); 90 }); 91 }; 92 93 94 function photocarousel_initCallback(carousel) 95 { 96 97 } 98 var numberC; 99 var numbers; 100 $('.calc-wrap .jcarousel-next ').on('click', function() { 101 102 numberC = $(this).closest('.calc-wrap').find('#item-number').text(); 103 numbers = $(this).closest('.calc-wrap').find('#count').text(); 104 if(numberC == numbers) 105 { 106 $(this).closest('.calc-wrap').find('#item-number').text('1'); 107 } 108 else 109 { 110 111 $(this).closest('.calc-wrap').find('#item-number').text(numberC*1 + 1); 112 } 113 }); 114 115 $('.calc-wrap .jcarousel-prev').on('click', function() { 116 117 numberC = $(this).closest('.calc-wrap').find('#item-number').text(); 118 numbers = $(this).closest('.calc-wrap').find('#count').text(); 119 if(numberC == 1) 120 { 121 $(this).closest('.calc-wrap').find('#item-number').text(numbers); 122 } 123 else 124 { 125 126 $(this).closest('.calc-wrap').find('#item-number').text(numberC*1 - 1); 127 } 128 }); 129 130 jQuery('.photo-jcarousel').jcarousel({ 131 wrap: 'circular', 132 scroll : 1, 133 //auto: 4, // СколÑко ÑекÑнд деÑжиÑÑÑÑ ÐºÐ°ÑÑинка 134 initCallback: photocarousel_initCallback, 135 //animation : "slow", 136 buttonNextHTML: null, 137 buttonPrevHTML: null 138 }); 139 140 jQuery('.photo-jcarousel-universities').jcarousel({ 141 wrap: 'circular', 142 scroll : 1, 143 initCallback: photocarousel_initCallback, 144 buttonNextHTML: null, 145 buttonPrevHTML: null 146 }); 147 148 149 150 /*********************************************************** 151 SLIDER 152 ***********************************************************/
153 jQuery('#mycarousel').jcarousel({ 154 wrap: 'circular', 155 scroll : 1, 156 auto: 6, // СколÑко ÑекÑнд деÑжиÑÑÑÑ ÐºÐ°ÑÑинка 157 initCallback: mycarousel_initCallback, 158 animation : "slow" 159 }); 160 161 /****************************************************** 162 FEEDBACK 163 *********************************************************/ 164 $('a.popup').fancybox({ 165 'overlayShow': false, // знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов можно поÑмоÑÑеÑÑ Ð½Ð° ÑайÑе ÑазÑабоÑÑика 166 'padding': 0, 167 'margin' : 0, 168 'scrolling' : 'no', 169 'titleShow': false, 170 'type': 'ajax' // опиÑание ÑкÑипÑа бÑÐ´ÐµÑ Ð´Ð°Ð½Ð¾ ниже по ÑекÑÑÑ:) 171 }); 172 173 /****************************************************** 174 FEEDBACK 175 *********************************************************/ 176 177 178 179 $('a.callback').fancybox({ 180 'overlayShow': false, // знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов можно поÑмоÑÑеÑÑ Ð½Ð° ÑайÑе ÑазÑабоÑÑика 181 'padding': 0, 182 'margin' : 0, 183 'scrolling' : 'no', 184 'titleShow': false, 185 'type': 'ajax', 186 'href': '/include/callback.php', // опиÑание ÑкÑипÑа бÑÐ´ÐµÑ Ð´Ð°Ð½Ð¾ ниже по ÑекÑÑÑ:) 187 188 'afterShow': function(){ 189 190 var ManagerName; 191 var id = this.element.attr('id'); 192 if (id == "anna") 193 { 194 ManagerName = "ÐÐ½Ð½Ñ ÐÑлÑевой"; 195 mailq = "[email protected]"; 196 vtiger_id = "d0b9aa437a1905d43423c8de943b7459"; 197 } 198 if (id == "daria") 199 { 200 ManagerName = "ÐаÑÑи ÐилÑко"; 201 mailq = "[email protected]"; 202 vtiger_id = "41643998ca611cc5f7ba3aacf9ee03f7"; 203 } 204 if (id == "vikaf") 205 { 206 ManagerName = "ÐикÑоÑии ФÑид"; 207 mailq = "[email protected]"; 208 vtiger_id = "ab1cb1c649d75242e86aa3e549530cca"; 209 } 210 if (id == "yuliab") 211 { 212 ManagerName = "Юлии ÐоÑковой"; 213 mailq = "[email protected]"; 214 vtiger_id = "acc797172ded0a11f7ebd93f03dac7ea"; 215 } 216 if (id == "tatyanad") 217 { 218 ManagerName = "ТаÑÑÑÐ½Ñ ÐаÑÑовой"; 219 mailq = "[email protected]"; 220 vtiger_id = "b382fcb5dcd5b72876ec14d4fe680086"; 221 } 222 if (id == "elenab") 223 { 224 ManagerName = "ÐÐ»ÐµÐ½Ñ Ðлиман"; 225 mailq = "[email protected]"; 226 vtiger_id = "c417a16a70cad5b72ef63cf5da54d57d"; 227 } 228 if (id == "marina") 229 { 230 ManagerName = "ÐаÑÐ¸Ð½Ñ ÐлеÑкой"; 231 mailq = "[email protected]"; 232 vtiger_id = "41643998ca611cc5f7ba3aacf9ee03f7"; 233 } 234 if (id == "tetiana") 235 { 236 ManagerName = "ТеÑÑÐ½Ñ Ð¯Ñковой"; 237 mailq = "[email protected]"; 238 vtiger_id = "c5896998788c431280d05057df0d54fe"; 239 } 240 if (id == "cons") 241 { 242 ManagerName = "конÑÑлÑÑанÑа IQ Consultancy"; 243 mailq = "[email protected]"; 244 vtiger_id = "41643998ca611cc5f7ba3aacf9ee03f7"; 245 } 246 $('#for').html(ManagerName); 247 $('#publicid_expert').val(vtiger_id); 248 $( "#callback-q input[name='form_text_44']" ).val(ManagerName); 249 $( "#callback-q input[name='form_text_45']" ).val(mailq); 250 251 } 252 253 }); 254 255 }); 256 257 /****************************************************** 258 ÐÐÐÐÐÐТЬ GET ÐÐÐ ÐÐÐТРРURL 259 *********************************************************/ 260 function setAttr(prmName,val){ 261 var res = ''; 262 var d = location.href.split("#")[0].split("?"); 263 var base = d[0]; 264 var query = d[1]; 265 if(query) { 266 var params = query.split("&"); 267 for(var i = 0; i < params.length; i++) { 268 var keyval = params[i].split("="); 269 if(keyval[0] != prmName) { 270 res += params[i] + '&'; 271 } 272 } 273 } 274 res += prmName + '=' + val; 275 window.location.href = base + '?' + res; 276 return false; 277 } 278 279 /****************************************************** 280 TABS UNIVERSITY DETAIL 281 *********************************************************/ 282 $(function () { 283 var tabContainers = $('div.tab-wrapper'); // полÑÑаем маÑÑив конÑейнеÑов 284 tabContainers.css({'left':'-1000%' , 'position':'absolute'}).filter(':first').css({'left':'0' , 'position':'static'}); // пÑÑÑем вÑе, кÑоме пеÑвого 285 // далее обÑабаÑÑваеÑÑÑ ÐºÐ»Ð¸Ðº по вкладке 286 $('div.type-tubs ul.tabNavigation a').click(function () { 287 288 tabContainers.css({'left':'-1000%' , 'position':'absolute'}); // пÑÑÑем вÑе ÑÐ°Ð±Ñ 289 tabContainers.filter(this.hash).css({'left':'0' , 'position':'static'}); // показÑваем ÑодеÑжимое ÑекÑÑего 290 $('div.type-tubs ul.tabNavigation li').removeClass('selected'); // Ñ Ð²ÑÐµÑ ÑбиÑаем клаÑÑ 'selected' 291 $(this).parent().addClass('selected'); // ÑекÑÑей вкладке добавлÑем клаÑÑ 'selected' 292 return false;
293 }).filter(':first').click(); 294 }); 295 296 /****************************************************** 297 LOG FUNCTION 298 *********************************************************/ 299 function writeLog(responseData, textStatus, errorThrown) { 300 jQuery.ajax({ 301 type: 'POST', 302 url: '/log/js_client_side_logging.php', 303 data: { 304 responseData: responseData, 305 textStatus: textStatus, 306 errorThrown: errorThrown, 307 }, 308 success: function() { 309 if (console && console.log) { 310 //console.log('JS error report successful.'); 311 } 312 }, 313 error: function() { 314 if (console && console.error) { 315 //console.error('JS error report submission failed!'); 316 } 317 } 318 }); 319 } 320 321 /****************************************************** 322 ÐÐÐÐЧÐÐ ÐÐ LP СÐÐЫТÐЯХ 323 *********************************************************/ 324 $(function () { 325 $('#events_checklists .event_checkbox').change(function(){ 326 try { 327 var $this = $( this ); 328 if( $this.prop('checked') ) { 329 if ( $('#events_reg').val() == "" ) { 330 $('#events_reg').val( $this.attr('event_name') ); 331 } else { 332 $('#events_reg').val( $('#events_reg').val() + ", " + $this.attr('event_name') ); 333 } 334 } else { 335 var val = $('#events_reg').val(); 336 $('#events_reg').val( val.replace( $this.attr('event_name'), "") ); 337 } 338 } catch (e) { 339 writeLog(e.name, e.message, e.stack); 340 } 341 }); 342 }); 343 344 /****************************************************** 345 УбиÑÐ°ÐµÑ Ð¿ÑокÑÑÑÐºÑ google каÑÑ 346 *********************************************************/ 347 348 var onMapMouseleaveHandler = function (event) { 349 var that = $(this); 350 351 that.on('click', onMapClickHandler); 352 that.off('mouseleave', onMapMouseleaveHandler); 353 that.find('iframe').css("pointer-events", "none"); 354 } 355 356 var onMapClickHandler = function (event) { 357 var that = $(this); 358 359 // Disable the click handler until the user leaves the map area 360 that.off('click', onMapClickHandler); 361 362 // Enable scrolling zoom 363 that.find('iframe').css("pointer-events", "auto"); 364 365 // Handle the mouse leave event 366 that.on('mouseleave', onMapMouseleaveHandler); 367 } 368 369 // Enable map zooming with mouse scroll when the user clicks the map 370 $('.maps.embed-container').on('click', onMapClickHandler); 371 372/* End */ 373; 374; /* Start:"a:4:{s:4:"full";s:38:"/js/jquery.fancybox.js?172122556748706";s:6:"source";s:22:"/js/jquery.fancybox.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 375/*! 376 * fancyBox - jQuery Plugin 377 * version: 2.1.5 (Fri, 14 Jun 2013) 378 * @requires jQuery v1.6 or later 379 * 380 * Examples at http://fancyapps.com/fancybox/ 381 * License: www.fancyapps.com/fancybox/#license 382 * 383 * Copyright 2012 Janis Skarnelis - [email protected] 384 * 385 */ 386 387(function (window, document, $, undefined) { 388 "use strict"; 389 390 var H = $("html"), 391 W = $(window), 392 D = $(document), 393 F = $.fancybox = function () { 394 F.open.apply( this, arguments ); 395 }, 396 IE = navigator.userAgent.match(/msie/i), 397 didUpdate = null, 398 isTouch = document.createTouch !== undefined, 399 400 isQuery = function(obj) { 401 return obj && obj.hasOwnProperty && obj instanceof $; 402 }, 403 isString = function(str) { 404 return str && $.type(str) === "string"; 405 }, 406 isPercentage = function(str) { 407 return isString(str) && str.indexOf('%') > 0; 408 }, 409 isScrollable = function(el) { 410 return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); 411 }, 412 getScalar = function(orig, dim) { 413 var value = parseInt(orig, 10) || 0; 414 415 if (dim && isPercentage(orig)) { 416 value = F.getViewport()[ dim ] / 100 * value; 417 } 418 419 return Math.ceil(value); 420 }, 421 getValue = function(value, dim) { 422 return getScalar(value, dim) + 'px'; 423 }; 424 425 $.extend(F, { 426 // The current version of fancyBox 427 version: '2.1.5', 428 429 defaults: { 430 padding : 15, 431 margin : 20, 432 433 width : 800, 434 height : 600, 435 minWidth : 100, 436 minHeight : 100, 437 maxWidth : 9999, 438 maxHeight : 9999,
vendor: 16,174 bytes, lines 439-1135
439 pixelRatio: 1, // Set to 2 for retina display support 440 441 autoSize : true, 442 autoHeight : false, 443 autoWidth : false, 444 445 autoResize : true, 446 autoCenter : !isTouch, 447 fitToView : true, 448 aspectRatio : false, 449 topRatio : 0.5, 450 leftRatio : 0.5, 451 452 scrolling : 'auto', // 'auto', 'yes' or 'no' 453 wrapCSS : '', 454 455 arrows : true, 456 closeBtn : true, 457 closeClick : false, 458 nextClick : false, 459 mouseWheel : true, 460 autoPlay : false, 461 playSpeed : 3000, 462 preload : 3, 463 modal : false, 464 loop : true, 465 466 ajax : { 467 dataType : 'html', 468 headers : { 'X-fancyBox': true } 469 }, 470 iframe : { 471 scrolling : 'auto', 472 preload : true 473 }, 474 swf : { 475 wmode: 'transparent', 476 allowfullscreen : 'true', 477 allowscriptaccess : 'always' 478 }, 479 480 keys : { 481 next : { 482 13 : 'left', // enter 483 34 : 'up', // page down 484 39 : 'left', // right arrow 485 40 : 'up' // down arrow 486 }, 487 prev : { 488 8 : 'right', // backspace 489 33 : 'down', // page up 490 37 : 'right', // left arrow 491 38 : 'down' // up arrow 492 }, 493 close : [27], // escape key 494 play : [32], // space - start/stop slideshow 495 toggle : [70] // letter "f" - toggle fullscreen 496 }, 497 498 direction : { 499 next : 'left', 500 prev : 'right' 501 }, 502 503 scrollOutside : true, 504 505 // Override some properties 506 index : 0, 507 type : null, 508 href : null, 509 content : null, 510 title : null, 511 512 // HTML templates 513 tpl: { 514 wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 515 image : '<img class="fancybox-image" src="{href}" alt="" />', 516 iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>', 517 error : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 518 closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>', 519 next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>', 520 prev : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>' 521 }, 522 523 // Properties for each animation type 524 // Opening fancyBox 525 openEffect : 'fade', // 'elastic', 'fade' or 'none' 526 openSpeed : 250, 527 openEasing : 'swing', 528 openOpacity : true, 529 openMethod : 'zoomIn', 530 531 // Closing fancyBox 532 closeEffect : 'fade', // 'elastic', 'fade' or 'none' 533 closeSpeed : 250, 534 closeEasing : 'swing', 535 closeOpacity : true, 536 closeMethod : 'zoomOut', 537 538 // Changing next gallery item 539 nextEffect : 'elastic', // 'elastic', 'fade' or 'none' 540 nextSpeed : 250, 541 nextEasing : 'swing', 542 nextMethod : 'changeIn', 543 544 // Changing previous gallery item 545 prevEffect : 'elastic', // 'elastic', 'fade' or 'none' 546 prevSpeed : 250, 547 prevEasing : 'swing', 548 prevMethod : 'changeOut', 549 550 // Enable default helpers 551 helpers : { 552 overlay : true, 553 title : true 554 }, 555 556 // Callbacks 557 onCancel : $.noop, // If canceling 558 beforeLoad : $.noop, // Before loading 559 afterLoad : $.noop, // After loading 560 beforeShow : $.noop, // Before changing in current item 561 afterShow : $.noop, // After opening 562 beforeChange : $.noop, // Before changing gallery item 563 beforeClose : $.noop, // Before closing 564 afterClose : $.noop // After closing 565 }, 566 567 //Current state 568 group : {}, // Selected group 569 opts : {}, // Group options 570 previous : null, // Previous element 571 coming : null, // Element being loaded 572 current : null, // Currently loaded element 573 isActive : false, // Is activated 574 isOpen : false, // Is currently open 575 isOpened : false, // Have been fully opened at least once 576 577 wrap : null, 578 skin : null, 579 outer : null, 580 inner : null, 581 582 player : { 583 timer : null, 584 isActive : false 585 }, 586 587 // Loaders 588 ajaxLoad : null, 589 imgPreload : null, 590 591 // Some collections 592 transitions : {}, 593 helpers : {}, 594 595 /* 596 * Static methods 597 */ 598 599 open: function (group, opts) { 600 if (!group) { 601 return; 602 } 603 604 if (!$.isPlainObject(opts)) { 605 opts = {}; 606 } 607 608 // Close if already active 609 if (false === F.close(true)) { 610 return; 611 } 612 613 // Normalize group 614 if (!$.isArray(group)) { 615 group = isQuery(group) ? $(group).get() : [group]; 616 } 617 618 // Recheck if the type of each element is `object` and set content type (image, ajax, etc) 619 $.each(group, function(i, element) { 620 var obj = {}, 621 href, 622 title, 623 content, 624 type, 625 rez, 626 hrefParts, 627 selector; 628 629 if ($.type(element) === "object") { 630 // Check if is DOM element 631 if (element.nodeType) { 632 element = $(element); 633 } 634 635 if (isQuery(element)) { 636 obj = { 637 href : element.data('fancybox-href') || element.attr('href'), 638 title : element.data('fancybox-title') || element.attr('title'), 639 isDom : true, 640 element : element 641 }; 642 643 if ($.metadata) { 644 $.extend(true, obj, element.metadata()); 645 } 646 647 } else { 648 obj = element; 649 } 650 } 651 652 href = opts.href || obj.href || (isString(element) ? element : null); 653 title = opts.title !== undefined ? opts.title : obj.title || ''; 654 655 content = opts.content || obj.content; 656 type = content ? 'html' : (opts.type || obj.type); 657 658 if (!type && obj.isDom) { 659 type = element.data('fancybox-type'); 660 661 if (!type) { 662 rez = element.prop('class').match(/fancybox\.(\w+)/); 663 type = rez ? rez[1] : null; 664 } 665 } 666 667 if (isString(href)) { 668 // Try to guess the content type 669 if (!type) { 670 if (F.isImage(href)) { 671 type = 'image'; 672 673 } else if (F.isSWF(href)) { 674 type = 'swf'; 675 676 } else if (href.charAt(0) === '#') { 677 type = 'inline'; 678 679 } else if (isString(element)) { 680 type = 'html'; 681 content = element; 682 } 683 } 684 685 // Split url into two pieces with source url and content selector, e.g, 686 // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" 687 if (type === 'ajax') { 688 hrefParts = href.split(/\s+/, 2); 689 href = hrefParts.shift(); 690 selector = hrefParts.shift(); 691 } 692 } 693 694 if (!content) { 695 if (type === 'inline') { 696 if (href) { 697 content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 698 699 } else if (obj.isDom) { 700 content = element; 701 } 702 703 } else if (type === 'html') { 704 content = href; 705 706 } else if (!type && !href && obj.isDom) { 707 type = 'inline'; 708 content = element; 709 } 710 } 711 712 $.extend(obj, { 713 href : href, 714 type : type, 715 content : content, 716 title : title, 717 selector : selector 718 }); 719 720 group[ i ] = obj; 721 }); 722 723 // Extend the defaults 724 F.opts = $.extend(true, {}, F.defaults, opts); 725 726 // All options are merged recursive except keys 727 if (opts.keys !== undefined) { 728 F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; 729 } 730 731 F.group = group; 732 733 return F._start(F.opts.index); 734 }, 735 736 // Cancel image loading or abort ajax request 737 cancel: function () { 738 var coming = F.coming; 739 740 if (!coming || false === F.trigger('onCancel')) { 741 return; 742 } 743 744 F.hideLoading(); 745 746 if (F.ajaxLoad) { 747 F.ajaxLoad.abort(); 748 } 749 750 F.ajaxLoad = null; 751 752 if (F.imgPreload) { 753 F.imgPreload.onload = F.imgPreload.onerror = null; 754 } 755 756 if (coming.wrap) { 757 coming.wrap.stop(true, true).trigger('onReset').remove(); 758 } 759 760 F.coming = null; 761 762 // If the first item has been canceled, then clear everything 763 if (!F.current) { 764 F._afterZoomOut( coming ); 765 } 766 }, 767 768 // Start closing animation if is open; remove immediately if opening/closing 769 close: function (event) { 770 F.cancel(); 771 772 if (false === F.trigger('beforeClose')) { 773 return; 774 } 775 776 F.unbindEvents(); 777 778 if (!F.isActive) { 779 return; 780 } 781 782 if (!F.isOpen || event === true) { 783 $('.fancybox-wrap').stop(true).trigger('onReset').remove(); 784 785 F._afterZoomOut(); 786 787 } else { 788 F.isOpen = F.isOpened = false; 789 F.isClosing = true; 790 791 $('.fancybox-item, .fancybox-nav').remove(); 792 793 F.wrap.stop(true, true).removeClass('fancybox-opened'); 794 795 F.transitions[ F.current.closeMethod ](); 796 } 797 }, 798 799 // Manage slideshow: 800 // $.fancybox.play(); - toggle slideshow 801 // $.fancybox.play( true ); - start 802 // $.fancybox.play( false ); - stop 803 play: function ( action ) { 804 var clear = function () { 805 clearTimeout(F.player.timer); 806 }, 807 set = function () { 808 clear(); 809 810 if (F.current && F.player.isActive) { 811 F.player.timer = setTimeout(F.next, F.current.playSpeed); 812 } 813 }, 814 stop = function () { 815 clear(); 816 817 D.unbind('.player'); 818 819 F.player.isActive = false; 820 821 F.trigger('onPlayEnd'); 822 }, 823 start = function () { 824 if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { 825 F.player.isActive = true; 826 827 D.bind({ 828 'onCancel.player beforeClose.player' : stop, 829 'onUpdate.player' : set, 830 'beforeLoad.player' : clear 831 }); 832 833 set(); 834 835 F.trigger('onPlayStart'); 836 } 837 }; 838 839 if (action === true || (!F.player.isActive && action !== false)) { 840 start(); 841 } else { 842 stop(); 843 } 844 }, 845 846 // Navigate to next gallery item 847 next: function ( direction ) { 848 var current = F.current; 849 850 if (current) { 851 if (!isString(direction)) { 852 direction = current.direction.next; 853 } 854 855 F.jumpto(current.index + 1, direction, 'next'); 856 } 857 }, 858 859 // Navigate to previous gallery item 860 prev: function ( direction ) { 861 var current = F.current; 862 863 if (current) { 864 if (!isString(direction)) { 865 direction = current.direction.prev; 866 } 867 868 F.jumpto(current.index - 1, direction, 'prev'); 869 } 870 }, 871 872 // Navigate to gallery item by index 873 jumpto: function ( index, direction, router ) { 874 var current = F.current; 875 876 if (!current) { 877 return; 878 } 879 880 index = getScalar(index); 881 882 F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; 883 F.router = router || 'jumpto'; 884 885 if (current.loop) { 886 if (index < 0) { 887 index = current.group.length + (index % current.group.length); 888 } 889 890 index = index % current.group.length; 891 } 892 893 if (current.group[ index ] !== undefined) { 894 F.cancel(); 895 896 F._start(index); 897 } 898 }, 899 900 // Center inside viewport and toggle position type to fixed or absolute if needed 901 reposition: function (e, onlyAbsolute) { 902 var current = F.current, 903 wrap = current ? current.wrap : null, 904 pos; 905 906 if (wrap) { 907 pos = F._getPosition(onlyAbsolute); 908 909 if (e && e.type === 'scroll') { 910 delete pos.position; 911 912 wrap.stop(true, true).animate(pos, 200); 913 914 } else { 915 wrap.css(pos); 916 917 current.pos = $.extend({}, current.dim, pos); 918 } 919 } 920 }, 921 922 update: function (e) { 923 var type = (e && e.type), 924 anyway = !type || type === 'orientationchange'; 925 926 if (anyway) { 927 clearTimeout(didUpdate); 928 929 didUpdate = null; 930 } 931 932 if (!F.isOpen || didUpdate) { 933 return; 934 } 935 936 didUpdate = setTimeout(function() { 937 var current = F.current; 938 939 if (!current || F.isClosing) { 940 return; 941 } 942 943 F.wrap.removeClass('fancybox-tmp'); 944 945 if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { 946 F._setDimension(); 947 } 948 949 if (!(type === 'scroll' && current.canShrink)) { 950 F.reposition(e); 951 } 952 953 F.trigger('onUpdate'); 954 955 didUpdate = null; 956 957 }, (anyway && !isTouch ? 0 : 300)); 958 }, 959 960 // Shrink content to fit inside viewport or restore if resized 961 toggle: function ( action ) { 962 if (F.isOpen) { 963 F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; 964 965 // Help browser to restore document dimensions 966 if (isTouch) { 967 F.wrap.removeAttr('style').addClass('fancybox-tmp'); 968 969 F.trigger('onUpdate'); 970 } 971 972 F.update(); 973 } 974 }, 975 976 hideLoading: function () { 977 D.unbind('.loading'); 978 979 $('#fancybox-loading').remove(); 980 }, 981 982 showLoading: function () { 983 var el, viewport; 984 985 F.hideLoading(); 986 987 el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body'); 988 989 // If user will press the escape-button, the request will be canceled 990 D.bind('keydown.loading', function(e) { 991 if ((e.which || e.keyCode) === 27) { 992 e.preventDefault(); 993 994 F.cancel(); 995 } 996 }); 997 998 if (!F.defaults.fixed) { 999 viewport = F.getViewport(); 1000 1001 el.css({ 1002 position : 'absolute', 1003 top : (viewport.h * 0.5) + viewport.y, 1004 left : (viewport.w * 0.5) + viewport.x 1005 }); 1006 } 1007 }, 1008 1009 getViewport: function () { 1010 var locked = (F.current && F.current.locked) || false, 1011 rez = { 1012 x: W.scrollLeft(), 1013 y: W.scrollTop() 1014 }; 1015 1016 if (locked) { 1017 rez.w = locked[0].clientWidth; 1018 rez.h = locked[0].clientHeight; 1019 1020 } else { 1021 // See http://bugs.jquery.com/ticket/6724 1022 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); 1023 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); 1024 } 1025 1026 return rez; 1027 }, 1028 1029 // Unbind the keyboard / clicking actions 1030 unbindEvents: function () { 1031 if (F.wrap && isQuery(F.wrap)) { 1032 F.wrap.unbind('.fb'); 1033 } 1034 1035 D.unbind('.fb'); 1036 W.unbind('.fb'); 1037 }, 1038 1039 bindEvents: function () { 1040 var current = F.current, 1041 keys; 1042 1043 if (!current) { 1044 return; 1045 } 1046 1047 // Changing document height on iOS devices triggers a 'resize' event, 1048 // that can change document height... repeating infinitely 1049 W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); 1050 1051 keys = current.keys; 1052 1053 if (keys) { 1054 D.bind('keydown.fb', function (e) { 1055 var code = e.which || e.keyCode, 1056 target = e.target || e.srcElement; 1057 1058 // Skip esc key if loading, because showLoading will cancel preloading 1059 if (code === 27 && F.coming) { 1060 return false; 1061 } 1062 1063 // Ignore key combinations and key events within form elements 1064 if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { 1065 $.each(keys, function(i, val) { 1066 if (current.group.length > 1 && val[ code ] !== undefined) { 1067 F[ i ]( val[ code ] ); 1068 1069 e.preventDefault(); 1070 return false; 1071 } 1072 1073 if ($.inArray(code, val) > -1) { 1074 F[ i ] (); 1075 1076 e.preventDefault(); 1077 return false; 1078 } 1079 }); 1080 } 1081 }); 1082 } 1083 1084 if ($.fn.mousewheel && current.mouseWheel) { 1085 F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) { 1086 var target = e.target || null, 1087 parent = $(target), 1088 canScroll = false; 1089 1090 while (parent.length) { 1091 if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { 1092 break; 1093 } 1094 1095 canScroll = isScrollable( parent[0] ); 1096 parent = $(parent).parent(); 1097 } 1098 1099 if (delta !== 0 && !canScroll) { 1100 if (F.group.length > 1 && !current.canShrink) { 1101 if (deltaY > 0 || deltaX > 0) { 1102 F.prev( deltaY > 0 ? 'down' : 'left' ); 1103 1104 } else if (deltaY < 0 || deltaX < 0) { 1105 F.next( deltaY < 0 ? 'up' : 'right' ); 1106 } 1107 1108 e.preventDefault(); 1109 } 1110 } 1111 }); 1112 } 1113 }, 1114 1115 trigger: function (event, o) { 1116 var ret, obj = o || F.coming || F.current; 1117 1118 if (!obj) { 1119 return; 1120 } 1121 1122 if ($.isFunction( obj[event] )) { 1123 ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); 1124 } 1125 1126 if (ret === false) { 1127 return false; 1128 } 1129 1130 if (obj.helpers) { 1131 $.each(obj.helpers, function (helper, opts) { 1132 if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { 1133 F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj); 1134 } 1135 });
vendor: 8,050 bytes, lines 1135-1494
1135 1136 } 1137 1138 D.trigger(event); 1139 }, 1140 1141 isImage: function (str) { 1142 return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i); 1143 }, 1144 1145 isSWF: function (str) { 1146 return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i); 1147 }, 1148 1149 _start: function (index) { 1150 var coming = {}, 1151 obj, 1152 href, 1153 type, 1154 margin, 1155 padding; 1156 1157 index = getScalar( index ); 1158 obj = F.group[ index ] || null; 1159 1160 if (!obj) { 1161 return false; 1162 } 1163 1164 coming = $.extend(true, {}, F.opts, obj); 1165 1166 // Convert margin and padding properties to array - top, right, bottom, left 1167 margin = coming.margin; 1168 padding = coming.padding; 1169 1170 if ($.type(margin) === 'number') { 1171 coming.margin = [margin, margin, margin, margin]; 1172 } 1173 1174 if ($.type(padding) === 'number') { 1175 coming.padding = [padding, padding, padding, padding]; 1176 } 1177 1178 // 'modal' propery is just a shortcut 1179 if (coming.modal) { 1180 $.extend(true, coming, { 1181 closeBtn : false, 1182 closeClick : false, 1183 nextClick : false, 1184 arrows : false, 1185 mouseWheel : false, 1186 keys : null, 1187 helpers: { 1188 overlay : { 1189 closeClick : false 1190 } 1191 } 1192 }); 1193 } 1194 1195 // 'autoSize' property is a shortcut, too 1196 if (coming.autoSize) { 1197 coming.autoWidth = coming.autoHeight = true; 1198 } 1199 1200 if (coming.width === 'auto') { 1201 coming.autoWidth = true; 1202 } 1203 1204 if (coming.height === 'auto') { 1205 coming.autoHeight = true; 1206 } 1207 1208 /* 1209 * Add reference to the group, so it`s possible to access from callbacks, example: 1210 * afterLoad : function() { 1211 * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); 1212 * } 1213 */ 1214 1215 coming.group = F.group; 1216 coming.index = index; 1217 1218 // Give a chance for callback or helpers to update coming item (type, title, etc) 1219 F.coming = coming; 1220 1221 if (false === F.trigger('beforeLoad')) { 1222 F.coming = null; 1223 1224 return; 1225 } 1226 1227 type = coming.type; 1228 href = coming.href; 1229 1230 if (!type) { 1231 F.coming = null; 1232 1233 //If we can not determine content type then drop silently or display next/prev item if looping through gallery 1234 if (F.current && F.router && F.router !== 'jumpto') { 1235 F.current.index = index; 1236 1237 return F[ F.router ]( F.direction ); 1238 } 1239 1240 return false; 1241 } 1242 1243 F.isActive = true; 1244 1245 if (type === 'image' || type === 'swf') { 1246 coming.autoHeight = coming.autoWidth = false; 1247 coming.scrolling = 'visible'; 1248 } 1249 1250 if (type === 'image') { 1251 coming.aspectRatio = true; 1252 } 1253 1254 if (type === 'iframe' && isTouch) { 1255 coming.scrolling = 'scroll'; 1256 } 1257 1258 // Build the neccessary markup 1259 coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); 1260 1261 $.extend(coming, { 1262 skin : $('.fancybox-skin', coming.wrap), 1263 outer : $('.fancybox-outer', coming.wrap), 1264 inner : $('.fancybox-inner', coming.wrap) 1265 }); 1266 1267 $.each(["Top", "Right", "Bottom", "Left"], function(i, v) { 1268 coming.skin.css('padding' + v, getValue(coming.padding[ i ])); 1269 }); 1270 1271 F.trigger('onReady'); 1272 1273 // Check before try to load; 'inline' and 'html' types need content, others - href 1274 if (type === 'inline' || type === 'html') { 1275 if (!coming.content || !coming.content.length) { 1276 return F._error( 'content' ); 1277 } 1278 1279 } else if (!href) { 1280 return F._error( 'href' ); 1281 } 1282 1283 if (type === 'image') { 1284 F._loadImage(); 1285 1286 } else if (type === 'ajax') { 1287 F._loadAjax(); 1288 1289 } else if (type === 'iframe') { 1290 F._loadIframe(); 1291 1292 } else { 1293 F._afterLoad(); 1294 } 1295 }, 1296 1297 _error: function ( type ) { 1298 $.extend(F.coming, { 1299 type : 'html', 1300 autoWidth : true, 1301 autoHeight : true, 1302 minWidth : 0, 1303 minHeight : 0, 1304 scrolling : 'no', 1305 hasError : type, 1306 content : F.coming.tpl.error 1307 }); 1308 1309 F._afterLoad(); 1310 }, 1311 1312 _loadImage: function () { 1313 // Reset preload image so it is later possible to check "complete" property 1314 var img = F.imgPreload = new Image(); 1315 1316 img.onload = function () { 1317 this.onload = this.onerror = null; 1318 1319 F.coming.width = this.width / F.opts.pixelRatio; 1320 F.coming.height = this.height / F.opts.pixelRatio; 1321 1322 F._afterLoad(); 1323 }; 1324 1325 img.onerror = function () { 1326 this.onload = this.onerror = null; 1327 1328 F._error( 'image' ); 1329 }; 1330 1331 img.src = F.coming.href; 1332 1333 if (img.complete !== true) { 1334 F.showLoading(); 1335 } 1336 }, 1337 1338 _loadAjax: function () { 1339 var coming = F.coming; 1340 1341 F.showLoading(); 1342 1343 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { 1344 url: coming.href, 1345 error: function (jqXHR, textStatus) { 1346 if (F.coming && textStatus !== 'abort') { 1347 F._error( 'ajax', jqXHR ); 1348 1349 } else { 1350 F.hideLoading(); 1351 } 1352 }, 1353 success: function (data, textStatus) { 1354 if (textStatus === 'success') { 1355 coming.content = data; 1356 1357 F._afterLoad(); 1358 } 1359 } 1360 })); 1361 }, 1362 1363 _loadIframe: function() { 1364 var coming = F.coming, 1365 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) 1366 .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling) 1367 .attr('src', coming.href); 1368 1369 // This helps IE 1370 $(coming.wrap).bind('onReset', function () { 1371 try { 1372 $(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); 1373 } catch (e) {} 1374 }); 1375 1376 if (coming.iframe.preload) { 1377 F.showLoading(); 1378 1379 iframe.one('load', function() { 1380 $(this).data('ready', 1); 1381 1382 // iOS will lose scrolling if we resize 1383 if (!isTouch) { 1384 $(this).bind('load.fb', F.update); 1385 } 1386 1387 // Without this trick: 1388 // - iframe won't scroll on iOS devices 1389 // - IE7 sometimes displays empty iframe 1390 $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); 1391 1392 F._afterLoad(); 1393 }); 1394 } 1395 1396 coming.content = iframe.appendTo( coming.inner ); 1397 1398 if (!coming.iframe.preload) { 1399 F._afterLoad(); 1400 } 1401 }, 1402 1403 _preloadImages: function() { 1404 var group = F.group, 1405 current = F.current, 1406 len = group.length, 1407 cnt = current.preload ? Math.min(current.preload, len - 1) : 0, 1408 item, 1409 i; 1410 1411 for (i = 1; i <= cnt; i += 1) { 1412 item = group[ (current.index + i ) % len ]; 1413 1414 if (item.type === 'image' && item.href) { 1415 new Image().src = item.href; 1416 } 1417 } 1418 }, 1419 1420 _afterLoad: function () { 1421 var coming = F.coming, 1422 previous = F.current, 1423 placeholder = 'fancybox-placeholder', 1424 current, 1425 content, 1426 type, 1427 scrolling, 1428 href, 1429 embed; 1430 1431 F.hideLoading(); 1432 1433 if (!coming || F.isActive === false) { 1434 return; 1435 } 1436 1437 if (false === F.trigger('afterLoad', coming, previous)) { 1438 coming.wrap.stop(true).trigger('onReset').remove(); 1439 1440 F.coming = null; 1441 1442 return; 1443 } 1444 1445 if (previous) { 1446 F.trigger('beforeChange', previous); 1447 1448 previous.wrap.stop(true).removeClass('fancybox-opened') 1449 .find('.fancybox-item, .fancybox-nav') 1450 .remove(); 1451 } 1452 1453 F.unbindEvents(); 1454 1455 current = coming; 1456 content = coming.content; 1457 type = coming.type; 1458 scrolling = coming.scrolling; 1459 1460 $.extend(F, { 1461 wrap : current.wrap, 1462 skin : current.skin, 1463 outer : current.outer, 1464 inner : current.inner, 1465 current : current, 1466 previous : previous 1467 }); 1468 1469 href = current.href; 1470 1471 switch (type) { 1472 case 'inline': 1473 case 'ajax': 1474 case 'html': 1475 if (current.selector) { 1476 content = $('<div>').html(content).find(current.selector); 1477 1478 } else if (isQuery(content)) { 1479 if (!content.data(placeholder)) { 1480 content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() ); 1481 } 1482 1483 content = content.show().detach(); 1484 1485 current.wrap.bind('onReset', function () { 1486 if ($(this).find(content).length) { 1487 content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false); 1488 } 1489 }); 1490 } 1491 break; 1492 1493 case 'image': 1494 content = current.tpl.image.replace(
vendor: 14,919 bytes, lines 1494-2063
1494'{href}', href); 1495 break; 1496 1497 case 'swf': 1498 content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>'; 1499 embed = ''; 1500 1501 $.each(current.swf, function(name, val) { 1502 content += '<param name="' + name + '" value="' + val + '"></param>'; 1503 embed += ' ' + name + '="' + val + '"'; 1504 }); 1505 1506 content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>'; 1507 break; 1508 } 1509 1510 if (!(isQuery(content) && content.parent().is(current.inner))) { 1511 current.inner.append( content ); 1512 } 1513 1514 // Give a chance for helpers or callbacks to update elements 1515 F.trigger('beforeShow'); 1516 1517 // Set scrolling before calculating dimensions 1518 current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); 1519 1520 // Set initial dimensions and start position 1521 F._setDimension(); 1522 1523 F.reposition(); 1524 1525 F.isOpen = false; 1526 F.coming = null; 1527 1528 F.bindEvents(); 1529 1530 if (!F.isOpened) { 1531 $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); 1532 1533 } else if (previous.prevMethod) { 1534 F.transitions[ previous.prevMethod ](); 1535 } 1536 1537 F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); 1538 1539 F._preloadImages(); 1540 }, 1541 1542 _setDimension: function () { 1543 var viewport = F.getViewport(), 1544 steps = 0, 1545 canShrink = false, 1546 canExpand = false, 1547 wrap = F.wrap, 1548 skin = F.skin, 1549 inner = F.inner, 1550 current = F.current, 1551 width = current.width, 1552 height = current.height, 1553 minWidth = current.minWidth, 1554 minHeight = current.minHeight, 1555 maxWidth = current.maxWidth, 1556 maxHeight = current.maxHeight, 1557 scrolling = current.scrolling, 1558 scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, 1559 margin = current.margin, 1560 wMargin = getScalar(margin[1] + margin[3]), 1561 hMargin = getScalar(margin[0] + margin[2]), 1562 wPadding, 1563 hPadding, 1564 wSpace, 1565 hSpace, 1566 origWidth, 1567 origHeight, 1568 origMaxWidth, 1569 origMaxHeight, 1570 ratio, 1571 width_, 1572 height_, 1573 maxWidth_, 1574 maxHeight_, 1575 iframe, 1576 body; 1577 1578 // Reset dimensions so we could re-check actual size 1579 wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); 1580 1581 wPadding = getScalar(skin.outerWidth(true) - skin.width()); 1582 hPadding = getScalar(skin.outerHeight(true) - skin.height()); 1583 1584 // Any space between content and viewport (margin, padding, border, title) 1585 wSpace = wMargin + wPadding; 1586 hSpace = hMargin + hPadding; 1587 1588 origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; 1589 origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; 1590 1591 if (current.type === 'iframe') { 1592 iframe = current.content; 1593 1594 if (current.autoHeight && iframe.data('ready') === 1) { 1595 try { 1596 if (iframe[0].contentWindow.document.location) { 1597 inner.width( origWidth ).height(9999); 1598 1599 body = iframe.contents().find('body'); 1600 1601 if (scrollOut) { 1602 body.css('overflow-x', 'hidden'); 1603 } 1604 1605 origHeight = body.outerHeight(true); 1606 } 1607 1608 } catch (e) {} 1609 } 1610 1611 } else if (current.autoWidth || current.autoHeight) { 1612 inner.addClass( 'fancybox-tmp' ); 1613 1614 // Set width or height in case we need to calculate only one dimension 1615 if (!current.autoWidth) { 1616 inner.width( origWidth ); 1617 } 1618 1619 if (!current.autoHeight) { 1620 inner.height( origHeight ); 1621 } 1622 1623 if (current.autoWidth) { 1624 origWidth = inner.width(); 1625 } 1626 1627 if (current.autoHeight) { 1628 origHeight = inner.height(); 1629 } 1630 1631 inner.removeClass( 'fancybox-tmp' ); 1632 } 1633 1634 width = getScalar( origWidth ); 1635 height = getScalar( origHeight ); 1636 1637 ratio = origWidth / origHeight; 1638 1639 // Calculations for the content 1640 minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); 1641 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); 1642 1643 minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); 1644 maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); 1645 1646 // These will be used to determine if wrap can fit in the viewport 1647 origMaxWidth = maxWidth; 1648 origMaxHeight = maxHeight; 1649 1650 if (current.fitToView) { 1651 maxWidth = Math.min(viewport.w - wSpace, maxWidth); 1652 maxHeight = Math.min(viewport.h - hSpace, maxHeight); 1653 } 1654 1655 maxWidth_ = viewport.w - wMargin; 1656 maxHeight_ = viewport.h - hMargin; 1657 1658 if (current.aspectRatio) { 1659 if (width > maxWidth) { 1660 width = maxWidth; 1661 height = getScalar(width / ratio); 1662 } 1663 1664 if (height > maxHeight) { 1665 height = maxHeight; 1666 width = getScalar(height * ratio); 1667 } 1668 1669 if (width < minWidth) { 1670 width = minWidth; 1671 height = getScalar(width / ratio); 1672 } 1673 1674 if (height < minHeight) { 1675 height = minHeight; 1676 width = getScalar(height * ratio); 1677 } 1678 1679 } else { 1680 width = Math.max(minWidth, Math.min(width, maxWidth)); 1681 1682 if (current.autoHeight && current.type !== 'iframe') { 1683 inner.width( width ); 1684 1685 height = inner.height(); 1686 } 1687 1688 height = Math.max(minHeight, Math.min(height, maxHeight)); 1689 } 1690 1691 // Try to fit inside viewport (including the title) 1692 if (current.fitToView) { 1693 inner.width( width ).height( height ); 1694 1695 wrap.width( width + wPadding ); 1696 1697 // Real wrap dimensions 1698 width_ = wrap.width(); 1699 height_ = wrap.height(); 1700 1701 if (current.aspectRatio) { 1702 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { 1703 if (steps++ > 19) { 1704 break; 1705 } 1706 1707 height = Math.max(minHeight, Math.min(maxHeight, height - 10)); 1708 width = getScalar(height * ratio); 1709 1710 if (width < minWidth) { 1711 width = minWidth; 1712 height = getScalar(width / ratio); 1713 } 1714 1715 if (width > maxWidth) { 1716 width = maxWidth; 1717 height = getScalar(width / ratio); 1718 } 1719 1720 inner.width( width ).height( height ); 1721 1722 wrap.width( width + wPadding ); 1723 1724 width_ = wrap.width(); 1725 height_ = wrap.height(); 1726 } 1727 1728 } else { 1729 width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); 1730 height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); 1731 } 1732 } 1733 1734 if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { 1735 width += scrollOut; 1736 } 1737 1738 inner.width( width ).height( height ); 1739 1740 wrap.width( width + wPadding ); 1741 1742 width_ = wrap.width(); 1743 height_ = wrap.height(); 1744 1745 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; 1746 canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); 1747 1748 $.extend(current, { 1749 dim : { 1750 width : getValue( width_ ), 1751 height : getValue( height_ ) 1752 }, 1753 origWidth : origWidth, 1754 origHeight : origHeight, 1755 canShrink : canShrink, 1756 canExpand : canExpand, 1757 wPadding : wPadding, 1758 hPadding : hPadding, 1759 wrapSpace : height_ - skin.outerHeight(true), 1760 skinSpace : skin.height() - height 1761 }); 1762 1763 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { 1764 inner.height('auto'); 1765 } 1766 }, 1767 1768 _getPosition: function (onlyAbsolute) { 1769 var current = F.current, 1770 viewport = F.getViewport(), 1771 margin = current.margin, 1772 width = F.wrap.width() + margin[1] + margin[3], 1773 height = F.wrap.height() + margin[0] + margin[2], 1774 rez = { 1775 position: 'absolute', 1776 top : margin[0], 1777 left : margin[3] 1778 }; 1779 1780 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { 1781 rez.position = 'fixed'; 1782 1783 } else if (!current.locked) { 1784 rez.top += viewport.y; 1785 rez.left += viewport.x; 1786 } 1787 1788 rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); 1789 rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); 1790 1791 return rez; 1792 }, 1793 1794 _afterZoomIn: function () { 1795 var current = F.current; 1796 1797 if (!current) { 1798 return; 1799 } 1800 1801 F.isOpen = F.isOpened = true; 1802 1803 F.wrap.css('overflow', 'visible').addClass('fancybox-opened'); 1804 1805 F.update(); 1806 1807 // Assign a click event 1808 if ( current.closeClick || (current.nextClick && F.group.length > 1) ) { 1809 F.inner.css('cursor', 'pointer').bind('click.fb', function(e) { 1810 if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { 1811 e.preventDefault(); 1812 1813 F[ current.closeClick ? 'close' : 'next' ](); 1814 } 1815 }); 1816 } 1817 1818 // Create a close button 1819 if (current.closeBtn) { 1820 $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) { 1821 e.preventDefault(); 1822 1823 F.close(); 1824 }); 1825 } 1826 1827 // Create navigation arrows 1828 if (current.arrows && F.group.length > 1) { 1829 if (current.loop || current.index > 0) { 1830 $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev); 1831 } 1832 1833 if (current.loop || current.index < F.group.length - 1) { 1834 $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next); 1835 } 1836 } 1837 1838 F.trigger('afterShow'); 1839 1840 // Stop the slideshow if this is the last item 1841 if (!current.loop && current.index === current.group.length - 1) { 1842 F.play( false ); 1843 1844 } else if (F.opts.autoPlay && !F.player.isActive) { 1845 F.opts.autoPlay = false; 1846 1847 F.play(); 1848 } 1849 }, 1850 1851 _afterZoomOut: function ( obj ) { 1852 obj = obj || F.current; 1853 1854 $('.fancybox-wrap').trigger('onReset').remove(); 1855 1856 $.extend(F, { 1857 group : {}, 1858 opts : {}, 1859 router : false, 1860 current : null, 1861 isActive : false, 1862 isOpened : false, 1863 isOpen : false, 1864 isClosing : false, 1865 wrap : null, 1866 skin : null, 1867 outer : null, 1868 inner : null 1869 }); 1870 1871 F.trigger('afterClose', obj); 1872 } 1873 }); 1874 1875 /* 1876 * Default transitions 1877 */ 1878 1879 F.transitions = { 1880 getOrigPosition: function () { 1881 var current = F.current, 1882 element = current.element, 1883 orig = current.orig, 1884 pos = {}, 1885 width = 50, 1886 height = 50, 1887 hPadding = current.hPadding, 1888 wPadding = current.wPadding, 1889 viewport = F.getViewport(); 1890 1891 if (!orig && current.isDom && element.is(':visible')) { 1892 orig = element.find('img:first'); 1893 1894 if (!orig.length) { 1895 orig = element; 1896 } 1897 } 1898 1899 if (isQuery(orig)) { 1900 pos = orig.offset(); 1901 1902 if (orig.is('img')) { 1903 width = orig.outerWidth(); 1904 height = orig.outerHeight(); 1905 } 1906 1907 } else { 1908 pos.top = viewport.y + (viewport.h - height) * current.topRatio; 1909 pos.left = viewport.x + (viewport.w - width) * current.leftRatio; 1910 } 1911 1912 if (F.wrap.css('position') === 'fixed' || current.locked) { 1913 pos.top -= viewport.y; 1914 pos.left -= viewport.x; 1915 } 1916 1917 pos = { 1918 top : getValue(pos.top - hPadding * current.topRatio), 1919 left : getValue(pos.left - wPadding * current.leftRatio), 1920 width : getValue(width + wPadding), 1921 height : getValue(height + hPadding) 1922 }; 1923 1924 return pos; 1925 }, 1926 1927 step: function (now, fx) { 1928 var ratio, 1929 padding, 1930 value, 1931 prop = fx.prop, 1932 current = F.current, 1933 wrapSpace = current.wrapSpace, 1934 skinSpace = current.skinSpace; 1935 1936 if (prop === 'width' || prop === 'height') { 1937 ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); 1938 1939 if (F.isClosing) { 1940 ratio = 1 - ratio; 1941 } 1942 1943 padding = prop === 'width' ? current.wPadding : current.hPadding; 1944 value = now - padding; 1945 1946 F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); 1947 F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); 1948 } 1949 }, 1950 1951 zoomIn: function () { 1952 var current = F.current, 1953 startPos = current.pos, 1954 effect = current.openEffect, 1955 elastic = effect === 'elastic', 1956 endPos = $.extend({opacity : 1}, startPos); 1957 1958 // Remove "position" property that breaks older IE 1959 delete endPos.position; 1960 1961 if (elastic) { 1962 startPos = this.getOrigPosition(); 1963 1964 if (current.openOpacity) { 1965 startPos.opacity = 0.1; 1966 } 1967 1968 } else if (effect === 'fade') { 1969 startPos.opacity = 0.1; 1970 } 1971 1972 F.wrap.css(startPos).animate(endPos, { 1973 duration : effect === 'none' ? 0 : current.openSpeed, 1974 easing : current.openEasing, 1975 step : elastic ? this.step : null, 1976 complete : F._afterZoomIn 1977 }); 1978 }, 1979 1980 zoomOut: function () { 1981 var current = F.current, 1982 effect = current.closeEffect, 1983 elastic = effect === 'elastic', 1984 endPos = {opacity : 0.1}; 1985 1986 if (elastic) { 1987 endPos = this.getOrigPosition(); 1988 1989 if (current.closeOpacity) { 1990 endPos.opacity = 0.1; 1991 } 1992 } 1993 1994 F.wrap.animate(endPos, { 1995 duration : effect === 'none' ? 0 : current.closeSpeed, 1996 easing : current.closeEasing, 1997 step : elastic ? this.step : null, 1998 complete : F._afterZoomOut 1999 }); 2000 }, 2001 2002 changeIn: function () { 2003 var current = F.current, 2004 effect = current.nextEffect, 2005 startPos = current.pos, 2006 endPos = { opacity : 1 }, 2007 direction = F.direction, 2008 distance = 200, 2009 field; 2010 2011 startPos.opacity = 0.1; 2012 2013 if (effect === 'elastic') { 2014 field = direction === 'down' || direction === 'up' ? 'top' : 'left'; 2015 2016 if (direction === 'down' || direction === 'right') { 2017 startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); 2018 endPos[ field ] = '+=' + distance + 'px'; 2019 2020 } else { 2021 startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); 2022 endPos[ field ] = '-=' + distance + 'px'; 2023 } 2024 } 2025 2026 // Workaround for http://bugs.jquery.com/ticket/12273 2027 if (effect === 'none') { 2028 F._afterZoomIn(); 2029 2030 } else { 2031 F.wrap.css(startPos).animate(endPos, { 2032 duration : current.nextSpeed, 2033 easing : current.nextEasing, 2034 complete : F._afterZoomIn 2035 }); 2036 } 2037 }, 2038 2039 changeOut: function () { 2040 var previous = F.previous, 2041 effect = previous.prevEffect, 2042 endPos = { opacity : 0.1 }, 2043 direction = F.direction, 2044 distance = 200; 2045 2046 if (effect === 'elastic') { 2047 endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; 2048 } 2049 2050 previous.wrap.animate(endPos, { 2051 duration : effect === 'none' ? 0 : previous.prevSpeed, 2052 easing : previous.prevEasing, 2053 complete : function () { 2054 $(this).trigger('onReset').remove(); 2055 } 2056 }); 2057 } 2058 }; 2059 2060 /* 2061 * Overlay helper 2062 */ 2063
2064 F.helpers.overlay = { 2065 defaults : { 2066 closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay 2067 speedOut : 200, // duration of fadeOut animation 2068 showEarly : true, // indicates if should be opened immediately or wait until the content is ready 2069 css : {}, // custom CSS properties 2070 locked : !isTouch, // if true, the content will be locked into overlay 2071 fixed : true // if false, the overlay CSS position property will not be set to "fixed" 2072 }, 2073 2074 overlay : null, // current handle 2075 fixed : false, // indicates if the overlay has position "fixed" 2076 el : $('html'), // element that contains "the lock" 2077 2078 // Public methods 2079 create : function(opts) { 2080 opts = $.extend({}, this.defaults, opts); 2081 2082 if (this.overlay) { 2083 this.close(); 2084 } 2085 2086 this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( F.coming ? F.coming.parent : opts.parent ); 2087 this.fixed = false; 2088 2089 if (opts.fixed && F.defaults.fixed) { 2090 this.overlay.addClass('fancybox-overlay-fixed'); 2091 2092 this.fixed = true; 2093 } 2094 }, 2095 2096 open : function(opts) { 2097 var that = this; 2098 2099 opts = $.extend({}, this.defaults, opts); 2100 2101 if (this.overlay) { 2102 this.overlay.unbind('.overlay').width('auto').height('auto'); 2103 2104 } else { 2105 this.create(opts); 2106 } 2107 2108 if (!this.fixed) { 2109 W.bind('resize.overlay', $.proxy( this.update, this) ); 2110 2111 this.update(); 2112 } 2113 2114 if (opts.closeClick) { 2115 this.overlay.bind('click.overlay', function(e) { 2116 if ($(e.target).hasClass('fancybox-overlay')) { 2117 if (F.isActive) { 2118 F.close(); 2119 } else { 2120 that.close(); 2121 } 2122 2123 return false; 2124 } 2125 }); 2126 } 2127 2128 this.overlay.css( opts.css ).show(); 2129 }, 2130 2131 close : function() { 2132 var scrollV, scrollH; 2133 2134 W.unbind('resize.overlay'); 2135 2136 if (this.el.hasClass('fancybox-lock')) { 2137 $('.fancybox-margin').removeClass('fancybox-margin'); 2138 2139 scrollV = W.scrollTop(); 2140 scrollH = W.scrollLeft(); 2141 2142 this.el.removeClass('fancybox-lock'); 2143 2144 W.scrollTop( scrollV ).scrollLeft( scrollH ); 2145 } 2146 2147 $('.fancybox-overlay').remove().hide(); 2148 2149 $.extend(this, { 2150 overlay : null, 2151 fixed : false 2152 }); 2153 }, 2154 2155 // Private, callbacks 2156 2157 update : function () { 2158 var width = '100%', offsetWidth; 2159 2160 // Reset width/height so it will not mess 2161 this.overlay.width(width).height('100%'); 2162 2163 // jQuery does not return reliable result for IE 2164 if (IE) { 2165 offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); 2166 2167 if (D.width() > offsetWidth) { 2168 width = D.width(); 2169 } 2170 2171 } else if (D.width() > W.width()) { 2172 width = D.width(); 2173 } 2174 2175 this.overlay.width(width).height(D.height()); 2176 }, 2177 2178 // This is where we can manipulate DOM, because later it would cause iframes to reload 2179 onReady : function (opts, obj) { 2180 var overlay = this.overlay; 2181 2182 $('.fancybox-overlay').stop(true, true); 2183 2184 if (!overlay) { 2185 this.create(opts); 2186 } 2187 2188 if (opts.locked && this.fixed && obj.fixed) { 2189 if (!overlay) { 2190 this.margin = D.height() > W.height() ? $('html').css('margin-right').replace("px", "") : false; 2191 } 2192 2193 obj.locked = this.overlay.append( obj.wrap ); 2194 obj.fixed = false; 2195 } 2196 2197 if (opts.showEarly === true) { 2198 this.beforeShow.apply(this, arguments); 2199 } 2200 }, 2201 2202 beforeShow : function(opts, obj) { 2203 var scrollV, scrollH; 2204 2205 if (obj.locked) { 2206 if (this.margin !== false) { 2207 $('*').filter(function(){ 2208 return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") ); 2209 }).addClass('fancybox-margin'); 2210 2211 this.el.addClass('fancybox-margin'); 2212 } 2213 2214 scrollV = W.scrollTop(); 2215 scrollH = W.scrollLeft(); 2216 2217 this.el.addClass('fancybox-lock'); 2218 2219 W.scrollTop( scrollV ).scrollLeft( scrollH ); 2220 } 2221 2222 this.open(opts); 2223 }, 2224 2225 onUpdate : function() { 2226 if (!this.fixed) { 2227 this.update(); 2228 } 2229 }, 2230 2231 afterClose: function (opts) { 2232 // Remove overlay if exists and fancyBox is not opening 2233 // (e.g., it is not being open using afterClose callback) 2234 //if (this.overlay && !F.isActive) { 2235 if (this.overlay && !F.coming) { 2236 this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); 2237 } 2238 } 2239 }; 2240 2241 /* 2242 * Title helper 2243 */ 2244 2245 F.helpers.title = { 2246 defaults : { 2247 type : 'float', // 'float', 'inside', 'outside' or 'over', 2248 position : 'bottom' // 'top' or 'bottom' 2249 }, 2250 2251 beforeShow: function (opts) { 2252 var current = F.current, 2253 text = current.title, 2254 type = opts.type, 2255 title, 2256 target; 2257 2258 if ($.isFunction(text)) { 2259 text = text.call(current.element, current); 2260 } 2261 2262 if (!isString(text) || $.trim(text) === '') { 2263 return; 2264 } 2265 2266 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
vendor: 4,223 bytes, lines 2266-2430
2266' + text + '</div>'); 2267 2268 switch (type) { 2269 case 'inside': 2270 target = F.skin; 2271 break; 2272 2273 case 'outside': 2274 target = F.wrap; 2275 break; 2276 2277 case 'over': 2278 target = F.inner; 2279 break; 2280 2281 default: // 'float' 2282 target = F.skin; 2283 2284 title.appendTo('body'); 2285 2286 if (IE) { 2287 title.width( title.width() ); 2288 } 2289 2290 title.wrapInner('<span class="child"></span>'); 2291 2292 //Increase bottom margin so this title will also fit into viewport 2293 F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); 2294 break; 2295 } 2296 2297 title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); 2298 } 2299 }; 2300 2301 // jQuery plugin initialization 2302 $.fn.fancybox = function (options) { 2303 var index, 2304 that = $(this), 2305 selector = this.selector || '', 2306 run = function(e) { 2307 var what = $(this).blur(), idx = index, relType, relVal; 2308 2309 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { 2310 relType = options.groupAttr || 'data-fancybox-group'; 2311 relVal = what.attr(relType); 2312 2313 if (!relVal) { 2314 relType = 'rel'; 2315 relVal = what.get(0)[ relType ]; 2316 } 2317 2318 if (relVal && relVal !== '' && relVal !== 'nofollow') { 2319 what = selector.length ? $(selector) : that; 2320 what = what.filter('[' + relType + '="' + relVal + '"]'); 2321 idx = what.index(this); 2322 } 2323 2324 options.index = idx; 2325 2326 // Stop an event from bubbling if everything is fine 2327 if (F.open(what, options) !== false) { 2328 e.preventDefault(); 2329 } 2330 } 2331 }; 2332 2333 options = options || {}; 2334 index = options.index || 0; 2335 2336 if (!selector || options.live === false) { 2337 that.unbind('click.fb-start').bind('click.fb-start', run); 2338 2339 } else { 2340 D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); 2341 } 2342 2343 this.filter('[data-fancybox-start=1]').trigger('click'); 2344 2345 return this; 2346 }; 2347 2348 // Tests that need a body at doc ready 2349 D.ready(function() { 2350 var w1, w2; 2351 2352 if ( $.scrollbarWidth === undefined ) { 2353 // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth 2354 $.scrollbarWidth = function() { 2355 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), 2356 child = parent.children(), 2357 width = child.innerWidth() - child.height( 99 ).innerWidth(); 2358 2359 parent.remove(); 2360 2361 return width; 2362 }; 2363 } 2364 2365 if ( $.support.fixedPosition === undefined ) { 2366 $.support.fixedPosition = (function() { 2367 var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'), 2368 fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); 2369 2370 elem.remove(); 2371 2372 return fixed; 2373 }()); 2374 } 2375 2376 $.extend(F.defaults, { 2377 scrollbarWidth : $.scrollbarWidth(), 2378 fixed : $.support.fixedPosition, 2379 parent : $('body') 2380 }); 2381 2382 //Get real width of page scroll-bar 2383 w1 = $(window).width(); 2384 2385 H.addClass('fancybox-lock-test'); 2386 2387 w2 = $(window).width(); 2388 2389 H.removeClass('fancybox-lock-test'); 2390 2391 $("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head"); 2392 }); 2393 2394}(window, document, jQuery)); 2395/* End */ 2396; 2397; /* Start:"a:4:{s:4:"full";s:39:"/js/jquery.jcarousel.js?172122556736009";s:6:"source";s:23:"/js/jquery.jcarousel.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 2398/*! 2399 * jCarousel - Riding carousels with jQuery 2400 * http://sorgalla.com/jcarousel/ 2401 * 2402 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com) 2403 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 2404 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 2405 * 2406 * Built on top of the jQuery library 2407 * http://jquery.com 2408 * 2409 * Inspired by the "Carousel Component" by Bill Scott 2410 * http://billwscott.com/carousel/ 2411 */ 2412 2413/*global window, jQuery */ 2414(function($) { 2415 // Default configuration properties. 2416 var defaults = { 2417 vertical: false, 2418 rtl: false, 2419 start: 1, 2420 offset: 1, 2421 size: null, 2422 scroll: 3, 2423 visible: null, 2424 animation: 'normal', 2425 easing: 'swing', 2426 auto: 0, 2427 wrap: null, 2428 initCallback: null, 2429 setupCallback: null, 2430 reloadCallback: null,
2431 itemLoadCallback: null, 2432 itemFirstInCallback: null, 2433 itemFirstOutCallback: null, 2434 itemLastInCallback: null, 2435 itemLastOutCallback: null, 2436 itemVisibleInCallback: null, 2437 itemVisibleOutCallback: null, 2438 animationStepCallback: null, 2439 buttonNextHTML: '<div></div>', 2440 buttonPrevHTML: '<div></div>', 2441 buttonNextEvent: 'click', 2442 buttonPrevEvent: 'click', 2443 buttonNextCallback: null, 2444 buttonPrevCallback: null, 2445 itemFallbackDimension: null 2446 }, windowLoaded = false; 2447 2448 $(window).bind('load.jcarousel', function() { windowLoaded = true; }); 2449 2450 /** 2451 * The jCarousel object. 2452 * 2453 * @constructor 2454 * @class jcarousel 2455 * @param e {HTMLElement} The element to create the carousel for. 2456 * @param o {Object} A set of key/value pairs to set as configuration properties. 2457 * @cat Plugins/jCarousel 2458 */ 2459 $.jcarousel = function(e, o) { 2460 this.options = $.extend({}, defaults, o || {}); 2461 2462 this.locked = false; 2463 this.autoStopped = false; 2464 2465 this.container = null; 2466 this.clip = null; 2467 this.list = null; 2468 this.buttonNext = null; 2469 this.buttonPrev = null; 2470 this.buttonNextState = null; 2471 this.buttonPrevState = null; 2472 2473 // Only set if not explicitly passed as option 2474 if (!o || o.rtl === undefined) { 2475 this.options.rtl = ($(e).attr('dir') || $('html').attr('dir') || '').toLowerCase() == 'rtl'; 2476 } 2477 2478 this.wh = !this.options.vertical ? 'width' : 'height'; 2479 this.lt = !this.options.vertical ? (this.options.rtl ? 'right' : 'left') : 'top'; 2480 2481 // Extract skin class 2482 var skin = '', split = e.className.split(' '); 2483 2484 for (var i = 0; i < split.length; i++) { 2485 if (split[i].indexOf('jcarousel-skin') != -1) { 2486 $(e).removeClass(split[i]); 2487 skin = split[i]; 2488 break; 2489 } 2490 } 2491 2492 if (e.nodeName.toUpperCase() == 'UL' || e.nodeName.toUpperCase() == 'OL') { 2493 this.list = $(e); 2494 this.clip = this.list.parents('.jcarousel-clip'); 2495 this.container = this.list.parents('.jcarousel-container'); 2496 } else { 2497 this.container = $(e); 2498 this.list = this.container.find('ul,ol').eq(0); 2499 this.clip = this.container.find('.jcarousel-clip'); 2500 } 2501 2502 if (this.clip.size() === 0) { 2503 this.clip = this.list.wrap('<div></div>').parent(); 2504 } 2505 2506 if (this.container.size() === 0) { 2507 this.container = this.clip.wrap('<div></div>').parent(); 2508 } 2509 2510 if (skin !== '' && this.container.parent()[0].className.indexOf('jcarousel-skin') == -1) { 2511 this.container.wrap('<div class=" '+ skin + '"></div>'); 2512 } 2513 2514 this.buttonPrev = $('.jcarousel-prev', this.container); 2515 2516 if (this.buttonPrev.size() === 0 && this.options.buttonPrevHTML !== null) { 2517 this.buttonPrev = $(this.options.buttonPrevHTML).appendTo(this.container); 2518 } 2519 2520 this.buttonPrev.addClass(this.className('jcarousel-prev')); 2521 2522 this.buttonNext = $('.jcarousel-next', this.container); 2523 2524 if (this.buttonNext.size() === 0 && this.options.buttonNextHTML !== null) { 2525 this.buttonNext = $(this.options.buttonNextHTML).appendTo(this.container); 2526 } 2527 2528 this.buttonNext.addClass(this.className('jcarousel-next')); 2529 2530 this.clip.addClass(this.className('jcarousel-clip')).css({ 2531 position: 'relative' 2532 }); 2533 2534 this.list.addClass(this.className('jcarousel-list')).css({ 2535 overflow: 'hidden', 2536 position: 'relative', 2537 top: 0, 2538 margin: 0, 2539 padding: 0 2540 }).css((this.options.rtl ? 'right' : 'left'), 0); 2541 2542 this.container.addClass(this.className('jcarousel-container')).css({ 2543 position: 'relative' 2544 }); 2545 2546 if (!this.options.vertical && this.options.rtl) {
2547 this.container.addClass('jcarousel-direction-rtl').attr('dir', 'rtl'); 2548 } 2549 2550 var di = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null; 2551 var li = this.list.children('li'); 2552 2553 var self = this; 2554 2555 if (li.size() > 0) { 2556 var wh = 0, j = this.options.offset; 2557 li.each(function() { 2558 self.format(this, j++); 2559 wh += self.dimension(this, di); 2560 }); 2561 2562 this.list.css(this.wh, (wh + 100) + 'px'); 2563 2564 // Only set if not explicitly passed as option 2565 if (!o || o.size === undefined) { 2566 this.options.size = li.size(); 2567 } 2568 } 2569 2570 // For whatever reason, .show() does not work in Safari... 2571 this.container.css('display', 'block'); 2572 this.buttonNext.css('display', 'block'); 2573 this.buttonPrev.css('display', 'block'); 2574 2575 this.funcNext = function() { self.next(); return false; }; 2576 this.funcPrev = function() { self.prev(); return false; }; 2577 this.funcResize = function() { 2578 if (self.resizeTimer) { 2579 clearTimeout(self.resizeTimer); 2580 } 2581 2582 self.resizeTimer = setTimeout(function() { 2583 self.reload(); 2584 }, 100); 2585 }; 2586 2587 if (this.options.initCallback !== null) { 2588 this.options.initCallback(this, 'init'); 2589 } 2590 2591 if (!windowLoaded && $jc.isSafari()) { 2592 this.buttons(false, false); 2593 $(window).bind('load.jcarousel', function() { self.setup(); }); 2594 } else { 2595 this.setup(); 2596 } 2597 }; 2598 2599 // Create shortcut for internal use 2600 var $jc = $.jcarousel; 2601 2602 $jc.fn = $jc.prototype = { 2603 jcarousel: '0.2.9' 2604 }; 2605 2606 $jc.fn.extend = $jc.extend = $.extend; 2607 2608 $jc.fn.extend({ 2609 /** 2610 * Setups the carousel. 2611 * 2612 * @method setup 2613 * @return undefined 2614 */ 2615 setup: function() { 2616 this.first = null; 2617 this.last = null; 2618 this.prevFirst = null; 2619 this.prevLast = null; 2620 this.animating = false; 2621 this.timer = null; 2622 this.resizeTimer = null; 2623 this.tail = null; 2624 this.inTail = false; 2625 2626 if (this.locked) { 2627 return; 2628 } 2629 2630 this.list.css(this.lt, this.pos(this.options.offset) + 'px'); 2631 var p = this.pos(this.options.start, true); 2632 this.prevFirst = this.prevLast = null; 2633 this.animate(p, false); 2634 2635 $(window).unbind('resize.jcarousel', this.funcResize).bind('resize.jcarousel', this.funcResize); 2636 2637 if (this.options.setupCallback !== null) { 2638 this.options.setupCallback(this); 2639 } 2640 }, 2641 2642 /** 2643 * Clears the list and resets the carousel. 2644 * 2645 * @method reset 2646 * @return undefined 2647 */ 2648 reset: function() { 2649 this.list.empty(); 2650 2651 this.list.css(this.lt, '0px'); 2652 this.list.css(this.wh, '10px'); 2653 2654 if (this.options.initCallback !== null) { 2655 this.options.initCallback(this, 'reset'); 2656 } 2657 2658 this.setup(); 2659 }, 2660 2661 /** 2662 * Reloads the carousel and adjusts positions. 2663 * 2664 * @method reload 2665 * @return undefined 2666 */ 2667 reload: function() { 2668 if (this.tail !== null && this.inTail) { 2669 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + this.tail); 2670 } 2671 2672 this.tail = null; 2673 this.inTail = false; 2674 2675 if (this.options.reloadCallback !== null) { 2676 this.options.reloadCallback(this); 2677 } 2678 2679 if (this.options.visible !== null) { 2680 var self = this; 2681 var di = Math.ceil(this.clipping() / this.options.visible), wh = 0, lt = 0; 2682 this.list.children('li').each(function(i) { 2683 wh += self.dimension(this, di); 2684 if (i + 1 < self.first) { 2685 lt = wh; 2686 } 2687 }); 2688 2689 this.list.css(this.wh, wh + 'px'); 2690 this.list.css(this.lt, -lt + 'px'); 2691 } 2692 2693 this.scroll(this.first, false); 2694 }, 2695 2696 /** 2697 * Locks the carousel. 2698 * 2699 * @method lock 2700 * @return undefined 2701 */ 2702 lock: function() { 2703 this.locked = true; 2704 this.buttons(); 2705 }, 2706 2707 /** 2708 * Unlocks the carousel. 2709 * 2710 * @method unlock 2711 * @return undefined 2712 */ 2713 unlock: function() { 2714 this.locked = false;
2715 this.buttons(); 2716 }, 2717 2718 /** 2719 * Sets the size of the carousel. 2720 * 2721 * @method size 2722 * @return undefined 2723 * @param s {Number} The size of the carousel. 2724 */ 2725 size: function(s) { 2726 if (s !== undefined) { 2727 this.options.size = s; 2728 if (!this.locked) { 2729 this.buttons(); 2730 } 2731 } 2732 2733 return this.options.size; 2734 }, 2735 2736 /** 2737 * Checks whether a list element exists for the given index (or index range). 2738 * 2739 * @method get 2740 * @return bool 2741 * @param i {Number} The index of the (first) element. 2742 * @param i2 {Number} The index of the last element. 2743 */ 2744 has: function(i, i2) { 2745 if (i2 === undefined || !i2) { 2746 i2 = i; 2747 } 2748 2749 if (this.options.size !== null && i2 > this.options.size) { 2750 i2 = this.options.size; 2751 } 2752 2753 for (var j = i; j <= i2; j++) { 2754 var e = this.get(j); 2755 if (!e.length || e.hasClass('jcarousel-item-placeholder')) { 2756 return false; 2757 } 2758 } 2759 2760 return true; 2761 }, 2762 2763 /** 2764 * Returns a jQuery object with list element for the given index. 2765 * 2766 * @method get 2767 * @return jQuery 2768 * @param i {Number} The index of the element. 2769 */ 2770 get: function(i) { 2771 return $('>.jcarousel-item-' + i, this.list); 2772 }, 2773 2774 /** 2775 * Adds an element for the given index to the list. 2776 * If the element already exists, it updates the inner html. 2777 * Returns the created element as jQuery object. 2778 * 2779 * @method add 2780 * @return jQuery 2781 * @param i {Number} The index of the element. 2782 * @param s {String} The innerHTML of the element. 2783 */ 2784 add: function(i, s) { 2785 var e = this.get(i), old = 0, n = $(s); 2786 2787 if (e.length === 0) { 2788 var c, j = $jc.intval(i); 2789 e = this.create(i); 2790 while (true) { 2791 c = this.get(--j); 2792 if (j <= 0 || c.length) { 2793 if (j <= 0) { 2794 this.list.prepend(e); 2795 } else { 2796 c.after(e); 2797 } 2798 break; 2799 } 2800 } 2801 } else { 2802 old = this.dimension(e); 2803 } 2804 2805 if (n.get(0).nodeName.toUpperCase() == 'LI') { 2806 e.replaceWith(n); 2807 e = n; 2808 } else { 2809 e.empty().append(s); 2810 } 2811 2812 this.format(e.removeClass(this.className('jcarousel-item-placeholder')), i); 2813 2814 var di = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null; 2815 var wh = this.dimension(e, di) - old; 2816 2817 if (i > 0 && i < this.first) { 2818 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - wh + 'px'); 2819 } 2820 2821 this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) + wh + 'px'); 2822 2823 return e; 2824 }, 2825 2826 /** 2827 * Removes an element for the given index from the list. 2828 * 2829 * @method remove 2830 * @return undefined 2831 * @param i {Number} The index of the element. 2832 */ 2833 remove: function(i) { 2834 var e = this.get(i); 2835 2836 // Check if item exists and is not currently visible 2837 if (!e.length || (i >= this.first && i <= this.last)) { 2838 return; 2839 } 2840 2841 var d = this.dimension(e); 2842 2843 if (i < this.first) { 2844 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + d + 'px'); 2845 } 2846 2847 e.remove(); 2848 2849 this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) - d + 'px'); 2850 }, 2851 2852 /** 2853 * Moves the carousel forwards. 2854 * 2855 * @method next 2856 * @return undefined 2857 */ 2858 next: function() { 2859 if (this.tail !== null && !this.inTail) { 2860 this.scrollTail(false); 2861 } else { 2862 this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'last') && this.options.size !== null && this.last == this.options.size) ? 1 : this.first + this.options.scroll); 2863 } 2864 }, 2865 2866 /** 2867 * Moves the carousel backwards. 2868 * 2869 * @method prev 2870 * @return undefined 2871 */ 2872 prev: function() { 2873 if (this.tail !== null && this.inTail) { 2874 this.scrollTail(true); 2875 } else { 2876 this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'first') && this.options.size !== null && this.first == 1) ? this.options.size : this.first - this.options.scroll); 2877 } 2878 }, 2879 2880 /** 2881 * Scrolls the tail of the carousel. 2882 * 2883 * @method scrollTail 2884 * @return undefined 2885 * @param b {Boolean} Whether scroll the tail back or forward. 2886 */ 2887 scrollTail: function(b) { 2888 if (this.locked || this.animating || !this.tail) { 2889 return; 2890 } 2891 2892 this.pauseAuto(); 2893 2894 var pos = $jc.intval(this.list.css(this.lt)); 2895 2896 pos = !b ? pos - this.tail : pos + this.tail; 2897 this.inTail = !b; 2898 2899 // Save for callbacks 2900 this.prevFirst = this.first; 2901 this.prevLast = this.last; 2902 2903 this.animate(pos); 2904 }, 2905 2906 /** 2907 * Scrolls the carousel to a certain position. 2908 * 2909 * @method scroll 2910 * @return undefined 2911 * @param i {Number} The index of the element to scoll to. 2912 * @param a {Boolean} Flag indicating whether to perform animation. 2913 */ 2914 scroll: function(i, a) { 2915 if (this.locked || this.animating) { 2916 return; 2917 } 2918 2919 this.pauseAuto(); 2920 this.animate(this.pos(i), a); 2921 }, 2922 2923 /** 2924 * Prepares the carousel and return the position for a certian index. 2925 * 2926 * @method pos 2927 * @return {Number} 2928 * @param i {Number} The index of the element to scoll to. 2929 * @param fv {Boolean} Whether to force last item to be visible. 2930 */ 2931 pos: function(i, fv) { 2932 var pos = $jc.intval(this.list.css(this.lt)); 2933 2934 if (this.locked || this.animating) { 2935 return pos; 2936 } 2937 2938 if (this.options.wrap != 'circular') { 2939 i = i < 1 ? 1 : (this.options.size && i > this.options.size ? this.options.size : i); 2940 } 2941 2942 var back = this.first > i; 2943 2944 // Create placeholders, new list width/height 2945 // and new list position 2946 var f = this.options.wrap != 'circular' && this.first <= 1 ? 1 : this.first; 2947 var c = back ? this.get(f) : this.get(this.last); 2948 var j = back ? f : f - 1; 2949 var e = null, l = 0, p = false, d = 0, g; 2950 2951 while (back ? --j >= i : ++j < i) { 2952 e = this.get(j); 2953 p = !e.length; 2954 if (e.length === 0) { 2955 e = this.create(j).addClass(this.className('jcarousel-item-placeholder')); 2956 c[back ? 'before' : 'after' ](e); 2957 2958 if (this.first !== null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) { 2959 g = this.get(this.index(j)); 2960 if (g.length) { 2961 e = this.add(j, g.clone(true)); 2962 } 2963 } 2964 } 2965 2966 c = e; 2967 d = this.dimension(e); 2968 2969 if (p) { 2970 l += d; 2971 } 2972 2973 if (this.first !== null && (this.options.wrap == 'circular' || (j >= 1 && (this.options.size === null || j <= this.options.size)))) { 2974 pos = back ? pos + d : pos - d; 2975 } 2976 } 2977 2978 // Calculate visible items 2979 var clipping = this.clipping(), cache = [], visible = 0, v = 0; 2980 c = this.get(i - 1); 2981 j = i; 2982 2983 while (++visible) { 2984 e = this.get(j); 2985 p = !e.length; 2986 if (e.length === 0) { 2987 e = this.create(j).addClass(this.className('jcarousel-item-placeholder')); 2988 // This should only happen on a next scroll 2989 if (c.length === 0) { 2990 this.list.prepend(e); 2991 } else { 2992 c[back ? 'before' : 'after' ](e); 2993 } 2994 2995 if (this.first !== null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) { 2996 g = this.get(this.index(j)); 2997 if (g.length) { 2998 e = this.add(j, g.clone(true)); 2999 } 3000 } 3001 } 3002 3003 c = e; 3004 d = this.dimension(e); 3005 if (d === 0) { 3006 throw new Error('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...'); 3007 } 3008 3009 if (this.options.wrap != 'circular' && this.options.size !== null && j > this.options.size) { 3010 cache.push(e); 3011 } else if (p) { 3012 l += d; 3013 } 3014 3015 v += d; 3016 3017 if (v >= clipping) { 3018 break; 3019 } 3020 3021 j++; 3022 } 3023 3024 // Remove out-of-range placeholders 3025 for (var x = 0; x < cache.length; x++) { 3026 cache[x].remove(); 3027 } 3028 3029 // Resize list 3030 if (l > 0) { 3031 this.list.css(this.wh, this.dimension(this.list) + l + 'px'); 3032 3033 if (back) { 3034 pos -= l; 3035 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - l + 'px'); 3036 } 3037 } 3038 3039 // Calculate first and last item 3040 var last = i + visible - 1; 3041 if (this.options.wrap != 'circular' && this.options.size && last > this.options.size) { 3042 last = this.options.size; 3043 } 3044 3045 if (j > last) { 3046 visible = 0; 3047 j = last; 3048 v = 0; 3049 while (++visible) { 3050 e = this.get(j--); 3051 if (!e.length) { 3052 break; 3053 } 3054 v += this.dimension(e); 3055 if (v >= clipping) { 3056 break; 3057 } 3058 } 3059 } 3060 3061 var first = last - visible + 1; 3062 if (this.options.wrap != 'circular' && first < 1) { 3063 first = 1; 3064 } 3065 3066 if (this.inTail && back) { 3067 pos += this.tail; 3068 this.inTail = false;
3069 } 3070 3071 this.tail = null; 3072 if (this.options.wrap != 'circular' && last == this.options.size && (last - visible + 1) >= 1) { 3073 var m = $jc.intval(this.get(last).css(!this.options.vertical ? 'marginRight' : 'marginBottom')); 3074 if ((v - m) > clipping) { 3075 this.tail = v - clipping - m; 3076 } 3077 } 3078 3079 if (fv && i === this.options.size && this.tail) { 3080 pos -= this.tail; 3081 this.inTail = true; 3082 } 3083 3084 // Adjust position 3085 while (i-- > first) { 3086 pos += this.dimension(this.get(i)); 3087 } 3088 3089 // Save visible item range 3090 this.prevFirst = this.first; 3091 this.prevLast = this.last; 3092 this.first = first; 3093 this.last = last; 3094 3095 return pos; 3096 }, 3097 3098 /** 3099 * Animates the carousel to a certain position. 3100 * 3101 * @method animate 3102 * @return undefined 3103 * @param p {Number} Position to scroll to. 3104 * @param a {Boolean} Flag indicating whether to perform animation. 3105 */ 3106 animate: function(p, a) { 3107 if (this.locked || this.animating) { 3108 return; 3109 } 3110 3111 this.animating = true; 3112 3113 var self = this; 3114 var scrolled = function() { 3115 self.animating = false; 3116 3117 if (p === 0) { 3118 self.list.css(self.lt, 0); 3119 } 3120 3121 if (!self.autoStopped && (self.options.wrap == 'circular' || self.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size === null || self.last < self.options.size || (self.last == self.options.size && self.tail !== null && !self.inTail))) { 3122 self.startAuto(); 3123 } 3124 3125 self.buttons(); 3126 self.notify('onAfterAnimation'); 3127 3128 // This function removes items which are appended automatically for circulation. 3129 // This prevents the list from growing infinitely. 3130 if (self.options.wrap == 'circular' && self.options.size !== null) { 3131 for (var i = self.prevFirst; i <= self.prevLast; i++) { 3132 if (i !== null && !(i >= self.first && i <= self.last) && (i < 1 || i > self.options.size)) { 3133 self.remove(i); 3134 } 3135 } 3136 } 3137 }; 3138 3139 this.notify('onBeforeAnimation'); 3140 3141 // Animate 3142 if (!this.options.animation || a === false) { 3143 this.list.css(this.lt, p + 'px'); 3144 scrolled(); 3145 } else { 3146 var o = !this.options.vertical ? (this.options.rtl ? {'right': p} : {'left': p}) : {'top': p}; 3147 // Define animation settings. 3148 var settings = { 3149 duration: this.options.animation, 3150 easing: this.options.easing, 3151 complete: scrolled 3152 }; 3153 // If we have a step callback, specify it as well. 3154 if ($.isFunction(this.options.animationStepCallback)) { 3155 settings.step = this.options.animationStepCallback; 3156 } 3157 // Start the animation. 3158 this.list.animate(o, settings); 3159 } 3160 }, 3161 3162 /** 3163 * Starts autoscrolling. 3164 * 3165 * @method auto 3166 * @return undefined 3167 * @param s {Number} Seconds to periodically autoscroll the content. 3168 */ 3169 startAuto: function(s) { 3170 if (s !== undefined) { 3171 this.options.auto = s; 3172 } 3173 3174 if (this.options.auto === 0) { 3175 return this.stopAuto(); 3176 } 3177 3178 if (this.timer !== null) { 3179 return; 3180 } 3181 3182 this.autoStopped = false; 3183 3184 var self = this; 3185 this.timer = window.setTimeout(function() { self.next(); }, this.options.auto * 1000); 3186 }, 3187 3188 /** 3189 * Stops autoscrolling. 3190 * 3191 * @method stopAuto 3192 * @return undefined 3193 */ 3194 stopAuto: function() { 3195 this.pauseAuto(); 3196 this.autoStopped = true; 3197 }, 3198 3199 /** 3200 * Pauses autoscrolling. 3201 * 3202 * @method pauseAuto 3203 * @return undefined 3204 */ 3205 pauseAuto: function() { 3206 if (this.timer === null) { 3207 return; 3208 } 3209 3210 window.clearTimeout(this.timer); 3211 this.timer = null; 3212 }, 3213 3214 /** 3215 * Sets the states of the prev/next buttons. 3216 * 3217 * @method buttons 3218 * @return undefined 3219 */ 3220 buttons: function(n, p) { 3221 if (n == null) { 3222 n = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'first') || this.options.size === null || this.last < this.options.size); 3223 if (!this.locked && (!this.options.wrap || this.options.wrap == 'first') && this.options.size !== null && this.last >= this.options.size) { 3224 n = this.tail !== null && !this.inTail; 3225 } 3226 } 3227 3228 if (p == null) { 3229 p = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'last') || this.first > 1); 3230 if (!this.locked && (!this.options.wrap || this.options.wrap == 'last') && this.options.size !== null && this.first == 1) { 3231 p = this.tail !== null && this.inTail; 3232 } 3233 } 3234 3235 var self = this; 3236 3237 if (this.buttonNext.size() > 0) { 3238 this.buttonNext.unbind(this.options.buttonNextEvent + '.jcarousel', this.funcNext); 3239 3240 if (n) { 3241 this.buttonNext.bind(this.options.buttonNextEvent + '.jcarousel', this.funcNext); 3242 } 3243 3244 this.buttonNext[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true); 3245 3246 if (this.options.buttonNextCallback !== null && this.buttonNext.data('jcarou
3246selstate') != n) { 3247 this.buttonNext.each(function() { self.options.buttonNextCallback(self, this, n); }).data('jcarouselstate', n); 3248 } 3249 } else { 3250 if (this.options.buttonNextCallback !== null && this.buttonNextState != n) { 3251 this.options.buttonNextCallback(self, null, n); 3252 } 3253 } 3254 3255 if (this.buttonPrev.size() > 0) { 3256 this.buttonPrev.unbind(this.options.buttonPrevEvent + '.jcarousel', this.funcPrev); 3257 3258 if (p) { 3259 this.buttonPrev.bind(this.options.buttonPrevEvent + '.jcarousel', this.funcPrev); 3260 } 3261 3262 this.buttonPrev[p ? 'removeClass' : 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled', p ? false : true); 3263 3264 if (this.options.buttonPrevCallback !== null && this.buttonPrev.data('jcarouselstate') != p) { 3265 this.buttonPrev.each(function() { self.options.buttonPrevCallback(self, this, p); }).data('jcarouselstate', p); 3266 } 3267 } else { 3268 if (this.options.buttonPrevCallback !== null && this.buttonPrevState != p) { 3269 this.options.buttonPrevCallback(self, null, p); 3270 } 3271 } 3272 3273 this.buttonNextState = n; 3274 this.buttonPrevState = p; 3275 }, 3276 3277 /** 3278 * Notify callback of a specified event. 3279 * 3280 * @method notify 3281 * @return undefined 3282 * @param evt {String} The event name 3283 */ 3284 notify: function(evt) { 3285 var state = this.prevFirst === null ? 'init' : (this.prevFirst < this.first ? 'next' : 'prev'); 3286 3287 // Load items 3288 this.callback('itemLoadCallback', evt, state); 3289 3290 if (this.prevFirst !== this.first) { 3291 this.callback('itemFirstInCallback', evt, state, this.first); 3292 this.callback('itemFirstOutCallback', evt, state, this.prevFirst); 3293 } 3294 3295 if (this.prevLast !== this.last) { 3296 this.callback('itemLastInCallback', evt, state, this.last); 3297 this.callback('itemLastOutCallback', evt, state, this.prevLast); 3298 } 3299 3300 this.callback('itemVisibleInCallback', evt, state, this.first, this.last, this.prevFirst, this.prevLast); 3301 this.callback('itemVisibleOutCallback', evt, state, this.prevFirst, this.prevLast, this.first, this.last); 3302 }, 3303 3304 callback: function(cb, evt, state, i1, i2, i3, i4) { 3305 if (this.options[cb] == null || (typeof this.options[cb] != 'object' && evt != 'onAfterAnimation')) { 3306 return; 3307 } 3308 3309 var callback = typeof this.options[cb] == 'object' ? this.options[cb][evt] : this.options[cb]; 3310 3311 if (!$.isFunction(callback)) { 3312 return; 3313 } 3314 3315 var self = this; 3316 3317 if (i1 === undefined) { 3318 callback(self, state, evt); 3319 } else if (i2 === undefined) { 3320 this.get(i1).each(function() { callback(self, this, i1, state, evt); }); 3321 } else { 3322 var call = function(i) { 3323 self.get(i).each(function() { callback(self, this, i, state, evt); }); 3324 }; 3325 for (var i = i1; i <= i2; i++) { 3326 if (i !== null && !(i >= i3 && i <= i4)) { 3327 call(i); 3328 } 3329 } 3330 } 3331 }, 3332 3333 create: function(i) { 3334 return this.format('<li></li>', i); 3335 }, 3336 3337 format: function(e, i) { 3338 e = $(e); 3339 var split = e.get(0).className.split(' '); 3340 for (var j = 0; j < split.length; j++) { 3341 if (split[j].indexOf('jcarousel-') != -1) { 3342 e.removeClass(split[j]); 3343 } 3344 } 3345 e.addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-' + i)).css({ 3346 'float': (this.options.rtl ? 'right' : 'left'), 3347 'list-style': 'none' 3348 }).attr('jcarouselindex', i); 3349 return e; 3350 }, 3351 3352 className: function(c) { 3353 return c + ' ' + c + (!this.options.vertical ? '-horizontal' : '-vertical'); 3354 }, 3355 3356 dimension: function(e, d) { 3357 var el = $(e); 3358 3359 if (d == null) { 3360 return !this.options.vertical ? 3361 ((el.innerWidth() + 3362 $jc.intval(el.css('margin-left')) + 3363 $jc.intval(el.css('margin-right')) + 3364 $jc.intval(el.css('border-left-width')) + 3365 $jc.intval(el.css('border-right-width'))) || $jc.intval(this.options.itemFallbackDimension)) :
3366 ((el.innerHeight() + 3367 $jc.intval(el.css('margin-top')) + 3368 $jc.intval(el.css('margin-bottom')) + 3369 $jc.intval(el.css('border-top-width')) + 3370 $jc.intval(el.css('border-bottom-width'))) || $jc.intval(this.options.itemFallbackDimension)); 3371 } else { 3372 var w = !this.options.vertical ? 3373 d - $jc.intval(el.css('marginLeft')) - $jc.intval(el.css('marginRight')) : 3374 d - $jc.intval(el.css('marginTop')) - $jc.intval(el.css('marginBottom')); 3375 3376 $(el).css(this.wh, w + 'px'); 3377 3378 return this.dimension(el); 3379 } 3380 }, 3381 3382 clipping: function() { 3383 return !this.options.vertical ? 3384 this.clip[0].offsetWidth - $jc.intval(this.clip.css('borderLeftWidth')) - $jc.intval(this.clip.css('borderRightWidth')) : 3385 this.clip[0].offsetHeight - $jc.intval(this.clip.css('borderTopWidth')) - $jc.intval(this.clip.css('borderBottomWidth')); 3386 }, 3387 3388 index: function(i, s) { 3389 if (s == null) { 3390 s = this.options.size; 3391 } 3392 3393 return Math.round((((i-1) / s) - Math.floor((i-1) / s)) * s) + 1; 3394 } 3395 }); 3396 3397 $jc.extend({ 3398 /** 3399 * Gets/Sets the global default configuration properties. 3400 * 3401 * @method defaults 3402 * @return {Object} 3403 * @param d {Object} A set of key/value pairs to set as configuration properties. 3404 */ 3405 defaults: function(d) { 3406 return $.extend(defaults, d || {}); 3407 }, 3408 3409 intval: function(v) { 3410 v = parseInt(v, 10); 3411 return isNaN(v) ? 0 : v; 3412 }, 3413 3414 windowLoaded: function() { 3415 windowLoaded = true; 3416 }, 3417 3418 isSafari: function() { 3419 var ua = navigator.userAgent.toLowerCase(), 3420 match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || [], 3421 browser = match[1] || ""; 3422 3423 return browser === 'webkit'; 3424 } 3425 }); 3426 3427 /** 3428 * Creates a carousel for all matched elements. 3429 * 3430 * @example $("#mycarousel").jcarousel(); 3431 * @before <ul id="mycarousel" class="jcarousel-skin-name"><li>First item</li><li>Second item</li></ul> 3432 * @result 3433 * 3434 * <div class="jcarousel-skin-name"> 3435 * <div class="jcarousel-container"> 3436 * <div class="jcarousel-clip"> 3437 * <ul class="jcarousel-list"> 3438 * <li class="jcarousel-item-1">First item</li> 3439 * <li class="jcarousel-item-2">Second item</li> 3440 * </ul> 3441 * </div> 3442 * <div disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div> 3443 * <div class="jcarousel-next"></div> 3444 * </div> 3445 * </div> 3446 * 3447 * @method jcarousel 3448 * @return jQuery 3449 * @param o {Hash|String} A set of key/value pairs to set as configuration properties or a method name to call on a formerly created instance. 3450 */ 3451 $.fn.jcarousel = function(o) { 3452 if (typeof o == 'string') { 3453 var instance = $(this).data('jcarousel'), args = Array.prototype.slice.call(arguments, 1); 3454 return instance[o].apply(instance, args); 3455 } else { 3456 return this.each(function() { 3457 var instance = $(this).data('jcarousel'); 3458 if (instance) { 3459 if (o) { 3460 $.extend(instance.options, o); 3461 } 3462 instance.reload(); 3463 } else { 3464 $(this).data('jcarousel', new $jc(this, o)); 3465 } 3466 }); 3467 } 3468 }; 3469 3470})(jQuery); 3471 3472/* End */ 3473; 3474; /* Start:"a:4:{s:4:"full";s:47:"/js/jquery-ui-1.10.3.custom.js?1721225567416213";s:6:"source";s:30:"/js/jquery-ui-1.10.3.custom.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 3475/*! jQuery UI - v1.10.3 - 2013-09-01 3476* http://jqueryui.com 3477* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js 3478* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ 3479 3480(function( $, undefined ) { 3481 3482var uuid = 0, 3483 runiqueId = /^ui-id-\d+$/; 3484
vendor: 5,040 bytes, lines 3485-3672
3485// $.ui might exist from components with no dependencies, e.g., $.ui.position 3486$.ui = $.ui || {}; 3487 3488$.extend( $.ui, { 3489 version: "1.10.3", 3490 3491 keyCode: { 3492 BACKSPACE: 8, 3493 COMMA: 188, 3494 DELETE: 46, 3495 DOWN: 40, 3496 END: 35, 3497 ENTER: 13, 3498 ESCAPE: 27, 3499 HOME: 36, 3500 LEFT: 37, 3501 NUMPAD_ADD: 107, 3502 NUMPAD_DECIMAL: 110, 3503 NUMPAD_DIVIDE: 111, 3504 NUMPAD_ENTER: 108, 3505 NUMPAD_MULTIPLY: 106, 3506 NUMPAD_SUBTRACT: 109, 3507 PAGE_DOWN: 34, 3508 PAGE_UP: 33, 3509 PERIOD: 190, 3510 RIGHT: 39, 3511 SPACE: 32, 3512 TAB: 9, 3513 UP: 38 3514 } 3515}); 3516 3517// plugins 3518$.fn.extend({ 3519 focus: (function( orig ) { 3520 return function( delay, fn ) { 3521 return typeof delay === "number" ? 3522 this.each(function() { 3523 var elem = this; 3524 setTimeout(function() { 3525 $( elem ).focus(); 3526 if ( fn ) { 3527 fn.call( elem ); 3528 } 3529 }, delay ); 3530 }) : 3531 orig.apply( this, arguments ); 3532 }; 3533 })( $.fn.focus ), 3534 3535 scrollParent: function() { 3536 var scrollParent; 3537 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { 3538 scrollParent = this.parents().filter(function() { 3539 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 3540 }).eq(0); 3541 } else { 3542 scrollParent = this.parents().filter(function() { 3543 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); 3544 }).eq(0); 3545 } 3546 3547 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; 3548 }, 3549 3550 zIndex: function( zIndex ) { 3551 if ( zIndex !== undefined ) { 3552 return this.css( "zIndex", zIndex ); 3553 } 3554 3555 if ( this.length ) { 3556 var elem = $( this[ 0 ] ), position, value; 3557 while ( elem.length && elem[ 0 ] !== document ) { 3558 // Ignore z-index if position is set to a value where z-index is ignored by the browser 3559 // This makes behavior of this function consistent across browsers 3560 // WebKit always returns auto if the element is positioned 3561 position = elem.css( "position" ); 3562 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 3563 // IE returns 0 when zIndex is not specified 3564 // other browsers return a string 3565 // we ignore the case of nested elements with an explicit value of 0 3566 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 3567 value = parseInt( elem.css( "zIndex" ), 10 ); 3568 if ( !isNaN( value ) && value !== 0 ) { 3569 return value; 3570 } 3571 } 3572 elem = elem.parent(); 3573 } 3574 } 3575 3576 return 0; 3577 }, 3578 3579 uniqueId: function() { 3580 return this.each(function() { 3581 if ( !this.id ) { 3582 this.id = "ui-id-" + (++uuid); 3583 } 3584 }); 3585 }, 3586 3587 removeUniqueId: function() { 3588 return this.each(function() { 3589 if ( runiqueId.test( this.id ) ) { 3590 $( this ).removeAttr( "id" ); 3591 } 3592 }); 3593 } 3594}); 3595 3596// selectors 3597function focusable( element, isTabIndexNotNaN ) { 3598 var map, mapName, img, 3599 nodeName = element.nodeName.toLowerCase(); 3600 if ( "area" === nodeName ) { 3601 map = element.parentNode; 3602 mapName = map.name; 3603 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 3604 return false; 3605 } 3606 img = $( "img[usemap=#" + mapName + "]" )[0]; 3607 return !!img && visible( img ); 3608 } 3609 return ( /input|select|textarea|button|object/.test( nodeName ) ? 3610 !element.disabled : 3611 "a" === nodeName ? 3612 element.href || isTabIndexNotNaN : 3613 isTabIndexNotNaN) && 3614 // the element and all of its ancestors must be visible 3615 visible( element ); 3616} 3617 3618function visible( element ) { 3619 return $.expr.filters.visible( element ) && 3620 !$( element ).parents().addBack().filter(function() { 3621 return $.css( this, "visibility" ) === "hidden"; 3622 }).length; 3623} 3624 3625$.extend( $.expr[ ":" ], { 3626 data: $.expr.createPseudo ? 3627 $.expr.createPseudo(function( dataName ) { 3628 return function( elem ) { 3629 return !!$.data( elem, dataName ); 3630 }; 3631 }) : 3632 // support: jQuery <1.8 3633 function( elem, i, match ) { 3634 return !!$.data( elem, match[ 3 ] ); 3635 }, 3636 3637 focusable: function( element ) { 3638 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 3639 }, 3640 3641 tabbable: function( element ) { 3642 var tabIndex = $.attr( element, "tabindex" ), 3643 isTabIndexNaN = isNaN( tabIndex ); 3644 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 3645 } 3646}); 3647 3648// support: jQuery <1.8 3649if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 3650 $.each( [ "Width", "Height" ], function( i, name ) { 3651 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 3652 type = name.toLowerCase(), 3653 orig = { 3654 innerWidth: $.fn.innerWidth, 3655 innerHeight: $.fn.innerHeight, 3656 outerWidth: $.fn.outerWidth, 3657 outerHeight: $.fn.outerHeight 3658 }; 3659 3660 function reduce( elem, size, border, margin ) { 3661 $.each( side, function() { 3662 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 3663 if ( border ) { 3664 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 3665 } 3666 if ( margin ) { 3667 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 3668 } 3669 }); 3670 return size; 3671 } 3672
3673 $.fn[ "inner" + name ] = function( size ) { 3674 if ( size === undefined ) { 3675 return orig[ "inner" + name ].call( this ); 3676 } 3677 3678 return this.each(function() { 3679 $( this ).css( type, reduce( this, size ) + "px" ); 3680 }); 3681 }; 3682 3683 $.fn[ "outer" + name] = function( size, margin ) { 3684 if ( typeof size !== "number" ) { 3685 return orig[ "outer" + name ].call( this, size ); 3686 } 3687 3688 return this.each(function() { 3689 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 3690 }); 3691 }; 3692 }); 3693} 3694 3695// support: jQuery <1.8 3696if ( !$.fn.addBack ) { 3697 $.fn.addBack = function( selector ) { 3698 return this.add( selector == null ? 3699 this.prevObject : this.prevObject.filter( selector ) 3700 ); 3701 }; 3702} 3703 3704// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) 3705if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { 3706 $.fn.removeData = (function( removeData ) { 3707 return function( key ) { 3708 if ( arguments.length ) { 3709 return removeData.call( this, $.camelCase( key ) ); 3710 } else { 3711 return removeData.call( this ); 3712 } 3713 }; 3714 })( $.fn.removeData ); 3715} 3716 3717 3718 3719 3720 3721// deprecated 3722$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 3723 3724$.support.selectstart = "onselectstart" in document.createElement( "div" ); 3725$.fn.extend({ 3726 disableSelection: function() { 3727 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 3728 ".ui-disableSelection", function( event ) { 3729 event.preventDefault(); 3730 }); 3731 }, 3732 3733 enableSelection: function() { 3734 return this.unbind( ".ui-disableSelection" ); 3735 } 3736}); 3737 3738$.extend( $.ui, { 3739 // $.ui.plugin is deprecated. Use $.widget() extensions instead. 3740 plugin: { 3741 add: function( module, option, set ) { 3742 var i, 3743 proto = $.ui[ module ].prototype; 3744 for ( i in set ) { 3745 proto.plugins[ i ] = proto.plugins[ i ] || []; 3746 proto.plugins[ i ].push( [ option, set[ i ] ] ); 3747 } 3748 }, 3749 call: function( instance, name, args ) { 3750 var i, 3751 set = instance.plugins[ name ]; 3752 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 3753 return; 3754 } 3755 3756 for ( i = 0; i < set.length; i++ ) { 3757 if ( instance.options[ set[ i ][ 0 ] ] ) { 3758 set[ i ][ 1 ].apply( instance.element, args ); 3759 } 3760 } 3761 } 3762 }, 3763 3764 // only used by resizable 3765 hasScroll: function( el, a ) { 3766 3767 //If overflow is hidden, the element might have extra content, but the user wants to hide it 3768 if ( $( el ).css( "overflow" ) === "hidden") { 3769 return false; 3770 } 3771 3772 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 3773 has = false; 3774 3775 if ( el[ scroll ] > 0 ) { 3776 return true; 3777 } 3778 3779 // TODO: determine which cases actually cause this to happen 3780 // if the element doesn't have the scroll set, see if it's possible to 3781 // set the scroll 3782 el[ scroll ] = 1; 3783 has = ( el[ scroll ] > 0 ); 3784 el[ scroll ] = 0; 3785 return has; 3786 } 3787}); 3788 3789})( jQuery ); 3790(function( $, undefined ) { 3791 3792var uuid = 0, 3793 slice = Array.prototype.slice, 3794 _cleanData = $.cleanData; 3795$.cleanData = function( elems ) { 3796 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 3797 try { 3798 $( elem ).triggerHandler( "remove" ); 3799 // http://bugs.jquery.com/ticket/8235 3800 } catch( e ) {} 3801 } 3802 _cleanData( elems ); 3803}; 3804 3805$.widget = function( name, base, prototype ) { 3806 var fullName, existingConstructor, constructor, basePrototype, 3807 // proxiedPrototype allows the provided prototype to remain unmodified 3808 // so that it can be used as a mixin for multiple widgets (#8876) 3809 proxiedPrototype = {}, 3810 namespace = name.split( "." )[ 0 ]; 3811 3812 name = name.split( "." )[ 1 ]; 3813 fullName = namespace + "-" + name; 3814 3815 if ( !prototype ) { 3816 prototype = base; 3817 base = $.Widget; 3818 } 3819 3820 // create selector for plugin 3821 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 3822 return !!$.data( elem, fullName ); 3823 }; 3824 3825 $[ namespace ] = $[ namespace ] || {}; 3826 existingConstructor = $[ namespace ][ name ]; 3827 constructor = $[ namespace ][ name ] = function( options, element ) { 3828 // allow instantiation without "new" keyword 3829 if ( !this._createWidget ) { 3830 return new constructor( options, element ); 3831 } 3832 3833 // allow instantiation without initializing for simple inheritance 3834 // must use "new" keyword (the code above always passes args) 3835 if ( arguments.length ) { 3836 this._createWidget( options, element ); 3837 } 3838 }; 3839 // extend with the existing constructor to carry over any static properties 3840 $.extend( constructor, existingConstructor, { 3841 version: prototype.version, 3842 // copy the object used to create the prototype in case we need to 3843 // redefine the widget later 3844 _proto: $.extend( {}, prototype ), 3845 // track widgets that inherit from this widget in case this widget is 3846 // redefined after a widget inherits from it 3847 _childConstructors: [] 3848 }); 3849 3850 basePrototype = new base(); 3851 // we need to make the options hash a property directly on the new instance 3852 // otherwise we'll modify the options hash on the prototype that we're 3853 // inheriting from 3854 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 3855 $.each( prototype, function( prop, value ) { 3856 if ( !$.isFunction( value ) ) { 3857 proxiedPrototype[ prop ] = value; 3858 return; 3859 } 3860 proxiedPrototype[ prop ] = (function() { 3861 var _super = function() { 3862 return base.prototype[ prop ].apply( this, arguments ); 3863 }, 3864 _superApply = function( args ) { 3865 return base.prototype[ prop ].apply( this, args ); 3866 }; 3867 return function() { 3868 var __super = this._super, 3869 __superApply = this._superApply, 3870 returnValue; 3871 3872 this._super = _super; 3873 this._superApply = _superApply; 3874
vendor: 11,913 bytes, lines 3875-4286
3875 returnValue = value.apply( this, arguments ); 3876 3877 this._super = __super; 3878 this._superApply = __superApply; 3879 3880 return returnValue; 3881 }; 3882 })(); 3883 }); 3884 constructor.prototype = $.widget.extend( basePrototype, { 3885 // TODO: remove support for widgetEventPrefix 3886 // always use the name + a colon as the prefix, e.g., draggable:start 3887 // don't prefix for widgets that aren't DOM-based 3888 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 3889 }, proxiedPrototype, { 3890 constructor: constructor, 3891 namespace: namespace, 3892 widgetName: name, 3893 widgetFullName: fullName 3894 }); 3895 3896 // If this widget is being redefined then we need to find all widgets that 3897 // are inheriting from it and redefine all of them so that they inherit from 3898 // the new version of this widget. We're essentially trying to replace one 3899 // level in the prototype chain. 3900 if ( existingConstructor ) { 3901 $.each( existingConstructor._childConstructors, function( i, child ) { 3902 var childPrototype = child.prototype; 3903 3904 // redefine the child widget using the same prototype that was 3905 // originally used, but inherit from the new version of the base 3906 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 3907 }); 3908 // remove the list of existing child constructors from the old constructor 3909 // so the old child constructors can be garbage collected 3910 delete existingConstructor._childConstructors; 3911 } else { 3912 base._childConstructors.push( constructor ); 3913 } 3914 3915 $.widget.bridge( name, constructor ); 3916}; 3917 3918$.widget.extend = function( target ) { 3919 var input = slice.call( arguments, 1 ), 3920 inputIndex = 0, 3921 inputLength = input.length, 3922 key, 3923 value; 3924 for ( ; inputIndex < inputLength; inputIndex++ ) { 3925 for ( key in input[ inputIndex ] ) { 3926 value = input[ inputIndex ][ key ]; 3927 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 3928 // Clone objects 3929 if ( $.isPlainObject( value ) ) { 3930 target[ key ] = $.isPlainObject( target[ key ] ) ? 3931 $.widget.extend( {}, target[ key ], value ) : 3932 // Don't extend strings, arrays, etc. with objects 3933 $.widget.extend( {}, value ); 3934 // Copy everything else by reference 3935 } else { 3936 target[ key ] = value; 3937 } 3938 } 3939 } 3940 } 3941 return target; 3942}; 3943 3944$.widget.bridge = function( name, object ) { 3945 var fullName = object.prototype.widgetFullName || name; 3946 $.fn[ name ] = function( options ) { 3947 var isMethodCall = typeof options === "string", 3948 args = slice.call( arguments, 1 ), 3949 returnValue = this; 3950 3951 // allow multiple hashes to be passed on init 3952 options = !isMethodCall && args.length ? 3953 $.widget.extend.apply( null, [ options ].concat(args) ) : 3954 options; 3955 3956 if ( isMethodCall ) { 3957 this.each(function() { 3958 var methodValue, 3959 instance = $.data( this, fullName ); 3960 if ( !instance ) { 3961 return $.error( "cannot call methods on " + name + " prior to initialization; " + 3962 "attempted to call method '" + options + "'" ); 3963 } 3964 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 3965 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 3966 } 3967 methodValue = instance[ options ].apply( instance, args ); 3968 if ( methodValue !== instance && methodValue !== undefined ) { 3969 returnValue = methodValue && methodValue.jquery ? 3970 returnValue.pushStack( methodValue.get() ) : 3971 methodValue; 3972 return false; 3973 } 3974 }); 3975 } else { 3976 this.each(function() { 3977 var instance = $.data( this, fullName ); 3978 if ( instance ) { 3979 instance.option( options || {} )._init(); 3980 } else { 3981 $.data( this, fullName, new object( options, this ) ); 3982 } 3983 }); 3984 } 3985 3986 return returnValue; 3987 }; 3988}; 3989 3990$.Widget = function( /* options, element */ ) {}; 3991$.Widget._childConstructors = []; 3992 3993$.Widget.prototype = { 3994 widgetName: "widget", 3995 widgetEventPrefix: "", 3996 defaultElement: "<div>", 3997 options: { 3998 disabled: false, 3999 4000 // callbacks 4001 create: null 4002 }, 4003 _createWidget: function( options, element ) { 4004 element = $( element || this.defaultElement || this )[ 0 ]; 4005 this.element = $( element ); 4006 this.uuid = uuid++; 4007 this.eventNamespace = "." + this.widgetName + this.uuid; 4008 this.options = $.widget.extend( {}, 4009 this.options, 4010 this._getCreateOptions(), 4011 options ); 4012 4013 this.bindings = $(); 4014 this.hoverable = $(); 4015 this.focusable = $(); 4016 4017 if ( element !== this ) { 4018 $.data( element, this.widgetFullName, this ); 4019 this._on( true, this.element, { 4020 remove: function( event ) { 4021 if ( event.target === element ) { 4022 this.destroy(); 4023 } 4024 } 4025 }); 4026 this.document = $( element.style ? 4027 // element within the document 4028 element.ownerDocument : 4029 // element is window or document 4030 element.document || element ); 4031 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 4032 } 4033 4034 this._create(); 4035 this._trigger( "create", null, this._getCreateEventData() ); 4036 this._init(); 4037 }, 4038 _getCreateOptions: $.noop, 4039 _getCreateEventData: $.noop, 4040 _create: $.noop, 4041 _init: $.noop, 4042 4043 destroy: function() { 4044 this._destroy(); 4045 // we can probably remove the unbind calls in 2.0 4046 // all event bindings should go through this._on() 4047 this.element 4048 .unbind( this.eventNamespace ) 4049 // 1.9 BC for #7810 4050 // TODO remove dual storage 4051 .removeData( this.widgetName ) 4052 .removeData( this.widgetFullName ) 4053 // support: jquery <1.6.3 4054 // http://bugs.jquery.com/ticket/9413 4055 .removeData( $.camelCase( this.widgetFullName ) ); 4056 this.widget() 4057 .unbind( this.eventNamespace ) 4058 .removeAttr( "aria-disabled" ) 4059 .removeClass( 4060 this.widgetFullName + "-disabled " + 4061 "ui-state-disabled" ); 4062 4063 // clean up events and states 4064 this.bindings.unbind( this.eventNamespace ); 4065 this.hoverable.removeClass( "ui-state-hover" ); 4066 this.focusable.removeClass( "ui-state-focus" ); 4067 }, 4068 _destroy: $.noop, 4069 4070 widget: function() { 4071 return this.element; 4072 }, 4073 4074 option: function( key, value ) { 4075 var options = key, 4076 parts, 4077 curOption, 4078 i; 4079 4080 if ( arguments.length === 0 ) { 4081 // don't return a reference to the internal hash 4082 return $.widget.extend( {}, this.options ); 4083 } 4084 4085 if ( typeof key === "string" ) { 4086 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 4087 options = {}; 4088 parts = key.split( "." ); 4089 key = parts.shift(); 4090 if ( parts.length ) { 4091 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 4092 for ( i = 0; i < parts.length - 1; i++ ) { 4093 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 4094 curOption = curOption[ parts[ i ] ]; 4095 } 4096 key = parts.pop(); 4097 if ( value === undefined ) { 4098 return curOption[ key ] === undefined ? null : curOption[ key ]; 4099 } 4100 curOption[ key ] = value; 4101 } else { 4102 if ( value === undefined ) { 4103 return this.options[ key ] === undefined ? null : this.options[ key ]; 4104 } 4105 options[ key ] = value; 4106 } 4107 } 4108 4109 this._setOptions( options ); 4110 4111 return this; 4112 }, 4113 _setOptions: function( options ) { 4114 var key; 4115 4116 for ( key in options ) { 4117 this._setOption( key, options[ key ] ); 4118 } 4119 4120 return this; 4121 }, 4122 _setOption: function( key, value ) { 4123 this.options[ key ] = value; 4124 4125 if ( key === "disabled" ) { 4126 this.widget() 4127 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 4128 .attr( "aria-disabled", value ); 4129 this.hoverable.removeClass( "ui-state-hover" ); 4130 this.focusable.removeClass( "ui-state-focus" ); 4131 } 4132 4133 return this; 4134 }, 4135 4136 enable: function() { 4137 return this._setOption( "disabled", false ); 4138 }, 4139 disable: function() { 4140 return this._setOption( "disabled", true ); 4141 }, 4142 4143 _on: function( suppressDisabledCheck, element, handlers ) { 4144 var delegateElement, 4145 instance = this; 4146 4147 // no suppressDisabledCheck flag, shuffle arguments 4148 if ( typeof suppressDisabledCheck !== "boolean" ) { 4149 handlers = element; 4150 element = suppressDisabledCheck; 4151 suppressDisabledCheck = false; 4152 } 4153 4154 // no element argument, shuffle and use this.element 4155 if ( !handlers ) { 4156 handlers = element; 4157 element = this.element; 4158 delegateElement = this.widget(); 4159 } else { 4160 // accept selectors, DOM elements 4161 element = delegateElement = $( element ); 4162 this.bindings = this.bindings.add( element ); 4163 } 4164 4165 $.each( handlers, function( event, handler ) { 4166 function handlerProxy() { 4167 // allow widgets to customize the disabled handling 4168 // - disabled as an array instead of boolean 4169 // - disabled class as method for disabling individual parts 4170 if ( !suppressDisabledCheck && 4171 ( instance.options.disabled === true || 4172 $( this ).hasClass( "ui-state-disabled" ) ) ) { 4173 return; 4174 } 4175 return ( typeof handler === "string" ? instance[ handler ] : handler ) 4176 .apply( instance, arguments ); 4177 } 4178 4179 // copy the guid so direct unbinding works 4180 if ( typeof handler !== "string" ) { 4181 handlerProxy.guid = handler.guid = 4182 handler.guid || handlerProxy.guid || $.guid++; 4183 } 4184 4185 var match = event.match( /^(\w+)\s*(.*)$/ ), 4186 eventName = match[1] + instance.eventNamespace, 4187 selector = match[2]; 4188 if ( selector ) { 4189 delegateElement.delegate( selector, eventName, handlerProxy ); 4190 } else { 4191 element.bind( eventName, handlerProxy ); 4192 } 4193 }); 4194 }, 4195 4196 _off: function( element, eventName ) { 4197 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 4198 element.unbind( eventName ).undelegate( eventName ); 4199 }, 4200 4201 _delay: function( handler, delay ) { 4202 function handlerProxy() { 4203 return ( typeof handler === "string" ? instance[ handler ] : handler ) 4204 .apply( instance, arguments ); 4205 } 4206 var instance = this; 4207 return setTimeout( handlerProxy, delay || 0 ); 4208 }, 4209 4210 _hoverable: function( element ) { 4211 this.hoverable = this.hoverable.add( element ); 4212 this._on( element, { 4213 mouseenter: function( event ) { 4214 $( event.currentTarget ).addClass( "ui-state-hover" ); 4215 }, 4216 mouseleave: function( event ) { 4217 $( event.currentTarget ).removeClass( "ui-state-hover" ); 4218 } 4219 }); 4220 }, 4221 4222 _focusable: function( element ) { 4223 this.focusable = this.focusable.add( element ); 4224 this._on( element, { 4225 focusin: function( event ) { 4226 $( event.currentTarget ).addClass( "ui-state-focus" ); 4227 }, 4228 focusout: function( event ) { 4229 $( event.currentTarget ).removeClass( "ui-state-focus" ); 4230 } 4231 }); 4232 }, 4233 4234 _trigger: function( type, event, data ) { 4235 var prop, orig, 4236 callback = this.options[ type ]; 4237 4238 data = data || {}; 4239 event = $.Event( event ); 4240 event.type = ( type === this.widgetEventPrefix ? 4241 type : 4242 this.widgetEventPrefix + type ).toLowerCase(); 4243 // the original event may come from any element 4244 // so we need to reset the target on the new event 4245 event.target = this.element[ 0 ]; 4246 4247 // copy original event properties over to the new event 4248 orig = event.originalEvent; 4249 if ( orig ) { 4250 for ( prop in orig ) { 4251 if ( !( prop in event ) ) { 4252 event[ prop ] = orig[ prop ]; 4253 } 4254 } 4255 } 4256 4257 this.element.trigger( event, data ); 4258 return !( $.isFunction( callback ) && 4259 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 4260 event.isDefaultPrevented() ); 4261 } 4262}; 4263 4264$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 4265 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 4266 if ( typeof options === "string" ) { 4267 options = { effect: options }; 4268 } 4269 var hasOptions, 4270 effectName = !options ? 4271 method : 4272 options === true || typeof options === "number" ? 4273 defaultEffect : 4274 options.effect || defaultEffect; 4275 options = options || {}; 4276 if ( typeof options === "number" ) { 4277 options = { duration: options }; 4278 } 4279 hasOptions = !$.isEmptyObject( options ); 4280 options.complete = callback; 4281 if ( options.delay ) { 4282 element.delay( options.delay ); 4283 } 4284 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 4285 element[ method ]( options ); 4286 } else if ( effectName !== method && element[ effectName ] ) {
vendor: 54,147 bytes, lines 4287-6017
4287 element[ effectName ]( options.duration, options.easing, callback ); 4288 } else { 4289 element.queue(function( next ) { 4290 $( this )[ method ](); 4291 if ( callback ) { 4292 callback.call( element[ 0 ] ); 4293 } 4294 next(); 4295 }); 4296 } 4297 }; 4298}); 4299 4300})( jQuery ); 4301(function( $, undefined ) { 4302 4303var mouseHandled = false; 4304$( document ).mouseup( function() { 4305 mouseHandled = false; 4306}); 4307 4308$.widget("ui.mouse", { 4309 version: "1.10.3", 4310 options: { 4311 cancel: "input,textarea,button,select,option", 4312 distance: 1, 4313 delay: 0 4314 }, 4315 _mouseInit: function() { 4316 var that = this; 4317 4318 this.element 4319 .bind("mousedown."+this.widgetName, function(event) { 4320 return that._mouseDown(event); 4321 }) 4322 .bind("click."+this.widgetName, function(event) { 4323 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { 4324 $.removeData(event.target, that.widgetName + ".preventClickEvent"); 4325 event.stopImmediatePropagation(); 4326 return false; 4327 } 4328 }); 4329 4330 this.started = false; 4331 }, 4332 4333 // TODO: make sure destroying one instance of mouse doesn't mess with 4334 // other instances of mouse 4335 _mouseDestroy: function() { 4336 this.element.unbind("."+this.widgetName); 4337 if ( this._mouseMoveDelegate ) { 4338 $(document) 4339 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 4340 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 4341 } 4342 }, 4343 4344 _mouseDown: function(event) { 4345 // don't let more than one widget handle mouseStart 4346 if( mouseHandled ) { return; } 4347 4348 // we may have missed mouseup (out of window) 4349 (this._mouseStarted && this._mouseUp(event)); 4350 4351 this._mouseDownEvent = event; 4352 4353 var that = this, 4354 btnIsLeft = (event.which === 1), 4355 // event.target.nodeName works around a bug in IE 8 with 4356 // disabled inputs (#7620) 4357 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 4358 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 4359 return true; 4360 } 4361 4362 this.mouseDelayMet = !this.options.delay; 4363 if (!this.mouseDelayMet) { 4364 this._mouseDelayTimer = setTimeout(function() { 4365 that.mouseDelayMet = true; 4366 }, this.options.delay); 4367 } 4368 4369 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 4370 this._mouseStarted = (this._mouseStart(event) !== false); 4371 if (!this._mouseStarted) { 4372 event.preventDefault(); 4373 return true; 4374 } 4375 } 4376 4377 // Click event may never have fired (Gecko & Opera) 4378 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { 4379 $.removeData(event.target, this.widgetName + ".preventClickEvent"); 4380 } 4381 4382 // these delegates are required to keep context 4383 this._mouseMoveDelegate = function(event) { 4384 return that._mouseMove(event); 4385 }; 4386 this._mouseUpDelegate = function(event) { 4387 return that._mouseUp(event); 4388 }; 4389 $(document) 4390 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) 4391 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); 4392 4393 event.preventDefault(); 4394 4395 mouseHandled = true; 4396 return true; 4397 }, 4398 4399 _mouseMove: function(event) { 4400 // IE mouseup check - mouseup happened when mouse was out of window 4401 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { 4402 return this._mouseUp(event); 4403 } 4404 4405 if (this._mouseStarted) { 4406 this._mouseDrag(event); 4407 return event.preventDefault(); 4408 } 4409 4410 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 4411 this._mouseStarted = 4412 (this._mouseStart(this._mouseDownEvent, event) !== false); 4413 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 4414 } 4415 4416 return !this._mouseStarted; 4417 }, 4418 4419 _mouseUp: function(event) { 4420 $(document) 4421 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 4422 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 4423 4424 if (this._mouseStarted) { 4425 this._mouseStarted = false; 4426 4427 if (event.target === this._mouseDownEvent.target) { 4428 $.data(event.target, this.widgetName + ".preventClickEvent", true); 4429 } 4430 4431 this._mouseStop(event); 4432 } 4433 4434 return false; 4435 }, 4436 4437 _mouseDistanceMet: function(event) { 4438 return (Math.max( 4439 Math.abs(this._mouseDownEvent.pageX - event.pageX), 4440 Math.abs(this._mouseDownEvent.pageY - event.pageY) 4441 ) >= this.options.distance 4442 ); 4443 }, 4444 4445 _mouseDelayMet: function(/* event */) { 4446 return this.mouseDelayMet; 4447 }, 4448 4449 // These are placeholder methods, to be overriden by extending plugin 4450 _mouseStart: function(/* event */) {}, 4451 _mouseDrag: function(/* event */) {}, 4452 _mouseStop: function(/* event */) {}, 4453 _mouseCapture: function(/* event */) { return true; } 4454}); 4455 4456})(jQuery); 4457(function( $, undefined ) { 4458 4459$.ui = $.ui || {}; 4460 4461var cachedScrollbarWidth, 4462 max = Math.max, 4463 abs = Math.abs, 4464 round = Math.round, 4465 rhorizontal = /left|center|right/, 4466 rvertical = /top|center|bottom/, 4467 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 4468 rposition = /^\w+/, 4469 rpercent = /%$/, 4470 _position = $.fn.position; 4471 4472function getOffsets( offsets, width, height ) { 4473 return [ 4474 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 4475 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 4476 ]; 4477} 4478 4479function parseCss( element, property ) { 4480 return parseInt( $.css( element, property ), 10 ) || 0; 4481} 4482 4483function getDimensions( elem ) { 4484 var raw = elem[0]; 4485 if ( raw.nodeType === 9 ) { 4486 return { 4487 width: elem.width(), 4488 height: elem.height(), 4489 offset: { top: 0, left: 0 } 4490 }; 4491 } 4492 if ( $.isWindow( raw ) ) { 4493 return { 4494 width: elem.width(), 4495 height: elem.height(), 4496 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 4497 }; 4498 } 4499 if ( raw.preventDefault ) { 4500 return { 4501 width: 0, 4502 height: 0, 4503 offset: { top: raw.pageY, left: raw.pageX } 4504 }; 4505 } 4506 return { 4507 width: elem.outerWidth(), 4508 height: elem.outerHeight(), 4509 offset: elem.offset() 4510 }; 4511} 4512 4513$.position = { 4514 scrollbarWidth: function() { 4515 if ( cachedScrollbarWidth !== undefined ) { 4516 return cachedScrollbarWidth; 4517 } 4518 var w1, w2, 4519 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 4520 innerDiv = div.children()[0]; 4521 4522 $( "body" ).append( div ); 4523 w1 = innerDiv.offsetWidth; 4524 div.css( "overflow", "scroll" ); 4525 4526 w2 = innerDiv.offsetWidth; 4527 4528 if ( w1 === w2 ) { 4529 w2 = div[0].clientWidth; 4530 } 4531 4532 div.remove(); 4533 4534 return (cachedScrollbarWidth = w1 - w2); 4535 }, 4536 getScrollInfo: function( within ) { 4537 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 4538 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 4539 hasOverflowX = overflowX === "scroll" || 4540 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 4541 hasOverflowY = overflowY === "scroll" || 4542 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 4543 return { 4544 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 4545 height: hasOverflowX ? $.position.scrollbarWidth() : 0 4546 }; 4547 }, 4548 getWithinInfo: function( element ) { 4549 var withinElement = $( element || window ), 4550 isWindow = $.isWindow( withinElement[0] ); 4551 return { 4552 element: withinElement, 4553 isWindow: isWindow, 4554 offset: withinElement.offset() || { left: 0, top: 0 }, 4555 scrollLeft: withinElement.scrollLeft(), 4556 scrollTop: withinElement.scrollTop(), 4557 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 4558 height: isWindow ? withinElement.height() : withinElement.outerHeight() 4559 }; 4560 } 4561}; 4562 4563$.fn.position = function( options ) { 4564 if ( !options || !options.of ) { 4565 return _position.apply( this, arguments ); 4566 } 4567 4568 // make a copy, we don't want to modify arguments 4569 options = $.extend( {}, options ); 4570 4571 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 4572 target = $( options.of ), 4573 within = $.position.getWithinInfo( options.within ), 4574 scrollInfo = $.position.getScrollInfo( within ), 4575 collision = ( options.collision || "flip" ).split( " " ), 4576 offsets = {}; 4577 4578 dimensions = getDimensions( target ); 4579 if ( target[0].preventDefault ) { 4580 // force left top to allow flipping 4581 options.at = "left top"; 4582 } 4583 targetWidth = dimensions.width; 4584 targetHeight = dimensions.height; 4585 targetOffset = dimensions.offset; 4586 // clone to reuse original targetOffset later 4587 basePosition = $.extend( {}, targetOffset ); 4588 4589 // force my and at to have valid horizontal and vertical positions 4590 // if a value is missing or invalid, it will be converted to center 4591 $.each( [ "my", "at" ], function() { 4592 var pos = ( options[ this ] || "" ).split( " " ), 4593 horizontalOffset, 4594 verticalOffset; 4595 4596 if ( pos.length === 1) { 4597 pos = rhorizontal.test( pos[ 0 ] ) ? 4598 pos.concat( [ "center" ] ) : 4599 rvertical.test( pos[ 0 ] ) ? 4600 [ "center" ].concat( pos ) : 4601 [ "center", "center" ]; 4602 } 4603 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 4604 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 4605 4606 // calculate offsets 4607 horizontalOffset = roffset.exec( pos[ 0 ] ); 4608 verticalOffset = roffset.exec( pos[ 1 ] ); 4609 offsets[ this ] = [ 4610 horizontalOffset ? horizontalOffset[ 0 ] : 0, 4611 verticalOffset ? verticalOffset[ 0 ] : 0 4612 ]; 4613 4614 // reduce to just the positions without the offsets 4615 options[ this ] = [ 4616 rposition.exec( pos[ 0 ] )[ 0 ], 4617 rposition.exec( pos[ 1 ] )[ 0 ] 4618 ]; 4619 }); 4620 4621 // normalize collision option 4622 if ( collision.length === 1 ) { 4623 collision[ 1 ] = collision[ 0 ]; 4624 } 4625 4626 if ( options.at[ 0 ] === "right" ) { 4627 basePosition.left += targetWidth; 4628 } else if ( options.at[ 0 ] === "center" ) { 4629 basePosition.left += targetWidth / 2; 4630 } 4631 4632 if ( options.at[ 1 ] === "bottom" ) { 4633 basePosition.top += targetHeight; 4634 } else if ( options.at[ 1 ] === "center" ) { 4635 basePosition.top += targetHeight / 2; 4636 } 4637 4638 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 4639 basePosition.left += atOffset[ 0 ]; 4640 basePosition.top += atOffset[ 1 ]; 4641 4642 return this.each(function() { 4643 var collisionPosition, using, 4644 elem = $( this ), 4645 elemWidth = elem.outerWidth(), 4646 elemHeight = elem.outerHeight(), 4647 marginLeft = parseCss( this, "marginLeft" ), 4648 marginTop = parseCss( this, "marginTop" ), 4649 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 4650 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 4651 position = $.extend( {}, basePosition ), 4652 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 4653 4654 if ( options.my[ 0 ] === "right" ) { 4655 position.left -= elemWidth; 4656 } else if ( options.my[ 0 ] === "center" ) { 4657 position.left -= elemWidth / 2; 4658 } 4659 4660 if ( options.my[ 1 ] === "bottom" ) { 4661 position.top -= elemHeight; 4662 } else if ( options.my[ 1 ] === "center" ) { 4663 position.top -= elemHeight / 2; 4664 } 4665 4666 position.left += myOffset[ 0 ]; 4667 position.top += myOffset[ 1 ]; 4668 4669 // if the browser doesn't support fractions, then round for consistent results 4670 if ( !$.support.offsetFractions ) { 4671 position.left = round( position.left ); 4672 position.top = round( position.top ); 4673 } 4674 4675 collisionPosition = { 4676 marginLeft: marginLeft, 4677 marginTop: marginTop 4678 }; 4679 4680 $.each( [ "left", "top" ], function( i, dir ) { 4681 if ( $.ui.position[ collision[ i ] ] ) { 4682 $.ui.position[ collision[ i ] ][ dir ]( position, { 4683 targetWidth: targetWidth, 4684 targetHeight: targetHeight, 4685 elemWidth: elemWidth, 4686 elemHeight: elemHeight, 4687 collisionPosition: collisionPosition, 4688 collisionWidth: collisionWidth, 4689 collisionHeight: collisionHeight, 4690 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 4691 my: options.my, 4692 at: options.at, 4693 within: within, 4694 elem : elem 4695 }); 4696 } 4697 }); 4698 4699 if ( options.using ) { 4700 // adds feedback as second argument to using callback, if present 4701 using = function( props ) { 4702 var left = targetOffset.left - position.left, 4703 right = left + targetWidth - elemWidth, 4704 top = targetOffset.top - position.top, 4705 bottom = top + targetHeight - elemHeight, 4706 feedback = { 4707 target: { 4708 element: target, 4709 left: targetOffset.left, 4710 top: targetOffset.top, 4711 width: targetWidth, 4712 height: targetHeight 4713 }, 4714 element: { 4715 element: elem, 4716 left: position.left, 4717 top: position.top, 4718 width: elemWidth, 4719 height: elemHeight 4720 }, 4721 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 4722 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 4723 }; 4724 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 4725 feedback.horizontal = "center"; 4726 } 4727 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 4728 feedback.vertical = "middle"; 4729 } 4730 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 4731 feedback.important = "horizontal"; 4732 } else { 4733 feedback.important = "vertical"; 4734 } 4735 options.using.call( this, props, feedback ); 4736 }; 4737 } 4738 4739 elem.offset( $.extend( position, { using: using } ) ); 4740 }); 4741}; 4742 4743$.ui.position = { 4744 fit: { 4745 left: function( position, data ) { 4746 var within = data.within, 4747 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 4748 outerWidth = within.width, 4749 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 4750 overLeft = withinOffset - collisionPosLeft, 4751 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 4752 newOverRight; 4753 4754 // element is wider than within 4755 if ( data.collisionWidth > outerWidth ) { 4756 // element is initially over the left side of within 4757 if ( overLeft > 0 && overRight <= 0 ) { 4758 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 4759 position.left += overLeft - newOverRight; 4760 // element is initially over right side of within 4761 } else if ( overRight > 0 && overLeft <= 0 ) { 4762 position.left = withinOffset; 4763 // element is initially over both left and right sides of within 4764 } else { 4765 if ( overLeft > overRight ) { 4766 position.left = withinOffset + outerWidth - data.collisionWidth; 4767 } else { 4768 position.left = withinOffset; 4769 } 4770 } 4771 // too far left -> align with left edge 4772 } else if ( overLeft > 0 ) { 4773 position.left += overLeft; 4774 // too far right -> align with right edge 4775 } else if ( overRight > 0 ) { 4776 position.left -= overRight; 4777 // adjust based on position and margin 4778 } else { 4779 position.left = max( position.left - collisionPosLeft, position.left ); 4780 } 4781 }, 4782 top: function( position, data ) { 4783 var within = data.within, 4784 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 4785 outerHeight = data.within.height, 4786 collisionPosTop = position.top - data.collisionPosition.marginTop, 4787 overTop = withinOffset - collisionPosTop, 4788 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 4789 newOverBottom; 4790 4791 // element is taller than within 4792 if ( data.collisionHeight > outerHeight ) { 4793 // element is initially over the top of within 4794 if ( overTop > 0 && overBottom <= 0 ) { 4795 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 4796 position.top += overTop - newOverBottom; 4797 // element is initially over bottom of within 4798 } else if ( overBottom > 0 && overTop <= 0 ) { 4799 position.top = withinOffset; 4800 // element is initially over both top and bottom of within 4801 } else { 4802 if ( overTop > overBottom ) { 4803 position.top = withinOffset + outerHeight - data.collisionHeight; 4804 } else { 4805 position.top = withinOffset; 4806 } 4807 } 4808 // too far up -> align with top 4809 } else if ( overTop > 0 ) { 4810 position.top += overTop; 4811 // too far down -> align with bottom edge 4812 } else if ( overBottom > 0 ) { 4813 position.top -= overBottom; 4814 // adjust based on position and margin 4815 } else { 4816 position.top = max( position.top - collisionPosTop, position.top ); 4817 } 4818 } 4819 }, 4820 flip: { 4821 left: function( position, data ) { 4822 var within = data.within, 4823 withinOffset = within.offset.left + within.scrollLeft, 4824 outerWidth = within.width, 4825 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 4826 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 4827 overLeft = collisionPosLeft - offsetLeft, 4828 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 4829 myOffset = data.my[ 0 ] === "left" ? 4830 -data.elemWidth : 4831 data.my[ 0 ] === "right" ? 4832 data.elemWidth : 4833 0, 4834 atOffset = data.at[ 0 ] === "left" ? 4835 data.targetWidth : 4836 data.at[ 0 ] === "right" ? 4837 -data.targetWidth : 4838 0, 4839 offset = -2 * data.offset[ 0 ], 4840 newOverRight, 4841 newOverLeft; 4842 4843 if ( overLeft < 0 ) { 4844 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 4845 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 4846 position.left += myOffset + atOffset + offset; 4847 } 4848 } 4849 else if ( overRight > 0 ) { 4850 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 4851 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 4852 position.left += myOffset + atOffset + offset; 4853 } 4854 } 4855 }, 4856 top: function( position, data ) { 4857 var within = data.within, 4858 withinOffset = within.offset.top + within.scrollTop, 4859 outerHeight = within.height, 4860 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 4861 collisionPosTop = position.top - data.collisionPosition.marginTop, 4862 overTop = collisionPosTop - offsetTop, 4863 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 4864 top = data.my[ 1 ] === "top", 4865 myOffset = top ? 4866 -data.elemHeight : 4867 data.my[ 1 ] === "bottom" ? 4868 data.elemHeight : 4869 0, 4870 atOffset = data.at[ 1 ] === "top" ? 4871 data.targetHeight : 4872 data.at[ 1 ] === "bottom" ? 4873 -data.targetHeight : 4874 0, 4875 offset = -2 * data.offset[ 1 ], 4876 newOverTop, 4877 newOverBottom; 4878 if ( overTop < 0 ) { 4879 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 4880 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 4881 position.top += myOffset + atOffset + offset; 4882 } 4883 } 4884 else if ( overBottom > 0 ) { 4885 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 4886 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 4887 position.top += myOffset + atOffset + offset; 4888 } 4889 } 4890 } 4891 }, 4892 flipfit: { 4893 left: function() { 4894 $.ui.position.flip.left.apply( this, arguments ); 4895 $.ui.position.fit.left.apply( this, arguments ); 4896 }, 4897 top: function() { 4898 $.ui.position.flip.top.apply( this, arguments ); 4899 $.ui.position.fit.top.apply( this, arguments ); 4900 } 4901 } 4902}; 4903 4904// fraction support test 4905(function () { 4906 var testElement, testElementParent, testElementStyle, offsetLeft, i, 4907 body = document.getElementsByTagName( "body" )[ 0 ], 4908 div = document.createElement( "div" ); 4909 4910 //Create a "fake body" for testing based on method used in jQuery.support 4911 testElement = document.createElement( body ? "div" : "body" ); 4912 testElementStyle = { 4913 visibility: "hidden", 4914 width: 0, 4915 height: 0, 4916 border: 0, 4917 margin: 0, 4918 background: "none" 4919 }; 4920 if ( body ) { 4921 $.extend( testElementStyle, { 4922 position: "absolute", 4923 left: "-1000px", 4924 top: "-1000px" 4925 }); 4926 } 4927 for ( i in testElementStyle ) { 4928 testElement.style[ i ] = testElementStyle[ i ]; 4929 } 4930 testElement.appendChild( div ); 4931 testElementParent = body || document.documentElement; 4932 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 4933 4934 div.style.cssText = "position: absolute; left: 10.7432222px;"; 4935 4936 offsetLeft = $( div ).offset().left; 4937 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 4938 4939 testElement.innerHTML = ""; 4940 testElementParent.removeChild( testElement ); 4941})(); 4942 4943}( jQuery ) ); 4944(function( $, undefined ) { 4945 4946$.widget("ui.draggable", $.ui.mouse, { 4947 version: "1.10.3", 4948 widgetEventPrefix: "drag", 4949 options: { 4950 addClasses: true, 4951 appendTo: "parent", 4952 axis: false, 4953 connectToSortable: false, 4954 containment: false, 4955 cursor: "auto", 4956 cursorAt: false, 4957 grid: false, 4958 handle: false, 4959 helper: "original", 4960 iframeFix: false, 4961 opacity: false, 4962 refreshPositions: false, 4963 revert: false, 4964 revertDuration: 500, 4965 scope: "default", 4966 scroll: true, 4967 scrollSensitivity: 20, 4968 scrollSpeed: 20, 4969 snap: false, 4970 snapMode: "both", 4971 snapTolerance: 20, 4972 stack: false, 4973 zIndex: false, 4974 4975 // callbacks 4976 drag: null, 4977 start: null, 4978 stop: null 4979 }, 4980 _create: function() { 4981 4982 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { 4983 this.element[0].style.position = "relative"; 4984 } 4985 if (this.options.addClasses){ 4986 this.element.addClass("ui-draggable"); 4987 } 4988 if (this.options.disabled){ 4989 this.element.addClass("ui-draggable-disabled"); 4990 } 4991 4992 this._mouseInit(); 4993 4994 }, 4995 4996 _destroy: function() { 4997 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 4998 this._mouseDestroy(); 4999 }, 5000 5001 _mouseCapture: function(event) { 5002 5003 var o = this.options; 5004 5005 // among others, prevent a drag on a resizable-handle 5006 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { 5007 return false; 5008 } 5009 5010 //Quit if we're not on a valid handle 5011 this.handle = this._getHandle(event); 5012 if (!this.handle) { 5013 return false; 5014 } 5015 5016 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 5017 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") 5018 .css({ 5019 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 5020 position: "absolute", opacity: "0.001", zIndex: 1000 5021 }) 5022 .css($(this).offset()) 5023 .appendTo("body"); 5024 }); 5025 5026 return true; 5027 5028 }, 5029 5030 _mouseStart: function(event) { 5031 5032 var o = this.options; 5033 5034 //Create and append the visible helper 5035 this.helper = this._createHelper(event); 5036 5037 this.helper.addClass("ui-draggable-dragging"); 5038 5039 //Cache the helper size 5040 this._cacheHelperProportions(); 5041 5042 //If ddmanager is used for droppables, set the global draggable 5043 if($.ui.ddmanager) { 5044 $.ui.ddmanager.current = this; 5045 } 5046 5047 /* 5048 * - Position generation - 5049 * This block generates everything position related - it's the core of draggables. 5050 */ 5051 5052 //Cache the margins of the original element 5053 this._cacheMargins(); 5054 5055 //Store the helper's css position 5056 this.cssPosition = this.helper.css( "position" ); 5057 this.scrollParent = this.helper.scrollParent(); 5058 this.offsetParent = this.helper.offsetParent(); 5059 this.offsetParentCssPosition = this.offsetParent.css( "position" ); 5060 5061 //The element's absolute position on the page minus margins 5062 this.offset = this.positionAbs = this.element.offset(); 5063 this.offset = { 5064 top: this.offset.top - this.margins.top, 5065 left: this.offset.left - this.margins.left 5066 }; 5067 5068 //Reset scroll cache 5069 this.offset.scroll = false; 5070 5071 $.extend(this.offset, { 5072 click: { //Where the click happened, relative to the element 5073 left: event.pageX - this.offset.left, 5074 top: event.pageY - this.offset.top 5075 }, 5076 parent: this._getParentOffset(), 5077 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 5078 }); 5079 5080 //Generate the original position 5081 this.originalPosition = this.position = this._generatePosition(event); 5082 this.originalPageX = event.pageX; 5083 this.originalPageY = event.pageY; 5084 5085 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 5086 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 5087 5088 //Set a containment if given in the options 5089 this._setContainment(); 5090 5091 //Trigger event + callbacks 5092 if(this._trigger("start", event) === false) { 5093 this._clear(); 5094 return false; 5095 } 5096 5097 //Recache the helper size 5098 this._cacheHelperProportions(); 5099 5100 //Prepare the droppable offsets 5101 if ($.ui.ddmanager && !o.dropBehaviour) { 5102 $.ui.ddmanager.prepareOffsets(this, event); 5103 } 5104 5105 5106 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 5107 5108 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 5109 if ( $.ui.ddmanager ) { 5110 $.ui.ddmanager.dragStart(this, event); 5111 } 5112 5113 return true; 5114 }, 5115 5116 _mouseDrag: function(event, noPropagation) { 5117 // reset any necessary cached properties (see #5009) 5118 if ( this.offsetParentCssPosition === "fixed" ) { 5119 this.offset.parent = this._getParentOffset(); 5120 } 5121 5122 //Compute the helpers position 5123 this.position = this._generatePosition(event); 5124 this.positionAbs = this._convertPositionTo("absolute"); 5125 5126 //Call plugins and callbacks and use the resulting position if something is returned 5127 if (!noPropagation) { 5128 var ui = this._uiHash(); 5129 if(this._trigger("drag", event, ui) === false) { 5130 this._mouseUp({}); 5131 return false; 5132 } 5133 this.position = ui.position; 5134 } 5135 5136 if(!this.options.axis || this.options.axis !== "y") { 5137 this.helper[0].style.left = this.position.left+"px"; 5138 } 5139 if(!this.options.axis || this.options.axis !== "x") { 5140 this.helper[0].style.top = this.position.top+"px"; 5141 } 5142 if($.ui.ddmanager) { 5143 $.ui.ddmanager.drag(this, event); 5144 } 5145 5146 return false; 5147 }, 5148 5149 _mouseStop: function(event) { 5150 5151 //If we are using droppables, inform the manager about the drop 5152 var that = this, 5153 dropped = false; 5154 if ($.ui.ddmanager && !this.options.dropBehaviour) { 5155 dropped = $.ui.ddmanager.drop(this, event); 5156 } 5157 5158 //if a drop comes from outside (a sortable) 5159 if(this.dropped) { 5160 dropped = this.dropped; 5161 this.dropped = false; 5162 } 5163 5164 //if the original element is no longer in the DOM don't bother to continue (see #8269) 5165 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { 5166 return false; 5167 } 5168 5169 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))) { 5170 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 5171 if(that._trigger("stop", event) !== false) { 5172 that._clear(); 5173 } 5174 }); 5175 } else { 5176 if(this._trigger("stop", event) !== false) { 5177 this._clear(); 5178 } 5179 } 5180 5181 return false; 5182 }, 5183 5184 _mouseUp: function(event) { 5185 //Remove frame helpers 5186 $("div.ui-draggable-iframeFix").each(function() { 5187 this.parentNode.removeChild(this); 5188 }); 5189 5190 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 5191 if( $.ui.ddmanager ) { 5192 $.ui.ddmanager.dragStop(this, event); 5193 } 5194 5195 return $.ui.mouse.prototype._mouseUp.call(this, event); 5196 }, 5197 5198 cancel: function() { 5199 5200 if(this.helper.is(".ui-draggable-dragging")) { 5201 this._mouseUp({}); 5202 } else { 5203 this._clear(); 5204 } 5205 5206 return this; 5207 5208 }, 5209 5210 _getHandle: function(event) { 5211 return this.options.handle ? 5212 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 5213 true; 5214 }, 5215 5216 _createHelper: function(event) { 5217 5218 var o = this.options, 5219 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); 5220 5221 if(!helper.parents("body").length) { 5222 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); 5223 } 5224 5225 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { 5226 helper.css("position", "absolute"); 5227 } 5228 5229 return helper; 5230 5231 }, 5232 5233 _adjustOffsetFromHelper: function(obj) { 5234 if (typeof obj === "string") { 5235 obj = obj.split(" "); 5236 } 5237 if ($.isArray(obj)) { 5238 obj = {left: +obj[0], top: +obj[1] || 0}; 5239 } 5240 if ("left" in obj) { 5241 this.offset.click.left = obj.left + this.margins.left; 5242 } 5243 if ("right" in obj) { 5244 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 5245 } 5246 if ("top" in obj) { 5247 this.offset.click.top = obj.top + this.margins.top; 5248 } 5249 if ("bottom" in obj) { 5250 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 5251 } 5252 }, 5253 5254 _getParentOffset: function() { 5255 5256 //Get the offsetParent and cache its position 5257 var po = this.offsetParent.offset(); 5258 5259 // This is a special case where we need to modify a offset calculated on start, since the following happened: 5260 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 5261 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 5262 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 5263 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 5264 po.left += this.scrollParent.scrollLeft(); 5265 po.top += this.scrollParent.scrollTop(); 5266 } 5267 5268 //This needs to be actually done for all browsers, since pageX/pageY includes this information 5269 //Ugly IE fix 5270 if((this.offsetParent[0] === document.body) || 5271 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 5272 po = { top: 0, left: 0 }; 5273 } 5274 5275 return { 5276 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 5277 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 5278 }; 5279 5280 }, 5281 5282 _getRelativeOffset: function() { 5283 5284 if(this.cssPosition === "relative") { 5285 var p = this.element.position(); 5286 return { 5287 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 5288 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 5289 }; 5290 } else { 5291 return { top: 0, left: 0 }; 5292 } 5293 5294 }, 5295 5296 _cacheMargins: function() { 5297 this.margins = { 5298 left: (parseInt(this.element.css("marginLeft"),10) || 0), 5299 top: (parseInt(this.element.css("marginTop"),10) || 0), 5300 right: (parseInt(this.element.css("marginRight"),10) || 0), 5301 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 5302 }; 5303 }, 5304 5305 _cacheHelperProportions: function() { 5306 this.helperProportions = { 5307 width: this.helper.outerWidth(), 5308 height: this.helper.outerHeight() 5309 }; 5310 }, 5311 5312 _setContainment: function() { 5313 5314 var over, c, ce, 5315 o = this.options; 5316 5317 if ( !o.containment ) { 5318 this.containment = null; 5319 return; 5320 } 5321 5322 if ( o.containment === "window" ) { 5323 this.containment = [ 5324 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 5325 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 5326 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, 5327 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 5328 ]; 5329 return; 5330 } 5331 5332 if ( o.containment === "document") { 5333 this.containment = [ 5334 0, 5335 0, 5336 $( document ).width() - this.helperProportions.width - this.margins.left, 5337 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top 5338 ]; 5339 return; 5340 } 5341 5342 if ( o.containment.constructor === Array ) { 5343 this.containment = o.containment; 5344 return; 5345 } 5346 5347 if ( o.containment === "parent" ) { 5348 o.containment = this.helper[ 0 ].parentNode; 5349 } 5350 5351 c = $( o.containment ); 5352 ce = c[ 0 ]; 5353 5354 if( !ce ) { 5355 return; 5356 } 5357 5358 over = c.css( "overflow" ) !== "hidden"; 5359 5360 this.containment = [ 5361 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 5362 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , 5363 ( 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, 5364 ( 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 5365 ]; 5366 this.relative_container = c; 5367 }, 5368 5369 _convertPositionTo: function(d, pos) { 5370 5371 if(!pos) { 5372 pos = this.position; 5373 } 5374 5375 var mod = d === "absolute" ? 1 : -1, 5376 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; 5377 5378 //Cache the scroll 5379 if (!this.offset.scroll) { 5380 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 5381 } 5382 5383 return { 5384 top: ( 5385 pos.top + // The absolute mouse position 5386 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5387 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 5388 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) 5389 ), 5390 left: ( 5391 pos.left + // The absolute mouse position 5392 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 5393 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 5394 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) 5395 ) 5396 }; 5397 5398 }, 5399 5400 _generatePosition: function(event) { 5401 5402 var containment, co, top, left, 5403 o = this.options, 5404 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, 5405 pageX = event.pageX, 5406 pageY = event.pageY; 5407 5408 //Cache the scroll 5409 if (!this.offset.scroll) { 5410 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; 5411 } 5412 5413 /* 5414 * - Position constraining - 5415 * Constrain the position to a mix of grid, containment. 5416 */ 5417 5418 // If we are not dragging yet, we won't check for options 5419 if ( this.originalPosition ) { 5420 if ( this.containment ) { 5421 if ( this.relative_container ){ 5422 co = this.relative_container.offset(); 5423 containment = [ 5424 this.containment[ 0 ] + co.left, 5425 this.containment[ 1 ] + co.top, 5426 this.containment[ 2 ] + co.left, 5427 this.containment[ 3 ] + co.top 5428 ]; 5429 } 5430 else { 5431 containment = this.containment; 5432 } 5433 5434 if(event.pageX - this.offset.click.left < containment[0]) { 5435 pageX = containment[0] + this.offset.click.left; 5436 } 5437 if(event.pageY - this.offset.click.top < containment[1]) { 5438 pageY = containment[1] + this.offset.click.top; 5439 } 5440 if(event.pageX - this.offset.click.left > containment[2]) { 5441 pageX = containment[2] + this.offset.click.left; 5442 } 5443 if(event.pageY - this.offset.click.top > containment[3]) { 5444 pageY = containment[3] + this.offset.click.top; 5445 } 5446 } 5447 5448 if(o.grid) { 5449 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 5450 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 5451 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; 5452 5453 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 5454 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; 5455 } 5456 5457 } 5458 5459 return { 5460 top: ( 5461 pageY - // The absolute mouse position 5462 this.offset.click.top - // Click offset (relative to the element) 5463 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 5464 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 5465 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) 5466 ), 5467 left: ( 5468 pageX - // The absolute mouse position 5469 this.offset.click.left - // Click offset (relative to the element) 5470 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 5471 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 5472 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) 5473 ) 5474 }; 5475 5476 }, 5477 5478 _clear: function() { 5479 this.helper.removeClass("ui-draggable-dragging"); 5480 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { 5481 this.helper.remove(); 5482 } 5483 this.helper = null; 5484 this.cancelHelperRemoval = false; 5485 }, 5486 5487 // From now on bulk stuff - mainly helpers 5488 5489 _trigger: function(type, event, ui) { 5490 ui = ui || this._uiHash(); 5491 $.ui.plugin.call(this, type, [event, ui]); 5492 //The absolute position has to be recalculated after plugins 5493 if(type === "drag") { 5494 this.positionAbs = this._convertPositionTo("absolute"); 5495 } 5496 return $.Widget.prototype._trigger.call(this, type, event, ui); 5497 }, 5498 5499 plugins: {}, 5500 5501 _uiHash: function() { 5502 return { 5503 helper: this.helper, 5504 position: this.position, 5505 originalPosition: this.originalPosition, 5506 offset: this.positionAbs 5507 }; 5508 } 5509 5510}); 5511 5512$.ui.plugin.add("draggable", "connectToSortable", { 5513 start: function(event, ui) { 5514 5515 var inst = $(this).data("ui-draggable"), o = inst.options, 5516 uiSortable = $.extend({}, ui, { item: inst.element }); 5517 inst.sortables = []; 5518 $(o.connectToSortable).each(function() { 5519 var sortable = $.data(this, "ui-sortable"); 5520 if (sortable && !sortable.options.disabled) { 5521 inst.sortables.push({ 5522 instance: sortable, 5523 shouldRevert: sortable.options.revert 5524 }); 5525 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). 5526 sortable._trigger("activate", event, uiSortable); 5527 } 5528 }); 5529 5530 }, 5531 stop: function(event, ui) { 5532 5533 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 5534 var inst = $(this).data("ui-draggable"), 5535 uiSortable = $.extend({}, ui, { item: inst.element }); 5536 5537 $.each(inst.sortables, function() { 5538 if(this.instance.isOver) { 5539 5540 this.instance.isOver = 0; 5541 5542 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 5543 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 5544 5545 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" 5546 if(this.shouldRevert) { 5547 this.instance.options.revert = this.shouldRevert; 5548 } 5549 5550 //Trigger the stop of the sortable 5551 this.instance._mouseStop(event); 5552 5553 this.instance.options.helper = this.instance.options._helper; 5554 5555 //If the helper has been the original item, restore properties in the sortable 5556 if(inst.options.helper === "original") { 5557 this.instance.currentItem.css({ top: "auto", left: "auto" }); 5558 } 5559 5560 } else { 5561 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 5562 this.instance._trigger("deactivate", event, uiSortable); 5563 } 5564 5565 }); 5566 5567 }, 5568 drag: function(event, ui) { 5569 5570 var inst = $(this).data("ui-draggable"), that = this; 5571 5572 $.each(inst.sortables, function() { 5573 5574 var innermostIntersecting = false, 5575 thisSortable = this; 5576 5577 //Copy over some variables to allow calling the sortable's native _intersectsWith 5578 this.instance.positionAbs = inst.positionAbs; 5579 this.instance.helperProportions = inst.helperProportions; 5580 this.instance.offset.click = inst.offset.click; 5581 5582 if(this.instance._intersectsWith(this.instance.containerCache)) { 5583 innermostIntersecting = true; 5584 $.each(inst.sortables, function () { 5585 this.instance.positionAbs = inst.positionAbs; 5586 this.instance.helperProportions = inst.helperProportions; 5587 this.instance.offset.click = inst.offset.click; 5588 if (this !== thisSortable && 5589 this.instance._intersectsWith(this.instance.containerCache) && 5590 $.contains(thisSortable.instance.element[0], this.instance.element[0]) 5591 ) { 5592 innermostIntersecting = false; 5593 } 5594 return innermostIntersecting; 5595 }); 5596 } 5597 5598 5599 if(innermostIntersecting) { 5600 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 5601 if(!this.instance.isOver) { 5602 5603 this.instance.isOver = 1; 5604 //Now we fake the start of dragging for the sortable instance, 5605 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 5606 //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) 5607 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); 5608 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 5609 this.instance.options.helper = function() { return ui.helper[0]; }; 5610 5611 event.target = this.instance.currentItem[0]; 5612 this.instance._mouseCapture(event, true); 5613 this.instance._mouseStart(event, true, true); 5614 5615 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 5616 this.instance.offset.click.top = inst.offset.click.top; 5617 this.instance.offset.click.left = inst.offset.click.left; 5618 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 5619 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 5620 5621 inst._trigger("toSortable", event); 5622 inst.dropped = this.instance.element; //draggable revert needs that 5623 //hack so receive/update callbacks work (mostly) 5624 inst.currentItem = inst.element; 5625 this.instance.fromOutside = inst; 5626 5627 } 5628 5629 //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 5630 if(this.instance.currentItem) { 5631 this.instance._mouseDrag(event); 5632 } 5633 5634 } else { 5635 5636 //If it doesn't intersect with the sortable, and it intersected before, 5637 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 5638 if(this.instance.isOver) { 5639 5640 this.instance.isOver = 0; 5641 this.instance.cancelHelperRemoval = true; 5642 5643 //Prevent reverting on this forced stop 5644 this.instance.options.revert = false; 5645 5646 // The out event needs to be triggered independently 5647 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); 5648 5649 this.instance._mouseStop(event, true); 5650 this.instance.options.helper = this.instance.options._helper; 5651 5652 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 5653 this.instance.currentItem.remove(); 5654 if(this.instance.placeholder) { 5655 this.instance.placeholder.remove(); 5656 } 5657 5658 inst._trigger("fromSortable", event); 5659 inst.dropped = false; //draggable revert needs that 5660 } 5661 5662 } 5663 5664 }); 5665 5666 } 5667}); 5668 5669$.ui.plugin.add("draggable", "cursor", { 5670 start: function() { 5671 var t = $("body"), o = $(this).data("ui-draggable").options; 5672 if (t.css("cursor")) { 5673 o._cursor = t.css("cursor"); 5674 } 5675 t.css("cursor", o.cursor); 5676 }, 5677 stop: function() { 5678 var o = $(this).data("ui-draggable").options; 5679 if (o._cursor) { 5680 $("body").css("cursor", o._cursor); 5681 } 5682 } 5683}); 5684 5685$.ui.plugin.add("draggable", "opacity", { 5686 start: function(event, ui) { 5687 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 5688 if(t.css("opacity")) { 5689 o._opacity = t.css("opacity"); 5690 } 5691 t.css("opacity", o.opacity); 5692 }, 5693 stop: function(event, ui) { 5694 var o = $(this).data("ui-draggable").options; 5695 if(o._opacity) { 5696 $(ui.helper).css("opacity", o._opacity); 5697 } 5698 } 5699}); 5700 5701$.ui.plugin.add("draggable", "scroll", { 5702 start: function() { 5703 var i = $(this).data("ui-draggable"); 5704 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 5705 i.overflowOffset = i.scrollParent.offset(); 5706 } 5707 }, 5708 drag: function( event ) { 5709 5710 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; 5711 5712 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { 5713 5714 if(!o.axis || o.axis !== "x") { 5715 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 5716 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 5717 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { 5718 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 5719 } 5720 } 5721 5722 if(!o.axis || o.axis !== "y") { 5723 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 5724 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 5725 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { 5726 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 5727 } 5728 } 5729 5730 } else { 5731 5732 if(!o.axis || o.axis !== "x") { 5733 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 5734 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 5735 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 5736 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 5737 } 5738 } 5739 5740 if(!o.axis || o.axis !== "y") { 5741 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 5742 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 5743 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 5744 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 5745 } 5746 } 5747 5748 } 5749 5750 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 5751 $.ui.ddmanager.prepareOffsets(i, event); 5752 } 5753 5754 } 5755}); 5756 5757$.ui.plugin.add("draggable", "snap", { 5758 start: function() { 5759 5760 var i = $(this).data("ui-draggable"), 5761 o = i.options; 5762 5763 i.snapElements = []; 5764 5765 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { 5766 var $t = $(this), 5767 $o = $t.offset(); 5768 if(this !== i.element[0]) { 5769 i.snapElements.push({ 5770 item: this, 5771 width: $t.outerWidth(), height: $t.outerHeight(), 5772 top: $o.top, left: $o.left 5773 }); 5774 } 5775 }); 5776 5777 }, 5778 drag: function(event, ui) { 5779 5780 var ts, bs, ls, rs, l, r, t, b, i, first, 5781 inst = $(this).data("ui-draggable"), 5782 o = inst.options, 5783 d = o.snapTolerance, 5784 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 5785 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 5786 5787 for (i = inst.snapElements.length - 1; i >= 0; i--){ 5788 5789 l = inst.snapElements[i].left; 5790 r = l + inst.snapElements[i].width; 5791 t = inst.snapElements[i].top; 5792 b = t + inst.snapElements[i].height; 5793 5794 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 5795 if(inst.snapElements[i].snapping) { 5796 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 5797 } 5798 inst.snapElements[i].snapping = false; 5799 continue; 5800 } 5801 5802 if(o.snapMode !== "inner") { 5803 ts = Math.abs(t - y2) <= d; 5804 bs = Math.abs(b - y1) <= d; 5805 ls = Math.abs(l - x2) <= d; 5806 rs = Math.abs(r - x1) <= d; 5807 if(ts) { 5808 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 5809 } 5810 if(bs) { 5811 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 5812 } 5813 if(ls) { 5814 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 5815 } 5816 if(rs) { 5817 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 5818 } 5819 } 5820 5821 first = (ts || bs || ls || rs); 5822 5823 if(o.snapMode !== "outer") { 5824 ts = Math.abs(t - y1) <= d; 5825 bs = Math.abs(b - y2) <= d; 5826 ls = Math.abs(l - x1) <= d; 5827 rs = Math.abs(r - x2) <= d; 5828 if(ts) { 5829 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 5830 } 5831 if(bs) { 5832 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 5833 } 5834 if(ls) { 5835 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 5836 } 5837 if(rs) { 5838 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 5839 } 5840 } 5841 5842 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { 5843 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 5844 } 5845 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 5846 5847 } 5848 5849 } 5850}); 5851 5852$.ui.plugin.add("draggable", "stack", { 5853 start: function() { 5854 var min, 5855 o = this.data("ui-draggable").options, 5856 group = $.makeArray($(o.stack)).sort(function(a,b) { 5857 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 5858 }); 5859 5860 if (!group.length) { return; } 5861 5862 min = parseInt($(group[0]).css("zIndex"), 10) || 0; 5863 $(group).each(function(i) { 5864 $(this).css("zIndex", min + i); 5865 }); 5866 this.css("zIndex", (min + group.length)); 5867 } 5868}); 5869 5870$.ui.plugin.add("draggable", "zIndex", { 5871 start: function(event, ui) { 5872 var t = $(ui.helper), o = $(this).data("ui-draggable").options; 5873 if(t.css("zIndex")) { 5874 o._zIndex = t.css("zIndex"); 5875 } 5876 t.css("zIndex", o.zIndex); 5877 }, 5878 stop: function(event, ui) { 5879 var o = $(this).data("ui-draggable").options; 5880 if(o._zIndex) { 5881 $(ui.helper).css("zIndex", o._zIndex); 5882 } 5883 } 5884}); 5885 5886})(jQuery); 5887(function( $, undefined ) { 5888 5889function isOverAxis( x, reference, size ) { 5890 return ( x > reference ) && ( x < ( reference + size ) ); 5891} 5892 5893$.widget("ui.droppable", { 5894 version: "1.10.3", 5895 widgetEventPrefix: "drop", 5896 options: { 5897 accept: "*", 5898 activeClass: false, 5899 addClasses: true, 5900 greedy: false, 5901 hoverClass: false, 5902 scope: "default", 5903 tolerance: "intersect", 5904 5905 // callbacks 5906 activate: null, 5907 deactivate: null, 5908 drop: null, 5909 out: null, 5910 over: null 5911 }, 5912 _create: function() { 5913 5914 var o = this.options, 5915 accept = o.accept; 5916 5917 this.isover = false; 5918 this.isout = true; 5919 5920 this.accept = $.isFunction(accept) ? accept : function(d) { 5921 return d.is(accept); 5922 }; 5923 5924 //Store the droppable's proportions 5925 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 5926 5927 // Add the reference and positions to the manager 5928 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 5929 $.ui.ddmanager.droppables[o.scope].push(this); 5930 5931 (o.addClasses && this.element.addClass("ui-droppable")); 5932 5933 }, 5934 5935 _destroy: function() { 5936 var i = 0, 5937 drop = $.ui.ddmanager.droppables[this.options.scope]; 5938 5939 for ( ; i < drop.length; i++ ) { 5940 if ( drop[i] === this ) { 5941 drop.splice(i, 1); 5942 } 5943 } 5944 5945 this.element.removeClass("ui-droppable ui-droppable-disabled"); 5946 }, 5947 5948 _setOption: function(key, value) { 5949 5950 if(key === "accept") { 5951 this.accept = $.isFunction(value) ? value : function(d) { 5952 return d.is(value); 5953 }; 5954 } 5955 $.Widget.prototype._setOption.apply(this, arguments); 5956 }, 5957 5958 _activate: function(event) { 5959 var draggable = $.ui.ddmanager.current; 5960 if(this.options.activeClass) { 5961 this.element.addClass(this.options.activeClass); 5962 } 5963 if(draggable){ 5964 this._trigger("activate", event, this.ui(draggable)); 5965 } 5966 }, 5967 5968 _deactivate: function(event) { 5969 var draggable = $.ui.ddmanager.current; 5970 if(this.options.activeClass) { 5971 this.element.removeClass(this.options.activeClass); 5972 } 5973 if(draggable){ 5974 this._trigger("deactivate", event, this.ui(draggable)); 5975 } 5976 }, 5977 5978 _over: function(event) { 5979 5980 var draggable = $.ui.ddmanager.current; 5981 5982 // Bail if draggable and droppable are same element 5983 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 5984 return; 5985 } 5986 5987 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 5988 if(this.options.hoverClass) { 5989 this.element.addClass(this.options.hoverClass); 5990 } 5991 this._trigger("over", event, this.ui(draggable)); 5992 } 5993 5994 }, 5995 5996 _out: function(event) { 5997 5998 var draggable = $.ui.ddmanager.current; 5999 6000 // Bail if draggable and droppable are same element 6001 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 6002 return; 6003 } 6004 6005 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 6006 if(this.options.hoverClass) { 6007 this.element.removeClass(this.options.hoverClass); 6008 } 6009 this._trigger("out", event, this.ui(draggable)); 6010 } 6011 6012 }, 6013 6014 _drop: function(event,custom) { 6015 6016 var draggable = custom || $.ui.ddmanager.current, 6017 childrenIntersection = false;
6018 6019 // Bail if draggable and droppable are same element 6020 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { 6021 return false; 6022 } 6023 6024 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { 6025 var inst = $.data(this, "ui-droppable"); 6026 if( 6027 inst.options.greedy && 6028 !inst.options.disabled && 6029 inst.options.scope === draggable.options.scope && 6030 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && 6031 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 6032 ) { childrenIntersection = true; return false; } 6033 }); 6034 if(childrenIntersection) { 6035 return false; 6036 } 6037 6038 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 6039 if(this.options.activeClass) { 6040 this.element.removeClass(this.options.activeClass); 6041 } 6042 if(this.options.hoverClass) { 6043 this.element.removeClass(this.options.hoverClass); 6044 } 6045 this._trigger("drop", event, this.ui(draggable)); 6046 return this.element; 6047 } 6048 6049 return false; 6050 6051 }, 6052 6053 ui: function(c) { 6054 return { 6055 draggable: (c.currentItem || c.element), 6056 helper: c.helper, 6057 position: c.position, 6058 offset: c.positionAbs 6059 }; 6060 } 6061 6062}); 6063 6064$.ui.intersect = function(draggable, droppable, toleranceMode) { 6065 6066 if (!droppable.offset) { 6067 return false; 6068 } 6069 6070 var draggableLeft, draggableTop, 6071 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 6072 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, 6073 l = droppable.offset.left, r = l + droppable.proportions.width, 6074 t = droppable.offset.top, b = t + droppable.proportions.height; 6075 6076 switch (toleranceMode) { 6077 case "fit": 6078 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); 6079 case "intersect": 6080 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half 6081 x2 - (draggable.helperProportions.width / 2) < r && // Left Half 6082 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half 6083 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 6084 case "pointer": 6085 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); 6086 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); 6087 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); 6088 case "touch": 6089 return ( 6090 (y1 >= t && y1 <= b) || // Top edge touching 6091 (y2 >= t && y2 <= b) || // Bottom edge touching 6092 (y1 < t && y2 > b) // Surrounded vertically 6093 ) && ( 6094 (x1 >= l && x1 <= r) || // Left edge touching 6095 (x2 >= l && x2 <= r) || // Right edge touching 6096 (x1 < l && x2 > r) // Surrounded horizontally 6097 ); 6098 default: 6099 return false; 6100 } 6101 6102}; 6103 6104/* 6105 This manager tracks offsets of draggables and droppables 6106*/ 6107$.ui.ddmanager = { 6108 current: null, 6109 droppables: { "default": [] }, 6110 prepareOffsets: function(t, event) { 6111 6112 var i, j, 6113 m = $.ui.ddmanager.droppables[t.options.scope] || [], 6114 type = event ? event.type : null, // workaround for #2317 6115 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); 6116 6117 droppablesLoop: for (i = 0; i < m.length; i++) { 6118 6119 //No disabled and non-accepted 6120 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { 6121 continue; 6122 } 6123 6124 // Filter out elements in the current dragged item 6125 for (j=0; j < list.length; j++) { 6126 if(list[j] === m[i].element[0]) { 6127 m[i].proportions.height = 0; 6128 continue droppablesLoop; 6129 } 6130 } 6131 6132 m[i].visible = m[i].element.css("display") !== "none"; 6133 if(!m[i].visible) { 6134 continue; 6135 } 6136 6137 //Activate the droppable if used directly from draggables 6138 if(type === "mousedown") { 6139 m[i]._activate.call(m[i], event); 6140 } 6141 6142 m[i].offset = m[i].element.offset(); 6143 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 6144 6145 } 6146 6147 }, 6148 drop: function(draggable, event) { 6149 6150 var dropped = false;
vendor: 22,517 bytes, lines 6151-6939
6151 // Create a copy of the droppables in case the list changes during the drop (#9116) 6152 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { 6153 6154 if(!this.options) { 6155 return; 6156 } 6157 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { 6158 dropped = this._drop.call(this, event) || dropped; 6159 } 6160 6161 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 6162 this.isout = true; 6163 this.isover = false; 6164 this._deactivate.call(this, event); 6165 } 6166 6167 }); 6168 return dropped; 6169 6170 }, 6171 dragStart: function( draggable, event ) { 6172 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 6173 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { 6174 if( !draggable.options.refreshPositions ) { 6175 $.ui.ddmanager.prepareOffsets( draggable, event ); 6176 } 6177 }); 6178 }, 6179 drag: function(draggable, event) { 6180 6181 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 6182 if(draggable.options.refreshPositions) { 6183 $.ui.ddmanager.prepareOffsets(draggable, event); 6184 } 6185 6186 //Run through all droppables and check their positions based on specific tolerance options 6187 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 6188 6189 if(this.options.disabled || this.greedyChild || !this.visible) { 6190 return; 6191 } 6192 6193 var parentInstance, scope, parent, 6194 intersects = $.ui.intersect(draggable, this, this.options.tolerance), 6195 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); 6196 if(!c) { 6197 return; 6198 } 6199 6200 if (this.options.greedy) { 6201 // find droppable parents with same scope 6202 scope = this.options.scope; 6203 parent = this.element.parents(":data(ui-droppable)").filter(function () { 6204 return $.data(this, "ui-droppable").options.scope === scope; 6205 }); 6206 6207 if (parent.length) { 6208 parentInstance = $.data(parent[0], "ui-droppable"); 6209 parentInstance.greedyChild = (c === "isover"); 6210 } 6211 } 6212 6213 // we just moved into a greedy child 6214 if (parentInstance && c === "isover") { 6215 parentInstance.isover = false; 6216 parentInstance.isout = true; 6217 parentInstance._out.call(parentInstance, event); 6218 } 6219 6220 this[c] = true; 6221 this[c === "isout" ? "isover" : "isout"] = false; 6222 this[c === "isover" ? "_over" : "_out"].call(this, event); 6223 6224 // we just moved out of a greedy child 6225 if (parentInstance && c === "isout") { 6226 parentInstance.isout = false; 6227 parentInstance.isover = true; 6228 parentInstance._over.call(parentInstance, event); 6229 } 6230 }); 6231 6232 }, 6233 dragStop: function( draggable, event ) { 6234 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 6235 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 6236 if( !draggable.options.refreshPositions ) { 6237 $.ui.ddmanager.prepareOffsets( draggable, event ); 6238 } 6239 } 6240}; 6241 6242})(jQuery); 6243(function( $, undefined ) { 6244 6245function num(v) { 6246 return parseInt(v, 10) || 0; 6247} 6248 6249function isNumber(value) { 6250 return !isNaN(parseInt(value, 10)); 6251} 6252 6253$.widget("ui.resizable", $.ui.mouse, { 6254 version: "1.10.3", 6255 widgetEventPrefix: "resize", 6256 options: { 6257 alsoResize: false, 6258 animate: false, 6259 animateDuration: "slow", 6260 animateEasing: "swing", 6261 aspectRatio: false, 6262 autoHide: false, 6263 containment: false, 6264 ghost: false, 6265 grid: false, 6266 handles: "e,s,se", 6267 helper: false, 6268 maxHeight: null, 6269 maxWidth: null, 6270 minHeight: 10, 6271 minWidth: 10, 6272 // See #7960 6273 zIndex: 90, 6274 6275 // callbacks 6276 resize: null, 6277 start: null, 6278 stop: null 6279 }, 6280 _create: function() { 6281 6282 var n, i, handle, axis, hname, 6283 that = this, 6284 o = this.options; 6285 this.element.addClass("ui-resizable"); 6286 6287 $.extend(this, { 6288 _aspectRatio: !!(o.aspectRatio), 6289 aspectRatio: o.aspectRatio, 6290 originalElement: this.element, 6291 _proportionallyResizeElements: [], 6292 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 6293 }); 6294 6295 //Wrap the element if it cannot hold child nodes 6296 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 6297 6298 //Create a wrapper element and set the wrapper to the new current internal element 6299 this.element.wrap( 6300 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ 6301 position: this.element.css("position"), 6302 width: this.element.outerWidth(), 6303 height: this.element.outerHeight(), 6304 top: this.element.css("top"), 6305 left: this.element.css("left") 6306 }) 6307 ); 6308 6309 //Overwrite the original this.element 6310 this.element = this.element.parent().data( 6311 "ui-resizable", this.element.data("ui-resizable") 6312 ); 6313 6314 this.elementIsWrapper = true; 6315 6316 //Move margins to the wrapper 6317 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 6318 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 6319 6320 //Prevent Safari textarea resize 6321 this.originalResizeStyle = this.originalElement.css("resize"); 6322 this.originalElement.css("resize", "none"); 6323 6324 //Push the actual element to our proportionallyResize internal array 6325 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); 6326 6327 // avoid IE jump (hard set the margin) 6328 this.originalElement.css({ margin: this.originalElement.css("margin") }); 6329 6330 // fix handlers offset 6331 this._proportionallyResize(); 6332 6333 } 6334 6335 this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" }); 6336 if(this.handles.constructor === String) { 6337 6338 if ( this.handles === "all") { 6339 this.handles = "n,e,s,w,se,sw,ne,nw"; 6340 } 6341 6342 n = this.handles.split(","); 6343 this.handles = {}; 6344 6345 for(i = 0; i < n.length; i++) { 6346 6347 handle = $.trim(n[i]); 6348 hname = "ui-resizable-"+handle; 6349 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); 6350 6351 // Apply zIndex to all handles - see #7960 6352 axis.css({ zIndex: o.zIndex }); 6353 6354 //TODO : What's going on here? 6355 if ("se" === handle) { 6356 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); 6357 } 6358 6359 //Insert into internal handles object and append to element 6360 this.handles[handle] = ".ui-resizable-"+handle; 6361 this.element.append(axis); 6362 } 6363 6364 } 6365 6366 this._renderAxis = function(target) { 6367 6368 var i, axis, padPos, padWrapper; 6369 6370 target = target || this.element; 6371 6372 for(i in this.handles) { 6373 6374 if(this.handles[i].constructor === String) { 6375 this.handles[i] = $(this.handles[i], this.element).show(); 6376 } 6377 6378 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 6379 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 6380 6381 axis = $(this.handles[i], this.element); 6382 6383 //Checking the correct pad and border 6384 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 6385 6386 //The padding type i have to apply... 6387 padPos = [ "padding", 6388 /ne|nw|n/.test(i) ? "Top" : 6389 /se|sw|s/.test(i) ? "Bottom" : 6390 /^e$/.test(i) ? "Right" : "Left" ].join(""); 6391 6392 target.css(padPos, padWrapper); 6393 6394 this._proportionallyResize(); 6395 6396 } 6397 6398 //TODO: What's that good for? There's not anything to be executed left 6399 if(!$(this.handles[i]).length) { 6400 continue; 6401 } 6402 } 6403 }; 6404 6405 //TODO: make renderAxis a prototype function 6406 this._renderAxis(this.element); 6407 6408 this._handles = $(".ui-resizable-handle", this.element) 6409 .disableSelection(); 6410 6411 //Matching axis name 6412 this._handles.mouseover(function() { 6413 if (!that.resizing) { 6414 if (this.className) { 6415 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 6416 } 6417 //Axis, default = se 6418 that.axis = axis && axis[1] ? axis[1] : "se"; 6419 } 6420 }); 6421 6422 //If we want to auto hide the elements 6423 if (o.autoHide) { 6424 this._handles.hide(); 6425 $(this.element) 6426 .addClass("ui-resizable-autohide") 6427 .mouseenter(function() { 6428 if (o.disabled) { 6429 return; 6430 } 6431 $(this).removeClass("ui-resizable-autohide"); 6432 that._handles.show(); 6433 }) 6434 .mouseleave(function(){ 6435 if (o.disabled) { 6436 return; 6437 } 6438 if (!that.resizing) { 6439 $(this).addClass("ui-resizable-autohide"); 6440 that._handles.hide(); 6441 } 6442 }); 6443 } 6444 6445 //Initialize the mouse interaction 6446 this._mouseInit(); 6447 6448 }, 6449 6450 _destroy: function() { 6451 6452 this._mouseDestroy(); 6453 6454 var wrapper, 6455 _destroy = function(exp) { 6456 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 6457 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); 6458 }; 6459 6460 //TODO: Unwrap at same DOM position 6461 if (this.elementIsWrapper) { 6462 _destroy(this.element); 6463 wrapper = this.element; 6464 this.originalElement.css({ 6465 position: wrapper.css("position"), 6466 width: wrapper.outerWidth(), 6467 height: wrapper.outerHeight(), 6468 top: wrapper.css("top"), 6469 left: wrapper.css("left") 6470 }).insertAfter( wrapper ); 6471 wrapper.remove(); 6472 } 6473 6474 this.originalElement.css("resize", this.originalResizeStyle); 6475 _destroy(this.originalElement); 6476 6477 return this; 6478 }, 6479 6480 _mouseCapture: function(event) { 6481 var i, handle, 6482 capture = false; 6483 6484 for (i in this.handles) { 6485 handle = $(this.handles[i])[0]; 6486 if (handle === event.target || $.contains(handle, event.target)) { 6487 capture = true; 6488 } 6489 } 6490 6491 return !this.options.disabled && capture; 6492 }, 6493 6494 _mouseStart: function(event) { 6495 6496 var curleft, curtop, cursor, 6497 o = this.options, 6498 iniPos = this.element.position(), 6499 el = this.element; 6500 6501 this.resizing = true; 6502 6503 // bugfix for http://dev.jquery.com/ticket/1749 6504 if ( (/absolute/).test( el.css("position") ) ) { 6505 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); 6506 } else if (el.is(".ui-draggable")) { 6507 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); 6508 } 6509 6510 this._renderProxy(); 6511 6512 curleft = num(this.helper.css("left")); 6513 curtop = num(this.helper.css("top")); 6514 6515 if (o.containment) { 6516 curleft += $(o.containment).scrollLeft() || 0; 6517 curtop += $(o.containment).scrollTop() || 0; 6518 } 6519 6520 //Store needed variables 6521 this.offset = this.helper.offset(); 6522 this.position = { left: curleft, top: curtop }; 6523 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 6524 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 6525 this.originalPosition = { left: curleft, top: curtop }; 6526 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 6527 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 6528 6529 //Aspect Ratio 6530 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 6531 6532 cursor = $(".ui-resizable-" + this.axis).css("cursor"); 6533 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); 6534 6535 el.addClass("ui-resizable-resizing"); 6536 this._propagate("start", event); 6537 return true; 6538 }, 6539 6540 _mouseDrag: function(event) { 6541 6542 //Increase performance, avoid regex 6543 var data, 6544 el = this.helper, props = {}, 6545 smp = this.originalMousePosition, 6546 a = this.axis, 6547 prevTop = this.position.top, 6548 prevLeft = this.position.left, 6549 prevWidth = this.size.width, 6550 prevHeight = this.size.height, 6551 dx = (event.pageX-smp.left)||0, 6552 dy = (event.pageY-smp.top)||0, 6553 trigger = this._change[a]; 6554 6555 if (!trigger) { 6556 return false; 6557 } 6558 6559 // Calculate the attrs that will be change 6560 data = trigger.apply(this, [event, dx, dy]); 6561 6562 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 6563 this._updateVirtualBoundaries(event.shiftKey); 6564 if (this._aspectRatio || event.shiftKey) { 6565 data = this._updateRatio(data, event); 6566 } 6567 6568 data = this._respectSize(data, event); 6569 6570 this._updateCache(data); 6571 6572 // plugins callbacks need to be called first 6573 this._propagate("resize", event); 6574 6575 if (this.position.top !== prevTop) { 6576 props.top = this.position.top + "px"; 6577 } 6578 if (this.position.left !== prevLeft) { 6579 props.left = this.position.left + "px"; 6580 } 6581 if (this.size.width !== prevWidth) { 6582 props.width = this.size.width + "px"; 6583 } 6584 if (this.size.height !== prevHeight) { 6585 props.height = this.size.height + "px"; 6586 } 6587 el.css(props); 6588 6589 if (!this._helper && this._proportionallyResizeElements.length) { 6590 this._proportionallyResize(); 6591 } 6592 6593 // Call the user callback if the element was resized 6594 if ( ! $.isEmptyObject(props) ) { 6595 this._trigger("resize", event, this.ui()); 6596 } 6597 6598 return false; 6599 }, 6600 6601 _mouseStop: function(event) { 6602 6603 this.resizing = false; 6604 var pr, ista, soffseth, soffsetw, s, left, top, 6605 o = this.options, that = this; 6606 6607 if(this._helper) { 6608 6609 pr = this._proportionallyResizeElements; 6610 ista = pr.length && (/textarea/i).test(pr[0].nodeName); 6611 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; 6612 soffsetw = ista ? 0 : that.sizeDiff.width; 6613 6614 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; 6615 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; 6616 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 6617 6618 if (!o.animate) { 6619 this.element.css($.extend(s, { top: top, left: left })); 6620 } 6621 6622 that.helper.height(that.size.height); 6623 that.helper.width(that.size.width); 6624 6625 if (this._helper && !o.animate) { 6626 this._proportionallyResize(); 6627 } 6628 } 6629 6630 $("body").css("cursor", "auto"); 6631 6632 this.element.removeClass("ui-resizable-resizing"); 6633 6634 this._propagate("stop", event); 6635 6636 if (this._helper) { 6637 this.helper.remove(); 6638 } 6639 6640 return false; 6641 6642 }, 6643 6644 _updateVirtualBoundaries: function(forceAspectRatio) { 6645 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 6646 o = this.options; 6647 6648 b = { 6649 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 6650 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 6651 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 6652 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 6653 }; 6654 6655 if(this._aspectRatio || forceAspectRatio) { 6656 // We want to create an enclosing box whose aspect ration is the requested one 6657 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 6658 pMinWidth = b.minHeight * this.aspectRatio; 6659 pMinHeight = b.minWidth / this.aspectRatio; 6660 pMaxWidth = b.maxHeight * this.aspectRatio; 6661 pMaxHeight = b.maxWidth / this.aspectRatio; 6662 6663 if(pMinWidth > b.minWidth) { 6664 b.minWidth = pMinWidth; 6665 } 6666 if(pMinHeight > b.minHeight) { 6667 b.minHeight = pMinHeight; 6668 } 6669 if(pMaxWidth < b.maxWidth) { 6670 b.maxWidth = pMaxWidth; 6671 } 6672 if(pMaxHeight < b.maxHeight) { 6673 b.maxHeight = pMaxHeight; 6674 } 6675 } 6676 this._vBoundaries = b; 6677 }, 6678 6679 _updateCache: function(data) { 6680 this.offset = this.helper.offset(); 6681 if (isNumber(data.left)) { 6682 this.position.left = data.left; 6683 } 6684 if (isNumber(data.top)) { 6685 this.position.top = data.top; 6686 } 6687 if (isNumber(data.height)) { 6688 this.size.height = data.height; 6689 } 6690 if (isNumber(data.width)) { 6691 this.size.width = data.width; 6692 } 6693 }, 6694 6695 _updateRatio: function( data ) { 6696 6697 var cpos = this.position, 6698 csize = this.size, 6699 a = this.axis; 6700 6701 if (isNumber(data.height)) { 6702 data.width = (data.height * this.aspectRatio); 6703 } else if (isNumber(data.width)) { 6704 data.height = (data.width / this.aspectRatio); 6705 } 6706 6707 if (a === "sw") { 6708 data.left = cpos.left + (csize.width - data.width); 6709 data.top = null; 6710 } 6711 if (a === "nw") { 6712 data.top = cpos.top + (csize.height - data.height); 6713 data.left = cpos.left + (csize.width - data.width); 6714 } 6715 6716 return data; 6717 }, 6718 6719 _respectSize: function( data ) { 6720 6721 var o = this._vBoundaries, 6722 a = this.axis, 6723 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 6724 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), 6725 dw = this.originalPosition.left + this.originalSize.width, 6726 dh = this.position.top + this.size.height, 6727 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 6728 if (isminw) { 6729 data.width = o.minWidth; 6730 } 6731 if (isminh) { 6732 data.height = o.minHeight; 6733 } 6734 if (ismaxw) { 6735 data.width = o.maxWidth; 6736 } 6737 if (ismaxh) { 6738 data.height = o.maxHeight; 6739 } 6740 6741 if (isminw && cw) { 6742 data.left = dw - o.minWidth; 6743 } 6744 if (ismaxw && cw) { 6745 data.left = dw - o.maxWidth; 6746 } 6747 if (isminh && ch) { 6748 data.top = dh - o.minHeight; 6749 } 6750 if (ismaxh && ch) { 6751 data.top = dh - o.maxHeight; 6752 } 6753 6754 // fixing jump error on top/left - bug #2330 6755 if (!data.width && !data.height && !data.left && data.top) { 6756 data.top = null; 6757 } else if (!data.width && !data.height && !data.top && data.left) { 6758 data.left = null; 6759 } 6760 6761 return data; 6762 }, 6763 6764 _proportionallyResize: function() { 6765 6766 if (!this._proportionallyResizeElements.length) { 6767 return; 6768 } 6769 6770 var i, j, borders, paddings, prel, 6771 element = this.helper || this.element; 6772 6773 for ( i=0; i < this._proportionallyResizeElements.length; i++) { 6774 6775 prel = this._proportionallyResizeElements[i]; 6776 6777 if (!this.borderDif) { 6778 this.borderDif = []; 6779 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; 6780 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; 6781 6782 for ( j = 0; j < borders.length; j++ ) { 6783 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); 6784 } 6785 } 6786 6787 prel.css({ 6788 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 6789 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 6790 }); 6791 6792 } 6793 6794 }, 6795 6796 _renderProxy: function() { 6797 6798 var el = this.element, o = this.options; 6799 this.elementOffset = el.offset(); 6800 6801 if(this._helper) { 6802 6803 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); 6804 6805 this.helper.addClass(this._helper).css({ 6806 width: this.element.outerWidth() - 1, 6807 height: this.element.outerHeight() - 1, 6808 position: "absolute", 6809 left: this.elementOffset.left +"px", 6810 top: this.elementOffset.top +"px", 6811 zIndex: ++o.zIndex //TODO: Don't modify option 6812 }); 6813 6814 this.helper 6815 .appendTo("body") 6816 .disableSelection(); 6817 6818 } else { 6819 this.helper = this.element; 6820 } 6821 6822 }, 6823 6824 _change: { 6825 e: function(event, dx) { 6826 return { width: this.originalSize.width + dx }; 6827 }, 6828 w: function(event, dx) { 6829 var cs = this.originalSize, sp = this.originalPosition; 6830 return { left: sp.left + dx, width: cs.width - dx }; 6831 }, 6832 n: function(event, dx, dy) { 6833 var cs = this.originalSize, sp = this.originalPosition; 6834 return { top: sp.top + dy, height: cs.height - dy }; 6835 }, 6836 s: function(event, dx, dy) { 6837 return { height: this.originalSize.height + dy }; 6838 }, 6839 se: function(event, dx, dy) { 6840 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 6841 }, 6842 sw: function(event, dx, dy) { 6843 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 6844 }, 6845 ne: function(event, dx, dy) { 6846 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 6847 }, 6848 nw: function(event, dx, dy) { 6849 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 6850 } 6851 }, 6852 6853 _propagate: function(n, event) { 6854 $.ui.plugin.call(this, n, [event, this.ui()]); 6855 (n !== "resize" && this._trigger(n, event, this.ui())); 6856 }, 6857 6858 plugins: {}, 6859 6860 ui: function() { 6861 return { 6862 originalElement: this.originalElement, 6863 element: this.element, 6864 helper: this.helper, 6865 position: this.position, 6866 size: this.size, 6867 originalSize: this.originalSize, 6868 originalPosition: this.originalPosition 6869 }; 6870 } 6871 6872}); 6873 6874/* 6875 * Resizable Extensions 6876 */ 6877 6878$.ui.plugin.add("resizable", "animate", { 6879 6880 stop: function( event ) { 6881 var that = $(this).data("ui-resizable"), 6882 o = that.options, 6883 pr = that._proportionallyResizeElements, 6884 ista = pr.length && (/textarea/i).test(pr[0].nodeName), 6885 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, 6886 soffsetw = ista ? 0 : that.sizeDiff.width, 6887 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 6888 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, 6889 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; 6890 6891 that.element.animate( 6892 $.extend(style, top && left ? { top: top, left: left } : {}), { 6893 duration: o.animateDuration, 6894 easing: o.animateEasing, 6895 step: function() { 6896 6897 var data = { 6898 width: parseInt(that.element.css("width"), 10), 6899 height: parseInt(that.element.css("height"), 10), 6900 top: parseInt(that.element.css("top"), 10), 6901 left: parseInt(that.element.css("left"), 10) 6902 }; 6903 6904 if (pr && pr.length) { 6905 $(pr[0]).css({ width: data.width, height: data.height }); 6906 } 6907 6908 // propagating resize, and updating values for each animation step 6909 that._updateCache(data); 6910 that._propagate("resize", event); 6911 6912 } 6913 } 6914 ); 6915 } 6916 6917}); 6918 6919$.ui.plugin.add("resizable", "containment", { 6920 6921 start: function() { 6922 var element, p, co, ch, cw, width, height, 6923 that = $(this).data("ui-resizable"), 6924 o = that.options, 6925 el = that.element, 6926 oc = o.containment, 6927 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 6928 6929 if (!ce) { 6930 return; 6931 } 6932 6933 that.containerElement = $(ce); 6934 6935 if (/document/.test(oc) || oc === document) { 6936 that.containerOffset = { left: 0, top: 0 }; 6937 that.containerPosition = { left: 0, top: 0 }; 6938 6939 that.parentData = {
6940 element: $(document), left: 0, top: 0, 6941 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 6942 }; 6943 } 6944 6945 // i'm a node, so compute top, left, right, bottom 6946 else { 6947 element = $(ce); 6948 p = []; 6949 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 6950 6951 that.containerOffset = element.offset(); 6952 that.containerPosition = element.position(); 6953 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 6954 6955 co = that.containerOffset; 6956 ch = that.containerSize.height; 6957 cw = that.containerSize.width; 6958 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); 6959 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 6960 6961 that.parentData = { 6962 element: ce, left: co.left, top: co.top, width: width, height: height 6963 }; 6964 } 6965 }, 6966 6967 resize: function( event ) { 6968 var woset, hoset, isParent, isOffsetRelative, 6969 that = $(this).data("ui-resizable"), 6970 o = that.options, 6971 co = that.containerOffset, cp = that.position, 6972 pRatio = that._aspectRatio || event.shiftKey, 6973 cop = { top:0, left:0 }, ce = that.containerElement; 6974 6975 if (ce[0] !== document && (/static/).test(ce.css("position"))) { 6976 cop = co; 6977 } 6978 6979 if (cp.left < (that._helper ? co.left : 0)) { 6980 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 6981 if (pRatio) { 6982 that.size.height = that.size.width / that.aspectRatio; 6983 } 6984 that.position.left = o.helper ? co.left : 0; 6985 } 6986 6987 if (cp.top < (that._helper ? co.top : 0)) { 6988 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 6989 if (pRatio) { 6990 that.size.width = that.size.height * that.aspectRatio; 6991 } 6992 that.position.top = that._helper ? co.top : 0; 6993 } 6994 6995 that.offset.left = that.parentData.left+that.position.left; 6996 that.offset.top = that.parentData.top+that.position.top; 6997 6998 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); 6999 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 7000 7001 isParent = that.containerElement.get(0) === that.element.parent().get(0); 7002 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); 7003 7004 if(isParent && isOffsetRelative) { 7005 woset -= that.parentData.left; 7006 } 7007 7008 if (woset + that.size.width >= that.parentData.width) { 7009 that.size.width = that.parentData.width - woset; 7010 if (pRatio) { 7011 that.size.height = that.size.width / that.aspectRatio; 7012 } 7013 } 7014 7015 if (hoset + that.size.height >= that.parentData.height) { 7016 that.size.height = that.parentData.height - hoset; 7017 if (pRatio) { 7018 that.size.width = that.size.height * that.aspectRatio; 7019 } 7020 } 7021 }, 7022 7023 stop: function(){ 7024 var that = $(this).data("ui-resizable"), 7025 o = that.options, 7026 co = that.containerOffset, 7027 cop = that.containerPosition, 7028 ce = that.containerElement, 7029 helper = $(that.helper), 7030 ho = helper.offset(), 7031 w = helper.outerWidth() - that.sizeDiff.width, 7032 h = helper.outerHeight() - that.sizeDiff.height; 7033 7034 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { 7035 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 7036 } 7037 7038 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { 7039 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 7040 } 7041 7042 } 7043}); 7044 7045$.ui.plugin.add("resizable", "alsoResize", { 7046 7047 start: function () { 7048 var that = $(this).data("ui-resizable"), 7049 o = that.options, 7050 _store = function (exp) { 7051 $(exp).each(function() { 7052 var el = $(this); 7053 el.data("ui-resizable-alsoresize", { 7054 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 7055 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) 7056 }); 7057 }); 7058 }; 7059 7060 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { 7061 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 7062 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 7063 }else{ 7064 _store(o.alsoResize); 7065 } 7066 }, 7067 7068 resize: function (event, ui) { 7069 var that = $(this).data("ui-resizable"), 7070 o = that.options, 7071 os = that.originalSize, 7072 op = that.originalPosition, 7073 delta = { 7074 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 7075 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 7076 }, 7077 7078 _alsoResize = function (exp, c) { 7079 $(exp).each(function() { 7080 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, 7081 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; 7082
vendor: 32,676 bytes, lines 7083-8236
7083 $.each(css, function (i, prop) { 7084 var sum = (start[prop]||0) + (delta[prop]||0); 7085 if (sum && sum >= 0) { 7086 style[prop] = sum || null; 7087 } 7088 }); 7089 7090 el.css(style); 7091 }); 7092 }; 7093 7094 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { 7095 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 7096 }else{ 7097 _alsoResize(o.alsoResize); 7098 } 7099 }, 7100 7101 stop: function () { 7102 $(this).removeData("resizable-alsoresize"); 7103 } 7104}); 7105 7106$.ui.plugin.add("resizable", "ghost", { 7107 7108 start: function() { 7109 7110 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; 7111 7112 that.ghost = that.originalElement.clone(); 7113 that.ghost 7114 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 7115 .addClass("ui-resizable-ghost") 7116 .addClass(typeof o.ghost === "string" ? o.ghost : ""); 7117 7118 that.ghost.appendTo(that.helper); 7119 7120 }, 7121 7122 resize: function(){ 7123 var that = $(this).data("ui-resizable"); 7124 if (that.ghost) { 7125 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); 7126 } 7127 }, 7128 7129 stop: function() { 7130 var that = $(this).data("ui-resizable"); 7131 if (that.ghost && that.helper) { 7132 that.helper.get(0).removeChild(that.ghost.get(0)); 7133 } 7134 } 7135 7136}); 7137 7138$.ui.plugin.add("resizable", "grid", { 7139 7140 resize: function() { 7141 var that = $(this).data("ui-resizable"), 7142 o = that.options, 7143 cs = that.size, 7144 os = that.originalSize, 7145 op = that.originalPosition, 7146 a = that.axis, 7147 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, 7148 gridX = (grid[0]||1), 7149 gridY = (grid[1]||1), 7150 ox = Math.round((cs.width - os.width) / gridX) * gridX, 7151 oy = Math.round((cs.height - os.height) / gridY) * gridY, 7152 newWidth = os.width + ox, 7153 newHeight = os.height + oy, 7154 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), 7155 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), 7156 isMinWidth = o.minWidth && (o.minWidth > newWidth), 7157 isMinHeight = o.minHeight && (o.minHeight > newHeight); 7158 7159 o.grid = grid; 7160 7161 if (isMinWidth) { 7162 newWidth = newWidth + gridX; 7163 } 7164 if (isMinHeight) { 7165 newHeight = newHeight + gridY; 7166 } 7167 if (isMaxWidth) { 7168 newWidth = newWidth - gridX; 7169 } 7170 if (isMaxHeight) { 7171 newHeight = newHeight - gridY; 7172 } 7173 7174 if (/^(se|s|e)$/.test(a)) { 7175 that.size.width = newWidth; 7176 that.size.height = newHeight; 7177 } else if (/^(ne)$/.test(a)) { 7178 that.size.width = newWidth; 7179 that.size.height = newHeight; 7180 that.position.top = op.top - oy; 7181 } else if (/^(sw)$/.test(a)) { 7182 that.size.width = newWidth; 7183 that.size.height = newHeight; 7184 that.position.left = op.left - ox; 7185 } else { 7186 that.size.width = newWidth; 7187 that.size.height = newHeight; 7188 that.position.top = op.top - oy; 7189 that.position.left = op.left - ox; 7190 } 7191 } 7192 7193}); 7194 7195})(jQuery); 7196(function( $, undefined ) { 7197 7198$.widget("ui.selectable", $.ui.mouse, { 7199 version: "1.10.3", 7200 options: { 7201 appendTo: "body", 7202 autoRefresh: true, 7203 distance: 0, 7204 filter: "*", 7205 tolerance: "touch", 7206 7207 // callbacks 7208 selected: null, 7209 selecting: null, 7210 start: null, 7211 stop: null, 7212 unselected: null, 7213 unselecting: null 7214 }, 7215 _create: function() { 7216 var selectees, 7217 that = this; 7218 7219 this.element.addClass("ui-selectable"); 7220 7221 this.dragged = false; 7222 7223 // cache selectee children based on filter 7224 this.refresh = function() { 7225 selectees = $(that.options.filter, that.element[0]); 7226 selectees.addClass("ui-selectee"); 7227 selectees.each(function() { 7228 var $this = $(this), 7229 pos = $this.offset(); 7230 $.data(this, "selectable-item", { 7231 element: this, 7232 $element: $this, 7233 left: pos.left, 7234 top: pos.top, 7235 right: pos.left + $this.outerWidth(), 7236 bottom: pos.top + $this.outerHeight(), 7237 startselected: false, 7238 selected: $this.hasClass("ui-selected"), 7239 selecting: $this.hasClass("ui-selecting"), 7240 unselecting: $this.hasClass("ui-unselecting") 7241 }); 7242 }); 7243 }; 7244 this.refresh(); 7245 7246 this.selectees = selectees.addClass("ui-selectee"); 7247 7248 this._mouseInit(); 7249 7250 this.helper = $("<div class='ui-selectable-helper'></div>"); 7251 }, 7252 7253 _destroy: function() { 7254 this.selectees 7255 .removeClass("ui-selectee") 7256 .removeData("selectable-item"); 7257 this.element 7258 .removeClass("ui-selectable ui-selectable-disabled"); 7259 this._mouseDestroy(); 7260 }, 7261 7262 _mouseStart: function(event) { 7263 var that = this, 7264 options = this.options; 7265 7266 this.opos = [event.pageX, event.pageY]; 7267 7268 if (this.options.disabled) { 7269 return; 7270 } 7271 7272 this.selectees = $(options.filter, this.element[0]); 7273 7274 this._trigger("start", event); 7275 7276 $(options.appendTo).append(this.helper); 7277 // position helper (lasso) 7278 this.helper.css({ 7279 "left": event.pageX, 7280 "top": event.pageY, 7281 "width": 0, 7282 "height": 0 7283 }); 7284 7285 if (options.autoRefresh) { 7286 this.refresh(); 7287 } 7288 7289 this.selectees.filter(".ui-selected").each(function() { 7290 var selectee = $.data(this, "selectable-item"); 7291 selectee.startselected = true; 7292 if (!event.metaKey && !event.ctrlKey) { 7293 selectee.$element.removeClass("ui-selected"); 7294 selectee.selected = false; 7295 selectee.$element.addClass("ui-unselecting"); 7296 selectee.unselecting = true; 7297 // selectable UNSELECTING callback 7298 that._trigger("unselecting", event, { 7299 unselecting: selectee.element 7300 }); 7301 } 7302 }); 7303 7304 $(event.target).parents().addBack().each(function() { 7305 var doSelect, 7306 selectee = $.data(this, "selectable-item"); 7307 if (selectee) { 7308 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); 7309 selectee.$element 7310 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 7311 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 7312 selectee.unselecting = !doSelect; 7313 selectee.selecting = doSelect; 7314 selectee.selected = doSelect; 7315 // selectable (UN)SELECTING callback 7316 if (doSelect) { 7317 that._trigger("selecting", event, { 7318 selecting: selectee.element 7319 }); 7320 } else { 7321 that._trigger("unselecting", event, { 7322 unselecting: selectee.element 7323 }); 7324 } 7325 return false; 7326 } 7327 }); 7328 7329 }, 7330 7331 _mouseDrag: function(event) { 7332 7333 this.dragged = true; 7334 7335 if (this.options.disabled) { 7336 return; 7337 } 7338 7339 var tmp, 7340 that = this, 7341 options = this.options, 7342 x1 = this.opos[0], 7343 y1 = this.opos[1], 7344 x2 = event.pageX, 7345 y2 = event.pageY; 7346 7347 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 7348 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 7349 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 7350 7351 this.selectees.each(function() { 7352 var selectee = $.data(this, "selectable-item"), 7353 hit = false; 7354 7355 //prevent helper from being selected if appendTo: selectable 7356 if (!selectee || selectee.element === that.element[0]) { 7357 return; 7358 } 7359 7360 if (options.tolerance === "touch") { 7361 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 7362 } else if (options.tolerance === "fit") { 7363 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 7364 } 7365 7366 if (hit) { 7367 // SELECT 7368 if (selectee.selected) { 7369 selectee.$element.removeClass("ui-selected"); 7370 selectee.selected = false; 7371 } 7372 if (selectee.unselecting) { 7373 selectee.$element.removeClass("ui-unselecting"); 7374 selectee.unselecting = false; 7375 } 7376 if (!selectee.selecting) { 7377 selectee.$element.addClass("ui-selecting"); 7378 selectee.selecting = true; 7379 // selectable SELECTING callback 7380 that._trigger("selecting", event, { 7381 selecting: selectee.element 7382 }); 7383 } 7384 } else { 7385 // UNSELECT 7386 if (selectee.selecting) { 7387 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 7388 selectee.$element.removeClass("ui-selecting"); 7389 selectee.selecting = false; 7390 selectee.$element.addClass("ui-selected"); 7391 selectee.selected = true; 7392 } else { 7393 selectee.$element.removeClass("ui-selecting"); 7394 selectee.selecting = false; 7395 if (selectee.startselected) { 7396 selectee.$element.addClass("ui-unselecting"); 7397 selectee.unselecting = true; 7398 } 7399 // selectable UNSELECTING callback 7400 that._trigger("unselecting", event, { 7401 unselecting: selectee.element 7402 }); 7403 } 7404 } 7405 if (selectee.selected) { 7406 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 7407 selectee.$element.removeClass("ui-selected"); 7408 selectee.selected = false; 7409 7410 selectee.$element.addClass("ui-unselecting"); 7411 selectee.unselecting = true; 7412 // selectable UNSELECTING callback 7413 that._trigger("unselecting", event, { 7414 unselecting: selectee.element 7415 }); 7416 } 7417 } 7418 } 7419 }); 7420 7421 return false; 7422 }, 7423 7424 _mouseStop: function(event) { 7425 var that = this; 7426 7427 this.dragged = false; 7428 7429 $(".ui-unselecting", this.element[0]).each(function() { 7430 var selectee = $.data(this, "selectable-item"); 7431 selectee.$element.removeClass("ui-unselecting"); 7432 selectee.unselecting = false; 7433 selectee.startselected = false; 7434 that._trigger("unselected", event, { 7435 unselected: selectee.element 7436 }); 7437 }); 7438 $(".ui-selecting", this.element[0]).each(function() { 7439 var selectee = $.data(this, "selectable-item"); 7440 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); 7441 selectee.selecting = false; 7442 selectee.selected = true; 7443 selectee.startselected = true; 7444 that._trigger("selected", event, { 7445 selected: selectee.element 7446 }); 7447 }); 7448 this._trigger("stop", event); 7449 7450 this.helper.remove(); 7451 7452 return false; 7453 } 7454 7455}); 7456 7457})(jQuery); 7458(function( $, undefined ) { 7459 7460/*jshint loopfunc: true */ 7461 7462function isOverAxis( x, reference, size ) { 7463 return ( x > reference ) && ( x < ( reference + size ) ); 7464} 7465 7466function isFloating(item) { 7467 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); 7468} 7469 7470$.widget("ui.sortable", $.ui.mouse, { 7471 version: "1.10.3", 7472 widgetEventPrefix: "sort", 7473 ready: false, 7474 options: { 7475 appendTo: "parent", 7476 axis: false, 7477 connectWith: false, 7478 containment: false, 7479 cursor: "auto", 7480 cursorAt: false, 7481 dropOnEmpty: true, 7482 forcePlaceholderSize: false, 7483 forceHelperSize: false, 7484 grid: false, 7485 handle: false, 7486 helper: "original", 7487 items: "> *", 7488 opacity: false, 7489 placeholder: false, 7490 revert: false, 7491 scroll: true, 7492 scrollSensitivity: 20, 7493 scrollSpeed: 20, 7494 scope: "default", 7495 tolerance: "intersect", 7496 zIndex: 1000, 7497 7498 // callbacks 7499 activate: null, 7500 beforeStop: null, 7501 change: null, 7502 deactivate: null, 7503 out: null, 7504 over: null, 7505 receive: null, 7506 remove: null, 7507 sort: null, 7508 start: null, 7509 stop: null, 7510 update: null 7511 }, 7512 _create: function() { 7513 7514 var o = this.options; 7515 this.containerCache = {}; 7516 this.element.addClass("ui-sortable"); 7517 7518 //Get the items 7519 this.refresh(); 7520 7521 //Let's determine if the items are being displayed horizontally 7522 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; 7523 7524 //Let's determine the parent's offset 7525 this.offset = this.element.offset(); 7526 7527 //Initialize mouse events for interaction 7528 this._mouseInit(); 7529 7530 //We're ready to go 7531 this.ready = true; 7532 7533 }, 7534 7535 _destroy: function() { 7536 this.element 7537 .removeClass("ui-sortable ui-sortable-disabled"); 7538 this._mouseDestroy(); 7539 7540 for ( var i = this.items.length - 1; i >= 0; i-- ) { 7541 this.items[i].item.removeData(this.widgetName + "-item"); 7542 } 7543 7544 return this; 7545 }, 7546 7547 _setOption: function(key, value){ 7548 if ( key === "disabled" ) { 7549 this.options[ key ] = value; 7550 7551 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 7552 } else { 7553 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 7554 $.Widget.prototype._setOption.apply(this, arguments); 7555 } 7556 }, 7557 7558 _mouseCapture: function(event, overrideHandle) { 7559 var currentItem = null, 7560 validHandle = false, 7561 that = this; 7562 7563 if (this.reverting) { 7564 return false; 7565 } 7566 7567 if(this.options.disabled || this.options.type === "static") { 7568 return false; 7569 } 7570 7571 //We have to refresh the items data once first 7572 this._refreshItems(event); 7573 7574 //Find out if the clicked node (or one of its parents) is a actual item in this.items 7575 $(event.target).parents().each(function() { 7576 if($.data(this, that.widgetName + "-item") === that) { 7577 currentItem = $(this); 7578 return false; 7579 } 7580 }); 7581 if($.data(event.target, that.widgetName + "-item") === that) { 7582 currentItem = $(event.target); 7583 } 7584 7585 if(!currentItem) { 7586 return false; 7587 } 7588 if(this.options.handle && !overrideHandle) { 7589 $(this.options.handle, currentItem).find("*").addBack().each(function() { 7590 if(this === event.target) { 7591 validHandle = true; 7592 } 7593 }); 7594 if(!validHandle) { 7595 return false; 7596 } 7597 } 7598 7599 this.currentItem = currentItem; 7600 this._removeCurrentsFromItems(); 7601 return true; 7602 7603 }, 7604 7605 _mouseStart: function(event, overrideHandle, noActivation) { 7606 7607 var i, body, 7608 o = this.options; 7609 7610 this.currentContainer = this; 7611 7612 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 7613 this.refreshPositions(); 7614 7615 //Create and append the visible helper 7616 this.helper = this._createHelper(event); 7617 7618 //Cache the helper size 7619 this._cacheHelperProportions(); 7620 7621 /* 7622 * - Position generation - 7623 * This block generates everything position related - it's the core of draggables. 7624 */ 7625 7626 //Cache the margins of the original element 7627 this._cacheMargins(); 7628 7629 //Get the next scrolling parent 7630 this.scrollParent = this.helper.scrollParent(); 7631 7632 //The element's absolute position on the page minus margins 7633 this.offset = this.currentItem.offset(); 7634 this.offset = { 7635 top: this.offset.top - this.margins.top, 7636 left: this.offset.left - this.margins.left 7637 }; 7638 7639 $.extend(this.offset, { 7640 click: { //Where the click happened, relative to the element 7641 left: event.pageX - this.offset.left, 7642 top: event.pageY - this.offset.top 7643 }, 7644 parent: this._getParentOffset(), 7645 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 7646 }); 7647 7648 // Only after we got the offset, we can change the helper's position to absolute 7649 // TODO: Still need to figure out a way to make relative sorting possible 7650 this.helper.css("position", "absolute"); 7651 this.cssPosition = this.helper.css("position"); 7652 7653 //Generate the original position 7654 this.originalPosition = this._generatePosition(event); 7655 this.originalPageX = event.pageX; 7656 this.originalPageY = event.pageY; 7657 7658 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 7659 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 7660 7661 //Cache the former DOM position 7662 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 7663 7664 //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 7665 if(this.helper[0] !== this.currentItem[0]) { 7666 this.currentItem.hide(); 7667 } 7668 7669 //Create the placeholder 7670 this._createPlaceholder(); 7671 7672 //Set a containment if given in the options 7673 if(o.containment) { 7674 this._setContainment(); 7675 } 7676 7677 if( o.cursor && o.cursor !== "auto" ) { // cursor option 7678 body = this.document.find( "body" ); 7679 7680 // support: IE 7681 this.storedCursor = body.css( "cursor" ); 7682 body.css( "cursor", o.cursor ); 7683 7684 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); 7685 } 7686 7687 if(o.opacity) { // opacity option 7688 if (this.helper.css("opacity")) { 7689 this._storedOpacity = this.helper.css("opacity"); 7690 } 7691 this.helper.css("opacity", o.opacity); 7692 } 7693 7694 if(o.zIndex) { // zIndex option 7695 if (this.helper.css("zIndex")) { 7696 this._storedZIndex = this.helper.css("zIndex"); 7697 } 7698 this.helper.css("zIndex", o.zIndex); 7699 } 7700 7701 //Prepare scrolling 7702 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 7703 this.overflowOffset = this.scrollParent.offset(); 7704 } 7705 7706 //Call callbacks 7707 this._trigger("start", event, this._uiHash()); 7708 7709 //Recache the helper size 7710 if(!this._preserveHelperProportions) { 7711 this._cacheHelperProportions(); 7712 } 7713 7714 7715 //Post "activate" events to possible containers 7716 if( !noActivation ) { 7717 for ( i = this.containers.length - 1; i >= 0; i-- ) { 7718 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 7719 } 7720 } 7721 7722 //Prepare possible droppables 7723 if($.ui.ddmanager) { 7724 $.ui.ddmanager.current = this; 7725 } 7726 7727 if ($.ui.ddmanager && !o.dropBehaviour) { 7728 $.ui.ddmanager.prepareOffsets(this, event); 7729 } 7730 7731 this.dragging = true; 7732 7733 this.helper.addClass("ui-sortable-helper"); 7734 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 7735 return true; 7736 7737 }, 7738 7739 _mouseDrag: function(event) { 7740 var i, item, itemElement, intersection, 7741 o = this.options, 7742 scrolled = false; 7743 7744 //Compute the helpers position 7745 this.position = this._generatePosition(event); 7746 this.positionAbs = this._convertPositionTo("absolute"); 7747 7748 if (!this.lastPositionAbs) { 7749 this.lastPositionAbs = this.positionAbs; 7750 } 7751 7752 //Do scrolling 7753 if(this.options.scroll) { 7754 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { 7755 7756 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { 7757 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 7758 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 7759 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 7760 } 7761 7762 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { 7763 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 7764 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 7765 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 7766 } 7767 7768 } else { 7769 7770 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { 7771 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 7772 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { 7773 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 7774 } 7775 7776 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { 7777 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 7778 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { 7779 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 7780 } 7781 7782 } 7783 7784 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 7785 $.ui.ddmanager.prepareOffsets(this, event); 7786 } 7787 } 7788 7789 //Regenerate the absolute position used for position checks 7790 this.positionAbs = this._convertPositionTo("absolute"); 7791 7792 //Set the helper position 7793 if(!this.options.axis || this.options.axis !== "y") { 7794 this.helper[0].style.left = this.position.left+"px"; 7795 } 7796 if(!this.options.axis || this.options.axis !== "x") { 7797 this.helper[0].style.top = this.position.top+"px"; 7798 } 7799 7800 //Rearrange 7801 for (i = this.items.length - 1; i >= 0; i--) { 7802 7803 //Cache variables and intersection, continue if no intersection 7804 item = this.items[i]; 7805 itemElement = item.item[0]; 7806 intersection = this._intersectsWithPointer(item); 7807 if (!intersection) { 7808 continue; 7809 } 7810 7811 // Only put the placeholder inside the current Container, skip all 7812 // items form other containers. This works because when moving 7813 // an item from one container to another the 7814 // currentContainer is switched before the placeholder is moved. 7815 // 7816 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 7817 // beetween the outer and inner container. 7818 if (item.instance !== this.currentContainer) { 7819 continue; 7820 } 7821 7822 // cannot intersect with itself 7823 // no useless actions that have been done before 7824 // no action if the item moved is the parent of the item checked 7825 if (itemElement !== this.currentItem[0] && 7826 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && 7827 !$.contains(this.placeholder[0], itemElement) && 7828 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) 7829 ) { 7830 7831 this.direction = intersection === 1 ? "down" : "up"; 7832 7833 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { 7834 this._rearrange(event, item); 7835 } else { 7836 break; 7837 } 7838 7839 this._trigger("change", event, this._uiHash()); 7840 break; 7841 } 7842 } 7843 7844 //Post events to containers 7845 this._contactContainers(event); 7846 7847 //Interconnect with droppables 7848 if($.ui.ddmanager) { 7849 $.ui.ddmanager.drag(this, event); 7850 } 7851 7852 //Call callbacks 7853 this._trigger("sort", event, this._uiHash()); 7854 7855 this.lastPositionAbs = this.positionAbs; 7856 return false; 7857 7858 }, 7859 7860 _mouseStop: function(event, noPropagation) { 7861 7862 if(!event) { 7863 return; 7864 } 7865 7866 //If we are using droppables, inform the manager about the drop 7867 if ($.ui.ddmanager && !this.options.dropBehaviour) { 7868 $.ui.ddmanager.drop(this, event); 7869 } 7870 7871 if(this.options.revert) { 7872 var that = this, 7873 cur = this.placeholder.offset(), 7874 axis = this.options.axis, 7875 animation = {}; 7876 7877 if ( !axis || axis === "x" ) { 7878 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); 7879 } 7880 if ( !axis || axis === "y" ) { 7881 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); 7882 } 7883 this.reverting = true; 7884 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { 7885 that._clear(event); 7886 }); 7887 } else { 7888 this._clear(event, noPropagation); 7889 } 7890 7891 return false; 7892 7893 }, 7894 7895 cancel: function() { 7896 7897 if(this.dragging) { 7898 7899 this._mouseUp({ target: null }); 7900 7901 if(this.options.helper === "original") { 7902 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 7903 } else { 7904 this.currentItem.show(); 7905 } 7906 7907 //Post deactivating events to containers 7908 for (var i = this.containers.length - 1; i >= 0; i--){ 7909 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 7910 if(this.containers[i].containerCache.over) { 7911 this.containers[i]._trigger("out", null, this._uiHash(this)); 7912 this.containers[i].containerCache.over = 0; 7913 } 7914 } 7915 7916 } 7917 7918 if (this.placeholder) { 7919 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 7920 if(this.placeholder[0].parentNode) { 7921 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 7922 } 7923 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { 7924 this.helper.remove(); 7925 } 7926 7927 $.extend(this, { 7928 helper: null, 7929 dragging: false, 7930 reverting: false, 7931 _noFinalSort: null 7932 }); 7933 7934 if(this.domPosition.prev) { 7935 $(this.domPosition.prev).after(this.currentItem); 7936 } else { 7937 $(this.domPosition.parent).prepend(this.currentItem); 7938 } 7939 } 7940 7941 return this; 7942 7943 }, 7944 7945 serialize: function(o) { 7946 7947 var items = this._getItemsAsjQuery(o && o.connected), 7948 str = []; 7949 o = o || {}; 7950 7951 $(items).each(function() { 7952 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); 7953 if (res) { 7954 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); 7955 } 7956 }); 7957 7958 if(!str.length && o.key) { 7959 str.push(o.key + "="); 7960 } 7961 7962 return str.join("&"); 7963 7964 }, 7965 7966 toArray: function(o) { 7967 7968 var items = this._getItemsAsjQuery(o && o.connected), 7969 ret = []; 7970 7971 o = o || {}; 7972 7973 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); 7974 return ret; 7975 7976 }, 7977 7978 /* Be careful with the following core functions */ 7979 _intersectsWith: function(item) { 7980 7981 var x1 = this.positionAbs.left, 7982 x2 = x1 + this.helperProportions.width, 7983 y1 = this.positionAbs.top, 7984 y2 = y1 + this.helperProportions.height, 7985 l = item.left, 7986 r = l + item.width, 7987 t = item.top, 7988 b = t + item.height, 7989 dyClick = this.offset.click.top, 7990 dxClick = this.offset.click.left, 7991 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), 7992 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), 7993 isOverElement = isOverElementHeight && isOverElementWidth; 7994 7995 if ( this.options.tolerance === "pointer" || 7996 this.options.forcePointerForContainers || 7997 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) 7998 ) { 7999 return isOverElement; 8000 } else { 8001 8002 return (l < x1 + (this.helperProportions.width / 2) && // Right Half 8003 x2 - (this.helperProportions.width / 2) < r && // Left Half 8004 t < y1 + (this.helperProportions.height / 2) && // Bottom Half 8005 y2 - (this.helperProportions.height / 2) < b ); // Top Half 8006 8007 } 8008 }, 8009 8010 _intersectsWithPointer: function(item) { 8011 8012 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 8013 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 8014 isOverElement = isOverElementHeight && isOverElementWidth, 8015 verticalDirection = this._getDragVerticalDirection(), 8016 horizontalDirection = this._getDragHorizontalDirection(); 8017 8018 if (!isOverElement) { 8019 return false; 8020 } 8021 8022 return this.floating ? 8023 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) 8024 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); 8025 8026 }, 8027 8028 _intersectsWithSides: function(item) { 8029 8030 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 8031 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 8032 verticalDirection = this._getDragVerticalDirection(), 8033 horizontalDirection = this._getDragHorizontalDirection(); 8034 8035 if (this.floating && horizontalDirection) { 8036 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); 8037 } else { 8038 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); 8039 } 8040 8041 }, 8042 8043 _getDragVerticalDirection: function() { 8044 var delta = this.positionAbs.top - this.lastPositionAbs.top; 8045 return delta !== 0 && (delta > 0 ? "down" : "up"); 8046 }, 8047 8048 _getDragHorizontalDirection: function() { 8049 var delta = this.positionAbs.left - this.lastPositionAbs.left; 8050 return delta !== 0 && (delta > 0 ? "right" : "left"); 8051 }, 8052 8053 refresh: function(event) { 8054 this._refreshItems(event); 8055 this.refreshPositions(); 8056 return this; 8057 }, 8058 8059 _connectWith: function() { 8060 var options = this.options; 8061 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; 8062 }, 8063 8064 _getItemsAsjQuery: function(connected) { 8065 8066 var i, j, cur, inst, 8067 items = [], 8068 queries = [], 8069 connectWith = this._connectWith(); 8070 8071 if(connectWith && connected) { 8072 for (i = connectWith.length - 1; i >= 0; i--){ 8073 cur = $(connectWith[i]); 8074 for ( j = cur.length - 1; j >= 0; j--){ 8075 inst = $.data(cur[j], this.widgetFullName); 8076 if(inst && inst !== this && !inst.options.disabled) { 8077 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]); 8078 } 8079 } 8080 } 8081 } 8082 8083 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]); 8084 8085 for (i = queries.length - 1; i >= 0; i--){ 8086 queries[i][0].each(function() { 8087 items.push(this); 8088 }); 8089 } 8090 8091 return $(items); 8092 8093 }, 8094 8095 _removeCurrentsFromItems: function() { 8096 8097 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 8098 8099 this.items = $.grep(this.items, function (item) { 8100 for (var j=0; j < list.length; j++) { 8101 if(list[j] === item.item[0]) { 8102 return false; 8103 } 8104 } 8105 return true; 8106 }); 8107 8108 }, 8109 8110 _refreshItems: function(event) { 8111 8112 this.items = []; 8113 this.containers = [this]; 8114 8115 var i, j, cur, inst, targetData, _queries, item, queriesLength, 8116 items = this.items, 8117 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], 8118 connectWith = this._connectWith(); 8119 8120 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 8121 for (i = connectWith.length - 1; i >= 0; i--){ 8122 cur = $(connectWith[i]); 8123 for (j = cur.length - 1; j >= 0; j--){ 8124 inst = $.data(cur[j], this.widgetFullName); 8125 if(inst && inst !== this && !inst.options.disabled) { 8126 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 8127 this.containers.push(inst); 8128 } 8129 } 8130 } 8131 } 8132 8133 for (i = queries.length - 1; i >= 0; i--) { 8134 targetData = queries[i][1]; 8135 _queries = queries[i][0]; 8136 8137 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { 8138 item = $(_queries[j]); 8139 8140 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) 8141 8142 items.push({ 8143 item: item, 8144 instance: targetData, 8145 width: 0, height: 0, 8146 left: 0, top: 0 8147 }); 8148 } 8149 } 8150 8151 }, 8152 8153 refreshPositions: function(fast) { 8154 8155 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 8156 if(this.offsetParent && this.helper) { 8157 this.offset.parent = this._getParentOffset(); 8158 } 8159 8160 var i, item, t, p; 8161 8162 for (i = this.items.length - 1; i >= 0; i--){ 8163 item = this.items[i]; 8164 8165 //We ignore calculating positions of all connected containers when we're not over them 8166 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { 8167 continue; 8168 } 8169 8170 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 8171 8172 if (!fast) { 8173 item.width = t.outerWidth(); 8174 item.height = t.outerHeight(); 8175 } 8176 8177 p = t.offset(); 8178 item.left = p.left; 8179 item.top = p.top; 8180 } 8181 8182 if(this.options.custom && this.options.custom.refreshContainers) { 8183 this.options.custom.refreshContainers.call(this); 8184 } else { 8185 for (i = this.containers.length - 1; i >= 0; i--){ 8186 p = this.containers[i].element.offset(); 8187 this.containers[i].containerCache.left = p.left; 8188 this.containers[i].containerCache.top = p.top; 8189 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 8190 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 8191 } 8192 } 8193 8194 return this; 8195 }, 8196 8197 _createPlaceholder: function(that) { 8198 that = that || this; 8199 var className, 8200 o = that.options; 8201 8202 if(!o.placeholder || o.placeholder.constructor === String) { 8203 className = o.placeholder; 8204 o.placeholder = { 8205 element: function() { 8206 8207 var nodeName = that.currentItem[0].nodeName.toLowerCase(), 8208 element = $( "<" + nodeName + ">", that.document[0] ) 8209 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 8210 .removeClass("ui-sortable-helper"); 8211 8212 if ( nodeName === "tr" ) { 8213 that.currentItem.children().each(function() { 8214 $( "<td> </td>", that.document[0] ) 8215 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 8216 .appendTo( element ); 8217 }); 8218 } else if ( nodeName === "img" ) { 8219 element.attr( "src", that.currentItem.attr( "src" ) ); 8220 } 8221 8222 if ( !className ) { 8223 element.css( "visibility", "hidden" ); 8224 } 8225 8226 return element; 8227 }, 8228 update: function(container, p) { 8229 8230 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 8231 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 8232 if(className && !o.forcePlaceholderSize) { 8233 return; 8234 } 8235 8236 //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
8237 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } 8238 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } 8239 } 8240 }; 8241 } 8242 8243 //Create the placeholder 8244 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 8245 8246 //Append it after the actual current item 8247 that.currentItem.after(that.placeholder); 8248 8249 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 8250 o.placeholder.update(that, that.placeholder); 8251 8252 }, 8253 8254 _contactContainers: function(event) { 8255 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, 8256 innermostContainer = null, 8257 innermostIndex = null; 8258 8259 // get innermost container that intersects with item 8260 for (i = this.containers.length - 1; i >= 0; i--) { 8261 8262 // never consider a container that's located within the item itself 8263 if($.contains(this.currentItem[0], this.containers[i].element[0])) { 8264 continue; 8265 } 8266 8267 if(this._intersectsWith(this.containers[i].containerCache)) { 8268 8269 // if we've already found a container and it's more "inner" than this, then continue 8270 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { 8271 continue; 8272 } 8273 8274 innermostContainer = this.containers[i]; 8275 innermostIndex = i; 8276 8277 } else { 8278 // container doesn't intersect. trigger "out" event if necessary 8279 if(this.containers[i].containerCache.over) { 8280 this.containers[i]._trigger("out", event, this._uiHash(this)); 8281 this.containers[i].containerCache.over = 0; 8282 } 8283 } 8284 8285 } 8286 8287 // if no intersecting containers found, return 8288 if(!innermostContainer) { 8289 return; 8290 } 8291 8292 // move the item into the container if it's not there already 8293 if(this.containers.length === 1) { 8294 if (!this.containers[innermostIndex].containerCache.over) { 8295 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 8296 this.containers[innermostIndex].containerCache.over = 1; 8297 } 8298 } else { 8299 8300 //When entering a new container, we will find the item with the least distance and append our item near it 8301 dist = 10000; 8302 itemWithLeastDistance = null; 8303 floating = innermostContainer.floating || isFloating(this.currentItem); 8304 posProperty = floating ? "left" : "top"; 8305 sizeProperty = floating ? "width" : "height"; 8306 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 8307 for (j = this.items.length - 1; j >= 0; j--) { 8308 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { 8309 continue; 8310 } 8311 if(this.items[j].item[0] === this.currentItem[0]) { 8312 continue; 8313 } 8314 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { 8315 continue; 8316 } 8317 cur = this.items[j].item.offset()[posProperty]; 8318 nearBottom = false; 8319 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 8320 nearBottom = true; 8321 cur += this.items[j][sizeProperty]; 8322 } 8323 8324 if(Math.abs(cur - base) < dist) { 8325 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j
vendor: 13,544 bytes, lines 8325-8646
8325]; 8326 this.direction = nearBottom ? "up": "down"; 8327 } 8328 } 8329 8330 //Check if dropOnEmpty is enabled 8331 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { 8332 return; 8333 } 8334 8335 if(this.currentContainer === this.containers[innermostIndex]) { 8336 return; 8337 } 8338 8339 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 8340 this._trigger("change", event, this._uiHash()); 8341 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 8342 this.currentContainer = this.containers[innermostIndex]; 8343 8344 //Update the placeholder 8345 this.options.placeholder.update(this.currentContainer, this.placeholder); 8346 8347 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 8348 this.containers[innermostIndex].containerCache.over = 1; 8349 } 8350 8351 8352 }, 8353 8354 _createHelper: function(event) { 8355 8356 var o = this.options, 8357 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); 8358 8359 //Add the helper to the DOM if that didn't happen already 8360 if(!helper.parents("body").length) { 8361 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 8362 } 8363 8364 if(helper[0] === this.currentItem[0]) { 8365 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") }; 8366 } 8367 8368 if(!helper[0].style.width || o.forceHelperSize) { 8369 helper.width(this.currentItem.width()); 8370 } 8371 if(!helper[0].style.height || o.forceHelperSize) { 8372 helper.height(this.currentItem.height()); 8373 } 8374 8375 return helper; 8376 8377 }, 8378 8379 _adjustOffsetFromHelper: function(obj) { 8380 if (typeof obj === "string") { 8381 obj = obj.split(" "); 8382 } 8383 if ($.isArray(obj)) { 8384 obj = {left: +obj[0], top: +obj[1] || 0}; 8385 } 8386 if ("left" in obj) { 8387 this.offset.click.left = obj.left + this.margins.left; 8388 } 8389 if ("right" in obj) { 8390 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 8391 } 8392 if ("top" in obj) { 8393 this.offset.click.top = obj.top + this.margins.top; 8394 } 8395 if ("bottom" in obj) { 8396 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 8397 } 8398 }, 8399 8400 _getParentOffset: function() { 8401 8402 8403 //Get the offsetParent and cache its position 8404 this.offsetParent = this.helper.offsetParent(); 8405 var po = this.offsetParent.offset(); 8406 8407 // This is a special case where we need to modify a offset calculated on start, since the following happened: 8408 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 8409 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 8410 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 8411 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 8412 po.left += this.scrollParent.scrollLeft(); 8413 po.top += this.scrollParent.scrollTop(); 8414 } 8415 8416 // This needs to be actually done for all browsers, since pageX/pageY includes this information 8417 // with an ugly IE fix 8418 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { 8419 po = { top: 0, left: 0 }; 8420 } 8421 8422 return { 8423 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 8424 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 8425 }; 8426 8427 }, 8428 8429 _getRelativeOffset: function() { 8430 8431 if(this.cssPosition === "relative") { 8432 var p = this.currentItem.position(); 8433 return { 8434 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 8435 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 8436 }; 8437 } else { 8438 return { top: 0, left: 0 }; 8439 } 8440 8441 }, 8442 8443 _cacheMargins: function() { 8444 this.margins = { 8445 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 8446 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 8447 }; 8448 }, 8449 8450 _cacheHelperProportions: function() { 8451 this.helperProportions = { 8452 width: this.helper.outerWidth(), 8453 height: this.helper.outerHeight() 8454 }; 8455 }, 8456 8457 _setContainment: function() { 8458 8459 var ce, co, over, 8460 o = this.options; 8461 if(o.containment === "parent") { 8462 o.containment = this.helper[0].parentNode; 8463 } 8464 if(o.containment === "document" || o.containment === "window") { 8465 this.containment = [ 8466 0 - this.offset.relative.left - this.offset.parent.left, 8467 0 - this.offset.relative.top - this.offset.parent.top, 8468 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, 8469 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 8470 ]; 8471 } 8472 8473 if(!(/^(document|window|parent)$/).test(o.containment)) { 8474 ce = $(o.containment)[0]; 8475 co = $(o.containment).offset(); 8476 over = ($(ce).css("overflow") !== "hidden"); 8477 8478 this.containment = [ 8479 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 8480 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 8481 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, 8482 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 8483 ]; 8484 } 8485 8486 }, 8487 8488 _convertPositionTo: function(d, pos) { 8489 8490 if(!pos) { 8491 pos = this.position; 8492 } 8493 var mod = d === "absolute" ? 1 : -1, 8494 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, 8495 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); 8496 8497 return { 8498 top: ( 8499 pos.top + // The absolute mouse position 8500 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 8501 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) 8502 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 8503 ), 8504 left: ( 8505 pos.left + // The absolute mouse position 8506 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent 8507 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) 8508 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 8509 ) 8510 }; 8511 8512 }, 8513 8514 _generatePosition: function(event) { 8515 8516 var top, left, 8517 o = this.options, 8518 pageX = event.pageX, 8519 pageY = event.pageY, 8520 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); 8521 8522 // This is another very weird special case that only happens for relative elements: 8523 // 1. If the css position is relative 8524 // 2. and the scroll parent is the document or similar to the offset parent 8525 // we have to refresh the relative offset during the scroll so there are no jumps 8526 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { 8527 this.offset.relative = this._getRelativeOffset(); 8528 } 8529 8530 /* 8531 * - Position constraining - 8532 * Constrain the position to a mix of grid, containment. 8533 */ 8534 8535 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 8536 8537 if(this.containment) { 8538 if(event.pageX - this.offset.click.left < this.containment[0]) { 8539 pageX = this.containment[0] + this.offset.click.left; 8540 } 8541 if(event.pageY - this.offset.click.top < this.containment[1]) { 8542 pageY = this.containment[1] + this.offset.click.top; 8543 } 8544 if(event.pageX - this.offset.click.left > this.containment[2]) { 8545 pageX = this.containment[2] + this.offset.click.left; 8546 } 8547 if(event.pageY - this.offset.click.top > this.containment[3]) { 8548 pageY = this.containment[3] + this.offset.click.top; 8549 } 8550 } 8551 8552 if(o.grid) { 8553 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 8554 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; 8555 8556 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 8557 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; 8558 } 8559 8560 } 8561 8562 return { 8563 top: ( 8564 pageY - // The absolute mouse position 8565 this.offset.click.top - // Click offset (relative to the element) 8566 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent 8567 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) 8568 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 8569 ), 8570 left: ( 8571 pageX - // The absolute mouse position 8572 this.offset.click.left - // Click offset (relative to the element) 8573 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent 8574 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) 8575 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 8576 ) 8577 }; 8578 8579 }, 8580 8581 _rearrange: function(event, i, a, hardRefresh) { 8582 8583 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)); 8584 8585 //Various things done here to improve the performance: 8586 // 1. we create a setTimeout, that calls refreshPositions 8587 // 2. on the instance, we have a counter variable, that get's higher after every append 8588 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 8589 // 4. this lets only the last addition to the timeout stack through 8590 this.counter = this.counter ? ++this.counter : 1; 8591 var counter = this.counter; 8592 8593 this._delay(function() { 8594 if(counter === this.counter) { 8595 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 8596 } 8597 }); 8598 8599 }, 8600 8601 _clear: function(event, noPropagation) { 8602 8603 this.reverting = false; 8604 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 8605 // everything else normalized again 8606 var i, 8607 delayedTriggers = []; 8608 8609 // We first have to update the dom position of the actual currentItem 8610 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 8611 if(!this._noFinalSort && this.currentItem.parent().length) { 8612 this.placeholder.before(this.currentItem); 8613 } 8614 this._noFinalSort = null; 8615 8616 if(this.helper[0] === this.currentItem[0]) { 8617 for(i in this._storedCSS) { 8618 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { 8619 this._storedCSS[i] = ""; 8620 } 8621 } 8622 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 8623 } else { 8624 this.currentItem.show(); 8625 } 8626 8627 if(this.fromOutside && !noPropagation) { 8628 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 8629 } 8630 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { 8631 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 8632 } 8633 8634 // Check if the items Container has Changed and trigger appropriate 8635 // events. 8636 if (this !== this.currentContainer) { 8637 if(!noPropagation) { 8638 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 8639 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 8640 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 8641 } 8642 } 8643 8644 8645 //Post events to containers 8646 f
vendor: 40,230 bytes, lines 8646-10133
8646or (i = this.containers.length - 1; i >= 0; i--){ 8647 if(!noPropagation) { 8648 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 8649 } 8650 if(this.containers[i].containerCache.over) { 8651 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 8652 this.containers[i].containerCache.over = 0; 8653 } 8654 } 8655 8656 //Do what was originally in plugins 8657 if ( this.storedCursor ) { 8658 this.document.find( "body" ).css( "cursor", this.storedCursor ); 8659 this.storedStylesheet.remove(); 8660 } 8661 if(this._storedOpacity) { 8662 this.helper.css("opacity", this._storedOpacity); 8663 } 8664 if(this._storedZIndex) { 8665 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); 8666 } 8667 8668 this.dragging = false; 8669 if(this.cancelHelperRemoval) { 8670 if(!noPropagation) { 8671 this._trigger("beforeStop", event, this._uiHash()); 8672 for (i=0; i < delayedTriggers.length; i++) { 8673 delayedTriggers[i].call(this, event); 8674 } //Trigger all delayed events 8675 this._trigger("stop", event, this._uiHash()); 8676 } 8677 8678 this.fromOutside = false; 8679 return false; 8680 } 8681 8682 if(!noPropagation) { 8683 this._trigger("beforeStop", event, this._uiHash()); 8684 } 8685 8686 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 8687 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 8688 8689 if(this.helper[0] !== this.currentItem[0]) { 8690 this.helper.remove(); 8691 } 8692 this.helper = null; 8693 8694 if(!noPropagation) { 8695 for (i=0; i < delayedTriggers.length; i++) { 8696 delayedTriggers[i].call(this, event); 8697 } //Trigger all delayed events 8698 this._trigger("stop", event, this._uiHash()); 8699 } 8700 8701 this.fromOutside = false; 8702 return true; 8703 8704 }, 8705 8706 _trigger: function() { 8707 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 8708 this.cancel(); 8709 } 8710 }, 8711 8712 _uiHash: function(_inst) { 8713 var inst = _inst || this; 8714 return { 8715 helper: inst.helper, 8716 placeholder: inst.placeholder || $([]), 8717 position: inst.position, 8718 originalPosition: inst.originalPosition, 8719 offset: inst.positionAbs, 8720 item: inst.currentItem, 8721 sender: _inst ? _inst.element : null 8722 }; 8723 } 8724 8725}); 8726 8727})(jQuery); 8728(function( $, undefined ) { 8729 8730var uid = 0, 8731 hideProps = {}, 8732 showProps = {}; 8733 8734hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 8735 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 8736showProps.height = showProps.paddingTop = showProps.paddingBottom = 8737 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 8738 8739$.widget( "ui.accordion", { 8740 version: "1.10.3", 8741 options: { 8742 active: 0, 8743 animate: {}, 8744 collapsible: false, 8745 event: "click", 8746 header: "> li > :first-child,> :not(li):even", 8747 heightStyle: "auto", 8748 icons: { 8749 activeHeader: "ui-icon-triangle-1-s", 8750 header: "ui-icon-triangle-1-e" 8751 }, 8752 8753 // callbacks 8754 activate: null, 8755 beforeActivate: null 8756 }, 8757 8758 _create: function() { 8759 var options = this.options; 8760 this.prevShow = this.prevHide = $(); 8761 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) 8762 // ARIA 8763 .attr( "role", "tablist" ); 8764 8765 // don't allow collapsible: false and active: false / null 8766 if ( !options.collapsible && (options.active === false || options.active == null) ) { 8767 options.active = 0; 8768 } 8769 8770 this._processPanels(); 8771 // handle negative values 8772 if ( options.active < 0 ) { 8773 options.active += this.headers.length; 8774 } 8775 this._refresh(); 8776 }, 8777 8778 _getCreateEventData: function() { 8779 return { 8780 header: this.active, 8781 panel: !this.active.length ? $() : this.active.next(), 8782 content: !this.active.length ? $() : this.active.next() 8783 }; 8784 }, 8785 8786 _createIcons: function() { 8787 var icons = this.options.icons; 8788 if ( icons ) { 8789 $( "<span>" ) 8790 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 8791 .prependTo( this.headers ); 8792 this.active.children( ".ui-accordion-header-icon" ) 8793 .removeClass( icons.header ) 8794 .addClass( icons.activeHeader ); 8795 this.headers.addClass( "ui-accordion-icons" ); 8796 } 8797 }, 8798 8799 _destroyIcons: function() { 8800 this.headers 8801 .removeClass( "ui-accordion-icons" ) 8802 .children( ".ui-accordion-header-icon" ) 8803 .remove(); 8804 }, 8805 8806 _destroy: function() { 8807 var contents; 8808 8809 // clean up main element 8810 this.element 8811 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 8812 .removeAttr( "role" ); 8813 8814 // clean up headers 8815 this.headers 8816 .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) 8817 .removeAttr( "role" ) 8818 .removeAttr( "aria-selected" ) 8819 .removeAttr( "aria-controls" ) 8820 .removeAttr( "tabIndex" ) 8821 .each(function() { 8822 if ( /^ui-accordion/.test( this.id ) ) { 8823 this.removeAttribute( "id" ); 8824 } 8825 }); 8826 this._destroyIcons(); 8827 8828 // clean up content panels 8829 contents = this.headers.next() 8830 .css( "display", "" ) 8831 .removeAttr( "role" ) 8832 .removeAttr( "aria-expanded" ) 8833 .removeAttr( "aria-hidden" ) 8834 .removeAttr( "aria-labelledby" ) 8835 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 8836 .each(function() { 8837 if ( /^ui-accordion/.test( this.id ) ) { 8838 this.removeAttribute( "id" ); 8839 } 8840 }); 8841 if ( this.options.heightStyle !== "content" ) { 8842 contents.css( "height", "" ); 8843 } 8844 }, 8845 8846 _setOption: function( key, value ) { 8847 if ( key === "active" ) { 8848 // _activate() will handle invalid values and update this.options 8849 this._activate( value ); 8850 return; 8851 } 8852 8853 if ( key === "event" ) { 8854 if ( this.options.event ) { 8855 this._off( this.headers, this.options.event ); 8856 } 8857 this._setupEvents( value ); 8858 } 8859 8860 this._super( key, value ); 8861 8862 // setting collapsible: false while collapsed; open first panel 8863 if ( key === "collapsible" && !value && this.options.active === false ) { 8864 this._activate( 0 ); 8865 } 8866 8867 if ( key === "icons" ) { 8868 this._destroyIcons(); 8869 if ( value ) { 8870 this._createIcons(); 8871 } 8872 } 8873 8874 // #5332 - opacity doesn't cascade to positioned elements in IE 8875 // so we need to add the disabled class to the headers and panels 8876 if ( key === "disabled" ) { 8877 this.headers.add( this.headers.next() ) 8878 .toggleClass( "ui-state-disabled", !!value ); 8879 } 8880 }, 8881 8882 _keydown: function( event ) { 8883 /*jshint maxcomplexity:15*/ 8884 if ( event.altKey || event.ctrlKey ) { 8885 return; 8886 } 8887 8888 var keyCode = $.ui.keyCode, 8889 length = this.headers.length, 8890 currentIndex = this.headers.index( event.target ), 8891 toFocus = false; 8892 8893 switch ( event.keyCode ) { 8894 case keyCode.RIGHT: 8895 case keyCode.DOWN: 8896 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 8897 break; 8898 case keyCode.LEFT: 8899 case keyCode.UP: 8900 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 8901 break; 8902 case keyCode.SPACE: 8903 case keyCode.ENTER: 8904 this._eventHandler( event ); 8905 break; 8906 case keyCode.HOME: 8907 toFocus = this.headers[ 0 ]; 8908 break; 8909 case keyCode.END: 8910 toFocus = this.headers[ length - 1 ]; 8911 break; 8912 } 8913 8914 if ( toFocus ) { 8915 $( event.target ).attr( "tabIndex", -1 ); 8916 $( toFocus ).attr( "tabIndex", 0 ); 8917 toFocus.focus(); 8918 event.preventDefault(); 8919 } 8920 }, 8921 8922 _panelKeyDown : function( event ) { 8923 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 8924 $( event.currentTarget ).prev().focus(); 8925 } 8926 }, 8927 8928 refresh: function() { 8929 var options = this.options; 8930 this._processPanels(); 8931 8932 // was collapsed or no panel 8933 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { 8934 options.active = false; 8935 this.active = $(); 8936 // active false only when collapsible is true 8937 } else if ( options.active === false ) { 8938 this._activate( 0 ); 8939 // was active, but active panel is gone 8940 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 8941 // all remaining panel are disabled 8942 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { 8943 options.active = false; 8944 this.active = $(); 8945 // activate previous panel 8946 } else { 8947 this._activate( Math.max( 0, options.active - 1 ) ); 8948 } 8949 // was active, active panel still exists 8950 } else { 8951 // make sure active index is correct 8952 options.active = this.headers.index( this.active ); 8953 } 8954 8955 this._destroyIcons(); 8956 8957 this._refresh(); 8958 }, 8959 8960 _processPanels: function() { 8961 this.headers = this.element.find( this.options.header ) 8962 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 8963 8964 this.headers.next() 8965 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 8966 .filter(":not(.ui-accordion-content-active)") 8967 .hide(); 8968 }, 8969 8970 _refresh: function() { 8971 var maxHeight, 8972 options = this.options, 8973 heightStyle = options.heightStyle, 8974 parent = this.element.parent(), 8975 accordionId = this.accordionId = "ui-accordion-" + 8976 (this.element.attr( "id" ) || ++uid); 8977 8978 this.active = this._findActive( options.active ) 8979 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) 8980 .removeClass( "ui-corner-all" ); 8981 this.active.next() 8982 .addClass( "ui-accordion-content-active" ) 8983 .show(); 8984 8985 this.headers 8986 .attr( "role", "tab" ) 8987 .each(function( i ) { 8988 var header = $( this ), 8989 headerId = header.attr( "id" ), 8990 panel = header.next(), 8991 panelId = panel.attr( "id" ); 8992 if ( !headerId ) { 8993 headerId = accordionId + "-header-" + i; 8994 header.attr( "id", headerId ); 8995 } 8996 if ( !panelId ) { 8997 panelId = accordionId + "-panel-" + i; 8998 panel.attr( "id", panelId ); 8999 } 9000 header.attr( "aria-controls", panelId ); 9001 panel.attr( "aria-labelledby", headerId ); 9002 }) 9003 .next() 9004 .attr( "role", "tabpanel" ); 9005 9006 this.headers 9007 .not( this.active ) 9008 .attr({ 9009 "aria-selected": "false", 9010 tabIndex: -1 9011 }) 9012 .next() 9013 .attr({ 9014 "aria-expanded": "false", 9015 "aria-hidden": "true" 9016 }) 9017 .hide(); 9018 9019 // make sure at least one header is in the tab order 9020 if ( !this.active.length ) { 9021 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 9022 } else { 9023 this.active.attr({ 9024 "aria-selected": "true", 9025 tabIndex: 0 9026 }) 9027 .next() 9028 .attr({ 9029 "aria-expanded": "true", 9030 "aria-hidden": "false" 9031 }); 9032 } 9033 9034 this._createIcons(); 9035 9036 this._setupEvents( options.event ); 9037 9038 if ( heightStyle === "fill" ) { 9039 maxHeight = parent.height(); 9040 this.element.siblings( ":visible" ).each(function() { 9041 var elem = $( this ), 9042 position = elem.css( "position" ); 9043 9044 if ( position === "absolute" || position === "fixed" ) { 9045 return; 9046 } 9047 maxHeight -= elem.outerHeight( true ); 9048 }); 9049 9050 this.headers.each(function() { 9051 maxHeight -= $( this ).outerHeight( true ); 9052 }); 9053 9054 this.headers.next() 9055 .each(function() { 9056 $( this ).height( Math.max( 0, maxHeight - 9057 $( this ).innerHeight() + $( this ).height() ) ); 9058 }) 9059 .css( "overflow", "auto" ); 9060 } else if ( heightStyle === "auto" ) { 9061 maxHeight = 0; 9062 this.headers.next() 9063 .each(function() { 9064 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 9065 }) 9066 .height( maxHeight ); 9067 } 9068 }, 9069 9070 _activate: function( index ) { 9071 var active = this._findActive( index )[ 0 ]; 9072 9073 // trying to activate the already active panel 9074 if ( active === this.active[ 0 ] ) { 9075 return; 9076 } 9077 9078 // trying to collapse, simulate a click on the currently active header 9079 active = active || this.active[ 0 ]; 9080 9081 this._eventHandler({ 9082 target: active, 9083 currentTarget: active, 9084 preventDefault: $.noop 9085 }); 9086 }, 9087 9088 _findActive: function( selector ) { 9089 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 9090 }, 9091 9092 _setupEvents: function( event ) { 9093 var events = { 9094 keydown: "_keydown" 9095 }; 9096 if ( event ) { 9097 $.each( event.split(" "), function( index, eventName ) { 9098 events[ eventName ] = "_eventHandler"; 9099 }); 9100 } 9101 9102 this._off( this.headers.add( this.headers.next() ) ); 9103 this._on( this.headers, events ); 9104 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 9105 this._hoverable( this.headers ); 9106 this._focusable( this.headers ); 9107 }, 9108 9109 _eventHandler: function( event ) { 9110 var options = this.options, 9111 active = this.active, 9112 clicked = $( event.currentTarget ), 9113 clickedIsActive = clicked[ 0 ] === active[ 0 ], 9114 collapsing = clickedIsActive && options.collapsible, 9115 toShow = collapsing ? $() : clicked.next(), 9116 toHide = active.next(), 9117 eventData = { 9118 oldHeader: active, 9119 oldPanel: toHide, 9120 newHeader: collapsing ? $() : clicked, 9121 newPanel: toShow 9122 }; 9123 9124 event.preventDefault(); 9125 9126 if ( 9127 // click on active header, but not collapsible 9128 ( clickedIsActive && !options.collapsible ) || 9129 // allow canceling activation 9130 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 9131 return; 9132 } 9133 9134 options.active = collapsing ? false : this.headers.index( clicked ); 9135 9136 // when the call to ._toggle() comes after the class changes 9137 // it causes a very odd bug in IE 8 (see #6720) 9138 this.active = clickedIsActive ? $() : clicked; 9139 this._toggle( eventData ); 9140 9141 // switch classes 9142 // corner classes on the previously active header stay after the animation 9143 active.removeClass( "ui-accordion-header-active ui-state-active" ); 9144 if ( options.icons ) { 9145 active.children( ".ui-accordion-header-icon" ) 9146 .removeClass( options.icons.activeHeader ) 9147 .addClass( options.icons.header ); 9148 } 9149 9150 if ( !clickedIsActive ) { 9151 clicked 9152 .removeClass( "ui-corner-all" ) 9153 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 9154 if ( options.icons ) { 9155 clicked.children( ".ui-accordion-header-icon" ) 9156 .removeClass( options.icons.header ) 9157 .addClass( options.icons.activeHeader ); 9158 } 9159 9160 clicked 9161 .next() 9162 .addClass( "ui-accordion-content-active" ); 9163 } 9164 }, 9165 9166 _toggle: function( data ) { 9167 var toShow = data.newPanel, 9168 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 9169 9170 // handle activating a panel during the animation for another activation 9171 this.prevShow.add( this.prevHide ).stop( true, true ); 9172 this.prevShow = toShow; 9173 this.prevHide = toHide; 9174 9175 if ( this.options.animate ) { 9176 this._animate( toShow, toHide, data ); 9177 } else { 9178 toHide.hide(); 9179 toShow.show(); 9180 this._toggleComplete( data ); 9181 } 9182 9183 toHide.attr({ 9184 "aria-expanded": "false", 9185 "aria-hidden": "true" 9186 }); 9187 toHide.prev().attr( "aria-selected", "false" ); 9188 // if we're switching panels, remove the old header from the tab order 9189 // if we're opening from collapsed state, remove the previous header from the tab order 9190 // if we're collapsing, then keep the collapsing header in the tab order 9191 if ( toShow.length && toHide.length ) { 9192 toHide.prev().attr( "tabIndex", -1 ); 9193 } else if ( toShow.length ) { 9194 this.headers.filter(function() { 9195 return $( this ).attr( "tabIndex" ) === 0; 9196 }) 9197 .attr( "tabIndex", -1 ); 9198 } 9199 9200 toShow 9201 .attr({ 9202 "aria-expanded": "true", 9203 "aria-hidden": "false" 9204 }) 9205 .prev() 9206 .attr({ 9207 "aria-selected": "true", 9208 tabIndex: 0 9209 }); 9210 }, 9211 9212 _animate: function( toShow, toHide, data ) { 9213 var total, easing, duration, 9214 that = this, 9215 adjust = 0, 9216 down = toShow.length && 9217 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 9218 animate = this.options.animate || {}, 9219 options = down && animate.down || animate, 9220 complete = function() { 9221 that._toggleComplete( data ); 9222 }; 9223 9224 if ( typeof options === "number" ) { 9225 duration = options; 9226 } 9227 if ( typeof options === "string" ) { 9228 easing = options; 9229 } 9230 // fall back from options to animation in case of partial down settings 9231 easing = easing || options.easing || animate.easing; 9232 duration = duration || options.duration || animate.duration; 9233 9234 if ( !toHide.length ) { 9235 return toShow.animate( showProps, duration, easing, complete ); 9236 } 9237 if ( !toShow.length ) { 9238 return toHide.animate( hideProps, duration, easing, complete ); 9239 } 9240 9241 total = toShow.show().outerHeight(); 9242 toHide.animate( hideProps, { 9243 duration: duration, 9244 easing: easing, 9245 step: function( now, fx ) { 9246 fx.now = Math.round( now ); 9247 } 9248 }); 9249 toShow 9250 .hide() 9251 .animate( showProps, { 9252 duration: duration, 9253 easing: easing, 9254 complete: complete, 9255 step: function( now, fx ) { 9256 fx.now = Math.round( now ); 9257 if ( fx.prop !== "height" ) { 9258 adjust += fx.now; 9259 } else if ( that.options.heightStyle !== "content" ) { 9260 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 9261 adjust = 0; 9262 } 9263 } 9264 }); 9265 }, 9266 9267 _toggleComplete: function( data ) { 9268 var toHide = data.oldPanel; 9269 9270 toHide 9271 .removeClass( "ui-accordion-content-active" ) 9272 .prev() 9273 .removeClass( "ui-corner-top" ) 9274 .addClass( "ui-corner-all" ); 9275 9276 // Work around for rendering bug in IE (#5421) 9277 if ( toHide.length ) { 9278 toHide.parent()[0].className = toHide.parent()[0].className; 9279 } 9280 9281 this._trigger( "activate", null, data ); 9282 } 9283}); 9284 9285})( jQuery ); 9286(function( $, undefined ) { 9287 9288// used to prevent race conditions with remote data sources 9289var requestIndex = 0; 9290 9291$.widget( "ui.autocomplete", { 9292 version: "1.10.3", 9293 defaultElement: "<input>", 9294 options: { 9295 appendTo: null, 9296 autoFocus: false, 9297 delay: 300, 9298 minLength: 1, 9299 position: { 9300 my: "left top", 9301 at: "left bottom", 9302 collision: "none" 9303 }, 9304 source: null, 9305 9306 // callbacks 9307 change: null, 9308 close: null, 9309 focus: null, 9310 open: null, 9311 response: null, 9312 search: null, 9313 select: null 9314 }, 9315 9316 pending: 0, 9317 9318 _create: function() { 9319 // Some browsers only repeat keydown events, not keypress events, 9320 // so we use the suppressKeyPress flag to determine if we've already 9321 // handled the keydown event. #7269 9322 // Unfortunately the code for & in keypress is the same as the up arrow, 9323 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 9324 // events when we know the keydown event was used to modify the 9325 // search term. #7799 9326 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 9327 nodeName = this.element[0].nodeName.toLowerCase(), 9328 isTextarea = nodeName === "textarea", 9329 isInput = nodeName === "input"; 9330 9331 this.isMultiLine = 9332 // Textareas are always multi-line 9333 isTextarea ? true : 9334 // Inputs are always single-line, even if inside a contentEditable element 9335 // IE also treats inputs as contentEditable 9336 isInput ? false : 9337 // All other element types are determined by whether or not they're contentEditable 9338 this.element.prop( "isContentEditable" ); 9339 9340 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 9341 this.isNewMenu = true; 9342 9343 this.element 9344 .addClass( "ui-autocomplete-input" ) 9345 .attr( "autocomplete", "off" ); 9346 9347 this._on( this.element, { 9348 keydown: function( event ) { 9349 /*jshint maxcomplexity:15*/ 9350 if ( this.element.prop( "readOnly" ) ) { 9351 suppressKeyPress = true; 9352 suppressInput = true; 9353 suppressKeyPressRepeat = true; 9354 return; 9355 } 9356 9357 suppressKeyPress = false; 9358 suppressInput = false; 9359 suppressKeyPressRepeat = false; 9360 var keyCode = $.ui.keyCode; 9361 switch( event.keyCode ) { 9362 case keyCode.PAGE_UP: 9363 suppressKeyPress = true; 9364 this._move( "previousPage", event ); 9365 break; 9366 case keyCode.PAGE_DOWN: 9367 suppressKeyPress = true; 9368 this._move( "nextPage", event ); 9369 break; 9370 case keyCode.UP: 9371 suppressKeyPress = true; 9372 this._keyEvent( "previous", event ); 9373 break; 9374 case keyCode.DOWN: 9375 suppressKeyPress = true; 9376 this._keyEvent( "next", event ); 9377 break; 9378 case keyCode.ENTER: 9379 case keyCode.NUMPAD_ENTER: 9380 // when menu is open and has focus 9381 if ( this.menu.active ) { 9382 // #6055 - Opera still allows the keypress to occur 9383 // which causes forms to submit 9384 suppressKeyPress = true; 9385 event.preventDefault(); 9386 this.menu.select( event ); 9387 } 9388 break; 9389 case keyCode.TAB: 9390 if ( this.menu.active ) { 9391 this.menu.select( event ); 9392 } 9393 break; 9394 case keyCode.ESCAPE: 9395 if ( this.menu.element.is( ":visible" ) ) { 9396 this._value( this.term ); 9397 this.close( event ); 9398 // Different browsers have different default behavior for escape 9399 // Single press can mean undo or clear 9400 // Double press in IE means clear the whole form 9401 event.preventDefault(); 9402 } 9403 break; 9404 default: 9405 suppressKeyPressRepeat = true; 9406 // search timeout should be triggered before the input value is changed 9407 this._searchTimeout( event ); 9408 break; 9409 } 9410 }, 9411 keypress: function( event ) { 9412 if ( suppressKeyPress ) { 9413 suppressKeyPress = false; 9414 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 9415 event.preventDefault(); 9416 } 9417 return; 9418 } 9419 if ( suppressKeyPressRepeat ) { 9420 return; 9421 } 9422 9423 // replicate some key handlers to allow them to repeat in Firefox and Opera 9424 var keyCode = $.ui.keyCode; 9425 switch( event.keyCode ) { 9426 case keyCode.PAGE_UP: 9427 this._move( "previousPage", event ); 9428 break; 9429 case keyCode.PAGE_DOWN: 9430 this._move( "nextPage", event ); 9431 break; 9432 case keyCode.UP: 9433 this._keyEvent( "previous", event ); 9434 break; 9435 case keyCode.DOWN: 9436 this._keyEvent( "next", event ); 9437 break; 9438 } 9439 }, 9440 input: function( event ) { 9441 if ( suppressInput ) { 9442 suppressInput = false; 9443 event.preventDefault(); 9444 return; 9445 } 9446 this._searchTimeout( event ); 9447 }, 9448 focus: function() { 9449 this.selectedItem = null; 9450 this.previous = this._value(); 9451 }, 9452 blur: function( event ) { 9453 if ( this.cancelBlur ) { 9454 delete this.cancelBlur; 9455 return; 9456 } 9457 9458 clearTimeout( this.searching ); 9459 this.close( event ); 9460 this._change( event ); 9461 } 9462 }); 9463 9464 this._initSource(); 9465 this.menu = $( "<ul>" ) 9466 .addClass( "ui-autocomplete ui-front" ) 9467 .appendTo( this._appendTo() ) 9468 .menu({ 9469 // disable ARIA support, the live region takes care of that 9470 role: null 9471 }) 9472 .hide() 9473 .data( "ui-menu" ); 9474 9475 this._on( this.menu.element, { 9476 mousedown: function( event ) { 9477 // prevent moving focus out of the text field 9478 event.preventDefault(); 9479 9480 // IE doesn't prevent moving focus even with event.preventDefault() 9481 // so we set a flag to know when we should ignore the blur event 9482 this.cancelBlur = true; 9483 this._delay(function() { 9484 delete this.cancelBlur; 9485 }); 9486 9487 // clicking on the scrollbar causes focus to shift to the body 9488 // but we can't detect a mouseup or a click immediately afterward 9489 // so we have to track the next mousedown and close the menu if 9490 // the user clicks somewhere outside of the autocomplete 9491 var menuElement = this.menu.element[ 0 ]; 9492 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 9493 this._delay(function() { 9494 var that = this; 9495 this.document.one( "mousedown", function( event ) { 9496 if ( event.target !== that.element[ 0 ] && 9497 event.target !== menuElement && 9498 !$.contains( menuElement, event.target ) ) { 9499 that.close(); 9500 } 9501 }); 9502 }); 9503 } 9504 }, 9505 menufocus: function( event, ui ) { 9506 // support: Firefox 9507 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 9508 if ( this.isNewMenu ) { 9509 this.isNewMenu = false; 9510 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 9511 this.menu.blur(); 9512 9513 this.document.one( "mousemove", function() { 9514 $( event.target ).trigger( event.originalEvent ); 9515 }); 9516 9517 return; 9518 } 9519 } 9520 9521 var item = ui.item.data( "ui-autocomplete-item" ); 9522 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 9523 // use value to match what will end up in the input, if it was a key event 9524 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 9525 this._value( item.value ); 9526 } 9527 } else { 9528 // Normally the input is populated with the item's value as the 9529 // menu is navigated, causing screen readers to notice a change and 9530 // announce the item. Since the focus event was canceled, this doesn't 9531 // happen, so we update the live region so that screen readers can 9532 // still notice the change and announce it. 9533 this.liveRegion.text( item.value ); 9534 } 9535 }, 9536 menuselect: function( event, ui ) { 9537 var item = ui.item.data( "ui-autocomplete-item" ), 9538 previous = this.previous; 9539 9540 // only trigger when focus was lost (click on menu) 9541 if ( this.element[0] !== this.document[0].activeElement ) { 9542 this.element.focus(); 9543 this.previous = previous; 9544 // #6109 - IE triggers two focus events and the second 9545 // is asynchronous, so we need to reset the previous 9546 // term synchronously and asynchronously :-( 9547 this._delay(function() { 9548 this.previous = previous; 9549 this.selectedItem = item; 9550 }); 9551 } 9552 9553 if ( false !== this._trigger( "select", event, { item: item } ) ) { 9554 this._value( item.value ); 9555 } 9556 // reset the term after the select event 9557 // this allows custom select handling to work properly 9558 this.term = this._value(); 9559 9560 this.close( event ); 9561 this.selectedItem = item; 9562 } 9563 }); 9564 9565 this.liveRegion = $( "<span>", { 9566 role: "status", 9567 "aria-live": "polite" 9568 }) 9569 .addClass( "ui-helper-hidden-accessible" ) 9570 .insertBefore( this.element ); 9571 9572 // turning off autocomplete prevents the browser from remembering the 9573 // value when navigating through history, so we re-enable autocomplete 9574 // if the page is unloaded before the widget is destroyed. #7790 9575 this._on( this.window, { 9576 beforeunload: function() { 9577 this.element.removeAttr( "autocomplete" ); 9578 } 9579 }); 9580 }, 9581 9582 _destroy: function() { 9583 clearTimeout( this.searching ); 9584 this.element 9585 .removeClass( "ui-autocomplete-input" ) 9586 .removeAttr( "autocomplete" ); 9587 this.menu.element.remove(); 9588 this.liveRegion.remove(); 9589 }, 9590 9591 _setOption: function( key, value ) { 9592 this._super( key, value ); 9593 if ( key === "source" ) { 9594 this._initSource(); 9595 } 9596 if ( key === "appendTo" ) { 9597 this.menu.element.appendTo( this._appendTo() ); 9598 } 9599 if ( key === "disabled" && value && this.xhr ) { 9600 this.xhr.abort(); 9601 } 9602 }, 9603 9604 _appendTo: function() { 9605 var element = this.options.appendTo; 9606 9607 if ( element ) { 9608 element = element.jquery || element.nodeType ? 9609 $( element ) : 9610 this.document.find( element ).eq( 0 ); 9611 } 9612 9613 if ( !element ) { 9614 element = this.element.closest( ".ui-front" ); 9615 } 9616 9617 if ( !element.length ) { 9618 element = this.document[0].body; 9619 } 9620 9621 return element; 9622 }, 9623 9624 _initSource: function() { 9625 var array, url, 9626 that = this; 9627 if ( $.isArray(this.options.source) ) { 9628 array = this.options.source; 9629 this.source = function( request, response ) { 9630 response( $.ui.autocomplete.filter( array, request.term ) ); 9631 }; 9632 } else if ( typeof this.options.source === "string" ) { 9633 url = this.options.source; 9634 this.source = function( request, response ) { 9635 if ( that.xhr ) { 9636 that.xhr.abort(); 9637 } 9638 that.xhr = $.ajax({ 9639 url: url, 9640 data: request, 9641 dataType: "json", 9642 success: function( data ) { 9643 response( data ); 9644 }, 9645 error: function() { 9646 response( [] ); 9647 } 9648 }); 9649 }; 9650 } else { 9651 this.source = this.options.source; 9652 } 9653 }, 9654 9655 _searchTimeout: function( event ) { 9656 clearTimeout( this.searching ); 9657 this.searching = this._delay(function() { 9658 // only search if the value has changed 9659 if ( this.term !== this._value() ) { 9660 this.selectedItem = null; 9661 this.search( null, event ); 9662 } 9663 }, this.options.delay ); 9664 }, 9665 9666 search: function( value, event ) { 9667 value = value != null ? value : this._value(); 9668 9669 // always save the actual value, not the one passed as an argument 9670 this.term = this._value(); 9671 9672 if ( value.length < this.options.minLength ) { 9673 return this.close( event ); 9674 } 9675 9676 if ( this._trigger( "search", event ) === false ) { 9677 return; 9678 } 9679 9680 return this._search( value ); 9681 }, 9682 9683 _search: function( value ) { 9684 this.pending++; 9685 this.element.addClass( "ui-autocomplete-loading" ); 9686 this.cancelSearch = false; 9687 9688 this.source( { term: value }, this._response() ); 9689 }, 9690 9691 _response: function() { 9692 var that = this, 9693 index = ++requestIndex; 9694 9695 return function( content ) { 9696 if ( index === requestIndex ) { 9697 that.__response( content ); 9698 } 9699 9700 that.pending--; 9701 if ( !that.pending ) { 9702 that.element.removeClass( "ui-autocomplete-loading" ); 9703 } 9704 }; 9705 }, 9706 9707 __response: function( content ) { 9708 if ( content ) { 9709 content = this._normalize( content ); 9710 } 9711 this._trigger( "response", null, { content: content } ); 9712 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 9713 this._suggest( content ); 9714 this._trigger( "open" ); 9715 } else { 9716 // use ._close() instead of .close() so we don't cancel future searches 9717 this._close(); 9718 } 9719 }, 9720 9721 close: function( event ) { 9722 this.cancelSearch = true; 9723 this._close( event ); 9724 }, 9725 9726 _close: function( event ) { 9727 if ( this.menu.element.is( ":visible" ) ) { 9728 this.menu.element.hide(); 9729 this.menu.blur(); 9730 this.isNewMenu = true; 9731 this._trigger( "close", event ); 9732 } 9733 }, 9734 9735 _change: function( event ) { 9736 if ( this.previous !== this._value() ) { 9737 this._trigger( "change", event, { item: this.selectedItem } ); 9738 } 9739 }, 9740 9741 _normalize: function( items ) { 9742 // assume all items have the right format when the first item is complete 9743 if ( items.length && items[0].label && items[0].value ) { 9744 return items; 9745 } 9746 return $.map( items, function( item ) { 9747 if ( typeof item === "string" ) { 9748 return { 9749 label: item, 9750 value: item 9751 }; 9752 } 9753 return $.extend({ 9754 label: item.label || item.value, 9755 value: item.value || item.label 9756 }, item ); 9757 }); 9758 }, 9759 9760 _suggest: function( items ) { 9761 var ul = this.menu.element.empty(); 9762 this._renderMenu( ul, items ); 9763 this.isNewMenu = true; 9764 this.menu.refresh(); 9765 9766 // size and position menu 9767 ul.show(); 9768 this._resizeMenu(); 9769 ul.position( $.extend({ 9770 of: this.element 9771 }, this.options.position )); 9772 9773 if ( this.options.autoFocus ) { 9774 this.menu.next(); 9775 } 9776 }, 9777 9778 _resizeMenu: function() { 9779 var ul = this.menu.element; 9780 ul.outerWidth( Math.max( 9781 // Firefox wraps long text (possibly a rounding bug) 9782 // so we add 1px to avoid the wrapping (#7513) 9783 ul.width( "" ).outerWidth() + 1, 9784 this.element.outerWidth() 9785 ) ); 9786 }, 9787 9788 _renderMenu: function( ul, items ) { 9789 var that = this; 9790 $.each( items, function( index, item ) { 9791 that._renderItemData( ul, item ); 9792 }); 9793 }, 9794 9795 _renderItemData: function( ul, item ) { 9796 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 9797 }, 9798 9799 _renderItem: function( ul, item ) { 9800 return $( "<li>" ) 9801 .append( $( "<a>" ).text( item.label ) ) 9802 .appendTo( ul ); 9803 }, 9804 9805 _move: function( direction, event ) { 9806 if ( !this.menu.element.is( ":visible" ) ) { 9807 this.search( null, event ); 9808 return; 9809 } 9810 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 9811 this.menu.isLastItem() && /^next/.test( direction ) ) { 9812 this._value( this.term ); 9813 this.menu.blur(); 9814 return; 9815 } 9816 this.menu[ direction ]( event ); 9817 }, 9818 9819 widget: function() { 9820 return this.menu.element; 9821 }, 9822 9823 _value: function() { 9824 return this.valueMethod.apply( this.element, arguments ); 9825 }, 9826 9827 _keyEvent: function( keyEvent, event ) { 9828 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 9829 this._move( keyEvent, event ); 9830 9831 // prevents moving cursor to beginning/end of the text field in some browsers 9832 event.preventDefault(); 9833 } 9834 } 9835}); 9836 9837$.extend( $.ui.autocomplete, { 9838 escapeRegex: function( value ) { 9839 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 9840 }, 9841 filter: function(array, term) { 9842 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 9843 return $.grep( array, function(value) { 9844 return matcher.test( value.label || value.value || value ); 9845 }); 9846 } 9847}); 9848 9849 9850// live region extension, adding a `messages` option 9851// NOTE: This is an experimental API. We are still investigating 9852// a full solution for string manipulation and internationalization. 9853$.widget( "ui.autocomplete", $.ui.autocomplete, { 9854 options: { 9855 messages: { 9856 noResults: "No search results.", 9857 results: function( amount ) { 9858 return amount + ( amount > 1 ? " results are" : " result is" ) + 9859 " available, use up and down arrow keys to navigate."; 9860 } 9861 } 9862 }, 9863 9864 __response: function( content ) { 9865 var message; 9866 this._superApply( arguments ); 9867 if ( this.options.disabled || this.cancelSearch ) { 9868 return; 9869 } 9870 if ( content && content.length ) { 9871 message = this.options.messages.results( content.length ); 9872 } else { 9873 message = this.options.messages.noResults; 9874 } 9875 this.liveRegion.text( message ); 9876 } 9877}); 9878 9879}( jQuery )); 9880(function( $, undefined ) { 9881 9882var lastActive, startXPos, startYPos, clickDragged, 9883 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 9884 stateClasses = "ui-state-hover ui-state-active ", 9885 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", 9886 formResetHandler = function() { 9887 var form = $( this ); 9888 setTimeout(function() { 9889 form.find( ":ui-button" ).button( "refresh" ); 9890 }, 1 ); 9891 }, 9892 radioGroup = function( radio ) { 9893 var name = radio.name, 9894 form = radio.form, 9895 radios = $( [] ); 9896 if ( name ) { 9897 name = name.replace( /'/g, "\\'" ); 9898 if ( form ) { 9899 radios = $( form ).find( "[name='" + name + "']" ); 9900 } else { 9901 radios = $( "[name='" + name + "']", radio.ownerDocument ) 9902 .filter(function() { 9903 return !this.form; 9904 }); 9905 } 9906 } 9907 return radios; 9908 }; 9909 9910$.widget( "ui.button", { 9911 version: "1.10.3", 9912 defaultElement: "<button>", 9913 options: { 9914 disabled: null, 9915 text: true, 9916 label: null, 9917 icons: { 9918 primary: null, 9919 secondary: null 9920 } 9921 }, 9922 _create: function() { 9923 this.element.closest( "form" ) 9924 .unbind( "reset" + this.eventNamespace ) 9925 .bind( "reset" + this.eventNamespace, formResetHandler ); 9926 9927 if ( typeof this.options.disabled !== "boolean" ) { 9928 this.options.disabled = !!this.element.prop( "disabled" ); 9929 } else { 9930 this.element.prop( "disabled", this.options.disabled ); 9931 } 9932 9933 this._determineButtonType(); 9934 this.hasTitle = !!this.buttonElement.attr( "title" ); 9935 9936 var that = this, 9937 options = this.options, 9938 toggleButton = this.type === "checkbox" || this.type === "radio", 9939 activeClass = !toggleButton ? "ui-state-active" : "", 9940 focusClass = "ui-state-focus"; 9941 9942 if ( options.label === null ) { 9943 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 9944 } 9945 9946 this._hoverable( this.buttonElement ); 9947 9948 this.buttonElement 9949 .addClass( baseClasses ) 9950 .attr( "role", "button" ) 9951 .bind( "mouseenter" + this.eventNamespace, function() { 9952 if ( options.disabled ) { 9953 return; 9954 } 9955 if ( this === lastActive ) { 9956 $( this ).addClass( "ui-state-active" ); 9957 } 9958 }) 9959 .bind( "mouseleave" + this.eventNamespace, function() { 9960 if ( options.disabled ) { 9961 return; 9962 } 9963 $( this ).removeClass( activeClass ); 9964 }) 9965 .bind( "click" + this.eventNamespace, function( event ) { 9966 if ( options.disabled ) { 9967 event.preventDefault(); 9968 event.stopImmediatePropagation(); 9969 } 9970 }); 9971 9972 this.element 9973 .bind( "focus" + this.eventNamespace, function() { 9974 // no need to check disabled, focus won't be triggered anyway 9975 that.buttonElement.addClass( focusClass ); 9976 }) 9977 .bind( "blur" + this.eventNamespace, function() { 9978 that.buttonElement.removeClass( focusClass ); 9979 }); 9980 9981 if ( toggleButton ) { 9982 this.element.bind( "change" + this.eventNamespace, function() { 9983 if ( clickDragged ) { 9984 return; 9985 } 9986 that.refresh(); 9987 }); 9988 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 9989 // prevents issue where button state changes but checkbox/radio checked state 9990 // does not in Firefox (see ticket #6970) 9991 this.buttonElement 9992 .bind( "mousedown" + this.eventNamespace, function( event ) { 9993 if ( options.disabled ) { 9994 return; 9995 } 9996 clickDragged = false; 9997 startXPos = event.pageX; 9998 startYPos = event.pageY; 9999 }) 10000 .bind( "mouseup" + this.eventNamespace, function( event ) { 10001 if ( options.disabled ) { 10002 return; 10003 } 10004 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 10005 clickDragged = true; 10006 } 10007 }); 10008 } 10009 10010 if ( this.type === "checkbox" ) { 10011 this.buttonElement.bind( "click" + this.eventNamespace, function() { 10012 if ( options.disabled || clickDragged ) { 10013 return false; 10014 } 10015 }); 10016 } else if ( this.type === "radio" ) { 10017 this.buttonElement.bind( "click" + this.eventNamespace, function() { 10018 if ( options.disabled || clickDragged ) { 10019 return false; 10020 } 10021 $( this ).addClass( "ui-state-active" ); 10022 that.buttonElement.attr( "aria-pressed", "true" ); 10023 10024 var radio = that.element[ 0 ]; 10025 radioGroup( radio ) 10026 .not( radio ) 10027 .map(function() { 10028 return $( this ).button( "widget" )[ 0 ]; 10029 }) 10030 .removeClass( "ui-state-active" ) 10031 .attr( "aria-pressed", "false" ); 10032 }); 10033 } else { 10034 this.buttonElement 10035 .bind( "mousedown" + this.eventNamespace, function() { 10036 if ( options.disabled ) { 10037 return false; 10038 } 10039 $( this ).addClass( "ui-state-active" ); 10040 lastActive = this; 10041 that.document.one( "mouseup", function() { 10042 lastActive = null; 10043 }); 10044 }) 10045 .bind( "mouseup" + this.eventNamespace, function() { 10046 if ( options.disabled ) { 10047 return false; 10048 } 10049 $( this ).removeClass( "ui-state-active" ); 10050 }) 10051 .bind( "keydown" + this.eventNamespace, function(event) { 10052 if ( options.disabled ) { 10053 return false; 10054 } 10055 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 10056 $( this ).addClass( "ui-state-active" ); 10057 } 10058 }) 10059 // see #8559, we bind to blur here in case the button element loses 10060 // focus between keydown and keyup, it would be left in an "active" state 10061 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { 10062 $( this ).removeClass( "ui-state-active" ); 10063 }); 10064 10065 if ( this.buttonElement.is("a") ) { 10066 this.buttonElement.keyup(function(event) { 10067 if ( event.keyCode === $.ui.keyCode.SPACE ) { 10068 // TODO pass through original event correctly (just as 2nd argument doesn't work) 10069 $( this ).click(); 10070 } 10071 }); 10072 } 10073 } 10074 10075 // TODO: pull out $.Widget's handling for the disabled option into 10076 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 10077 // be overridden by individual plugins 10078 this._setOption( "disabled", options.disabled ); 10079 this._resetButton(); 10080 }, 10081 10082 _determineButtonType: function() { 10083 var ancestor, labelSelector, checked; 10084 10085 if ( this.element.is("[type=checkbox]") ) { 10086 this.type = "checkbox"; 10087 } else if ( this.element.is("[type=radio]") ) { 10088 this.type = "radio"; 10089 } else if ( this.element.is("input") ) { 10090 this.type = "input"; 10091 } else { 10092 this.type = "button"; 10093 } 10094 10095 if ( this.type === "checkbox" || this.type === "radio" ) { 10096 // we don't search against the document in case the element 10097 // is disconnected from the DOM 10098 ancestor = this.element.parents().last(); 10099 labelSelector = "label[for='" + this.element.attr("id") + "']"; 10100 this.buttonElement = ancestor.find( labelSelector ); 10101 if ( !this.buttonElement.length ) { 10102 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 10103 this.buttonElement = ancestor.filter( labelSelector ); 10104 if ( !this.buttonElement.length ) { 10105 this.buttonElement = ancestor.find( labelSelector ); 10106 } 10107 } 10108 this.element.addClass( "ui-helper-hidden-accessible" ); 10109 10110 checked = this.element.is( ":checked" ); 10111 if ( checked ) { 10112 this.buttonElement.addClass( "ui-state-active" ); 10113 } 10114 this.buttonElement.prop( "aria-pressed", checked ); 10115 } else { 10116 this.buttonElement = this.element; 10117 } 10118 }, 10119 10120 widget: function() { 10121 return this.buttonElement; 10122 }, 10123 10124 _destroy: function() { 10125 this.element 10126 .removeClass( "ui-helper-hidden-accessible" ); 10127 this.buttonElement 10128 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 10129 .removeAttr( "role" ) 10130 .removeAttr( "aria-pressed" ) 10131 .html( this.buttonElement.find(".ui-button-text").html() ); 10132 10133 if ( !this.hasTitle ) {
vendor: 3,948 bytes, lines 10134-10284
10134 this.buttonElement.removeAttr( "title" ); 10135 } 10136 }, 10137 10138 _setOption: function( key, value ) { 10139 this._super( key, value ); 10140 if ( key === "disabled" ) { 10141 if ( value ) { 10142 this.element.prop( "disabled", true ); 10143 } else { 10144 this.element.prop( "disabled", false ); 10145 } 10146 return; 10147 } 10148 this._resetButton(); 10149 }, 10150 10151 refresh: function() { 10152 //See #8237 & #8828 10153 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); 10154 10155 if ( isDisabled !== this.options.disabled ) { 10156 this._setOption( "disabled", isDisabled ); 10157 } 10158 if ( this.type === "radio" ) { 10159 radioGroup( this.element[0] ).each(function() { 10160 if ( $( this ).is( ":checked" ) ) { 10161 $( this ).button( "widget" ) 10162 .addClass( "ui-state-active" ) 10163 .attr( "aria-pressed", "true" ); 10164 } else { 10165 $( this ).button( "widget" ) 10166 .removeClass( "ui-state-active" ) 10167 .attr( "aria-pressed", "false" ); 10168 } 10169 }); 10170 } else if ( this.type === "checkbox" ) { 10171 if ( this.element.is( ":checked" ) ) { 10172 this.buttonElement 10173 .addClass( "ui-state-active" ) 10174 .attr( "aria-pressed", "true" ); 10175 } else { 10176 this.buttonElement 10177 .removeClass( "ui-state-active" ) 10178 .attr( "aria-pressed", "false" ); 10179 } 10180 } 10181 }, 10182 10183 _resetButton: function() { 10184 if ( this.type === "input" ) { 10185 if ( this.options.label ) { 10186 this.element.val( this.options.label ); 10187 } 10188 return; 10189 } 10190 var buttonElement = this.buttonElement.removeClass( typeClasses ), 10191 buttonText = $( "<span></span>", this.document[0] ) 10192 .addClass( "ui-button-text" ) 10193 .html( this.options.label ) 10194 .appendTo( buttonElement.empty() ) 10195 .text(), 10196 icons = this.options.icons, 10197 multipleIcons = icons.primary && icons.secondary, 10198 buttonClasses = []; 10199 10200 if ( icons.primary || icons.secondary ) { 10201 if ( this.options.text ) { 10202 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 10203 } 10204 10205 if ( icons.primary ) { 10206 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 10207 } 10208 10209 if ( icons.secondary ) { 10210 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 10211 } 10212 10213 if ( !this.options.text ) { 10214 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 10215 10216 if ( !this.hasTitle ) { 10217 buttonElement.attr( "title", $.trim( buttonText ) ); 10218 } 10219 } 10220 } else { 10221 buttonClasses.push( "ui-button-text-only" ); 10222 } 10223 buttonElement.addClass( buttonClasses.join( " " ) ); 10224 } 10225}); 10226 10227$.widget( "ui.buttonset", { 10228 version: "1.10.3", 10229 options: { 10230 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" 10231 }, 10232 10233 _create: function() { 10234 this.element.addClass( "ui-buttonset" ); 10235 }, 10236 10237 _init: function() { 10238 this.refresh(); 10239 }, 10240 10241 _setOption: function( key, value ) { 10242 if ( key === "disabled" ) { 10243 this.buttons.button( "option", key, value ); 10244 } 10245 10246 this._super( key, value ); 10247 }, 10248 10249 refresh: function() { 10250 var rtl = this.element.css( "direction" ) === "rtl"; 10251 10252 this.buttons = this.element.find( this.options.items ) 10253 .filter( ":ui-button" ) 10254 .button( "refresh" ) 10255 .end() 10256 .not( ":ui-button" ) 10257 .button() 10258 .end() 10259 .map(function() { 10260 return $( this ).button( "widget" )[ 0 ]; 10261 }) 10262 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 10263 .filter( ":first" ) 10264 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 10265 .end() 10266 .filter( ":last" ) 10267 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 10268 .end() 10269 .end(); 10270 }, 10271 10272 _destroy: function() { 10273 this.element.removeClass( "ui-buttonset" ); 10274 this.buttons 10275 .map(function() { 10276 return $( this ).button( "widget" )[ 0 ]; 10277 }) 10278 .removeClass( "ui-corner-left ui-corner-right" ) 10279 .end() 10280 .button( "destroy" ); 10281 } 10282}); 10283 10284}( jQuery )
vendor: 76,062 bytes, lines 10284-12309
10284 ); 10285(function( $, undefined ) { 10286 10287$.extend($.ui, { datepicker: { version: "1.10.3" } }); 10288 10289var PROP_NAME = "datepicker", 10290 instActive; 10291 10292/* Date picker manager. 10293 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 10294 Settings for (groups of) date pickers are maintained in an instance object, 10295 allowing multiple different settings on the same page. */ 10296 10297function Datepicker() { 10298 this._curInst = null; // The current instance in use 10299 this._keyEvent = false; // If the last event was a key event 10300 this._disabledInputs = []; // List of date picker inputs that have been disabled 10301 this._datepickerShowing = false; // True if the popup picker is showing , false if not 10302 this._inDialog = false; // True if showing within a "dialog", false if not 10303 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 10304 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 10305 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 10306 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 10307 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 10308 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 10309 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 10310 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 10311 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 10312 this.regional = []; // Available regional settings, indexed by language code 10313 this.regional[""] = { // Default regional settings 10314 closeText: "Done", // Display text for close link 10315 prevText: "Prev", // Display text for previous month link 10316 nextText: "Next", // Display text for next month link 10317 currentText: "Today", // Display text for current month link 10318 monthNames: ["January","February","March","April","May","June", 10319 "July","August","September","October","November","December"], // Names of months for drop-down and formatting 10320 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting 10321 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting 10322 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting 10323 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday 10324 weekHeader: "Wk", // Column header for week of the year 10325 dateFormat: "mm/dd/yy", // See format options on parseDate 10326 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 10327 isRTL: false, // True if right-to-left language, false if left-to-right 10328 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 10329 yearSuffix: "" // Additional text to append to the year in the month headers 10330 }; 10331 this._defaults = { // Global defaults for all the date picker instances 10332 showOn: "focus", // "focus" for popup on focus, 10333 // "button" for trigger button, or "both" for either 10334 showAnim: "fadeIn", // Name of jQuery animation for popup 10335 showOptions: {}, // Options for enhanced animations 10336 defaultDate: null, // Used when field is blank: actual date, 10337 // +/-number for offset from today, null for today 10338 appendText: "", // Display text following the input box, e.g. showing the format 10339 buttonText: "...", // Text for trigger button 10340 buttonImage: "", // URL for trigger button image 10341 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 10342 hideIfNoPrevNext: false, // True to hide next/previous month links 10343 // if not applicable, false to just disable them 10344 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 10345 gotoCurrent: false, // True if today link goes back to current selection instead 10346 changeMonth: false, // True if month can be selected directly, false if only prev/next 10347 changeYear: false, // True if year can be selected directly, false if only prev/next 10348 yearRange: "c-10:c+10", // Range of years to display in drop-down, 10349 // either relative to today's year (-nn:+nn), relative to currently displayed year 10350 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 10351 showOtherMonths: false, // True to show dates in other months, false to leave blank 10352 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 10353 showWeek: false, // True to show week of the year, false to not show it 10354 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 10355 // takes a Date and returns the number of the week for it 10356 shortYearCutoff: "+10", // Short year values < this are in the current century, 10357 // > this are in the previous century, 10358 // string value starting with "+" for current year + value 10359 minDate: null, // The earliest selectable date, or null for no limit 10360 maxDate: null, // The latest selectable date, or null for no limit 10361 duration: "fast", // Duration of display/closure 10362 beforeShowDay: null, // Function that takes a date and returns an array with 10363 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 10364 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 10365 beforeShow: null, // Function that takes an input field and 10366 // returns a set of custom settings for the date picker 10367 onSelect: null, // Define a callback function when a date is selected 10368 onChangeMonthYear: null, // Define a callback function when the month or year is changed 10369 onClose: null, // Define a callback function when the datepicker is closed 10370 numberOfMonths: 1, // Number of months to show at a time 10371 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 10372 stepMonths: 1, // Number of months to step back/forward 10373 stepBigMonths: 12, // Number of months to step back/forward for the big links 10374 altField: "", // Selector for an alternate field to store selected dates into 10375 altFormat: "", // The date format to use for the alternate field 10376 constrainInput: true, // The input is constrained by the current date format 10377 showButtonPanel: false, // True to show button panel, false to not show it 10378 autoSize: false, // True to size the input for the date format, false to leave as is 10379 disabled: false // The initial disabled state 10380 }; 10381 $.extend(this._defaults, this.regional[""]); 10382 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); 10383} 10384 10385$.extend(Datepicker.prototype, { 10386 /* Class name added to elements to indicate already configured with a date picker. */ 10387 markerClassName: "hasDatepicker", 10388 10389 //Keep track of the maximum number of rows displayed (see #7043) 10390 maxRows: 4, 10391 10392 // TODO rename to "widget" when switching to widget factory 10393 _widgetDatepicker: function() { 10394 return this.dpDiv; 10395 }, 10396 10397 /* Override the default settings for all instances of the date picker. 10398 * @param settings object - the new settings to use as defaults (anonymous object) 10399 * @return the manager object 10400 */ 10401 setDefaults: function(settings) { 10402 extendRemove(this._defaults, settings || {}); 10403 return this; 10404 }, 10405 10406 /* Attach the date picker to a jQuery selection. 10407 * @param target element - the target input field or division or span 10408 * @param settings object - the new settings to use for this date picker instance (anonymous) 10409 */ 10410 _attachDatepicker: function(target, settings) { 10411 var nodeName, inline, inst; 10412 nodeName = target.nodeName.toLowerCase(); 10413 inline = (nodeName === "div" || nodeName === "span"); 10414 if (!target.id) { 10415 this.uuid += 1; 10416 target.id = "dp" + this.uuid; 10417 } 10418 inst = this._newInst($(target), inline); 10419 inst.settings = $.extend({}, settings || {}); 10420 if (nodeName === "input") { 10421 this._connectDatepicker(target, inst); 10422 } else if (inline) { 10423 this._inlineDatepicker(target, inst); 10424 } 10425 }, 10426 10427 /* Create a new instance object. */ 10428 _newInst: function(target, inline) { 10429 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars 10430 return {id: id, input: target, // associated target 10431 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 10432 drawMonth: 0, drawYear: 0, // month being drawn 10433 inline: inline, // is datepicker inline or not 10434 dpDiv: (!inline ? this.dpDiv : // presentation div 10435 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; 10436 }, 10437 10438 /* Attach the date picker to an input field. */ 10439 _connectDatepicker: function(target, inst) { 10440 var input = $(target); 10441 inst.append = $([]); 10442 inst.trigger = $([]); 10443 if (input.hasClass(this.markerClassName)) { 10444 return; 10445 } 10446 this._attachments(input, inst); 10447 input.addClass(this.markerClassName).keydown(this._doKeyDown). 10448 keypress(this._doKeyPress).keyup(this._doKeyUp); 10449 this._autoSize(inst); 10450 $.data(target, PROP_NAME, inst); 10451 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 10452 if( inst.settings.disabled ) { 10453 this._disableDatepicker( target ); 10454 } 10455 }, 10456 10457 /* Make attachments based on settings. */ 10458 _attachments: function(input, inst) { 10459 var showOn, buttonText, buttonImage, 10460 appendText = this._get(inst, "appendText"), 10461 isRTL = this._get(inst, "isRTL"); 10462 10463 if (inst.append) { 10464 inst.append.remove(); 10465 } 10466 if (appendText) { 10467 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); 10468 input[isRTL ? "before" : "after"](inst.append); 10469 } 10470 10471 input.unbind("focus", this._showDatepicker); 10472 10473 if (inst.trigger) { 10474 inst.trigger.remove(); 10475 } 10476 10477 showOn = this._get(inst, "showOn"); 10478 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field 10479 input.focus(this._showDatepicker); 10480 } 10481 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked 10482 buttonText = this._get(inst, "buttonText"); 10483 buttonImage = this._get(inst, "buttonImage"); 10484 inst.trigger = $(this._get(inst, "buttonImageOnly") ? 10485 $("<img/>").addClass(this._triggerClass). 10486 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 10487 $("<button type='button'></button>").addClass(this._triggerClass). 10488 html(!buttonImage ? buttonText : $("<img/>").attr( 10489 { src:buttonImage, alt:buttonText, title:buttonText }))); 10490 input[isRTL ? "before" : "after"](inst.trigger); 10491 inst.trigger.click(function() { 10492 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { 10493 $.datepicker._hideDatepicker(); 10494 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { 10495 $.datepicker._hideDatepicker(); 10496 $.datepicker._showDatepicker(input[0]); 10497 } else { 10498 $.datepicker._showDatepicker(input[0]); 10499 } 10500 return false; 10501 }); 10502 } 10503 }, 10504 10505 /* Apply the maximum length for the date format. */ 10506 _autoSize: function(inst) { 10507 if (this._get(inst, "autoSize") && !inst.inline) { 10508 var findMax, max, maxI, i, 10509 date = new Date(2009, 12 - 1, 20), // Ensure double digits 10510 dateFormat = this._get(inst, "dateFormat"); 10511 10512 if (dateFormat.match(/[DM]/)) { 10513 findMax = function(names) { 10514 max = 0; 10515 maxI = 0; 10516 for (i = 0; i < names.length; i++) { 10517 if (names[i].length > max) { 10518 max = names[i].length; 10519 maxI = i; 10520 } 10521 } 10522 return maxI; 10523 }; 10524 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 10525 "monthNames" : "monthNamesShort")))); 10526 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 10527 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); 10528 } 10529 inst.input.attr("size", this._formatDate(inst, date).length); 10530 } 10531 }, 10532 10533 /* Attach an inline date picker to a div. */ 10534 _inlineDatepicker: function(target, inst) { 10535 var divSpan = $(target); 10536 if (divSpan.hasClass(this.markerClassName)) { 10537 return; 10538 } 10539 divSpan.addClass(this.markerClassName).append(inst.dpDiv); 10540 $.data(target, PROP_NAME, inst); 10541 this._setDate(inst, this._getDefaultDate(inst), true); 10542 this._updateDatepicker(inst); 10543 this._updateAlternate(inst); 10544 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 10545 if( inst.settings.disabled ) { 10546 this._disableDatepicker( target ); 10547 } 10548 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 10549 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 10550 inst.dpDiv.css( "display", "block" ); 10551 }, 10552 10553 /* Pop-up the date picker in a "dialog" box. 10554 * @param input element - ignored 10555 * @param date string or Date - the initial date to display 10556 * @param onSelect function - the function to call when a date is selected 10557 * @param settings object - update the dialog date picker instance's settings (anonymous object) 10558 * @param pos int[2] - coordinates for the dialog's position within the screen or 10559 * event - with x/y coordinates or 10560 * leave empty for default (screen centre) 10561 * @return the manager object 10562 */ 10563 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 10564 var id, browserWidth, browserHeight, scrollX, scrollY, 10565 inst = this._dialogInst; // internal instance 10566 10567 if (!inst) { 10568 this.uuid += 1; 10569 id = "dp" + this.uuid; 10570 this._dialogInput = $("<input type='text' id='" + id + 10571 "' style='position: absolute; top: -100px; width: 0px;'/>"); 10572 this._dialogInput.keydown(this._doKeyDown); 10573 $("body").append(this._dialogInput); 10574 inst = this._dialogInst = this._newInst(this._dialogInput, false); 10575 inst.settings = {}; 10576 $.data(this._dialogInput[0], PROP_NAME, inst); 10577 } 10578 extendRemove(inst.settings, settings || {}); 10579 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); 10580 this._dialogInput.val(date); 10581 10582 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 10583 if (!this._pos) { 10584 browserWidth = document.documentElement.clientWidth; 10585 browserHeight = document.documentElement.clientHeight; 10586 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 10587 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 10588 this._pos = // should use actual width/height below 10589 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 10590 } 10591 10592 // move input on screen for focus, but hidden behind dialog 10593 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); 10594 inst.settings.onSelect = onSelect; 10595 this._inDialog = true; 10596 this.dpDiv.addClass(this._dialogClass); 10597 this._showDatepicker(this._dialogInput[0]); 10598 if ($.blockUI) { 10599 $.blockUI(this.dpDiv); 10600 } 10601 $.data(this._dialogInput[0], PROP_NAME, inst); 10602 return this; 10603 }, 10604 10605 /* Detach a datepicker from its control. 10606 * @param target element - the target input field or division or span 10607 */ 10608 _destroyDatepicker: function(target) { 10609 var nodeName, 10610 $target = $(target), 10611 inst = $.data(target, PROP_NAME); 10612 10613 if (!$target.hasClass(this.markerClassName)) { 10614 return; 10615 } 10616 10617 nodeName = target.nodeName.toLowerCase(); 10618 $.removeData(target, PROP_NAME); 10619 if (nodeName === "input") { 10620 inst.append.remove(); 10621 inst.trigger.remove(); 10622 $target.removeClass(this.markerClassName). 10623 unbind("focus", this._showDatepicker). 10624 unbind("keydown", this._doKeyDown). 10625 unbind("keypress", this._doKeyPress). 10626 unbind("keyup", this._doKeyUp); 10627 } else if (nodeName === "div" || nodeName === "span") { 10628 $target.removeClass(this.markerClassName).empty(); 10629 } 10630 }, 10631 10632 /* Enable the date picker to a jQuery selection. 10633 * @param target element - the target input field or division or span 10634 */ 10635 _enableDatepicker: function(target) { 10636 var nodeName, inline, 10637 $target = $(target), 10638 inst = $.data(target, PROP_NAME); 10639 10640 if (!$target.hasClass(this.markerClassName)) { 10641 return; 10642 } 10643 10644 nodeName = target.nodeName.toLowerCase(); 10645 if (nodeName === "input") { 10646 target.disabled = false; 10647 inst.trigger.filter("button"). 10648 each(function() { this.disabled = false; }).end(). 10649 filter("img").css({opacity: "1.0", cursor: ""}); 10650 } else if (nodeName === "div" || nodeName === "span") { 10651 inline = $target.children("." + this._inlineClass); 10652 inline.children().removeClass("ui-state-disabled"); 10653 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 10654 prop("disabled", false); 10655 } 10656 this._disabledInputs = $.map(this._disabledInputs, 10657 function(value) { return (value === target ? null : value); }); // delete entry 10658 }, 10659 10660 /* Disable the date picker to a jQuery selection. 10661 * @param target element - the target input field or division or span 10662 */ 10663 _disableDatepicker: function(target) { 10664 var nodeName, inline, 10665 $target = $(target), 10666 inst = $.data(target, PROP_NAME); 10667 10668 if (!$target.hasClass(this.markerClassName)) { 10669 return; 10670 } 10671 10672 nodeName = target.nodeName.toLowerCase(); 10673 if (nodeName === "input") { 10674 target.disabled = true; 10675 inst.trigger.filter("button"). 10676 each(function() { this.disabled = true; }).end(). 10677 filter("img").css({opacity: "0.5", cursor: "default"}); 10678 } else if (nodeName === "div" || nodeName === "span") { 10679 inline = $target.children("." + this._inlineClass); 10680 inline.children().addClass("ui-state-disabled"); 10681 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 10682 prop("disabled", true); 10683 } 10684 this._disabledInputs = $.map(this._disabledInputs, 10685 function(value) { return (value === target ? null : value); }); // delete entry 10686 this._disabledInputs[this._disabledInputs.length] = target; 10687 }, 10688 10689 /* Is the first field in a jQuery collection disabled as a datepicker? 10690 * @param target element - the target input field or division or span 10691 * @return boolean - true if disabled, false if enabled 10692 */ 10693 _isDisabledDatepicker: function(target) { 10694 if (!target) { 10695 return false; 10696 } 10697 for (var i = 0; i < this._disabledInputs.length; i++) { 10698 if (this._disabledInputs[i] === target) { 10699 return true; 10700 } 10701 } 10702 return false; 10703 }, 10704 10705 /* Retrieve the instance data for the target control. 10706 * @param target element - the target input field or division or span 10707 * @return object - the associated instance data 10708 * @throws error if a jQuery problem getting data 10709 */ 10710 _getInst: function(target) { 10711 try { 10712 return $.data(target, PROP_NAME); 10713 } 10714 catch (err) { 10715 throw "Missing instance data for this datepicker"; 10716 } 10717 }, 10718 10719 /* Update or retrieve the settings for a date picker attached to an input field or division. 10720 * @param target element - the target input field or division or span 10721 * @param name object - the new settings to update or 10722 * string - the name of the setting to change or retrieve, 10723 * when retrieving also "all" for all instance settings or 10724 * "defaults" for all global defaults 10725 * @param value any - the new value for the setting 10726 * (omit if above is an object or to retrieve a value) 10727 */ 10728 _optionDatepicker: function(target, name, value) { 10729 var settings, date, minDate, maxDate, 10730 inst = this._getInst(target); 10731 10732 if (arguments.length === 2 && typeof name === "string") { 10733 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : 10734 (inst ? (name === "all" ? $.extend({}, inst.settings) : 10735 this._get(inst, name)) : null)); 10736 } 10737 10738 settings = name || {}; 10739 if (typeof name === "string") { 10740 settings = {}; 10741 settings[name] = value; 10742 } 10743 10744 if (inst) { 10745 if (this._curInst === inst) { 10746 this._hideDatepicker(); 10747 } 10748 10749 date = this._getDateDatepicker(target, true); 10750 minDate = this._getMinMaxDate(inst, "min"); 10751 maxDate = this._getMinMaxDate(inst, "max"); 10752 extendRemove(inst.settings, settings); 10753 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 10754 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { 10755 inst.settings.minDate = this._formatDate(inst, minDate); 10756 } 10757 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { 10758 inst.settings.maxDate = this._formatDate(inst, maxDate); 10759 } 10760 if ( "disabled" in settings ) { 10761 if ( settings.disabled ) { 10762 this._disableDatepicker(target); 10763 } else { 10764 this._enableDatepicker(target); 10765 } 10766 } 10767 this._attachments($(target), inst); 10768 this._autoSize(inst); 10769 this._setDate(inst, date); 10770 this._updateAlternate(inst); 10771 this._updateDatepicker(inst); 10772 } 10773 }, 10774 10775 // change method deprecated 10776 _changeDatepicker: function(target, name, value) { 10777 this._optionDatepicker(target, name, value); 10778 }, 10779 10780 /* Redraw the date picker attached to an input field or division. 10781 * @param target element - the target input field or division or span 10782 */ 10783 _refreshDatepicker: function(target) { 10784 var inst = this._getInst(target); 10785 if (inst) { 10786 this._updateDatepicker(inst); 10787 } 10788 }, 10789 10790 /* Set the dates for a jQuery selection. 10791 * @param target element - the target input field or division or span 10792 * @param date Date - the new date 10793 */ 10794 _setDateDatepicker: function(target, date) { 10795 var inst = this._getInst(target); 10796 if (inst) { 10797 this._setDate(inst, date); 10798 this._updateDatepicker(inst); 10799 this._updateAlternate(inst); 10800 } 10801 }, 10802 10803 /* Get the date(s) for the first entry in a jQuery selection. 10804 * @param target element - the target input field or division or span 10805 * @param noDefault boolean - true if no default date is to be used 10806 * @return Date - the current date 10807 */ 10808 _getDateDatepicker: function(target, noDefault) { 10809 var inst = this._getInst(target); 10810 if (inst && !inst.inline) { 10811 this._setDateFromField(inst, noDefault); 10812 } 10813 return (inst ? this._getDate(inst) : null); 10814 }, 10815 10816 /* Handle keystrokes. */ 10817 _doKeyDown: function(event) { 10818 var onSelect, dateStr, sel, 10819 inst = $.datepicker._getInst(event.target), 10820 handled = true, 10821 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); 10822 10823 inst._keyEvent = true; 10824 if ($.datepicker._datepickerShowing) { 10825 switch (event.keyCode) { 10826 case 9: $.datepicker._hideDatepicker(); 10827 handled = false; 10828 break; // hide on tab out 10829 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + 10830 $.datepicker._currentClass + ")", inst.dpDiv); 10831 if (sel[0]) { 10832 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 10833 } 10834 10835 onSelect = $.datepicker._get(inst, "onSelect"); 10836 if (onSelect) { 10837 dateStr = $.datepicker._formatDate(inst); 10838 10839 // trigger custom callback 10840 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 10841 } else { 10842 $.datepicker._hideDatepicker(); 10843 } 10844 10845 return false; // don't submit the form 10846 case 27: $.datepicker._hideDatepicker(); 10847 break; // hide on escape 10848 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10849 -$.datepicker._get(inst, "stepBigMonths") : 10850 -$.datepicker._get(inst, "stepMonths")), "M"); 10851 break; // previous month/year on page up/+ ctrl 10852 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10853 +$.datepicker._get(inst, "stepBigMonths") : 10854 +$.datepicker._get(inst, "stepMonths")), "M"); 10855 break; // next month/year on page down/+ ctrl 10856 case 35: if (event.ctrlKey || event.metaKey) { 10857 $.datepicker._clearDate(event.target); 10858 } 10859 handled = event.ctrlKey || event.metaKey; 10860 break; // clear on ctrl or command +end 10861 case 36: if (event.ctrlKey || event.metaKey) { 10862 $.datepicker._gotoToday(event.target); 10863 } 10864 handled = event.ctrlKey || event.metaKey; 10865 break; // current on ctrl or command +home 10866 case 37: if (event.ctrlKey || event.metaKey) { 10867 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); 10868 } 10869 handled = event.ctrlKey || event.metaKey; 10870 // -1 day on ctrl or command +left 10871 if (event.originalEvent.altKey) { 10872 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10873 -$.datepicker._get(inst, "stepBigMonths") : 10874 -$.datepicker._get(inst, "stepMonths")), "M"); 10875 } 10876 // next month/year on alt +left on Mac 10877 break; 10878 case 38: if (event.ctrlKey || event.metaKey) { 10879 $.datepicker._adjustDate(event.target, -7, "D"); 10880 } 10881 handled = event.ctrlKey || event.metaKey; 10882 break; // -1 week on ctrl or command +up 10883 case 39: if (event.ctrlKey || event.metaKey) { 10884 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); 10885 } 10886 handled = event.ctrlKey || event.metaKey; 10887 // +1 day on ctrl or command +right 10888 if (event.originalEvent.altKey) { 10889 $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10890 +$.datepicker._get(inst, "stepBigMonths") : 10891 +$.datepicker._get(inst, "stepMonths")), "M"); 10892 } 10893 // next month/year on alt +right 10894 break; 10895 case 40: if (event.ctrlKey || event.metaKey) { 10896 $.datepicker._adjustDate(event.target, +7, "D"); 10897 } 10898 handled = event.ctrlKey || event.metaKey; 10899 break; // +1 week on ctrl or command +down 10900 default: handled = false; 10901 } 10902 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home 10903 $.datepicker._showDatepicker(this); 10904 } else { 10905 handled = false; 10906 } 10907 10908 if (handled) { 10909 event.preventDefault(); 10910 event.stopPropagation(); 10911 } 10912 }, 10913 10914 /* Filter entered characters - based on date format. */ 10915 _doKeyPress: function(event) { 10916 var chars, chr, 10917 inst = $.datepicker._getInst(event.target); 10918 10919 if ($.datepicker._get(inst, "constrainInput")) { 10920 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); 10921 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); 10922 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); 10923 } 10924 }, 10925 10926 /* Synchronise manual entry and field/alternate field. */ 10927 _doKeyUp: function(event) { 10928 var date, 10929 inst = $.datepicker._getInst(event.target); 10930 10931 if (inst.input.val() !== inst.lastVal) { 10932 try { 10933 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 10934 (inst.input ? inst.input.val() : null), 10935 $.datepicker._getFormatConfig(inst)); 10936 10937 if (date) { // only if valid 10938 $.datepicker._setDateFromField(inst); 10939 $.datepicker._updateAlternate(inst); 10940 $.datepicker._updateDatepicker(inst); 10941 } 10942 } 10943 catch (err) { 10944 } 10945 } 10946 return true; 10947 }, 10948 10949 /* Pop-up the date picker for a given input field. 10950 * If false returned from beforeShow event handler do not show. 10951 * @param input element - the input field attached to the date picker or 10952 * event - if triggered by focus 10953 */ 10954 _showDatepicker: function(input) { 10955 input = input.target || input; 10956 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger 10957 input = $("input", input.parentNode)[0]; 10958 } 10959 10960 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here 10961 return; 10962 } 10963 10964 var inst, beforeShow, beforeShowSettings, isFixed, 10965 offset, showAnim, duration; 10966 10967 inst = $.datepicker._getInst(input); 10968 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { 10969 $.datepicker._curInst.dpDiv.stop(true, true); 10970 if ( inst && $.datepicker._datepickerShowing ) { 10971 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 10972 } 10973 } 10974 10975 beforeShow = $.datepicker._get(inst, "beforeShow"); 10976 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 10977 if(beforeShowSettings === false){ 10978 return; 10979 } 10980 extendRemove(inst.settings, beforeShowSettings); 10981 10982 inst.lastVal = null; 10983 $.datepicker._lastInput = input; 10984 $.datepicker._setDateFromField(inst); 10985 10986 if ($.datepicker._inDialog) { // hide cursor 10987 input.value = ""; 10988 } 10989 if (!$.datepicker._pos) { // position below input 10990 $.datepicker._pos = $.datepicker._findPos(input); 10991 $.datepicker._pos[1] += input.offsetHeight; // add the height 10992 } 10993 10994 isFixed = false; 10995 $(input).parents().each(function() { 10996 isFixed |= $(this).css("position") === "fixed"; 10997 return !isFixed; 10998 }); 10999 11000 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 11001 $.datepicker._pos = null; 11002 //to avoid flashes on Firefox 11003 inst.dpDiv.empty(); 11004 // determine sizing offscreen 11005 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); 11006 $.datepicker._updateDatepicker(inst); 11007 // fix width for dynamic number of date pickers 11008 // and adjust position before showing 11009 offset = $.datepicker._checkOffset(inst, offset, isFixed); 11010 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 11011 "static" : (isFixed ? "fixed" : "absolute")), display: "none", 11012 left: offset.left + "px", top: offset.top + "px"}); 11013 11014 if (!inst.inline) { 11015 showAnim = $.datepicker._get(inst, "showAnim"); 11016 duration = $.datepicker._get(inst, "duration"); 11017 inst.dpDiv.zIndex($(input).zIndex()+1); 11018 $.datepicker._datepickerShowing = true; 11019 11020 if ( $.effects && $.effects.effect[ showAnim ] ) { 11021 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); 11022 } else { 11023 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); 11024 } 11025 11026 if ( $.datepicker._shouldFocusInput( inst ) ) { 11027 inst.input.focus(); 11028 } 11029 11030 $.datepicker._curInst = inst; 11031 } 11032 }, 11033 11034 /* Generate the date picker content. */ 11035 _updateDatepicker: function(inst) { 11036 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 11037 instActive = inst; // for delegate hover events 11038 inst.dpDiv.empty().append(this._generateHTML(inst)); 11039 this._attachHandlers(inst); 11040 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); 11041 11042 var origyearshtml, 11043 numMonths = this._getNumberOfMonths(inst), 11044 cols = numMonths[1], 11045 width = 17; 11046 11047 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); 11048 if (cols > 1) { 11049 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); 11050 } 11051 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + 11052 "Class"]("ui-datepicker-multi"); 11053 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + 11054 "Class"]("ui-datepicker-rtl"); 11055 11056 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 11057 inst.input.focus(); 11058 } 11059 11060 // deffered render of the years select (to avoid flashes on Firefox) 11061 if( inst.yearshtml ){ 11062 origyearshtml = inst.yearshtml; 11063 setTimeout(function(){ 11064 //assure that inst.yearshtml didn't change. 11065 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 11066 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); 11067 } 11068 origyearshtml = inst.yearshtml = null; 11069 }, 0); 11070 } 11071 }, 11072 11073 // #6694 - don't focus the input if it's already focused 11074 // this breaks the change event in IE 11075 // Support: IE and jQuery <1.9 11076 _shouldFocusInput: function( inst ) { 11077 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 11078 }, 11079 11080 /* Check positioning to remain on screen. */ 11081 _checkOffset: function(inst, offset, isFixed) { 11082 var dpWidth = inst.dpDiv.outerWidth(), 11083 dpHeight = inst.dpDiv.outerHeight(), 11084 inputWidth = inst.input ? inst.input.outerWidth() : 0, 11085 inputHeight = inst.input ? inst.input.outerHeight() : 0, 11086 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), 11087 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 11088 11089 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); 11090 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; 11091 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 11092 11093 // now check if datepicker is showing outside window viewport - move to a better place if so. 11094 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 11095 Math.abs(offset.left + dpWidth - viewWidth) : 0); 11096 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 11097 Math.abs(dpHeight + inputHeight) : 0); 11098 11099 return offset; 11100 }, 11101 11102 /* Find an object's position on the screen. */ 11103 _findPos: function(obj) { 11104 var position, 11105 inst = this._getInst(obj), 11106 isRTL = this._get(inst, "isRTL"); 11107 11108 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { 11109 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; 11110 } 11111 11112 position = $(obj).offset(); 11113 return [position.left, position.top]; 11114 }, 11115 11116 /* Hide the date picker from view. 11117 * @param input element - the input field attached to the date picker 11118 */ 11119 _hideDatepicker: function(input) { 11120 var showAnim, duration, postProcess, onClose, 11121 inst = this._curInst; 11122 11123 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { 11124 return; 11125 } 11126 11127 if (this._datepickerShowing) { 11128 showAnim = this._get(inst, "showAnim"); 11129 duration = this._get(inst, "duration"); 11130 postProcess = function() { 11131 $.datepicker._tidyDialog(inst); 11132 }; 11133 11134 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 11135 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 11136 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); 11137 } else { 11138 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : 11139 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); 11140 } 11141 11142 if (!showAnim) { 11143 postProcess(); 11144 } 11145 this._datepickerShowing = false; 11146 11147 onClose = this._get(inst, "onClose"); 11148 if (onClose) { 11149 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); 11150 } 11151 11152 this._lastInput = null; 11153 if (this._inDialog) { 11154 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); 11155 if ($.blockUI) { 11156 $.unblockUI(); 11157 $("body").append(this.dpDiv); 11158 } 11159 } 11160 this._inDialog = false; 11161 } 11162 }, 11163 11164 /* Tidy up after a dialog display. */ 11165 _tidyDialog: function(inst) { 11166 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); 11167 }, 11168 11169 /* Close date picker if clicked elsewhere. */ 11170 _checkExternalClick: function(event) { 11171 if (!$.datepicker._curInst) { 11172 return; 11173 } 11174 11175 var $target = $(event.target), 11176 inst = $.datepicker._getInst($target[0]); 11177 11178 if ( ( ( $target[0].id !== $.datepicker._mainDivId && 11179 $target.parents("#" + $.datepicker._mainDivId).length === 0 && 11180 !$target.hasClass($.datepicker.markerClassName) && 11181 !$target.closest("." + $.datepicker._triggerClass).length && 11182 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 11183 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { 11184 $.datepicker._hideDatepicker(); 11185 } 11186 }, 11187 11188 /* Adjust one of the date sub-fields. */ 11189 _adjustDate: function(id, offset, period) { 11190 var target = $(id), 11191 inst = this._getInst(target[0]); 11192 11193 if (this._isDisabledDatepicker(target[0])) { 11194 return; 11195 } 11196 this._adjustInstDate(inst, offset + 11197 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning 11198 period); 11199 this._updateDatepicker(inst); 11200 }, 11201 11202 /* Action for current link. */ 11203 _gotoToday: function(id) { 11204 var date, 11205 target = $(id), 11206 inst = this._getInst(target[0]); 11207 11208 if (this._get(inst, "gotoCurrent") && inst.currentDay) { 11209 inst.selectedDay = inst.currentDay; 11210 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 11211 inst.drawYear = inst.selectedYear = inst.currentYear; 11212 } else { 11213 date = new Date(); 11214 inst.selectedDay = date.getDate(); 11215 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11216 inst.drawYear = inst.selectedYear = date.getFullYear(); 11217 } 11218 this._notifyChange(inst); 11219 this._adjustDate(target); 11220 }, 11221 11222 /* Action for selecting a new month/year. */ 11223 _selectMonthYear: function(id, select, period) { 11224 var target = $(id), 11225 inst = this._getInst(target[0]); 11226 11227 inst["selected" + (period === "M" ? "Month" : "Year")] = 11228 inst["draw" + (period === "M" ? "Month" : "Year")] = 11229 parseInt(select.options[select.selectedIndex].value,10); 11230 11231 this._notifyChange(inst); 11232 this._adjustDate(target); 11233 }, 11234 11235 /* Action for selecting a day. */ 11236 _selectDay: function(id, month, year, td) { 11237 var inst, 11238 target = $(id); 11239 11240 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 11241 return; 11242 } 11243 11244 inst = this._getInst(target[0]); 11245 inst.selectedDay = inst.currentDay = $("a", td).html(); 11246 inst.selectedMonth = inst.currentMonth = month; 11247 inst.selectedYear = inst.currentYear = year; 11248 this._selectDate(id, this._formatDate(inst, 11249 inst.currentDay, inst.currentMonth, inst.currentYear)); 11250 }, 11251 11252 /* Erase the input field and hide the date picker. */ 11253 _clearDate: function(id) { 11254 var target = $(id); 11255 this._selectDate(target, ""); 11256 }, 11257 11258 /* Update the input field with the selected date. */ 11259 _selectDate: function(id, dateStr) { 11260 var onSelect, 11261 target = $(id), 11262 inst = this._getInst(target[0]); 11263 11264 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 11265 if (inst.input) { 11266 inst.input.val(dateStr); 11267 } 11268 this._updateAlternate(inst); 11269 11270 onSelect = this._get(inst, "onSelect"); 11271 if (onSelect) { 11272 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 11273 } else if (inst.input) { 11274 inst.input.trigger("change"); // fire the change event 11275 } 11276 11277 if (inst.inline){ 11278 this._updateDatepicker(inst); 11279 } else { 11280 this._hideDatepicker(); 11281 this._lastInput = inst.input[0]; 11282 if (typeof(inst.input[0]) !== "object") { 11283 inst.input.focus(); // restore focus 11284 } 11285 this._lastInput = null; 11286 } 11287 }, 11288 11289 /* Update any alternate field to synchronise with the main field. */ 11290 _updateAlternate: function(inst) { 11291 var altFormat, date, dateStr, 11292 altField = this._get(inst, "altField"); 11293 11294 if (altField) { // update alternate field too 11295 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); 11296 date = this._getDate(inst); 11297 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 11298 $(altField).each(function() { $(this).val(dateStr); }); 11299 } 11300 }, 11301 11302 /* Set as beforeShowDay function to prevent selection of weekends. 11303 * @param date Date - the date to customise 11304 * @return [boolean, string] - is this date selectable?, what is its CSS class? 11305 */ 11306 noWeekends: function(date) { 11307 var day = date.getDay(); 11308 return [(day > 0 && day < 6), ""]; 11309 }, 11310 11311 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 11312 * @param date Date - the date to get the week for 11313 * @return number - the number of the week within the year that contains this date 11314 */ 11315 iso8601Week: function(date) { 11316 var time, 11317 checkDate = new Date(date.getTime()); 11318 11319 // Find Thursday of this week starting on Monday 11320 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 11321 11322 time = checkDate.getTime(); 11323 checkDate.setMonth(0); // Compare with Jan 1 11324 checkDate.setDate(1); 11325 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 11326 }, 11327 11328 /* Parse a string value into a date object. 11329 * See formatDate below for the possible formats. 11330 * 11331 * @param format string - the expected format of the date 11332 * @param value string - the date in the above format 11333 * @param settings Object - attributes include: 11334 * shortYearCutoff number - the cutoff year for determining the century (optional) 11335 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 11336 * dayNames string[7] - names of the days from Sunday (optional) 11337 * monthNamesShort string[12] - abbreviated names of the months (optional) 11338 * monthNames string[12] - names of the months (optional) 11339 * @return Date - the extracted date value or null if value is blank 11340 */ 11341 parseDate: function (format, value, settings) { 11342 if (format == null || value == null) { 11343 throw "Invalid arguments"; 11344 } 11345 11346 value = (typeof value === "object" ? value.toString() : value + ""); 11347 if (value === "") { 11348 return null; 11349 } 11350 11351 var iFormat, dim, extra, 11352 iValue = 0, 11353 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, 11354 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 11355 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), 11356 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 11357 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 11358 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 11359 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 11360 year = -1, 11361 month = -1, 11362 day = -1, 11363 doy = -1, 11364 literal = false, 11365 date, 11366 // Check whether a format character is doubled 11367 lookAhead = function(match) { 11368 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 11369 if (matches) { 11370 iFormat++; 11371 } 11372 return matches; 11373 }, 11374 // Extract a number from the string value 11375 getNumber = function(match) { 11376 var isDoubled = lookAhead(match), 11377 size = (match === "@" ? 14 : (match === "!" ? 20 : 11378 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), 11379 digits = new RegExp("^\\d{1," + size + "}"), 11380 num = value.substring(iValue).match(digits); 11381 if (!num) { 11382 throw "Missing number at position " + iValue; 11383 } 11384 iValue += num[0].length; 11385 return parseInt(num[0], 10); 11386 }, 11387 // Extract a name from the string value and convert to an index 11388 getName = function(match, shortNames, longNames) { 11389 var index = -1, 11390 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 11391 return [ [k, v] ]; 11392 }).sort(function (a, b) { 11393 return -(a[1].length - b[1].length); 11394 }); 11395 11396 $.each(names, function (i, pair) { 11397 var name = pair[1]; 11398 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { 11399 index = pair[0]; 11400 iValue += name.length; 11401 return false; 11402 } 11403 }); 11404 if (index !== -1) { 11405 return index + 1; 11406 } else { 11407 throw "Unknown name at position " + iValue; 11408 } 11409 }, 11410 // Confirm that a literal character matches the string value 11411 checkLiteral = function() { 11412 if (value.charAt(iValue) !== format.charAt(iFormat)) { 11413 throw "Unexpected literal at position " + iValue; 11414 } 11415 iValue++; 11416 }; 11417 11418 for (iFormat = 0; iFormat < format.length; iFormat++) { 11419 if (literal) { 11420 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 11421 literal = false; 11422 } else { 11423 checkLiteral(); 11424 } 11425 } else { 11426 switch (format.charAt(iFormat)) { 11427 case "d": 11428 day = getNumber("d"); 11429 break; 11430 case "D": 11431 getName("D", dayNamesShort, dayNames); 11432 break; 11433 case "o": 11434 doy = getNumber("o"); 11435 break; 11436 case "m": 11437 month = getNumber("m"); 11438 break; 11439 case "M": 11440 month = getName("M", monthNamesShort, monthNames); 11441 break; 11442 case "y": 11443 year = getNumber("y"); 11444 break; 11445 case "@": 11446 date = new Date(getNumber("@")); 11447 year = date.getFullYear(); 11448 month = date.getMonth() + 1; 11449 day = date.getDate(); 11450 break; 11451 case "!": 11452 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); 11453 year = date.getFullYear(); 11454 month = date.getMonth() + 1; 11455 day = date.getDate(); 11456 break; 11457 case "'": 11458 if (lookAhead("'")){ 11459 checkLiteral(); 11460 } else { 11461 literal = true; 11462 } 11463 break; 11464 default: 11465 checkLiteral(); 11466 } 11467 } 11468 } 11469 11470 if (iValue < value.length){ 11471 extra = value.substr(iValue); 11472 if (!/^\s+/.test(extra)) { 11473 throw "Extra/unparsed characters found in date: " + extra; 11474 } 11475 } 11476 11477 if (year === -1) { 11478 year = new Date().getFullYear(); 11479 } else if (year < 100) { 11480 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 11481 (year <= shortYearCutoff ? 0 : -100); 11482 } 11483 11484 if (doy > -1) { 11485 month = 1; 11486 day = doy; 11487 do { 11488 dim = this._getDaysInMonth(year, month - 1); 11489 if (day <= dim) { 11490 break; 11491 } 11492 month++; 11493 day -= dim; 11494 } while (true); 11495 } 11496 11497 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 11498 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { 11499 throw "Invalid date"; // E.g. 31/02/00 11500 } 11501 return date; 11502 }, 11503 11504 /* Standard date formats. */ 11505 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 11506 COOKIE: "D, dd M yy", 11507 ISO_8601: "yy-mm-dd", 11508 RFC_822: "D, d M y", 11509 RFC_850: "DD, dd-M-y", 11510 RFC_1036: "D, d M y", 11511 RFC_1123: "D, d M yy", 11512 RFC_2822: "D, d M yy", 11513 RSS: "D, d M y", // RFC 822 11514 TICKS: "!", 11515 TIMESTAMP: "@", 11516 W3C: "yy-mm-dd", // ISO 8601 11517 11518 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 11519 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 11520 11521 /* Format a date object into a string value. 11522 * The format can be combinations of the following: 11523 * d - day of month (no leading zero) 11524 * dd - day of month (two digit) 11525 * o - day of year (no leading zeros) 11526 * oo - day of year (three digit) 11527 * D - day name short 11528 * DD - day name long 11529 * m - month of year (no leading zero) 11530 * mm - month of year (two digit) 11531 * M - month name short 11532 * MM - month name long 11533 * y - year (two digit) 11534 * yy - year (four digit) 11535 * @ - Unix timestamp (ms since 01/01/1970) 11536 * ! - Windows ticks (100ns since 01/01/0001) 11537 * "..." - literal text 11538 * '' - single quote 11539 * 11540 * @param format string - the desired format of the date 11541 * @param date Date - the date value to format 11542 * @param settings Object - attributes include: 11543 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 11544 * dayNames string[7] - names of the days from Sunday (optional) 11545 * monthNamesShort string[12] - abbreviated names of the months (optional) 11546 * monthNames string[12] - names of the months (optional) 11547 * @return string - the date in the above format 11548 */ 11549 formatDate: function (format, date, settings) { 11550 if (!date) { 11551 return ""; 11552 } 11553 11554 var iFormat, 11555 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, 11556 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, 11557 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, 11558 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, 11559 // Check whether a format character is doubled 11560 lookAhead = function(match) { 11561 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 11562 if (matches) { 11563 iFormat++; 11564 } 11565 return matches; 11566 }, 11567 // Format a number, with leading zero if necessary 11568 formatNumber = function(match, value, len) { 11569 var num = "" + value; 11570 if (lookAhead(match)) { 11571 while (num.length < len) { 11572 num = "0" + num; 11573 } 11574 } 11575 return num; 11576 }, 11577 // Format a name, short or long as requested 11578 formatName = function(match, value, shortNames, longNames) { 11579 return (lookAhead(match) ? longNames[value] : shortNames[value]); 11580 }, 11581 output = "", 11582 literal = false; 11583 11584 if (date) { 11585 for (iFormat = 0; iFormat < format.length; iFormat++) { 11586 if (literal) { 11587 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 11588 literal = false; 11589 } else { 11590 output += format.charAt(iFormat); 11591 } 11592 } else { 11593 switch (format.charAt(iFormat)) { 11594 case "d": 11595 output += formatNumber("d", date.getDate(), 2); 11596 break; 11597 case "D": 11598 output += formatName("D", date.getDay(), dayNamesShort, dayNames); 11599 break; 11600 case "o": 11601 output += formatNumber("o", 11602 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 11603 break; 11604 case "m": 11605 output += formatNumber("m", date.getMonth() + 1, 2); 11606 break; 11607 case "M": 11608 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); 11609 break; 11610 case "y": 11611 output += (lookAhead("y") ? date.getFullYear() : 11612 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); 11613 break; 11614 case "@": 11615 output += date.getTime(); 11616 break; 11617 case "!": 11618 output += date.getTime() * 10000 + this._ticksTo1970; 11619 break; 11620 case "'": 11621 if (lookAhead("'")) { 11622 output += "'"; 11623 } else { 11624 literal = true; 11625 } 11626 break; 11627 default: 11628 output += format.charAt(iFormat); 11629 } 11630 } 11631 } 11632 } 11633 return output; 11634 }, 11635 11636 /* Extract all possible characters from the date format. */ 11637 _possibleChars: function (format) { 11638 var iFormat, 11639 chars = "", 11640 literal = false, 11641 // Check whether a format character is doubled 11642 lookAhead = function(match) { 11643 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); 11644 if (matches) { 11645 iFormat++; 11646 } 11647 return matches; 11648 }; 11649 11650 for (iFormat = 0; iFormat < format.length; iFormat++) { 11651 if (literal) { 11652 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { 11653 literal = false; 11654 } else { 11655 chars += format.charAt(iFormat); 11656 } 11657 } else { 11658 switch (format.charAt(iFormat)) { 11659 case "d": case "m": case "y": case "@": 11660 chars += "0123456789"; 11661 break; 11662 case "D": case "M": 11663 return null; // Accept anything 11664 case "'": 11665 if (lookAhead("'")) { 11666 chars += "'"; 11667 } else { 11668 literal = true; 11669 } 11670 break; 11671 default: 11672 chars += format.charAt(iFormat); 11673 } 11674 } 11675 } 11676 return chars; 11677 }, 11678 11679 /* Get a setting value, defaulting if necessary. */ 11680 _get: function(inst, name) { 11681 return inst.settings[name] !== undefined ? 11682 inst.settings[name] : this._defaults[name]; 11683 }, 11684 11685 /* Parse existing date and initialise date picker. */ 11686 _setDateFromField: function(inst, noDefault) { 11687 if (inst.input.val() === inst.lastVal) { 11688 return; 11689 } 11690 11691 var dateFormat = this._get(inst, "dateFormat"), 11692 dates = inst.lastVal = inst.input ? inst.input.val() : null, 11693 defaultDate = this._getDefaultDate(inst), 11694 date = defaultDate, 11695 settings = this._getFormatConfig(inst); 11696 11697 try { 11698 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 11699 } catch (event) { 11700 dates = (noDefault ? "" : dates); 11701 } 11702 inst.selectedDay = date.getDate(); 11703 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11704 inst.drawYear = inst.selectedYear = date.getFullYear(); 11705 inst.currentDay = (dates ? date.getDate() : 0); 11706 inst.currentMonth = (dates ? date.getMonth() : 0); 11707 inst.currentYear = (dates ? date.getFullYear() : 0); 11708 this._adjustInstDate(inst); 11709 }, 11710 11711 /* Retrieve the default date shown on opening. */ 11712 _getDefaultDate: function(inst) { 11713 return this._restrictMinMax(inst, 11714 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); 11715 }, 11716 11717 /* A date may be specified as an exact value or a relative one. */ 11718 _determineDate: function(inst, date, defaultDate) { 11719 var offsetNumeric = function(offset) { 11720 var date = new Date(); 11721 date.setDate(date.getDate() + offset); 11722 return date; 11723 }, 11724 offsetString = function(offset) { 11725 try { 11726 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), 11727 offset, $.datepicker._getFormatConfig(inst)); 11728 } 11729 catch (e) { 11730 // Ignore 11731 } 11732 11733 var date = (offset.toLowerCase().match(/^c/) ? 11734 $.datepicker._getDate(inst) : null) || new Date(), 11735 year = date.getFullYear(), 11736 month = date.getMonth(), 11737 day = date.getDate(), 11738 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 11739 matches = pattern.exec(offset); 11740 11741 while (matches) { 11742 switch (matches[2] || "d") { 11743 case "d" : case "D" : 11744 day += parseInt(matches[1],10); break; 11745 case "w" : case "W" : 11746 day += parseInt(matches[1],10) * 7; break; 11747 case "m" : case "M" : 11748 month += parseInt(matches[1],10); 11749 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 11750 break; 11751 case "y": case "Y" : 11752 year += parseInt(matches[1],10); 11753 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 11754 break; 11755 } 11756 matches = pattern.exec(offset); 11757 } 11758 return new Date(year, month, day); 11759 }, 11760 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : 11761 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 11762 11763 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); 11764 if (newDate) { 11765 newDate.setHours(0); 11766 newDate.setMinutes(0); 11767 newDate.setSeconds(0); 11768 newDate.setMilliseconds(0); 11769 } 11770 return this._daylightSavingAdjust(newDate); 11771 }, 11772 11773 /* Handle switch to/from daylight saving. 11774 * Hours may be non-zero on daylight saving cut-over: 11775 * > 12 when midnight changeover, but then cannot generate 11776 * midnight datetime, so jump to 1AM, otherwise reset. 11777 * @param date (Date) the date to check 11778 * @return (Date) the corrected date 11779 */ 11780 _daylightSavingAdjust: function(date) { 11781 if (!date) { 11782 return null; 11783 } 11784 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 11785 return date; 11786 }, 11787 11788 /* Set the date(s) directly. */ 11789 _setDate: function(inst, date, noChange) { 11790 var clear = !date, 11791 origMonth = inst.selectedMonth, 11792 origYear = inst.selectedYear, 11793 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 11794 11795 inst.selectedDay = inst.currentDay = newDate.getDate(); 11796 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 11797 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 11798 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { 11799 this._notifyChange(inst); 11800 } 11801 this._adjustInstDate(inst); 11802 if (inst.input) { 11803 inst.input.val(clear ? "" : this._formatDate(inst)); 11804 } 11805 }, 11806 11807 /* Retrieve the date(s) directly. */ 11808 _getDate: function(inst) { 11809 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : 11810 this._daylightSavingAdjust(new Date( 11811 inst.currentYear, inst.currentMonth, inst.currentDay))); 11812 return startDate; 11813 }, 11814 11815 /* Attach the onxxx handlers. These are declared statically so 11816 * they work with static code transformers like Caja. 11817 */ 11818 _attachHandlers: function(inst) { 11819 var stepMonths = this._get(inst, "stepMonths"), 11820 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 11821 inst.dpDiv.find("[data-handler]").map(function () { 11822 var handler = { 11823 prev: function () { 11824 $.datepicker._adjustDate(id, -stepMonths, "M"); 11825 }, 11826 next: function () { 11827 $.datepicker._adjustDate(id, +stepMonths, "M"); 11828 }, 11829 hide: function () { 11830 $.datepicker._hideDatepicker(); 11831 }, 11832 today: function () { 11833 $.datepicker._gotoToday(id); 11834 }, 11835 selectDay: function () { 11836 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); 11837 return false; 11838 }, 11839 selectMonth: function () { 11840 $.datepicker._selectMonthYear(id, this, "M"); 11841 return false; 11842 }, 11843 selectYear: function () { 11844 $.datepicker._selectMonthYear(id, this, "Y"); 11845 return false; 11846 } 11847 }; 11848 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); 11849 }); 11850 }, 11851 11852 /* Generate the HTML for the current state of the date picker. */ 11853 _generateHTML: function(inst) { 11854 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 11855 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 11856 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 11857 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 11858 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 11859 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 11860 tempDate = new Date(), 11861 today = this._daylightSavingAdjust( 11862 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time 11863 isRTL = this._get(inst, "isRTL"), 11864 showButtonPanel = this._get(inst, "showButtonPanel"), 11865 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), 11866 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), 11867 numMonths = this._getNumberOfMonths(inst), 11868 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), 11869 stepMonths = this._get(inst, "stepMonths"), 11870 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), 11871 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 11872 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), 11873 minDate = this._getMinMaxDate(inst, "min"), 11874 maxDate = this._getMinMaxDate(inst, "max"), 11875 drawMonth = inst.drawMonth - showCurrentAtPos, 11876 drawYear = inst.drawYear; 11877 11878 if (drawMonth < 0) { 11879 drawMonth += 12; 11880 drawYear--; 11881 } 11882 if (maxDate) { 11883 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 11884 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 11885 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 11886 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 11887 drawMonth--; 11888 if (drawMonth < 0) { 11889 drawMonth = 11; 11890 drawYear--; 11891 } 11892 } 11893 } 11894 inst.drawMonth = drawMonth; 11895 inst.drawYear = drawYear; 11896 11897 prevText = this._get(inst, "prevText"); 11898 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 11899 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 11900 this._getFormatConfig(inst))); 11901 11902 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 11903 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + 11904 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : 11905 (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>")); 11906 11907 nextText = this._get(inst, "nextText"); 11908 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 11909 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 11910 this._getFormatConfig(inst))); 11911 11912 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 11913 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + 11914 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : 11915 (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>")); 11916 11917 currentText = this._get(inst, "currentText"); 11918 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); 11919 currentText = (!navigationAsDateFormat ? currentText : 11920 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 11921 11922 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'>" + 11923 this._get(inst, "closeText") + "</button>" : ""); 11924 11925 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + 11926 (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'" + 11927 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; 11928 11929 firstDay = parseInt(this._get(inst, "firstDay"),10); 11930 firstDay = (isNaN(firstDay) ? 0 : firstDay); 11931 11932 showWeek = this._get(inst, "showWeek"); 11933 dayNames = this._get(inst, "dayNames"); 11934 dayNamesMin = this._get(inst, "dayNamesMin"); 11935 monthNames = this._get(inst, "monthNames"); 11936 monthNamesShort = this._get(inst, "monthNamesShort"); 11937 beforeShowDay = this._get(inst, "beforeShowDay"); 11938 showOtherMonths = this._get(inst, "showOtherMonths"); 11939 selectOtherMonths = this._get(inst, "selectOtherMonths"); 11940 defaultDate = this._getDefaultDate(inst); 11941 html = ""; 11942 dow; 11943 for (row = 0; row < numMonths[0]; row++) { 11944 group = ""; 11945 this.maxRows = 4; 11946 for (col = 0; col < numMonths[1]; col++) { 11947 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 11948 cornerClass = " ui-corner-all"; 11949 calender = ""; 11950 if (isMultiMonth) { 11951 calender += "<div class='ui-datepicker-group"; 11952 if (numMonths[1] > 1) { 11953 switch (col) { 11954 case 0: calender += " ui-datepicker-group-first"; 11955 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; 11956 case numMonths[1]-1: calender += " ui-datepicker-group-last"; 11957 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; 11958 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 11959 } 11960 } 11961 calender += "'>"; 11962 } 11963 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 11964 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + 11965 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + 11966 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 11967 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 11968 "</div><table class='ui-datepicker-calendar'><thead>" + 11969 "<tr>"; 11970 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); 11971 for (dow = 0; dow < 7; dow++) { // days of the week 11972 day = (dow + firstDay) % 7; 11973 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + 11974 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; 11975 } 11976 calender += thead + "</tr></thead><tbody>"; 11977 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 11978 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { 11979 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 11980 } 11981 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 11982 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 11983 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 11984 this.maxRows = numRows; 11985 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 11986 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows 11987 calender += "<tr>"; 11988 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 11989 this._get(inst, "calculateWeek")(printDate) + "</td>"); 11990 for (dow = 0; dow < 7; dow++) { // create date picker days 11991 daySettings = (beforeShowDay ? 11992 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); 11993 otherMonth = (printDate.getMonth() !== drawMonth); 11994 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 11995 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 11996 tbody += "<td class='" + 11997 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends 11998 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months 11999 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key 12000 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? 12001 // or defaultDate is current printedDate and defaultDate is selectedDate 12002 " " + this._dayOverClass : "") + // highlight selected day 12003 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days 12004 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates 12005 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day 12006 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) 12007 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title 12008 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions 12009 (otherMonth && !showOtherMonths ? " " : // display for other months 12010 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 12011 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + 12012 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day 12013 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months 12014 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date 12015 printDate.setDate(printDate.getDate() + 1); 12016 printDate = this._daylightSavingAdjust(printDate); 12017 } 12018 calender += tbody + "</tr>"; 12019 } 12020 drawMonth++; 12021 if (drawMonth > 11) { 12022 drawMonth = 0; 12023 drawYear++; 12024 } 12025 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + 12026 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); 12027 group += calender; 12028 } 12029 html += group; 12030 } 12031 html += buttonPanel; 12032 inst._keyEvent = false; 12033 return html; 12034 }, 12035 12036 /* Generate the month and year header. */ 12037 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 12038 secondary, monthNames, monthNamesShort) { 12039 12040 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 12041 changeMonth = this._get(inst, "changeMonth"), 12042 changeYear = this._get(inst, "changeYear"), 12043 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), 12044 html = "<div class='ui-datepicker-title'>", 12045 monthHtml = ""; 12046 12047 // month selection 12048 if (secondary || !changeMonth) { 12049 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; 12050 } else { 12051 inMinYear = (minDate && minDate.getFullYear() === drawYear); 12052 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); 12053 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; 12054 for ( month = 0; month < 12; month++) { 12055 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { 12056 monthHtml += "<option value='" + month + "'" + 12057 (month === drawMonth ? " selected='selected'" : "") + 12058 ">" + monthNamesShort[month] + "</option>"; 12059 } 12060 } 12061 monthHtml += "</select>"; 12062 } 12063 12064 if (!showMonthAfterYear) { 12065 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); 12066 } 12067 12068 // year selection 12069 if ( !inst.yearshtml ) { 12070 inst.yearshtml = ""; 12071 if (secondary || !changeYear) { 12072 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 12073 } else { 12074 // determine range of years to display 12075 years = this._get(inst, "yearRange").split(":"); 12076 thisYear = new Date().getFullYear(); 12077 determineYear = function(value) { 12078 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : 12079 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : 12080 parseInt(value, 10))); 12081 return (isNaN(year) ? thisYear : year); 12082 }; 12083 year = determineYear(years[0]); 12084 endYear = Math.max(year, determineYear(years[1] || "")); 12085 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 12086 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 12087 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; 12088 for (; year <= endYear; year++) { 12089 inst.yearshtml += "<option value='" + year + "'" + 12090 (year === drawYear ? " selected='selected'" : "") + 12091 ">" + year + "</option>"; 12092 } 12093 inst.yearshtml += "</select>"; 12094 12095 html += inst.yearshtml; 12096 inst.yearshtml = null; 12097 } 12098 } 12099 12100 html += this._get(inst, "yearSuffix"); 12101 if (showMonthAfterYear) { 12102 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; 12103 } 12104 html += "</div>"; // Close datepicker_header 12105 return html; 12106 }, 12107 12108 /* Adjust one of the date sub-fields. */ 12109 _adjustInstDate: function(inst, offset, period) { 12110 var year = inst.drawYear + (period === "Y" ? offset : 0), 12111 month = inst.drawMonth + (period === "M" ? offset : 0), 12112 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), 12113 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); 12114 12115 inst.selectedDay = date.getDate(); 12116 inst.drawMonth = inst.selectedMonth = date.getMonth(); 12117 inst.drawYear = inst.selectedYear = date.getFullYear(); 12118 if (period === "M" || period === "Y") { 12119 this._notifyChange(inst); 12120 } 12121 }, 12122 12123 /* Ensure a date is within any min/max bounds. */ 12124 _restrictMinMax: function(inst, date) { 12125 var minDate = this._getMinMaxDate(inst, "min"), 12126 maxDate = this._getMinMaxDate(inst, "max"), 12127 newDate = (minDate && date < minDate ? minDate : date); 12128 return (maxDate && newDate > maxDate ? maxDate : newDate); 12129 }, 12130 12131 /* Notify change of month/year. */ 12132 _notifyChange: function(inst) { 12133 var onChange = this._get(inst, "onChangeMonthYear"); 12134 if (onChange) { 12135 onChange.apply((inst.input ? inst.input[0] : null), 12136 [inst.selectedYear, inst.selectedMonth + 1, inst]); 12137 } 12138 }, 12139 12140 /* Determine the number of months to show. */ 12141 _getNumberOfMonths: function(inst) { 12142 var numMonths = this._get(inst, "numberOfMonths"); 12143 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); 12144 }, 12145 12146 /* Determine the current maximum date - ensure no time components are set. */ 12147 _getMinMaxDate: function(inst, minMax) { 12148 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); 12149 }, 12150 12151 /* Find the number of days in a given month. */ 12152 _getDaysInMonth: function(year, month) { 12153 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 12154 }, 12155 12156 /* Find the day of the week of the first of a month. */ 12157 _getFirstDayOfMonth: function(year, month) { 12158 return new Date(year, month, 1).getDay(); 12159 }, 12160 12161 /* Determines if we should allow a "next/prev" month display change. */ 12162 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 12163 var numMonths = this._getNumberOfMonths(inst), 12164 date = this._daylightSavingAdjust(new Date(curYear, 12165 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 12166 12167 if (offset < 0) { 12168 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 12169 } 12170 return this._isInRange(inst, date); 12171 }, 12172 12173 /* Is the given date in the accepted range? */ 12174 _isInRange: function(inst, date) { 12175 var yearSplit, currentYear, 12176 minDate = this._getMinMaxDate(inst, "min"), 12177 maxDate = this._getMinMaxDate(inst, "max"), 12178 minYear = null, 12179 maxYear = null, 12180 years = this._get(inst, "yearRange"); 12181 if (years){ 12182 yearSplit = years.split(":"); 12183 currentYear = new Date().getFullYear(); 12184 minYear = parseInt(yearSplit[0], 10); 12185 maxYear = parseInt(yearSplit[1], 10); 12186 if ( yearSplit[0].match(/[+\-].*/) ) { 12187 minYear += currentYear; 12188 } 12189 if ( yearSplit[1].match(/[+\-].*/) ) { 12190 maxYear += currentYear; 12191 } 12192 } 12193 12194 return ((!minDate || date.getTime() >= minDate.getTime()) && 12195 (!maxDate || date.getTime() <= maxDate.getTime()) && 12196 (!minYear || date.getFullYear() >= minYear) && 12197 (!maxYear || date.getFullYear() <= maxYear)); 12198 }, 12199 12200 /* Provide the configuration settings for formatting/parsing. */ 12201 _getFormatConfig: function(inst) { 12202 var shortYearCutoff = this._get(inst, "shortYearCutoff"); 12203 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : 12204 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 12205 return {shortYearCutoff: shortYearCutoff, 12206 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), 12207 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; 12208 }, 12209 12210 /* Format the given date for display. */ 12211 _formatDate: function(inst, day, month, year) { 12212 if (!day) { 12213 inst.currentDay = inst.selectedDay; 12214 inst.currentMonth = inst.selectedMonth; 12215 inst.currentYear = inst.selectedYear; 12216 } 12217 var date = (day ? (typeof day === "object" ? day : 12218 this._daylightSavingAdjust(new Date(year, month, day))) : 12219 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 12220 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); 12221 } 12222}); 12223 12224/* 12225 * Bind hover events for datepicker elements. 12226 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 12227 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 12228 */ 12229function bindHover(dpDiv) { 12230 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 12231 return dpDiv.delegate(selector, "mouseout", function() { 12232 $(this).removeClass("ui-state-hover"); 12233 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 12234 $(this).removeClass("ui-datepicker-prev-hover"); 12235 } 12236 if (this.className.indexOf("ui-datepicker-next") !== -1) { 12237 $(this).removeClass("ui-datepicker-next-hover"); 12238 } 12239 }) 12240 .delegate(selector, "mouseover", function(){ 12241 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 12242 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); 12243 $(this).addClass("ui-state-hover"); 12244 if (this.className.indexOf("ui-datepicker-prev") !== -1) { 12245 $(this).addClass("ui-datepicker-prev-hover"); 12246 } 12247 if (this.className.indexOf("ui-datepicker-next") !== -1) { 12248 $(this).addClass("ui-datepicker-next-hover"); 12249 } 12250 } 12251 }); 12252} 12253 12254/* jQuery extend now ignores nulls! */ 12255function extendRemove(target, props) { 12256 $.extend(target, props); 12257 for (var name in props) { 12258 if (props[name] == null) { 12259 target[name] = props[name]; 12260 } 12261 } 12262 return target; 12263} 12264 12265/* Invoke the datepicker functionality. 12266 @param options string - a command, optionally followed by additional parameters or 12267 Object - settings for attaching new datepicker functionality 12268 @return jQuery object */ 12269$.fn.datepicker = function(options){ 12270 12271 /* Verify an empty collection wasn't passed - Fixes #6976 */ 12272 if ( !this.length ) { 12273 return this; 12274 } 12275 12276 /* Initialise the date picker. */ 12277 if (!$.datepicker.initialized) { 12278 $(document).mousedown($.datepicker._checkExternalClick); 12279 $.datepicker.initialized = true; 12280 } 12281 12282 /* Append datepicker main container to body if not exist. */ 12283 if ($("#"+$.datepicker._mainDivId).length === 0) { 12284 $("body").append($.datepicker.dpDiv); 12285 } 12286 12287 var otherArgs = Array.prototype.slice.call(arguments, 1); 12288 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { 12289 return $.datepicker["_" + options + "Datepicker"]. 12290 apply($.datepicker, [this[0]].concat(otherArgs)); 12291 } 12292 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { 12293 return $.datepicker["_" + options + "Datepicker"]. 12294 apply($.datepicker, [this[0]].concat(otherArgs)); 12295 } 12296 return this.each(function() { 12297 typeof options === "string" ? 12298 $.datepicker["_" + options + "Datepicker"]. 12299 apply($.datepicker, [this].concat(otherArgs)) : 12300 $.datepicker._attachDatepicker(this, options); 12301 }); 12302}; 12303 12304$.datepicker = new Datepicker(); // singleton instance 12305$.datepicker.initialized = false; 12306$.datepicker.uuid = new Date().getTime(); 12307$.datepicker.version = "1.10.3"; 12308 12309})(jQuery);
12310(function( $, undefined ) { 12311 12312$.widget( "ui.menu", { 12313 version: "1.10.3", 12314 defaultElement: "<ul>", 12315 delay: 300, 12316 options: { 12317 icons: { 12318 submenu: "ui-icon-carat-1-e" 12319 }, 12320 menus: "ul", 12321 position: { 12322 my: "left top", 12323 at: "right top" 12324 }, 12325 role: "menu", 12326 12327 // callbacks 12328 blur: null, 12329 focus: null, 12330 select: null 12331 }, 12332 12333 _create: function() { 12334 this.activeMenu = this.element; 12335 // flag used to prevent firing of the click handler 12336 // as the event bubbles up through nested menus 12337 this.mouseHandled = false; 12338 this.element 12339 .uniqueId() 12340 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 12341 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 12342 .attr({ 12343 role: this.options.role, 12344 tabIndex: 0 12345 }) 12346 // need to catch all clicks on disabled menu 12347 // not possible through _on 12348 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 12349 if ( this.options.disabled ) { 12350 event.preventDefault(); 12351 } 12352 }, this )); 12353 12354 if ( this.options.disabled ) { 12355 this.element 12356 .addClass( "ui-state-disabled" ) 12357 .attr( "aria-disabled", "true" ); 12358 } 12359 12360 this._on({ 12361 // Prevent focus from sticking to links inside menu after clicking 12362 // them (focus should always stay on UL during navigation). 12363 "mousedown .ui-menu-item > a": function( event ) { 12364 event.preventDefault(); 12365 }, 12366 "click .ui-state-disabled > a": function( event ) { 12367 event.preventDefault(); 12368 }, 12369 "click .ui-menu-item:has(a)": function( event ) { 12370 var target = $( event.target ).closest( ".ui-menu-item" ); 12371 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 12372 this.mouseHandled = true; 12373 12374 this.select( event ); 12375 // Open submenu on click 12376 if ( target.has( ".ui-menu" ).length ) { 12377 this.expand( event ); 12378 } else if ( !this.element.is( ":focus" ) ) { 12379 // Redirect focus to the menu 12380 this.element.trigger( "focus", [ true ] ); 12381 12382 // If the active item is on the top level, let it stay active. 12383 // Otherwise, blur the active item since it is no longer visible. 12384 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 12385 clearTimeout( this.timer ); 12386 } 12387 } 12388 } 12389 }, 12390 "mouseenter .ui-menu-item": function( event ) { 12391 var target = $( event.currentTarget ); 12392 // Remove ui-state-active class from siblings of the newly focused menu item 12393 // to avoid a jump caused by adjacent elements both having a class with a border 12394 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 12395 this.focus( event, target ); 12396 }, 12397 mouseleave: "collapseAll", 12398 "mouseleave .ui-menu": "collapseAll", 12399 focus: function( event, keepActiveItem ) { 12400 // If there's already an active item, keep it active 12401 // If not, activate the first item 12402 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 12403 12404 if ( !keepActiveItem ) { 12405 this.focus( event, item ); 12406 } 12407 }, 12408 blur: function( event ) { 12409 this._delay(function() { 12410 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 12411 this.collapseAll( event ); 12412 } 12413 }); 12414 }, 12415 keydown: "_keydown" 12416 }); 12417 12418 this.refresh(); 12419
vendor: 133,438 bytes, lines 12420-17635
12420 // Clicks outside of a menu collapse any open menus 12421 this._on( this.document, { 12422 click: function( event ) { 12423 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 12424 this.collapseAll( event ); 12425 } 12426 12427 // Reset the mouseHandled flag 12428 this.mouseHandled = false; 12429 } 12430 }); 12431 }, 12432 12433 _destroy: function() { 12434 // Destroy (sub)menus 12435 this.element 12436 .removeAttr( "aria-activedescendant" ) 12437 .find( ".ui-menu" ).addBack() 12438 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 12439 .removeAttr( "role" ) 12440 .removeAttr( "tabIndex" ) 12441 .removeAttr( "aria-labelledby" ) 12442 .removeAttr( "aria-expanded" ) 12443 .removeAttr( "aria-hidden" ) 12444 .removeAttr( "aria-disabled" ) 12445 .removeUniqueId() 12446 .show(); 12447 12448 // Destroy menu items 12449 this.element.find( ".ui-menu-item" ) 12450 .removeClass( "ui-menu-item" ) 12451 .removeAttr( "role" ) 12452 .removeAttr( "aria-disabled" ) 12453 .children( "a" ) 12454 .removeUniqueId() 12455 .removeClass( "ui-corner-all ui-state-hover" ) 12456 .removeAttr( "tabIndex" ) 12457 .removeAttr( "role" ) 12458 .removeAttr( "aria-haspopup" ) 12459 .children().each( function() { 12460 var elem = $( this ); 12461 if ( elem.data( "ui-menu-submenu-carat" ) ) { 12462 elem.remove(); 12463 } 12464 }); 12465 12466 // Destroy menu dividers 12467 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 12468 }, 12469 12470 _keydown: function( event ) { 12471 /*jshint maxcomplexity:20*/ 12472 var match, prev, character, skip, regex, 12473 preventDefault = true; 12474 12475 function escape( value ) { 12476 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 12477 } 12478 12479 switch ( event.keyCode ) { 12480 case $.ui.keyCode.PAGE_UP: 12481 this.previousPage( event ); 12482 break; 12483 case $.ui.keyCode.PAGE_DOWN: 12484 this.nextPage( event ); 12485 break; 12486 case $.ui.keyCode.HOME: 12487 this._move( "first", "first", event ); 12488 break; 12489 case $.ui.keyCode.END: 12490 this._move( "last", "last", event ); 12491 break; 12492 case $.ui.keyCode.UP: 12493 this.previous( event ); 12494 break; 12495 case $.ui.keyCode.DOWN: 12496 this.next( event ); 12497 break; 12498 case $.ui.keyCode.LEFT: 12499 this.collapse( event ); 12500 break; 12501 case $.ui.keyCode.RIGHT: 12502 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 12503 this.expand( event ); 12504 } 12505 break; 12506 case $.ui.keyCode.ENTER: 12507 case $.ui.keyCode.SPACE: 12508 this._activate( event ); 12509 break; 12510 case $.ui.keyCode.ESCAPE: 12511 this.collapse( event ); 12512 break; 12513 default: 12514 preventDefault = false; 12515 prev = this.previousFilter || ""; 12516 character = String.fromCharCode( event.keyCode ); 12517 skip = false; 12518 12519 clearTimeout( this.filterTimer ); 12520 12521 if ( character === prev ) { 12522 skip = true; 12523 } else { 12524 character = prev + character; 12525 } 12526 12527 regex = new RegExp( "^" + escape( character ), "i" ); 12528 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 12529 return regex.test( $( this ).children( "a" ).text() ); 12530 }); 12531 match = skip && match.index( this.active.next() ) !== -1 ? 12532 this.active.nextAll( ".ui-menu-item" ) : 12533 match; 12534 12535 // If no matches on the current filter, reset to the last character pressed 12536 // to move down the menu to the first item that starts with that character 12537 if ( !match.length ) { 12538 character = String.fromCharCode( event.keyCode ); 12539 regex = new RegExp( "^" + escape( character ), "i" ); 12540 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 12541 return regex.test( $( this ).children( "a" ).text() ); 12542 }); 12543 } 12544 12545 if ( match.length ) { 12546 this.focus( event, match ); 12547 if ( match.length > 1 ) { 12548 this.previousFilter = character; 12549 this.filterTimer = this._delay(function() { 12550 delete this.previousFilter; 12551 }, 1000 ); 12552 } else { 12553 delete this.previousFilter; 12554 } 12555 } else { 12556 delete this.previousFilter; 12557 } 12558 } 12559 12560 if ( preventDefault ) { 12561 event.preventDefault(); 12562 } 12563 }, 12564 12565 _activate: function( event ) { 12566 if ( !this.active.is( ".ui-state-disabled" ) ) { 12567 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 12568 this.expand( event ); 12569 } else { 12570 this.select( event ); 12571 } 12572 } 12573 }, 12574 12575 refresh: function() { 12576 var menus, 12577 icon = this.options.icons.submenu, 12578 submenus = this.element.find( this.options.menus ); 12579 12580 // Initialize nested menus 12581 submenus.filter( ":not(.ui-menu)" ) 12582 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 12583 .hide() 12584 .attr({ 12585 role: this.options.role, 12586 "aria-hidden": "true", 12587 "aria-expanded": "false" 12588 }) 12589 .each(function() { 12590 var menu = $( this ), 12591 item = menu.prev( "a" ), 12592 submenuCarat = $( "<span>" ) 12593 .addClass( "ui-menu-icon ui-icon " + icon ) 12594 .data( "ui-menu-submenu-carat", true ); 12595 12596 item 12597 .attr( "aria-haspopup", "true" ) 12598 .prepend( submenuCarat ); 12599 menu.attr( "aria-labelledby", item.attr( "id" ) ); 12600 }); 12601 12602 menus = submenus.add( this.element ); 12603 12604 // Don't refresh list items that are already adapted 12605 menus.children( ":not(.ui-menu-item):has(a)" ) 12606 .addClass( "ui-menu-item" ) 12607 .attr( "role", "presentation" ) 12608 .children( "a" ) 12609 .uniqueId() 12610 .addClass( "ui-corner-all" ) 12611 .attr({ 12612 tabIndex: -1, 12613 role: this._itemRole() 12614 }); 12615 12616 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 12617 menus.children( ":not(.ui-menu-item)" ).each(function() { 12618 var item = $( this ); 12619 // hyphen, em dash, en dash 12620 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { 12621 item.addClass( "ui-widget-content ui-menu-divider" ); 12622 } 12623 }); 12624 12625 // Add aria-disabled attribute to any disabled menu item 12626 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 12627 12628 // If the active item has been removed, blur the menu 12629 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 12630 this.blur(); 12631 } 12632 }, 12633 12634 _itemRole: function() { 12635 return { 12636 menu: "menuitem", 12637 listbox: "option" 12638 }[ this.options.role ]; 12639 }, 12640 12641 _setOption: function( key, value ) { 12642 if ( key === "icons" ) { 12643 this.element.find( ".ui-menu-icon" ) 12644 .removeClass( this.options.icons.submenu ) 12645 .addClass( value.submenu ); 12646 } 12647 this._super( key, value ); 12648 }, 12649 12650 focus: function( event, item ) { 12651 var nested, focused; 12652 this.blur( event, event && event.type === "focus" ); 12653 12654 this._scrollIntoView( item ); 12655 12656 this.active = item.first(); 12657 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 12658 // Only update aria-activedescendant if there's a role 12659 // otherwise we assume focus is managed elsewhere 12660 if ( this.options.role ) { 12661 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 12662 } 12663 12664 // Highlight active parent menu item, if any 12665 this.active 12666 .parent() 12667 .closest( ".ui-menu-item" ) 12668 .children( "a:first" ) 12669 .addClass( "ui-state-active" ); 12670 12671 if ( event && event.type === "keydown" ) { 12672 this._close(); 12673 } else { 12674 this.timer = this._delay(function() { 12675 this._close(); 12676 }, this.delay ); 12677 } 12678 12679 nested = item.children( ".ui-menu" ); 12680 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 12681 this._startOpening(nested); 12682 } 12683 this.activeMenu = item.parent(); 12684 12685 this._trigger( "focus", event, { item: item } ); 12686 }, 12687 12688 _scrollIntoView: function( item ) { 12689 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 12690 if ( this._hasScroll() ) { 12691 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 12692 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 12693 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 12694 scroll = this.activeMenu.scrollTop(); 12695 elementHeight = this.activeMenu.height(); 12696 itemHeight = item.height(); 12697 12698 if ( offset < 0 ) { 12699 this.activeMenu.scrollTop( scroll + offset ); 12700 } else if ( offset + itemHeight > elementHeight ) { 12701 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 12702 } 12703 } 12704 }, 12705 12706 blur: function( event, fromFocus ) { 12707 if ( !fromFocus ) { 12708 clearTimeout( this.timer ); 12709 } 12710 12711 if ( !this.active ) { 12712 return; 12713 } 12714 12715 this.active.children( "a" ).removeClass( "ui-state-focus" ); 12716 this.active = null; 12717 12718 this._trigger( "blur", event, { item: this.active } ); 12719 }, 12720 12721 _startOpening: function( submenu ) { 12722 clearTimeout( this.timer ); 12723 12724 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 12725 // shift in the submenu position when mousing over the carat icon 12726 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 12727 return; 12728 } 12729 12730 this.timer = this._delay(function() { 12731 this._close(); 12732 this._open( submenu ); 12733 }, this.delay ); 12734 }, 12735 12736 _open: function( submenu ) { 12737 var position = $.extend({ 12738 of: this.active 12739 }, this.options.position ); 12740 12741 clearTimeout( this.timer ); 12742 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 12743 .hide() 12744 .attr( "aria-hidden", "true" ); 12745 12746 submenu 12747 .show() 12748 .removeAttr( "aria-hidden" ) 12749 .attr( "aria-expanded", "true" ) 12750 .position( position ); 12751 }, 12752 12753 collapseAll: function( event, all ) { 12754 clearTimeout( this.timer ); 12755 this.timer = this._delay(function() { 12756 // If we were passed an event, look for the submenu that contains the event 12757 var currentMenu = all ? this.element : 12758 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 12759 12760 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 12761 if ( !currentMenu.length ) { 12762 currentMenu = this.element; 12763 } 12764 12765 this._close( currentMenu ); 12766 12767 this.blur( event ); 12768 this.activeMenu = currentMenu; 12769 }, this.delay ); 12770 }, 12771 12772 // With no arguments, closes the currently active menu - if nothing is active 12773 // it closes all menus. If passed an argument, it will search for menus BELOW 12774 _close: function( startMenu ) { 12775 if ( !startMenu ) { 12776 startMenu = this.active ? this.active.parent() : this.element; 12777 } 12778 12779 startMenu 12780 .find( ".ui-menu" ) 12781 .hide() 12782 .attr( "aria-hidden", "true" ) 12783 .attr( "aria-expanded", "false" ) 12784 .end() 12785 .find( "a.ui-state-active" ) 12786 .removeClass( "ui-state-active" ); 12787 }, 12788 12789 collapse: function( event ) { 12790 var newItem = this.active && 12791 this.active.parent().closest( ".ui-menu-item", this.element ); 12792 if ( newItem && newItem.length ) { 12793 this._close(); 12794 this.focus( event, newItem ); 12795 } 12796 }, 12797 12798 expand: function( event ) { 12799 var newItem = this.active && 12800 this.active 12801 .children( ".ui-menu " ) 12802 .children( ".ui-menu-item" ) 12803 .first(); 12804 12805 if ( newItem && newItem.length ) { 12806 this._open( newItem.parent() ); 12807 12808 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 12809 this._delay(function() { 12810 this.focus( event, newItem ); 12811 }); 12812 } 12813 }, 12814 12815 next: function( event ) { 12816 this._move( "next", "first", event ); 12817 }, 12818 12819 previous: function( event ) { 12820 this._move( "prev", "last", event ); 12821 }, 12822 12823 isFirstItem: function() { 12824 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 12825 }, 12826 12827 isLastItem: function() { 12828 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 12829 }, 12830 12831 _move: function( direction, filter, event ) { 12832 var next; 12833 if ( this.active ) { 12834 if ( direction === "first" || direction === "last" ) { 12835 next = this.active 12836 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 12837 .eq( -1 ); 12838 } else { 12839 next = this.active 12840 [ direction + "All" ]( ".ui-menu-item" ) 12841 .eq( 0 ); 12842 } 12843 } 12844 if ( !next || !next.length || !this.active ) { 12845 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 12846 } 12847 12848 this.focus( event, next ); 12849 }, 12850 12851 nextPage: function( event ) { 12852 var item, base, height; 12853 12854 if ( !this.active ) { 12855 this.next( event ); 12856 return; 12857 } 12858 if ( this.isLastItem() ) { 12859 return; 12860 } 12861 if ( this._hasScroll() ) { 12862 base = this.active.offset().top; 12863 height = this.element.height(); 12864 this.active.nextAll( ".ui-menu-item" ).each(function() { 12865 item = $( this ); 12866 return item.offset().top - base - height < 0; 12867 }); 12868 12869 this.focus( event, item ); 12870 } else { 12871 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 12872 [ !this.active ? "first" : "last" ]() ); 12873 } 12874 }, 12875 12876 previousPage: function( event ) { 12877 var item, base, height; 12878 if ( !this.active ) { 12879 this.next( event ); 12880 return; 12881 } 12882 if ( this.isFirstItem() ) { 12883 return; 12884 } 12885 if ( this._hasScroll() ) { 12886 base = this.active.offset().top; 12887 height = this.element.height(); 12888 this.active.prevAll( ".ui-menu-item" ).each(function() { 12889 item = $( this ); 12890 return item.offset().top - base + height > 0; 12891 }); 12892 12893 this.focus( event, item ); 12894 } else { 12895 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 12896 } 12897 }, 12898 12899 _hasScroll: function() { 12900 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 12901 }, 12902 12903 select: function( event ) { 12904 // TODO: It should never be possible to not have an active item at this 12905 // point, but the tests don't trigger mouseenter before click. 12906 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 12907 var ui = { item: this.active }; 12908 if ( !this.active.has( ".ui-menu" ).length ) { 12909 this.collapseAll( event, true ); 12910 } 12911 this._trigger( "select", event, ui ); 12912 } 12913}); 12914 12915}( jQuery )); 12916(function( $, undefined ) { 12917 12918$.widget( "ui.progressbar", { 12919 version: "1.10.3", 12920 options: { 12921 max: 100, 12922 value: 0, 12923 12924 change: null, 12925 complete: null 12926 }, 12927 12928 min: 0, 12929 12930 _create: function() { 12931 // Constrain initial value 12932 this.oldValue = this.options.value = this._constrainedValue(); 12933 12934 this.element 12935 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12936 .attr({ 12937 // Only set static values, aria-valuenow and aria-valuemax are 12938 // set inside _refreshValue() 12939 role: "progressbar", 12940 "aria-valuemin": this.min 12941 }); 12942 12943 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 12944 .appendTo( this.element ); 12945 12946 this._refreshValue(); 12947 }, 12948 12949 _destroy: function() { 12950 this.element 12951 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 12952 .removeAttr( "role" ) 12953 .removeAttr( "aria-valuemin" ) 12954 .removeAttr( "aria-valuemax" ) 12955 .removeAttr( "aria-valuenow" ); 12956 12957 this.valueDiv.remove(); 12958 }, 12959 12960 value: function( newValue ) { 12961 if ( newValue === undefined ) { 12962 return this.options.value; 12963 } 12964 12965 this.options.value = this._constrainedValue( newValue ); 12966 this._refreshValue(); 12967 }, 12968 12969 _constrainedValue: function( newValue ) { 12970 if ( newValue === undefined ) { 12971 newValue = this.options.value; 12972 } 12973 12974 this.indeterminate = newValue === false; 12975 12976 // sanitize value 12977 if ( typeof newValue !== "number" ) { 12978 newValue = 0; 12979 } 12980 12981 return this.indeterminate ? false : 12982 Math.min( this.options.max, Math.max( this.min, newValue ) ); 12983 }, 12984 12985 _setOptions: function( options ) { 12986 // Ensure "value" option is set after other values (like max) 12987 var value = options.value; 12988 delete options.value; 12989 12990 this._super( options ); 12991 12992 this.options.value = this._constrainedValue( value ); 12993 this._refreshValue(); 12994 }, 12995 12996 _setOption: function( key, value ) { 12997 if ( key === "max" ) { 12998 // Don't allow a max less than min 12999 value = Math.max( this.min, value ); 13000 } 13001 13002 this._super( key, value ); 13003 }, 13004 13005 _percentage: function() { 13006 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 13007 }, 13008 13009 _refreshValue: function() { 13010 var value = this.options.value, 13011 percentage = this._percentage(); 13012 13013 this.valueDiv 13014 .toggle( this.indeterminate || value > this.min ) 13015 .toggleClass( "ui-corner-right", value === this.options.max ) 13016 .width( percentage.toFixed(0) + "%" ); 13017 13018 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); 13019 13020 if ( this.indeterminate ) { 13021 this.element.removeAttr( "aria-valuenow" ); 13022 if ( !this.overlayDiv ) { 13023 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); 13024 } 13025 } else { 13026 this.element.attr({ 13027 "aria-valuemax": this.options.max, 13028 "aria-valuenow": value 13029 }); 13030 if ( this.overlayDiv ) { 13031 this.overlayDiv.remove(); 13032 this.overlayDiv = null; 13033 } 13034 } 13035 13036 if ( this.oldValue !== value ) { 13037 this.oldValue = value; 13038 this._trigger( "change" ); 13039 } 13040 if ( value === this.options.max ) { 13041 this._trigger( "complete" ); 13042 } 13043 } 13044}); 13045 13046})( jQuery ); 13047(function( $, undefined ) { 13048 13049// number of pages in a slider 13050// (how many times can you page up/down to go through the whole range) 13051var numPages = 5; 13052 13053$.widget( "ui.slider", $.ui.mouse, { 13054 version: "1.10.3", 13055 widgetEventPrefix: "slide", 13056 13057 options: { 13058 animate: false, 13059 distance: 0, 13060 max: 100, 13061 min: 0, 13062 orientation: "horizontal", 13063 range: false, 13064 step: 1, 13065 value: 0, 13066 values: null, 13067 13068 // callbacks 13069 change: null, 13070 slide: null, 13071 start: null, 13072 stop: null 13073 }, 13074 13075 _create: function() { 13076 this._keySliding = false; 13077 this._mouseSliding = false; 13078 this._animateOff = true; 13079 this._handleIndex = null; 13080 this._detectOrientation(); 13081 this._mouseInit(); 13082 13083 this.element 13084 .addClass( "ui-slider" + 13085 " ui-slider-" + this.orientation + 13086 " ui-widget" + 13087 " ui-widget-content" + 13088 " ui-corner-all"); 13089 13090 this._refresh(); 13091 this._setOption( "disabled", this.options.disabled ); 13092 13093 this._animateOff = false; 13094 }, 13095 13096 _refresh: function() { 13097 this._createRange(); 13098 this._createHandles(); 13099 this._setupEvents(); 13100 this._refreshValue(); 13101 }, 13102 13103 _createHandles: function() { 13104 var i, handleCount, 13105 options = this.options, 13106 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 13107 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 13108 handles = []; 13109 13110 handleCount = ( options.values && options.values.length ) || 1; 13111 13112 if ( existingHandles.length > handleCount ) { 13113 existingHandles.slice( handleCount ).remove(); 13114 existingHandles = existingHandles.slice( 0, handleCount ); 13115 } 13116 13117 for ( i = existingHandles.length; i < handleCount; i++ ) { 13118 handles.push( handle ); 13119 } 13120 13121 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 13122 13123 this.handle = this.handles.eq( 0 ); 13124 13125 this.handles.each(function( i ) { 13126 $( this ).data( "ui-slider-handle-index", i ); 13127 }); 13128 }, 13129 13130 _createRange: function() { 13131 var options = this.options, 13132 classes = ""; 13133 13134 if ( options.range ) { 13135 if ( options.range === true ) { 13136 if ( !options.values ) { 13137 options.values = [ this._valueMin(), this._valueMin() ]; 13138 } else if ( options.values.length && options.values.length !== 2 ) { 13139 options.values = [ options.values[0], options.values[0] ]; 13140 } else if ( $.isArray( options.values ) ) { 13141 options.values = options.values.slice(0); 13142 } 13143 } 13144 13145 if ( !this.range || !this.range.length ) { 13146 this.range = $( "<div></div>" ) 13147 .appendTo( this.element ); 13148 13149 classes = "ui-slider-range" + 13150 // note: this isn't the most fittingly semantic framework class for this element, 13151 // but worked best visually with a variety of themes 13152 " ui-widget-header ui-corner-all"; 13153 } else { 13154 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) 13155 // Handle range switching from true to min/max 13156 .css({ 13157 "left": "", 13158 "bottom": "" 13159 }); 13160 } 13161 13162 this.range.addClass( classes + 13163 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); 13164 } else { 13165 this.range = $([]); 13166 } 13167 }, 13168 13169 _setupEvents: function() { 13170 var elements = this.handles.add( this.range ).filter( "a" ); 13171 this._off( elements ); 13172 this._on( elements, this._handleEvents ); 13173 this._hoverable( elements ); 13174 this._focusable( elements ); 13175 }, 13176 13177 _destroy: function() { 13178 this.handles.remove(); 13179 this.range.remove(); 13180 13181 this.element 13182 .removeClass( "ui-slider" + 13183 " ui-slider-horizontal" + 13184 " ui-slider-vertical" + 13185 " ui-widget" + 13186 " ui-widget-content" + 13187 " ui-corner-all" ); 13188 13189 this._mouseDestroy(); 13190 }, 13191 13192 _mouseCapture: function( event ) { 13193 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 13194 that = this, 13195 o = this.options; 13196 13197 if ( o.disabled ) { 13198 return false; 13199 } 13200 13201 this.elementSize = { 13202 width: this.element.outerWidth(), 13203 height: this.element.outerHeight() 13204 }; 13205 this.elementOffset = this.element.offset(); 13206 13207 position = { x: event.pageX, y: event.pageY }; 13208 normValue = this._normValueFromMouse( position ); 13209 distance = this._valueMax() - this._valueMin() + 1; 13210 this.handles.each(function( i ) { 13211 var thisDistance = Math.abs( normValue - that.values(i) ); 13212 if (( distance > thisDistance ) || 13213 ( distance === thisDistance && 13214 (i === that._lastChangedValue || that.values(i) === o.min ))) { 13215 distance = thisDistance; 13216 closestHandle = $( this ); 13217 index = i; 13218 } 13219 }); 13220 13221 allowed = this._start( event, index ); 13222 if ( allowed === false ) { 13223 return false; 13224 } 13225 this._mouseSliding = true; 13226 13227 this._handleIndex = index; 13228 13229 closestHandle 13230 .addClass( "ui-state-active" ) 13231 .focus(); 13232 13233 offset = closestHandle.offset(); 13234 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 13235 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 13236 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 13237 top: event.pageY - offset.top - 13238 ( closestHandle.height() / 2 ) - 13239 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 13240 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 13241 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 13242 }; 13243 13244 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 13245 this._slide( event, index, normValue ); 13246 } 13247 this._animateOff = true; 13248 return true; 13249 }, 13250 13251 _mouseStart: function() { 13252 return true; 13253 }, 13254 13255 _mouseDrag: function( event ) { 13256 var position = { x: event.pageX, y: event.pageY }, 13257 normValue = this._normValueFromMouse( position ); 13258 13259 this._slide( event, this._handleIndex, normValue ); 13260 13261 return false; 13262 }, 13263 13264 _mouseStop: function( event ) { 13265 this.handles.removeClass( "ui-state-active" ); 13266 this._mouseSliding = false; 13267 13268 this._stop( event, this._handleIndex ); 13269 this._change( event, this._handleIndex ); 13270 13271 this._handleIndex = null; 13272 this._clickOffset = null; 13273 this._animateOff = false; 13274 13275 return false; 13276 }, 13277 13278 _detectOrientation: function() { 13279 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 13280 }, 13281 13282 _normValueFromMouse: function( position ) { 13283 var pixelTotal, 13284 pixelMouse, 13285 percentMouse, 13286 valueTotal, 13287 valueMouse; 13288 13289 if ( this.orientation === "horizontal" ) { 13290 pixelTotal = this.elementSize.width; 13291 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 13292 } else { 13293 pixelTotal = this.elementSize.height; 13294 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 13295 } 13296 13297 percentMouse = ( pixelMouse / pixelTotal ); 13298 if ( percentMouse > 1 ) { 13299 percentMouse = 1; 13300 } 13301 if ( percentMouse < 0 ) { 13302 percentMouse = 0; 13303 } 13304 if ( this.orientation === "vertical" ) { 13305 percentMouse = 1 - percentMouse; 13306 } 13307 13308 valueTotal = this._valueMax() - this._valueMin(); 13309 valueMouse = this._valueMin() + percentMouse * valueTotal; 13310 13311 return this._trimAlignValue( valueMouse ); 13312 }, 13313 13314 _start: function( event, index ) { 13315 var uiHash = { 13316 handle: this.handles[ index ], 13317 value: this.value() 13318 }; 13319 if ( this.options.values && this.options.values.length ) { 13320 uiHash.value = this.values( index ); 13321 uiHash.values = this.values(); 13322 } 13323 return this._trigger( "start", event, uiHash ); 13324 }, 13325 13326 _slide: function( event, index, newVal ) { 13327 var otherVal, 13328 newValues, 13329 allowed; 13330 13331 if ( this.options.values && this.options.values.length ) { 13332 otherVal = this.values( index ? 0 : 1 ); 13333 13334 if ( ( this.options.values.length === 2 && this.options.range === true ) && 13335 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 13336 ) { 13337 newVal = otherVal; 13338 } 13339 13340 if ( newVal !== this.values( index ) ) { 13341 newValues = this.values(); 13342 newValues[ index ] = newVal; 13343 // A slide can be canceled by returning false from the slide callback 13344 allowed = this._trigger( "slide", event, { 13345 handle: this.handles[ index ], 13346 value: newVal, 13347 values: newValues 13348 } ); 13349 otherVal = this.values( index ? 0 : 1 ); 13350 if ( allowed !== false ) { 13351 this.values( index, newVal, true ); 13352 } 13353 } 13354 } else { 13355 if ( newVal !== this.value() ) { 13356 // A slide can be canceled by returning false from the slide callback 13357 allowed = this._trigger( "slide", event, { 13358 handle: this.handles[ index ], 13359 value: newVal 13360 } ); 13361 if ( allowed !== false ) { 13362 this.value( newVal ); 13363 } 13364 } 13365 } 13366 }, 13367 13368 _stop: function( event, index ) { 13369 var uiHash = { 13370 handle: this.handles[ index ], 13371 value: this.value() 13372 }; 13373 if ( this.options.values && this.options.values.length ) { 13374 uiHash.value = this.values( index ); 13375 uiHash.values = this.values(); 13376 } 13377 13378 this._trigger( "stop", event, uiHash ); 13379 }, 13380 13381 _change: function( event, index ) { 13382 if ( !this._keySliding && !this._mouseSliding ) { 13383 var uiHash = { 13384 handle: this.handles[ index ], 13385 value: this.value() 13386 }; 13387 if ( this.options.values && this.options.values.length ) { 13388 uiHash.value = this.values( index ); 13389 uiHash.values = this.values(); 13390 } 13391 13392 //store the last changed value index for reference when handles overlap 13393 this._lastChangedValue = index; 13394 13395 this._trigger( "change", event, uiHash ); 13396 } 13397 }, 13398 13399 value: function( newValue ) { 13400 if ( arguments.length ) { 13401 this.options.value = this._trimAlignValue( newValue ); 13402 this._refreshValue(); 13403 this._change( null, 0 ); 13404 return; 13405 } 13406 13407 return this._value(); 13408 }, 13409 13410 values: function( index, newValue ) { 13411 var vals, 13412 newValues, 13413 i; 13414 13415 if ( arguments.length > 1 ) { 13416 this.options.values[ index ] = this._trimAlignValue( newValue ); 13417 this._refreshValue(); 13418 this._change( null, index ); 13419 return; 13420 } 13421 13422 if ( arguments.length ) { 13423 if ( $.isArray( arguments[ 0 ] ) ) { 13424 vals = this.options.values; 13425 newValues = arguments[ 0 ]; 13426 for ( i = 0; i < vals.length; i += 1 ) { 13427 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 13428 this._change( null, i ); 13429 } 13430 this._refreshValue(); 13431 } else { 13432 if ( this.options.values && this.options.values.length ) { 13433 return this._values( index ); 13434 } else { 13435 return this.value(); 13436 } 13437 } 13438 } else { 13439 return this._values(); 13440 } 13441 }, 13442 13443 _setOption: function( key, value ) { 13444 var i, 13445 valsLength = 0; 13446 13447 if ( key === "range" && this.options.range === true ) { 13448 if ( value === "min" ) { 13449 this.options.value = this._values( 0 ); 13450 this.options.values = null; 13451 } else if ( value === "max" ) { 13452 this.options.value = this._values( this.options.values.length-1 ); 13453 this.options.values = null; 13454 } 13455 } 13456 13457 if ( $.isArray( this.options.values ) ) { 13458 valsLength = this.options.values.length; 13459 } 13460 13461 $.Widget.prototype._setOption.apply( this, arguments ); 13462 13463 switch ( key ) { 13464 case "orientation": 13465 this._detectOrientation(); 13466 this.element 13467 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 13468 .addClass( "ui-slider-" + this.orientation ); 13469 this._refreshValue(); 13470 break; 13471 case "value": 13472 this._animateOff = true; 13473 this._refreshValue(); 13474 this._change( null, 0 ); 13475 this._animateOff = false; 13476 break; 13477 case "values": 13478 this._animateOff = true; 13479 this._refreshValue(); 13480 for ( i = 0; i < valsLength; i += 1 ) { 13481 this._change( null, i ); 13482 } 13483 this._animateOff = false; 13484 break; 13485 case "min": 13486 case "max": 13487 this._animateOff = true; 13488 this._refreshValue(); 13489 this._animateOff = false; 13490 break; 13491 case "range": 13492 this._animateOff = true; 13493 this._refresh(); 13494 this._animateOff = false; 13495 break; 13496 } 13497 }, 13498 13499 //internal value getter 13500 // _value() returns value trimmed by min and max, aligned by step 13501 _value: function() { 13502 var val = this.options.value; 13503 val = this._trimAlignValue( val ); 13504 13505 return val; 13506 }, 13507 13508 //internal values getter 13509 // _values() returns array of values trimmed by min and max, aligned by step 13510 // _values( index ) returns single value trimmed by min and max, aligned by step 13511 _values: function( index ) { 13512 var val, 13513 vals, 13514 i; 13515 13516 if ( arguments.length ) { 13517 val = this.options.values[ index ]; 13518 val = this._trimAlignValue( val ); 13519 13520 return val; 13521 } else if ( this.options.values && this.options.values.length ) { 13522 // .slice() creates a copy of the array 13523 // this copy gets trimmed by min and max and then returned 13524 vals = this.options.values.slice(); 13525 for ( i = 0; i < vals.length; i+= 1) { 13526 vals[ i ] = this._trimAlignValue( vals[ i ] ); 13527 } 13528 13529 return vals; 13530 } else { 13531 return []; 13532 } 13533 }, 13534 13535 // returns the step-aligned value that val is closest to, between (inclusive) min and max 13536 _trimAlignValue: function( val ) { 13537 if ( val <= this._valueMin() ) { 13538 return this._valueMin(); 13539 } 13540 if ( val >= this._valueMax() ) { 13541 return this._valueMax(); 13542 } 13543 var step = ( this.options.step > 0 ) ? this.options.step : 1, 13544 valModStep = (val - this._valueMin()) % step, 13545 alignValue = val - valModStep; 13546 13547 if ( Math.abs(valModStep) * 2 >= step ) { 13548 alignValue += ( valModStep > 0 ) ? step : ( -step ); 13549 } 13550 13551 // Since JavaScript has problems with large floats, round 13552 // the final value to 5 digits after the decimal point (see #4124) 13553 return parseFloat( alignValue.toFixed(5) ); 13554 }, 13555 13556 _valueMin: function() { 13557 return this.options.min; 13558 }, 13559 13560 _valueMax: function() { 13561 return this.options.max; 13562 }, 13563 13564 _refreshValue: function() { 13565 var lastValPercent, valPercent, value, valueMin, valueMax, 13566 oRange = this.options.range, 13567 o = this.options, 13568 that = this, 13569 animate = ( !this._animateOff ) ? o.animate : false, 13570 _set = {}; 13571 13572 if ( this.options.values && this.options.values.length ) { 13573 this.handles.each(function( i ) { 13574 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 13575 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13576 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13577 if ( that.options.range === true ) { 13578 if ( that.orientation === "horizontal" ) { 13579 if ( i === 0 ) { 13580 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 13581 } 13582 if ( i === 1 ) { 13583 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13584 } 13585 } else { 13586 if ( i === 0 ) { 13587 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 13588 } 13589 if ( i === 1 ) { 13590 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 13591 } 13592 } 13593 } 13594 lastValPercent = valPercent; 13595 }); 13596 } else { 13597 value = this.value(); 13598 valueMin = this._valueMin(); 13599 valueMax = this._valueMax(); 13600 valPercent = ( valueMax !== valueMin ) ? 13601 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 13602 0; 13603 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 13604 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 13605 13606 if ( oRange === "min" && this.orientation === "horizontal" ) { 13607 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 13608 } 13609 if ( oRange === "max" && this.orientation === "horizontal" ) { 13610 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13611 } 13612 if ( oRange === "min" && this.orientation === "vertical" ) { 13613 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 13614 } 13615 if ( oRange === "max" && this.orientation === "vertical" ) { 13616 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 13617 } 13618 } 13619 }, 13620 13621 _handleEvents: { 13622 keydown: function( event ) { 13623 /*jshint maxcomplexity:25*/ 13624 var allowed, curVal, newVal, step, 13625 index = $( event.target ).data( "ui-slider-handle-index" ); 13626 13627 switch ( event.keyCode ) { 13628 case $.ui.keyCode.HOME: 13629 case $.ui.keyCode.END: 13630 case $.ui.keyCode.PAGE_UP: 13631 case $.ui.keyCode.PAGE_DOWN: 13632 case $.ui.keyCode.UP: 13633 case $.ui.keyCode.RIGHT: 13634 case $.ui.keyCode.DOWN: 13635 case $.ui.keyCode.LEFT: 13636 event.preventDefault(); 13637 if ( !this._keySliding ) { 13638 this._keySliding = true; 13639 $( event.target ).addClass( "ui-state-active" ); 13640 allowed = this._start( event, index ); 13641 if ( allowed === false ) { 13642 return; 13643 } 13644 } 13645 break; 13646 } 13647 13648 step = this.options.step; 13649 if ( this.options.values && this.options.values.length ) { 13650 curVal = newVal = this.values( index ); 13651 } else { 13652 curVal = newVal = this.value(); 13653 } 13654 13655 switch ( event.keyCode ) { 13656 case $.ui.keyCode.HOME: 13657 newVal = this._valueMin(); 13658 break; 13659 case $.ui.keyCode.END: 13660 newVal = this._valueMax(); 13661 break; 13662 case $.ui.keyCode.PAGE_UP: 13663 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 13664 break; 13665 case $.ui.keyCode.PAGE_DOWN: 13666 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 13667 break; 13668 case $.ui.keyCode.UP: 13669 case $.ui.keyCode.RIGHT: 13670 if ( curVal === this._valueMax() ) { 13671 return; 13672 } 13673 newVal = this._trimAlignValue( curVal + step ); 13674 break; 13675 case $.ui.keyCode.DOWN: 13676 case $.ui.keyCode.LEFT: 13677 if ( curVal === this._valueMin() ) { 13678 return; 13679 } 13680 newVal = this._trimAlignValue( curVal - step ); 13681 break; 13682 } 13683 13684 this._slide( event, index, newVal ); 13685 }, 13686 click: function( event ) { 13687 event.preventDefault(); 13688 }, 13689 keyup: function( event ) { 13690 var index = $( event.target ).data( "ui-slider-handle-index" ); 13691 13692 if ( this._keySliding ) { 13693 this._keySliding = false; 13694 this._stop( event, index ); 13695 this._change( event, index ); 13696 $( event.target ).removeClass( "ui-state-active" ); 13697 } 13698 } 13699 } 13700 13701}); 13702 13703}(jQuery)); 13704(function( $ ) { 13705 13706function modifier( fn ) { 13707 return function() { 13708 var previous = this.element.val(); 13709 fn.apply( this, arguments ); 13710 this._refresh(); 13711 if ( previous !== this.element.val() ) { 13712 this._trigger( "change" ); 13713 } 13714 }; 13715} 13716 13717$.widget( "ui.spinner", { 13718 version: "1.10.3", 13719 defaultElement: "<input>", 13720 widgetEventPrefix: "spin", 13721 options: { 13722 culture: null, 13723 icons: { 13724 down: "ui-icon-triangle-1-s", 13725 up: "ui-icon-triangle-1-n" 13726 }, 13727 incremental: true, 13728 max: null, 13729 min: null, 13730 numberFormat: null, 13731 page: 10, 13732 step: 1, 13733 13734 change: null, 13735 spin: null, 13736 start: null, 13737 stop: null 13738 }, 13739 13740 _create: function() { 13741 // handle string values that need to be parsed 13742 this._setOption( "max", this.options.max ); 13743 this._setOption( "min", this.options.min ); 13744 this._setOption( "step", this.options.step ); 13745 13746 // format the value, but don't constrain 13747 this._value( this.element.val(), true ); 13748 13749 this._draw(); 13750 this._on( this._events ); 13751 this._refresh(); 13752 13753 // turning off autocomplete prevents the browser from remembering the 13754 // value when navigating through history, so we re-enable autocomplete 13755 // if the page is unloaded before the widget is destroyed. #7790 13756 this._on( this.window, { 13757 beforeunload: function() { 13758 this.element.removeAttr( "autocomplete" ); 13759 } 13760 }); 13761 }, 13762 13763 _getCreateOptions: function() { 13764 var options = {}, 13765 element = this.element; 13766 13767 $.each( [ "min", "max", "step" ], function( i, option ) { 13768 var value = element.attr( option ); 13769 if ( value !== undefined && value.length ) { 13770 options[ option ] = value; 13771 } 13772 }); 13773 13774 return options; 13775 }, 13776 13777 _events: { 13778 keydown: function( event ) { 13779 if ( this._start( event ) && this._keydown( event ) ) { 13780 event.preventDefault(); 13781 } 13782 }, 13783 keyup: "_stop", 13784 focus: function() { 13785 this.previous = this.element.val(); 13786 }, 13787 blur: function( event ) { 13788 if ( this.cancelBlur ) { 13789 delete this.cancelBlur; 13790 return; 13791 } 13792 13793 this._stop(); 13794 this._refresh(); 13795 if ( this.previous !== this.element.val() ) { 13796 this._trigger( "change", event ); 13797 } 13798 }, 13799 mousewheel: function( event, delta ) { 13800 if ( !delta ) { 13801 return; 13802 } 13803 if ( !this.spinning && !this._start( event ) ) { 13804 return false; 13805 } 13806 13807 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 13808 clearTimeout( this.mousewheelTimer ); 13809 this.mousewheelTimer = this._delay(function() { 13810 if ( this.spinning ) { 13811 this._stop( event ); 13812 } 13813 }, 100 ); 13814 event.preventDefault(); 13815 }, 13816 "mousedown .ui-spinner-button": function( event ) { 13817 var previous; 13818 13819 // We never want the buttons to have focus; whenever the user is 13820 // interacting with the spinner, the focus should be on the input. 13821 // If the input is focused then this.previous is properly set from 13822 // when the input first received focus. If the input is not focused 13823 // then we need to set this.previous based on the value before spinning. 13824 previous = this.element[0] === this.document[0].activeElement ? 13825 this.previous : this.element.val(); 13826 function checkFocus() { 13827 var isActive = this.element[0] === this.document[0].activeElement; 13828 if ( !isActive ) { 13829 this.element.focus(); 13830 this.previous = previous; 13831 // support: IE 13832 // IE sets focus asynchronously, so we need to check if focus 13833 // moved off of the input because the user clicked on the button. 13834 this._delay(function() { 13835 this.previous = previous; 13836 }); 13837 } 13838 } 13839 13840 // ensure focus is on (or stays on) the text field 13841 event.preventDefault(); 13842 checkFocus.call( this ); 13843 13844 // support: IE 13845 // IE doesn't prevent moving focus even with event.preventDefault() 13846 // so we set a flag to know when we should ignore the blur event 13847 // and check (again) if focus moved off of the input. 13848 this.cancelBlur = true; 13849 this._delay(function() { 13850 delete this.cancelBlur; 13851 checkFocus.call( this ); 13852 }); 13853 13854 if ( this._start( event ) === false ) { 13855 return; 13856 } 13857 13858 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13859 }, 13860 "mouseup .ui-spinner-button": "_stop", 13861 "mouseenter .ui-spinner-button": function( event ) { 13862 // button will add ui-state-active if mouse was down while mouseleave and kept down 13863 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 13864 return; 13865 } 13866 13867 if ( this._start( event ) === false ) { 13868 return false; 13869 } 13870 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 13871 }, 13872 // TODO: do we really want to consider this a stop? 13873 // shouldn't we just stop the repeater and wait until mouseup before 13874 // we trigger the stop event? 13875 "mouseleave .ui-spinner-button": "_stop" 13876 }, 13877 13878 _draw: function() { 13879 var uiSpinner = this.uiSpinner = this.element 13880 .addClass( "ui-spinner-input" ) 13881 .attr( "autocomplete", "off" ) 13882 .wrap( this._uiSpinnerHtml() ) 13883 .parent() 13884 // add buttons 13885 .append( this._buttonHtml() ); 13886 13887 this.element.attr( "role", "spinbutton" ); 13888 13889 // button bindings 13890 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 13891 .attr( "tabIndex", -1 ) 13892 .button() 13893 .removeClass( "ui-corner-all" ); 13894 13895 // IE 6 doesn't understand height: 50% for the buttons 13896 // unless the wrapper has an explicit height 13897 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 13898 uiSpinner.height() > 0 ) { 13899 uiSpinner.height( uiSpinner.height() ); 13900 } 13901 13902 // disable spinner if element was already disabled 13903 if ( this.options.disabled ) { 13904 this.disable(); 13905 } 13906 }, 13907 13908 _keydown: function( event ) { 13909 var options = this.options, 13910 keyCode = $.ui.keyCode; 13911 13912 switch ( event.keyCode ) { 13913 case keyCode.UP: 13914 this._repeat( null, 1, event ); 13915 return true; 13916 case keyCode.DOWN: 13917 this._repeat( null, -1, event ); 13918 return true; 13919 case keyCode.PAGE_UP: 13920 this._repeat( null, options.page, event ); 13921 return true; 13922 case keyCode.PAGE_DOWN: 13923 this._repeat( null, -options.page, event ); 13924 return true; 13925 } 13926 13927 return false; 13928 }, 13929 13930 _uiSpinnerHtml: function() { 13931 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 13932 }, 13933 13934 _buttonHtml: function() { 13935 return "" + 13936 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 13937 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 13938 "</a>" + 13939 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 13940 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 13941 "</a>"; 13942 }, 13943 13944 _start: function( event ) { 13945 if ( !this.spinning && this._trigger( "start", event ) === false ) { 13946 return false; 13947 } 13948 13949 if ( !this.counter ) { 13950 this.counter = 1; 13951 } 13952 this.spinning = true; 13953 return true; 13954 }, 13955 13956 _repeat: function( i, steps, event ) { 13957 i = i || 500; 13958 13959 clearTimeout( this.timer ); 13960 this.timer = this._delay(function() { 13961 this._repeat( 40, steps, event ); 13962 }, i ); 13963 13964 this._spin( steps * this.options.step, event ); 13965 }, 13966 13967 _spin: function( step, event ) { 13968 var value = this.value() || 0; 13969 13970 if ( !this.counter ) { 13971 this.counter = 1; 13972 } 13973 13974 value = this._adjustValue( value + step * this._increment( this.counter ) ); 13975 13976 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 13977 this._value( value ); 13978 this.counter++; 13979 } 13980 }, 13981 13982 _increment: function( i ) { 13983 var incremental = this.options.incremental; 13984 13985 if ( incremental ) { 13986 return $.isFunction( incremental ) ? 13987 incremental( i ) : 13988 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 13989 } 13990 13991 return 1; 13992 }, 13993 13994 _precision: function() { 13995 var precision = this._precisionOf( this.options.step ); 13996 if ( this.options.min !== null ) { 13997 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 13998 } 13999 return precision; 14000 }, 14001 14002 _precisionOf: function( num ) { 14003 var str = num.toString(), 14004 decimal = str.indexOf( "." ); 14005 return decimal === -1 ? 0 : str.length - decimal - 1; 14006 }, 14007 14008 _adjustValue: function( value ) { 14009 var base, aboveMin, 14010 options = this.options; 14011 14012 // make sure we're at a valid step 14013 // - find out where we are relative to the base (min or 0) 14014 base = options.min !== null ? options.min : 0; 14015 aboveMin = value - base; 14016 // - round to the nearest step 14017 aboveMin = Math.round(aboveMin / options.step) * options.step; 14018 // - rounding is based on 0, so adjust back to our base 14019 value = base + aboveMin; 14020 14021 // fix precision from bad JS floating point math 14022 value = parseFloat( value.toFixed( this._precision() ) ); 14023 14024 // clamp the value 14025 if ( options.max !== null && value > options.max) { 14026 return options.max; 14027 } 14028 if ( options.min !== null && value < options.min ) { 14029 return options.min; 14030 } 14031 14032 return value; 14033 }, 14034 14035 _stop: function( event ) { 14036 if ( !this.spinning ) { 14037 return; 14038 } 14039 14040 clearTimeout( this.timer ); 14041 clearTimeout( this.mousewheelTimer ); 14042 this.counter = 0; 14043 this.spinning = false; 14044 this._trigger( "stop", event ); 14045 }, 14046 14047 _setOption: function( key, value ) { 14048 if ( key === "culture" || key === "numberFormat" ) { 14049 var prevValue = this._parse( this.element.val() ); 14050 this.options[ key ] = value; 14051 this.element.val( this._format( prevValue ) ); 14052 return; 14053 } 14054 14055 if ( key === "max" || key === "min" || key === "step" ) { 14056 if ( typeof value === "string" ) { 14057 value = this._parse( value ); 14058 } 14059 } 14060 if ( key === "icons" ) { 14061 this.buttons.first().find( ".ui-icon" ) 14062 .removeClass( this.options.icons.up ) 14063 .addClass( value.up ); 14064 this.buttons.last().find( ".ui-icon" ) 14065 .removeClass( this.options.icons.down ) 14066 .addClass( value.down ); 14067 } 14068 14069 this._super( key, value ); 14070 14071 if ( key === "disabled" ) { 14072 if ( value ) { 14073 this.element.prop( "disabled", true ); 14074 this.buttons.button( "disable" ); 14075 } else { 14076 this.element.prop( "disabled", false ); 14077 this.buttons.button( "enable" ); 14078 } 14079 } 14080 }, 14081 14082 _setOptions: modifier(function( options ) { 14083 this._super( options ); 14084 this._value( this.element.val() ); 14085 }), 14086 14087 _parse: function( val ) { 14088 if ( typeof val === "string" && val !== "" ) { 14089 val = window.Globalize && this.options.numberFormat ? 14090 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 14091 } 14092 return val === "" || isNaN( val ) ? null : val; 14093 }, 14094 14095 _format: function( value ) { 14096 if ( value === "" ) { 14097 return ""; 14098 } 14099 return window.Globalize && this.options.numberFormat ? 14100 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 14101 value; 14102 }, 14103 14104 _refresh: function() { 14105 this.element.attr({ 14106 "aria-valuemin": this.options.min, 14107 "aria-valuemax": this.options.max, 14108 // TODO: what should we do with values that can't be parsed? 14109 "aria-valuenow": this._parse( this.element.val() ) 14110 }); 14111 }, 14112 14113 // update the value without triggering change 14114 _value: function( value, allowAny ) { 14115 var parsed; 14116 if ( value !== "" ) { 14117 parsed = this._parse( value ); 14118 if ( parsed !== null ) { 14119 if ( !allowAny ) { 14120 parsed = this._adjustValue( parsed ); 14121 } 14122 value = this._format( parsed ); 14123 } 14124 } 14125 this.element.val( value ); 14126 this._refresh(); 14127 }, 14128 14129 _destroy: function() { 14130 this.element 14131 .removeClass( "ui-spinner-input" ) 14132 .prop( "disabled", false ) 14133 .removeAttr( "autocomplete" ) 14134 .removeAttr( "role" ) 14135 .removeAttr( "aria-valuemin" ) 14136 .removeAttr( "aria-valuemax" ) 14137 .removeAttr( "aria-valuenow" ); 14138 this.uiSpinner.replaceWith( this.element ); 14139 }, 14140 14141 stepUp: modifier(function( steps ) { 14142 this._stepUp( steps ); 14143 }), 14144 _stepUp: function( steps ) { 14145 if ( this._start() ) { 14146 this._spin( (steps || 1) * this.options.step ); 14147 this._stop(); 14148 } 14149 }, 14150 14151 stepDown: modifier(function( steps ) { 14152 this._stepDown( steps ); 14153 }), 14154 _stepDown: function( steps ) { 14155 if ( this._start() ) { 14156 this._spin( (steps || 1) * -this.options.step ); 14157 this._stop(); 14158 } 14159 }, 14160 14161 pageUp: modifier(function( pages ) { 14162 this._stepUp( (pages || 1) * this.options.page ); 14163 }), 14164 14165 pageDown: modifier(function( pages ) { 14166 this._stepDown( (pages || 1) * this.options.page ); 14167 }), 14168 14169 value: function( newVal ) { 14170 if ( !arguments.length ) { 14171 return this._parse( this.element.val() ); 14172 } 14173 modifier( this._value ).call( this, newVal ); 14174 }, 14175 14176 widget: function() { 14177 return this.uiSpinner; 14178 } 14179}); 14180 14181}( jQuery ) ); 14182(function( $, undefined ) { 14183 14184var tabId = 0, 14185 rhash = /#.*$/; 14186 14187function getNextTabId() { 14188 return ++tabId; 14189} 14190 14191function isLocal( anchor ) { 14192 return anchor.hash.length > 1 && 14193 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === 14194 decodeURIComponent( location.href.replace( rhash, "" ) ); 14195} 14196 14197$.widget( "ui.tabs", { 14198 version: "1.10.3", 14199 delay: 300, 14200 options: { 14201 active: null, 14202 collapsible: false, 14203 event: "click", 14204 heightStyle: "content", 14205 hide: null, 14206 show: null, 14207 14208 // callbacks 14209 activate: null, 14210 beforeActivate: null, 14211 beforeLoad: null, 14212 load: null 14213 }, 14214 14215 _create: function() { 14216 var that = this, 14217 options = this.options; 14218 14219 this.running = false; 14220 14221 this.element 14222 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 14223 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 14224 // Prevent users from focusing disabled tabs via click 14225 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 14226 if ( $( this ).is( ".ui-state-disabled" ) ) { 14227 event.preventDefault(); 14228 } 14229 }) 14230 // support: IE <9 14231 // Preventing the default action in mousedown doesn't prevent IE 14232 // from focusing the element, so if the anchor gets focused, blur. 14233 // We don't have to worry about focusing the previously focused 14234 // element since clicking on a non-focusable element should focus 14235 // the body anyway. 14236 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 14237 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 14238 this.blur(); 14239 } 14240 }); 14241 14242 this._processTabs(); 14243 options.active = this._initialActive(); 14244 14245 // Take disabling tabs via class attribute from HTML 14246 // into account and update option properly. 14247 if ( $.isArray( options.disabled ) ) { 14248 options.disabled = $.unique( options.disabled.concat( 14249 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 14250 return that.tabs.index( li ); 14251 }) 14252 ) ).sort(); 14253 } 14254 14255 // check for length avoids error when initializing empty list 14256 if ( this.options.active !== false && this.anchors.length ) { 14257 this.active = this._findActive( options.active ); 14258 } else { 14259 this.active = $(); 14260 } 14261 14262 this._refresh(); 14263 14264 if ( this.active.length ) { 14265 this.load( options.active ); 14266 } 14267 }, 14268 14269 _initialActive: function() { 14270 var active = this.options.active, 14271 collapsible = this.options.collapsible, 14272 locationHash = location.hash.substring( 1 ); 14273 14274 if ( active === null ) { 14275 // check the fragment identifier in the URL 14276 if ( locationHash ) { 14277 this.tabs.each(function( i, tab ) { 14278 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 14279 active = i; 14280 return false; 14281 } 14282 }); 14283 } 14284 14285 // check for a tab marked active via a class 14286 if ( active === null ) { 14287 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 14288 } 14289 14290 // no active tab, set to false 14291 if ( active === null || active === -1 ) { 14292 active = this.tabs.length ? 0 : false; 14293 } 14294 } 14295 14296 // handle numbers: negative, out of range 14297 if ( active !== false ) { 14298 active = this.tabs.index( this.tabs.eq( active ) ); 14299 if ( active === -1 ) { 14300 active = collapsible ? false : 0; 14301 } 14302 } 14303 14304 // don't allow collapsible: false and active: false 14305 if ( !collapsible && active === false && this.anchors.length ) { 14306 active = 0; 14307 } 14308 14309 return active; 14310 }, 14311 14312 _getCreateEventData: function() { 14313 return { 14314 tab: this.active, 14315 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 14316 }; 14317 }, 14318 14319 _tabKeydown: function( event ) { 14320 /*jshint maxcomplexity:15*/ 14321 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 14322 selectedIndex = this.tabs.index( focusedTab ), 14323 goingForward = true; 14324 14325 if ( this._handlePageNav( event ) ) { 14326 return; 14327 } 14328 14329 switch ( event.keyCode ) { 14330 case $.ui.keyCode.RIGHT: 14331 case $.ui.keyCode.DOWN: 14332 selectedIndex++; 14333 break; 14334 case $.ui.keyCode.UP: 14335 case $.ui.keyCode.LEFT: 14336 goingForward = false; 14337 selectedIndex--; 14338 break; 14339 case $.ui.keyCode.END: 14340 selectedIndex = this.anchors.length - 1; 14341 break; 14342 case $.ui.keyCode.HOME: 14343 selectedIndex = 0; 14344 break; 14345 case $.ui.keyCode.SPACE: 14346 // Activate only, no collapsing 14347 event.preventDefault(); 14348 clearTimeout( this.activating ); 14349 this._activate( selectedIndex ); 14350 return; 14351 case $.ui.keyCode.ENTER: 14352 // Toggle (cancel delayed activation, allow collapsing) 14353 event.preventDefault(); 14354 clearTimeout( this.activating ); 14355 // Determine if we should collapse or activate 14356 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 14357 return; 14358 default: 14359 return; 14360 } 14361 14362 // Focus the appropriate tab, based on which key was pressed 14363 event.preventDefault(); 14364 clearTimeout( this.activating ); 14365 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 14366 14367 // Navigating with control key will prevent automatic activation 14368 if ( !event.ctrlKey ) { 14369 // Update aria-selected immediately so that AT think the tab is already selected. 14370 // Otherwise AT may confuse the user by stating that they need to activate the tab, 14371 // but the tab will already be activated by the time the announcement finishes. 14372 focusedTab.attr( "aria-selected", "false" ); 14373 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 14374 14375 this.activating = this._delay(function() { 14376 this.option( "active", selectedIndex ); 14377 }, this.delay ); 14378 } 14379 }, 14380 14381 _panelKeydown: function( event ) { 14382 if ( this._handlePageNav( event ) ) { 14383 return; 14384 } 14385 14386 // Ctrl+up moves focus to the current tab 14387 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 14388 event.preventDefault(); 14389 this.active.focus(); 14390 } 14391 }, 14392 14393 // Alt+page up/down moves focus to the previous/next tab (and activates) 14394 _handlePageNav: function( event ) { 14395 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 14396 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 14397 return true; 14398 } 14399 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 14400 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 14401 return true; 14402 } 14403 }, 14404 14405 _findNextTab: function( index, goingForward ) { 14406 var lastTabIndex = this.tabs.length - 1; 14407 14408 function constrain() { 14409 if ( index > lastTabIndex ) { 14410 index = 0; 14411 } 14412 if ( index < 0 ) { 14413 index = lastTabIndex; 14414 } 14415 return index; 14416 } 14417 14418 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 14419 index = goingForward ? index + 1 : index - 1; 14420 } 14421 14422 return index; 14423 }, 14424 14425 _focusNextTab: function( index, goingForward ) { 14426 index = this._findNextTab( index, goingForward ); 14427 this.tabs.eq( index ).focus(); 14428 return index; 14429 }, 14430 14431 _setOption: function( key, value ) { 14432 if ( key === "active" ) { 14433 // _activate() will handle invalid values and update this.options 14434 this._activate( value ); 14435 return; 14436 } 14437 14438 if ( key === "disabled" ) { 14439 // don't use the widget factory's disabled handling 14440 this._setupDisabled( value ); 14441 return; 14442 } 14443 14444 this._super( key, value); 14445 14446 if ( key === "collapsible" ) { 14447 this.element.toggleClass( "ui-tabs-collapsible", value ); 14448 // Setting collapsible: false while collapsed; open first panel 14449 if ( !value && this.options.active === false ) { 14450 this._activate( 0 ); 14451 } 14452 } 14453 14454 if ( key === "event" ) { 14455 this._setupEvents( value ); 14456 } 14457 14458 if ( key === "heightStyle" ) { 14459 this._setupHeightStyle( value ); 14460 } 14461 }, 14462 14463 _tabId: function( tab ) { 14464 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 14465 }, 14466 14467 _sanitizeSelector: function( hash ) { 14468 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 14469 }, 14470 14471 refresh: function() { 14472 var options = this.options, 14473 lis = this.tablist.children( ":has(a[href])" ); 14474 14475 // get disabled tabs from class attribute from HTML 14476 // this will get converted to a boolean if needed in _refresh() 14477 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 14478 return lis.index( tab ); 14479 }); 14480 14481 this._processTabs(); 14482 14483 // was collapsed or no tabs 14484 if ( options.active === false || !this.anchors.length ) { 14485 options.active = false; 14486 this.active = $(); 14487 // was active, but active tab is gone 14488 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 14489 // all remaining tabs are disabled 14490 if ( this.tabs.length === options.disabled.length ) { 14491 options.active = false; 14492 this.active = $(); 14493 // activate previous tab 14494 } else { 14495 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 14496 } 14497 // was active, active tab still exists 14498 } else { 14499 // make sure active index is correct 14500 options.active = this.tabs.index( this.active ); 14501 } 14502 14503 this._refresh(); 14504 }, 14505 14506 _refresh: function() { 14507 this._setupDisabled( this.options.disabled ); 14508 this._setupEvents( this.options.event ); 14509 this._setupHeightStyle( this.options.heightStyle ); 14510 14511 this.tabs.not( this.active ).attr({ 14512 "aria-selected": "false", 14513 tabIndex: -1 14514 }); 14515 this.panels.not( this._getPanelForTab( this.active ) ) 14516 .hide() 14517 .attr({ 14518 "aria-expanded": "false", 14519 "aria-hidden": "true" 14520 }); 14521 14522 // Make sure one tab is in the tab order 14523 if ( !this.active.length ) { 14524 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 14525 } else { 14526 this.active 14527 .addClass( "ui-tabs-active ui-state-active" ) 14528 .attr({ 14529 "aria-selected": "true", 14530 tabIndex: 0 14531 }); 14532 this._getPanelForTab( this.active ) 14533 .show() 14534 .attr({ 14535 "aria-expanded": "true", 14536 "aria-hidden": "false" 14537 }); 14538 } 14539 }, 14540 14541 _processTabs: function() { 14542 var that = this; 14543 14544 this.tablist = this._getList() 14545 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14546 .attr( "role", "tablist" ); 14547 14548 this.tabs = this.tablist.find( "> li:has(a[href])" ) 14549 .addClass( "ui-state-default ui-corner-top" ) 14550 .attr({ 14551 role: "tab", 14552 tabIndex: -1 14553 }); 14554 14555 this.anchors = this.tabs.map(function() { 14556 return $( "a", this )[ 0 ]; 14557 }) 14558 .addClass( "ui-tabs-anchor" ) 14559 .attr({ 14560 role: "presentation", 14561 tabIndex: -1 14562 }); 14563 14564 this.panels = $(); 14565 14566 this.anchors.each(function( i, anchor ) { 14567 var selector, panel, panelId, 14568 anchorId = $( anchor ).uniqueId().attr( "id" ), 14569 tab = $( anchor ).closest( "li" ), 14570 originalAriaControls = tab.attr( "aria-controls" ); 14571 14572 // inline tab 14573 if ( isLocal( anchor ) ) { 14574 selector = anchor.hash; 14575 panel = that.element.find( that._sanitizeSelector( selector ) ); 14576 // remote tab 14577 } else { 14578 panelId = that._tabId( tab ); 14579 selector = "#" + panelId; 14580 panel = that.element.find( selector ); 14581 if ( !panel.length ) { 14582 panel = that._createPanel( panelId ); 14583 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 14584 } 14585 panel.attr( "aria-live", "polite" ); 14586 } 14587 14588 if ( panel.length) { 14589 that.panels = that.panels.add( panel ); 14590 } 14591 if ( originalAriaControls ) { 14592 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 14593 } 14594 tab.attr({ 14595 "aria-controls": selector.substring( 1 ), 14596 "aria-labelledby": anchorId 14597 }); 14598 panel.attr( "aria-labelledby", anchorId ); 14599 }); 14600 14601 this.panels 14602 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14603 .attr( "role", "tabpanel" ); 14604 }, 14605 14606 // allow overriding how to find the list for rare usage scenarios (#7715) 14607 _getList: function() { 14608 return this.element.find( "ol,ul" ).eq( 0 ); 14609 }, 14610 14611 _createPanel: function( id ) { 14612 return $( "<div>" ) 14613 .attr( "id", id ) 14614 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 14615 .data( "ui-tabs-destroy", true ); 14616 }, 14617 14618 _setupDisabled: function( disabled ) { 14619 if ( $.isArray( disabled ) ) { 14620 if ( !disabled.length ) { 14621 disabled = false; 14622 } else if ( disabled.length === this.anchors.length ) { 14623 disabled = true; 14624 } 14625 } 14626 14627 // disable tabs 14628 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 14629 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 14630 $( li ) 14631 .addClass( "ui-state-disabled" ) 14632 .attr( "aria-disabled", "true" ); 14633 } else { 14634 $( li ) 14635 .removeClass( "ui-state-disabled" ) 14636 .removeAttr( "aria-disabled" ); 14637 } 14638 } 14639 14640 this.options.disabled = disabled; 14641 }, 14642 14643 _setupEvents: function( event ) { 14644 var events = { 14645 click: function( event ) { 14646 event.preventDefault(); 14647 } 14648 }; 14649 if ( event ) { 14650 $.each( event.split(" "), function( index, eventName ) { 14651 events[ eventName ] = "_eventHandler"; 14652 }); 14653 } 14654 14655 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 14656 this._on( this.anchors, events ); 14657 this._on( this.tabs, { keydown: "_tabKeydown" } ); 14658 this._on( this.panels, { keydown: "_panelKeydown" } ); 14659 14660 this._focusable( this.tabs ); 14661 this._hoverable( this.tabs ); 14662 }, 14663 14664 _setupHeightStyle: function( heightStyle ) { 14665 var maxHeight, 14666 parent = this.element.parent(); 14667 14668 if ( heightStyle === "fill" ) { 14669 maxHeight = parent.height(); 14670 maxHeight -= this.element.outerHeight() - this.element.height(); 14671 14672 this.element.siblings( ":visible" ).each(function() { 14673 var elem = $( this ), 14674 position = elem.css( "position" ); 14675 14676 if ( position === "absolute" || position === "fixed" ) { 14677 return; 14678 } 14679 maxHeight -= elem.outerHeight( true ); 14680 }); 14681 14682 this.element.children().not( this.panels ).each(function() { 14683 maxHeight -= $( this ).outerHeight( true ); 14684 }); 14685 14686 this.panels.each(function() { 14687 $( this ).height( Math.max( 0, maxHeight - 14688 $( this ).innerHeight() + $( this ).height() ) ); 14689 }) 14690 .css( "overflow", "auto" ); 14691 } else if ( heightStyle === "auto" ) { 14692 maxHeight = 0; 14693 this.panels.each(function() { 14694 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 14695 }).height( maxHeight ); 14696 } 14697 }, 14698 14699 _eventHandler: function( event ) { 14700 var options = this.options, 14701 active = this.active, 14702 anchor = $( event.currentTarget ), 14703 tab = anchor.closest( "li" ), 14704 clickedIsActive = tab[ 0 ] === active[ 0 ], 14705 collapsing = clickedIsActive && options.collapsible, 14706 toShow = collapsing ? $() : this._getPanelForTab( tab ), 14707 toHide = !active.length ? $() : this._getPanelForTab( active ), 14708 eventData = { 14709 oldTab: active, 14710 oldPanel: toHide, 14711 newTab: collapsing ? $() : tab, 14712 newPanel: toShow 14713 }; 14714 14715 event.preventDefault(); 14716 14717 if ( tab.hasClass( "ui-state-disabled" ) || 14718 // tab is already loading 14719 tab.hasClass( "ui-tabs-loading" ) || 14720 // can't switch durning an animation 14721 this.running || 14722 // click on active header, but not collapsible 14723 ( clickedIsActive && !options.collapsible ) || 14724 // allow canceling activation 14725 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 14726 return; 14727 } 14728 14729 options.active = collapsing ? false : this.tabs.index( tab ); 14730 14731 this.active = clickedIsActive ? $() : tab; 14732 if ( this.xhr ) { 14733 this.xhr.abort(); 14734 } 14735 14736 if ( !toHide.length && !toShow.length ) { 14737 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 14738 } 14739 14740 if ( toShow.length ) { 14741 this.load( this.tabs.index( tab ), event ); 14742 } 14743 this._toggle( event, eventData ); 14744 }, 14745 14746 // handles show/hide for selecting tabs 14747 _toggle: function( event, eventData ) { 14748 var that = this, 14749 toShow = eventData.newPanel, 14750 toHide = eventData.oldPanel; 14751 14752 this.running = true; 14753 14754 function complete() { 14755 that.running = false; 14756 that._trigger( "activate", event, eventData ); 14757 } 14758 14759 function show() { 14760 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 14761 14762 if ( toShow.length && that.options.show ) { 14763 that._show( toShow, that.options.show, complete ); 14764 } else { 14765 toShow.show(); 14766 complete(); 14767 } 14768 } 14769 14770 // start out by hiding, then showing, then completing 14771 if ( toHide.length && this.options.hide ) { 14772 this._hide( toHide, this.options.hide, function() { 14773 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14774 show(); 14775 }); 14776 } else { 14777 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 14778 toHide.hide(); 14779 show(); 14780 } 14781 14782 toHide.attr({ 14783 "aria-expanded": "false", 14784 "aria-hidden": "true" 14785 }); 14786 eventData.oldTab.attr( "aria-selected", "false" ); 14787 // If we're switching tabs, remove the old tab from the tab order. 14788 // If we're opening from collapsed state, remove the previous tab from the tab order. 14789 // If we're collapsing, then keep the collapsing tab in the tab order. 14790 if ( toShow.length && toHide.length ) { 14791 eventData.oldTab.attr( "tabIndex", -1 ); 14792 } else if ( toShow.length ) { 14793 this.tabs.filter(function() { 14794 return $( this ).attr( "tabIndex" ) === 0; 14795 }) 14796 .attr( "tabIndex", -1 ); 14797 } 14798 14799 toShow.attr({ 14800 "aria-expanded": "true", 14801 "aria-hidden": "false" 14802 }); 14803 eventData.newTab.attr({ 14804 "aria-selected": "true", 14805 tabIndex: 0 14806 }); 14807 }, 14808 14809 _activate: function( index ) { 14810 var anchor, 14811 active = this._findActive( index ); 14812 14813 // trying to activate the already active panel 14814 if ( active[ 0 ] === this.active[ 0 ] ) { 14815 return; 14816 } 14817 14818 // trying to collapse, simulate a click on the current active header 14819 if ( !active.length ) { 14820 active = this.active; 14821 } 14822 14823 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 14824 this._eventHandler({ 14825 target: anchor, 14826 currentTarget: anchor, 14827 preventDefault: $.noop 14828 }); 14829 }, 14830 14831 _findActive: function( index ) { 14832 return index === false ? $() : this.tabs.eq( index ); 14833 }, 14834 14835 _getIndex: function( index ) { 14836 // meta-function to give users option to provide a href string instead of a numerical index. 14837 if ( typeof index === "string" ) { 14838 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 14839 } 14840 14841 return index; 14842 }, 14843 14844 _destroy: function() { 14845 if ( this.xhr ) { 14846 this.xhr.abort(); 14847 } 14848 14849 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 14850 14851 this.tablist 14852 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 14853 .removeAttr( "role" ); 14854 14855 this.anchors 14856 .removeClass( "ui-tabs-anchor" ) 14857 .removeAttr( "role" ) 14858 .removeAttr( "tabIndex" ) 14859 .removeUniqueId(); 14860 14861 this.tabs.add( this.panels ).each(function() { 14862 if ( $.data( this, "ui-tabs-destroy" ) ) { 14863 $( this ).remove(); 14864 } else { 14865 $( this ) 14866 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 14867 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 14868 .removeAttr( "tabIndex" ) 14869 .removeAttr( "aria-live" ) 14870 .removeAttr( "aria-busy" ) 14871 .removeAttr( "aria-selected" ) 14872 .removeAttr( "aria-labelledby" ) 14873 .removeAttr( "aria-hidden" ) 14874 .removeAttr( "aria-expanded" ) 14875 .removeAttr( "role" ); 14876 } 14877 }); 14878 14879 this.tabs.each(function() { 14880 var li = $( this ), 14881 prev = li.data( "ui-tabs-aria-controls" ); 14882 if ( prev ) { 14883 li 14884 .attr( "aria-controls", prev ) 14885 .removeData( "ui-tabs-aria-controls" ); 14886 } else { 14887 li.removeAttr( "aria-controls" ); 14888 } 14889 }); 14890 14891 this.panels.show(); 14892 14893 if ( this.options.heightStyle !== "content" ) { 14894 this.panels.css( "height", "" ); 14895 } 14896 }, 14897 14898 enable: function( index ) { 14899 var disabled = this.options.disabled; 14900 if ( disabled === false ) { 14901 return; 14902 } 14903 14904 if ( index === undefined ) { 14905 disabled = false; 14906 } else { 14907 index = this._getIndex( index ); 14908 if ( $.isArray( disabled ) ) { 14909 disabled = $.map( disabled, function( num ) { 14910 return num !== index ? num : null; 14911 }); 14912 } else { 14913 disabled = $.map( this.tabs, function( li, num ) { 14914 return num !== index ? num : null; 14915 }); 14916 } 14917 } 14918 this._setupDisabled( disabled ); 14919 }, 14920 14921 disable: function( index ) { 14922 var disabled = this.options.disabled; 14923 if ( disabled === true ) { 14924 return; 14925 } 14926 14927 if ( index === undefined ) { 14928 disabled = true; 14929 } else { 14930 index = this._getIndex( index ); 14931 if ( $.inArray( index, disabled ) !== -1 ) { 14932 return; 14933 } 14934 if ( $.isArray( disabled ) ) { 14935 disabled = $.merge( [ index ], disabled ).sort(); 14936 } else { 14937 disabled = [ index ]; 14938 } 14939 } 14940 this._setupDisabled( disabled ); 14941 }, 14942 14943 load: function( index, event ) { 14944 index = this._getIndex( index ); 14945 var that = this, 14946 tab = this.tabs.eq( index ), 14947 anchor = tab.find( ".ui-tabs-anchor" ), 14948 panel = this._getPanelForTab( tab ), 14949 eventData = { 14950 tab: tab, 14951 panel: panel 14952 }; 14953 14954 // not remote 14955 if ( isLocal( anchor[ 0 ] ) ) { 14956 return; 14957 } 14958 14959 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 14960 14961 // support: jQuery <1.8 14962 // jQuery <1.8 returns false if the request is canceled in beforeSend, 14963 // but as of 1.8, $.ajax() always returns a jqXHR object. 14964 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 14965 tab.addClass( "ui-tabs-loading" ); 14966 panel.attr( "aria-busy", "true" ); 14967 14968 this.xhr 14969 .success(function( response ) { 14970 // support: jQuery <1.8 14971 // http://bugs.jquery.com/ticket/11778 14972 setTimeout(function() { 14973 panel.html( response ); 14974 that._trigger( "load", event, eventData ); 14975 }, 1 ); 14976 }) 14977 .complete(function( jqXHR, status ) { 14978 // support: jQuery <1.8 14979 // http://bugs.jquery.com/ticket/11778 14980 setTimeout(function() { 14981 if ( status === "abort" ) { 14982 that.panels.stop( false, true ); 14983 } 14984 14985 tab.removeClass( "ui-tabs-loading" ); 14986 panel.removeAttr( "aria-busy" ); 14987 14988 if ( jqXHR === that.xhr ) { 14989 delete that.xhr; 14990 } 14991 }, 1 ); 14992 }); 14993 } 14994 }, 14995 14996 _ajaxSettings: function( anchor, event, eventData ) { 14997 var that = this; 14998 return { 14999 url: anchor.attr( "href" ), 15000 beforeSend: function( jqXHR, settings ) { 15001 return that._trigger( "beforeLoad", event, 15002 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 15003 } 15004 }; 15005 }, 15006 15007 _getPanelForTab: function( tab ) { 15008 var id = $( tab ).attr( "aria-controls" ); 15009 return this.element.find( this._sanitizeSelector( "#" + id ) ); 15010 } 15011}); 15012 15013})( jQuery ); 15014(function( $ ) { 15015 15016var increments = 0; 15017 15018function addDescribedBy( elem, id ) { 15019 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 15020 describedby.push( id ); 15021 elem 15022 .data( "ui-tooltip-id", id ) 15023 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 15024} 15025 15026function removeDescribedBy( elem ) { 15027 var id = elem.data( "ui-tooltip-id" ), 15028 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 15029 index = $.inArray( id, describedby ); 15030 if ( index !== -1 ) { 15031 describedby.splice( index, 1 ); 15032 } 15033 15034 elem.removeData( "ui-tooltip-id" ); 15035 describedby = $.trim( describedby.join( " " ) ); 15036 if ( describedby ) { 15037 elem.attr( "aria-describedby", describedby ); 15038 } else { 15039 elem.removeAttr( "aria-describedby" ); 15040 } 15041} 15042 15043$.widget( "ui.tooltip", { 15044 version: "1.10.3", 15045 options: { 15046 content: function() { 15047 // support: IE<9, Opera in jQuery <1.7 15048 // .text() can't accept undefined, so coerce to a string 15049 var title = $( this ).attr( "title" ) || ""; 15050 // Escape title, since we're going from an attribute to raw HTML 15051 return $( "<a>" ).text( title ).html(); 15052 }, 15053 hide: true, 15054 // Disabled elements have inconsistent behavior across browsers (#8661) 15055 items: "[title]:not([disabled])", 15056 position: { 15057 my: "left top+15", 15058 at: "left bottom", 15059 collision: "flipfit flip" 15060 }, 15061 show: true, 15062 tooltipClass: null, 15063 track: false, 15064 15065 // callbacks 15066 close: null, 15067 open: null 15068 }, 15069 15070 _create: function() { 15071 this._on({ 15072 mouseover: "open", 15073 focusin: "open" 15074 }); 15075 15076 // IDs of generated tooltips, needed for destroy 15077 this.tooltips = {}; 15078 // IDs of parent tooltips where we removed the title attribute 15079 this.parents = {}; 15080 15081 if ( this.options.disabled ) { 15082 this._disable(); 15083 } 15084 }, 15085 15086 _setOption: function( key, value ) { 15087 var that = this; 15088 15089 if ( key === "disabled" ) { 15090 this[ value ? "_disable" : "_enable" ](); 15091 this.options[ key ] = value; 15092 // disable element style changes 15093 return; 15094 } 15095 15096 this._super( key, value ); 15097 15098 if ( key === "content" ) { 15099 $.each( this.tooltips, function( id, element ) { 15100 that._updateContent( element ); 15101 }); 15102 } 15103 }, 15104 15105 _disable: function() { 15106 var that = this; 15107 15108 // close open tooltips 15109 $.each( this.tooltips, function( id, element ) { 15110 var event = $.Event( "blur" ); 15111 event.target = event.currentTarget = element[0]; 15112 that.close( event, true ); 15113 }); 15114 15115 // remove title attributes to prevent native tooltips 15116 this.element.find( this.options.items ).addBack().each(function() { 15117 var element = $( this ); 15118 if ( element.is( "[title]" ) ) { 15119 element 15120 .data( "ui-tooltip-title", element.attr( "title" ) ) 15121 .attr( "title", "" ); 15122 } 15123 }); 15124 }, 15125 15126 _enable: function() { 15127 // restore title attributes 15128 this.element.find( this.options.items ).addBack().each(function() { 15129 var element = $( this ); 15130 if ( element.data( "ui-tooltip-title" ) ) { 15131 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15132 } 15133 }); 15134 }, 15135 15136 open: function( event ) { 15137 var that = this, 15138 target = $( event ? event.target : this.element ) 15139 // we need closest here due to mouseover bubbling, 15140 // but always pointing at the same event target 15141 .closest( this.options.items ); 15142 15143 // No element to show a tooltip for or the tooltip is already open 15144 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 15145 return; 15146 } 15147 15148 if ( target.attr( "title" ) ) { 15149 target.data( "ui-tooltip-title", target.attr( "title" ) ); 15150 } 15151 15152 target.data( "ui-tooltip-open", true ); 15153 15154 // kill parent tooltips, custom or native, for hover 15155 if ( event && event.type === "mouseover" ) { 15156 target.parents().each(function() { 15157 var parent = $( this ), 15158 blurEvent; 15159 if ( parent.data( "ui-tooltip-open" ) ) { 15160 blurEvent = $.Event( "blur" ); 15161 blurEvent.target = blurEvent.currentTarget = this; 15162 that.close( blurEvent, true ); 15163 } 15164 if ( parent.attr( "title" ) ) { 15165 parent.uniqueId(); 15166 that.parents[ this.id ] = { 15167 element: this, 15168 title: parent.attr( "title" ) 15169 }; 15170 parent.attr( "title", "" ); 15171 } 15172 }); 15173 } 15174 15175 this._updateContent( target, event ); 15176 }, 15177 15178 _updateContent: function( target, event ) { 15179 var content, 15180 contentOption = this.options.content, 15181 that = this, 15182 eventType = event ? event.type : null; 15183 15184 if ( typeof contentOption === "string" ) { 15185 return this._open( event, target, contentOption ); 15186 } 15187 15188 content = contentOption.call( target[0], function( response ) { 15189 // ignore async response if tooltip was closed already 15190 if ( !target.data( "ui-tooltip-open" ) ) { 15191 return; 15192 } 15193 // IE may instantly serve a cached response for ajax requests 15194 // delay this call to _open so the other call to _open runs first 15195 that._delay(function() { 15196 // jQuery creates a special event for focusin when it doesn't 15197 // exist natively. To improve performance, the native event 15198 // object is reused and the type is changed. Therefore, we can't 15199 // rely on the type being correct after the event finished 15200 // bubbling, so we set it back to the previous value. (#8740) 15201 if ( event ) { 15202 event.type = eventType; 15203 } 15204 this._open( event, target, response ); 15205 }); 15206 }); 15207 if ( content ) { 15208 this._open( event, target, content ); 15209 } 15210 }, 15211 15212 _open: function( event, target, content ) { 15213 var tooltip, events, delayedShow, 15214 positionOption = $.extend( {}, this.options.position ); 15215 15216 if ( !content ) { 15217 return; 15218 } 15219 15220 // Content can be updated multiple times. If the tooltip already 15221 // exists, then just update the content and bail. 15222 tooltip = this._find( target ); 15223 if ( tooltip.length ) { 15224 tooltip.find( ".ui-tooltip-content" ).html( content ); 15225 return; 15226 } 15227 15228 // if we have a title, clear it to prevent the native tooltip 15229 // we have to check first to avoid defining a title if none exists 15230 // (we don't want to cause an element to start matching [title]) 15231 // 15232 // We use removeAttr only for key events, to allow IE to export the correct 15233 // accessible attributes. For mouse events, set to empty string to avoid 15234 // native tooltip showing up (happens only when removing inside mouseover). 15235 if ( target.is( "[title]" ) ) { 15236 if ( event && event.type === "mouseover" ) { 15237 target.attr( "title", "" ); 15238 } else { 15239 target.removeAttr( "title" ); 15240 } 15241 } 15242 15243 tooltip = this._tooltip( target ); 15244 addDescribedBy( target, tooltip.attr( "id" ) ); 15245 tooltip.find( ".ui-tooltip-content" ).html( content ); 15246 15247 function position( event ) { 15248 positionOption.of = event; 15249 if ( tooltip.is( ":hidden" ) ) { 15250 return; 15251 } 15252 tooltip.position( positionOption ); 15253 } 15254 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 15255 this._on( this.document, { 15256 mousemove: position 15257 }); 15258 // trigger once to override element-relative positioning 15259 position( event ); 15260 } else { 15261 tooltip.position( $.extend({ 15262 of: target 15263 }, this.options.position ) ); 15264 } 15265 15266 tooltip.hide(); 15267 15268 this._show( tooltip, this.options.show ); 15269 // Handle tracking tooltips that are shown with a delay (#8644). As soon 15270 // as the tooltip is visible, position the tooltip using the most recent 15271 // event. 15272 if ( this.options.show && this.options.show.delay ) { 15273 delayedShow = this.delayedShow = setInterval(function() { 15274 if ( tooltip.is( ":visible" ) ) { 15275 position( positionOption.of ); 15276 clearInterval( delayedShow ); 15277 } 15278 }, $.fx.interval ); 15279 } 15280 15281 this._trigger( "open", event, { tooltip: tooltip } ); 15282 15283 events = { 15284 keyup: function( event ) { 15285 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 15286 var fakeEvent = $.Event(event); 15287 fakeEvent.currentTarget = target[0]; 15288 this.close( fakeEvent, true ); 15289 } 15290 }, 15291 remove: function() { 15292 this._removeTooltip( tooltip ); 15293 } 15294 }; 15295 if ( !event || event.type === "mouseover" ) { 15296 events.mouseleave = "close"; 15297 } 15298 if ( !event || event.type === "focusin" ) { 15299 events.focusout = "close"; 15300 } 15301 this._on( true, target, events ); 15302 }, 15303 15304 close: function( event ) { 15305 var that = this, 15306 target = $( event ? event.currentTarget : this.element ), 15307 tooltip = this._find( target ); 15308 15309 // disabling closes the tooltip, so we need to track when we're closing 15310 // to avoid an infinite loop in case the tooltip becomes disabled on close 15311 if ( this.closing ) { 15312 return; 15313 } 15314 15315 // Clear the interval for delayed tracking tooltips 15316 clearInterval( this.delayedShow ); 15317 15318 // only set title if we had one before (see comment in _open()) 15319 if ( target.data( "ui-tooltip-title" ) ) { 15320 target.attr( "title", target.data( "ui-tooltip-title" ) ); 15321 } 15322 15323 removeDescribedBy( target ); 15324 15325 tooltip.stop( true ); 15326 this._hide( tooltip, this.options.hide, function() { 15327 that._removeTooltip( $( this ) ); 15328 }); 15329 15330 target.removeData( "ui-tooltip-open" ); 15331 this._off( target, "mouseleave focusout keyup" ); 15332 // Remove 'remove' binding only on delegated targets 15333 if ( target[0] !== this.element[0] ) { 15334 this._off( target, "remove" ); 15335 } 15336 this._off( this.document, "mousemove" ); 15337 15338 if ( event && event.type === "mouseleave" ) { 15339 $.each( this.parents, function( id, parent ) { 15340 $( parent.element ).attr( "title", parent.title ); 15341 delete that.parents[ id ]; 15342 }); 15343 } 15344 15345 this.closing = true; 15346 this._trigger( "close", event, { tooltip: tooltip } ); 15347 this.closing = false; 15348 }, 15349 15350 _tooltip: function( element ) { 15351 var id = "ui-tooltip-" + increments++, 15352 tooltip = $( "<div>" ) 15353 .attr({ 15354 id: id, 15355 role: "tooltip" 15356 }) 15357 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 15358 ( this.options.tooltipClass || "" ) ); 15359 $( "<div>" ) 15360 .addClass( "ui-tooltip-content" ) 15361 .appendTo( tooltip ); 15362 tooltip.appendTo( this.document[0].body ); 15363 this.tooltips[ id ] = element; 15364 return tooltip; 15365 }, 15366 15367 _find: function( target ) { 15368 var id = target.data( "ui-tooltip-id" ); 15369 return id ? $( "#" + id ) : $(); 15370 }, 15371 15372 _removeTooltip: function( tooltip ) { 15373 tooltip.remove(); 15374 delete this.tooltips[ tooltip.attr( "id" ) ]; 15375 }, 15376 15377 _destroy: function() { 15378 var that = this; 15379 15380 // close open tooltips 15381 $.each( this.tooltips, function( id, element ) { 15382 // Delegate to close method to handle common cleanup 15383 var event = $.Event( "blur" ); 15384 event.target = event.currentTarget = element[0]; 15385 that.close( event, true ); 15386 15387 // Remove immediately; destroying an open tooltip doesn't use the 15388 // hide animation 15389 $( "#" + id ).remove(); 15390 15391 // Restore the title 15392 if ( element.data( "ui-tooltip-title" ) ) { 15393 element.attr( "title", element.data( "ui-tooltip-title" ) ); 15394 element.removeData( "ui-tooltip-title" ); 15395 } 15396 }); 15397 } 15398}); 15399 15400}( jQuery ) ); 15401(function($, undefined) { 15402 15403var dataSpace = "ui-effects-"; 15404 15405$.effects = { 15406 effect: {} 15407}; 15408 15409/*! 15410 * jQuery Color Animations v2.1.2 15411 * https://github.com/jquery/jquery-color 15412 * 15413 * Copyright 2013 jQuery Foundation and other contributors 15414 * Released under the MIT license. 15415 * http://jquery.org/license 15416 * 15417 * Date: Wed Jan 16 08:47:09 2013 -0600 15418 */ 15419(function( jQuery, undefined ) { 15420 15421 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 15422 15423 // plusequals test for += 100 -= 100 15424 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 15425 // a set of RE's that can match strings and generate color tuples. 15426 stringParsers = [{ 15427 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 15428 parse: function( execResult ) { 15429 return [ 15430 execResult[ 1 ], 15431 execResult[ 2 ], 15432 execResult[ 3 ], 15433 execResult[ 4 ] 15434 ]; 15435 } 15436 }, { 15437 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 15438 parse: function( execResult ) { 15439 return [ 15440 execResult[ 1 ] * 2.55, 15441 execResult[ 2 ] * 2.55, 15442 execResult[ 3 ] * 2.55, 15443 execResult[ 4 ] 15444 ]; 15445 } 15446 }, { 15447 // this regex ignores A-F because it's compared against an already lowercased string 15448 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 15449 parse: function( execResult ) { 15450 return [ 15451 parseInt( execResult[ 1 ], 16 ), 15452 parseInt( execResult[ 2 ], 16 ), 15453 parseInt( execResult[ 3 ], 16 ) 15454 ]; 15455 } 15456 }, { 15457 // this regex ignores A-F because it's compared against an already lowercased string 15458 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 15459 parse: function( execResult ) { 15460 return [ 15461 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 15462 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 15463 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 15464 ]; 15465 } 15466 }, { 15467 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 15468 space: "hsla", 15469 parse: function( execResult ) { 15470 return [ 15471 execResult[ 1 ], 15472 execResult[ 2 ] / 100, 15473 execResult[ 3 ] / 100, 15474 execResult[ 4 ] 15475 ]; 15476 } 15477 }], 15478 15479 // jQuery.Color( ) 15480 color = jQuery.Color = function( color, green, blue, alpha ) { 15481 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 15482 }, 15483 spaces = { 15484 rgba: { 15485 props: { 15486 red: { 15487 idx: 0, 15488 type: "byte" 15489 }, 15490 green: { 15491 idx: 1, 15492 type: "byte" 15493 }, 15494 blue: { 15495 idx: 2, 15496 type: "byte" 15497 } 15498 } 15499 }, 15500 15501 hsla: { 15502 props: { 15503 hue: { 15504 idx: 0, 15505 type: "degrees" 15506 }, 15507 saturation: { 15508 idx: 1, 15509 type: "percent" 15510 }, 15511 lightness: { 15512 idx: 2, 15513 type: "percent" 15514 } 15515 } 15516 } 15517 }, 15518 propTypes = { 15519 "byte": { 15520 floor: true, 15521 max: 255 15522 }, 15523 "percent": { 15524 max: 1 15525 }, 15526 "degrees": { 15527 mod: 360, 15528 floor: true 15529 } 15530 }, 15531 support = color.support = {}, 15532 15533 // element for support tests 15534 supportElem = jQuery( "<p>" )[ 0 ], 15535 15536 // colors = jQuery.Color.names 15537 colors, 15538 15539 // local aliases of functions called often 15540 each = jQuery.each; 15541 15542// determine rgba support immediately 15543supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 15544support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 15545 15546// define cache name and alpha properties 15547// for rgba and hsla spaces 15548each( spaces, function( spaceName, space ) { 15549 space.cache = "_" + spaceName; 15550 space.props.alpha = { 15551 idx: 3, 15552 type: "percent", 15553 def: 1 15554 }; 15555}); 15556 15557function clamp( value, prop, allowEmpty ) { 15558 var type = propTypes[ prop.type ] || {}; 15559 15560 if ( value == null ) { 15561 return (allowEmpty || !prop.def) ? null : prop.def; 15562 } 15563 15564 // ~~ is an short way of doing floor for positive numbers 15565 value = type.floor ? ~~value : parseFloat( value ); 15566 15567 // IE will pass in empty strings as value for alpha, 15568 // which will hit this case 15569 if ( isNaN( value ) ) { 15570 return prop.def; 15571 } 15572 15573 if ( type.mod ) { 15574 // we add mod before modding to make sure that negatives values 15575 // get converted properly: -10 -> 350 15576 return (value + type.mod) % type.mod; 15577 } 15578 15579 // for now all property types without mod have min and max 15580 return 0 > value ? 0 : type.max < value ? type.max : value; 15581} 15582 15583function stringParse( string ) { 15584 var inst = color(), 15585 rgba = inst._rgba = []; 15586 15587 string = string.toLowerCase(); 15588 15589 each( stringParsers, function( i, parser ) { 15590 var parsed, 15591 match = parser.re.exec( string ), 15592 values = match && parser.parse( match ), 15593 spaceName = parser.space || "rgba"; 15594 15595 if ( values ) { 15596 parsed = inst[ spaceName ]( values ); 15597 15598 // if this was an rgba parse the assignment might happen twice 15599 // oh well.... 15600 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 15601 rgba = inst._rgba = parsed._rgba; 15602 15603 // exit each( stringParsers ) here because we matched 15604 return false; 15605 } 15606 }); 15607 15608 // Found a stringParser that handled it 15609 if ( rgba.length ) { 15610 15611 // if this came from a parsed string, force "transparent" when alpha is 0 15612 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 15613 if ( rgba.join() === "0,0,0,0" ) { 15614 jQuery.extend( rgba, colors.transparent ); 15615 } 15616 return inst; 15617 } 15618 15619 // named colors 15620 return colors[ string ]; 15621} 15622 15623color.fn = jQuery.extend( color.prototype, { 15624 parse: function( red, green, blue, alpha ) { 15625 if ( red === undefined ) { 15626 this._rgba = [ null, null, null, null ]; 15627 return this; 15628 } 15629 if ( red.jquery || red.nodeType ) { 15630 red = jQuery( red ).css( green ); 15631 green = undefined; 15632 } 15633 15634 var inst = this, 15635 type = jQuery.type( red ), 15636 rgba = this._rgba = []; 15637 15638 // more than 1 argument specified - assume ( red, green, blue, alpha ) 15639 if ( green !== undefined ) { 15640 red = [ red, green, blue, alpha ]; 15641 type = "array"; 15642 } 15643 15644 if ( type === "string" ) { 15645 return this.parse( stringParse( red ) || colors._default ); 15646 } 15647 15648 if ( type === "array" ) { 15649 each( spaces.rgba.props, function( key, prop ) { 15650 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 15651 }); 15652 return this; 15653 } 15654 15655 if ( type === "object" ) { 15656 if ( red instanceof color ) { 15657 each( spaces, function( spaceName, space ) { 15658 if ( red[ space.cache ] ) { 15659 inst[ space.cache ] = red[ space.cache ].slice(); 15660 } 15661 }); 15662 } else { 15663 each( spaces, function( spaceName, space ) { 15664 var cache = space.cache; 15665 each( space.props, function( key, prop ) { 15666 15667 // if the cache doesn't exist, and we know how to convert 15668 if ( !inst[ cache ] && space.to ) { 15669 15670 // if the value was null, we don't need to copy it 15671 // if the key was alpha, we don't need to copy it either 15672 if ( key === "alpha" || red[ key ] == null ) { 15673 return; 15674 } 15675 inst[ cache ] = space.to( inst._rgba ); 15676 } 15677 15678 // this is the only case where we allow nulls for ALL properties. 15679 // call clamp with alwaysAllowEmpty 15680 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 15681 }); 15682 15683 // everything defined but alpha? 15684 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 15685 // use the default of 1 15686 inst[ cache ][ 3 ] = 1; 15687 if ( space.from ) { 15688 inst._rgba = space.from( inst[ cache ] ); 15689 } 15690 } 15691 }); 15692 } 15693 return this; 15694 } 15695 }, 15696 is: function( compare ) { 15697 var is = color( compare ), 15698 same = true, 15699 inst = this; 15700 15701 each( spaces, function( _, space ) { 15702 var localCache, 15703 isCache = is[ space.cache ]; 15704 if (isCache) { 15705 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 15706 each( space.props, function( _, prop ) { 15707 if ( isCache[ prop.idx ] != null ) { 15708 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 15709 return same; 15710 } 15711 }); 15712 } 15713 return same; 15714 }); 15715 return same; 15716 }, 15717 _space: function() { 15718 var used = [], 15719 inst = this; 15720 each( spaces, function( spaceName, space ) { 15721 if ( inst[ space.cache ] ) { 15722 used.push( spaceName ); 15723 } 15724 }); 15725 return used.pop(); 15726 }, 15727 transition: function( other, distance ) { 15728 var end = color( other ), 15729 spaceName = end._space(), 15730 space = spaces[ spaceName ], 15731 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 15732 start = startColor[ space.cache ] || space.to( startColor._rgba ), 15733 result = start.slice(); 15734 15735 end = end[ space.cache ]; 15736 each( space.props, function( key, prop ) { 15737 var index = prop.idx, 15738 startValue = start[ index ], 15739 endValue = end[ index ], 15740 type = propTypes[ prop.type ] || {}; 15741 15742 // if null, don't override start value 15743 if ( endValue === null ) { 15744 return; 15745 } 15746 // if null - use end 15747 if ( startValue === null ) { 15748 result[ index ] = endValue; 15749 } else { 15750 if ( type.mod ) { 15751 if ( endValue - startValue > type.mod / 2 ) { 15752 startValue += type.mod; 15753 } else if ( startValue - endValue > type.mod / 2 ) { 15754 startValue -= type.mod; 15755 } 15756 } 15757 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 15758 } 15759 }); 15760 return this[ spaceName ]( result ); 15761 }, 15762 blend: function( opaque ) { 15763 // if we are already opaque - return ourself 15764 if ( this._rgba[ 3 ] === 1 ) { 15765 return this; 15766 } 15767 15768 var rgb = this._rgba.slice(), 15769 a = rgb.pop(), 15770 blend = color( opaque )._rgba; 15771 15772 return color( jQuery.map( rgb, function( v, i ) { 15773 return ( 1 - a ) * blend[ i ] + a * v; 15774 })); 15775 }, 15776 toRgbaString: function() { 15777 var prefix = "rgba(", 15778 rgba = jQuery.map( this._rgba, function( v, i ) { 15779 return v == null ? ( i > 2 ? 1 : 0 ) : v; 15780 }); 15781 15782 if ( rgba[ 3 ] === 1 ) { 15783 rgba.pop(); 15784 prefix = "rgb("; 15785 } 15786 15787 return prefix + rgba.join() + ")"; 15788 }, 15789 toHslaString: function() { 15790 var prefix = "hsla(", 15791 hsla = jQuery.map( this.hsla(), function( v, i ) { 15792 if ( v == null ) { 15793 v = i > 2 ? 1 : 0; 15794 } 15795 15796 // catch 1 and 2 15797 if ( i && i < 3 ) { 15798 v = Math.round( v * 100 ) + "%"; 15799 } 15800 return v; 15801 }); 15802 15803 if ( hsla[ 3 ] === 1 ) { 15804 hsla.pop(); 15805 prefix = "hsl("; 15806 } 15807 return prefix + hsla.join() + ")"; 15808 }, 15809 toHexString: function( includeAlpha ) { 15810 var rgba = this._rgba.slice(), 15811 alpha = rgba.pop(); 15812 15813 if ( includeAlpha ) { 15814 rgba.push( ~~( alpha * 255 ) ); 15815 } 15816 15817 return "#" + jQuery.map( rgba, function( v ) { 15818 15819 // default to 0 when nulls exist 15820 v = ( v || 0 ).toString( 16 ); 15821 return v.length === 1 ? "0" + v : v; 15822 }).join(""); 15823 }, 15824 toString: function() { 15825 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 15826 } 15827}); 15828color.fn.parse.prototype = color.fn; 15829 15830// hsla conversions adapted from: 15831// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 15832 15833function hue2rgb( p, q, h ) { 15834 h = ( h + 1 ) % 1; 15835 if ( h * 6 < 1 ) { 15836 return p + (q - p) * h * 6; 15837 } 15838 if ( h * 2 < 1) { 15839 return q; 15840 } 15841 if ( h * 3 < 2 ) { 15842 return p + (q - p) * ((2/3) - h) * 6; 15843 } 15844 return p; 15845} 15846 15847spaces.hsla.to = function ( rgba ) { 15848 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 15849 return [ null, null, null, rgba[ 3 ] ]; 15850 } 15851 var r = rgba[ 0 ] / 255, 15852 g = rgba[ 1 ] / 255, 15853 b = rgba[ 2 ] / 255, 15854 a = rgba[ 3 ], 15855 max = Math.max( r, g, b ), 15856 min = Math.min( r, g, b ), 15857 diff = max - min, 15858 add = max + min, 15859 l = add * 0.5, 15860 h, s; 15861 15862 if ( min === max ) { 15863 h = 0; 15864 } else if ( r === max ) { 15865 h = ( 60 * ( g - b ) / diff ) + 360; 15866 } else if ( g === max ) { 15867 h = ( 60 * ( b - r ) / diff ) + 120; 15868 } else { 15869 h = ( 60 * ( r - g ) / diff ) + 240; 15870 } 15871 15872 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 15873 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 15874 if ( diff === 0 ) { 15875 s = 0; 15876 } else if ( l <= 0.5 ) { 15877 s = diff / add; 15878 } else { 15879 s = diff / ( 2 - add ); 15880 } 15881 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 15882}; 15883 15884spaces.hsla.from = function ( hsla ) { 15885 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 15886 return [ null, null, null, hsla[ 3 ] ]; 15887 } 15888 var h = hsla[ 0 ] / 360, 15889 s = hsla[ 1 ], 15890 l = hsla[ 2 ], 15891 a = hsla[ 3 ], 15892 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 15893 p = 2 * l - q; 15894 15895 return [ 15896 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 15897 Math.round( hue2rgb( p, q, h ) * 255 ), 15898 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 15899 a 15900 ]; 15901}; 15902 15903 15904each( spaces, function( spaceName, space ) { 15905 var props = space.props, 15906 cache = space.cache, 15907 to = space.to, 15908 from = space.from; 15909 15910 // makes rgba() and hsla() 15911 color.fn[ spaceName ] = function( value ) { 15912 15913 // generate a cache for this space if it doesn't exist 15914 if ( to && !this[ cache ] ) { 15915 this[ cache ] = to( this._rgba ); 15916 } 15917 if ( value === undefined ) { 15918 return this[ cache ].slice(); 15919 } 15920 15921 var ret, 15922 type = jQuery.type( value ), 15923 arr = ( type === "array" || type === "object" ) ? value : arguments, 15924 local = this[ cache ].slice(); 15925 15926 each( props, function( key, prop ) { 15927 var val = arr[ type === "object" ? key : prop.idx ]; 15928 if ( val == null ) { 15929 val = local[ prop.idx ]; 15930 } 15931 local[ prop.idx ] = clamp( val, prop ); 15932 }); 15933 15934 if ( from ) { 15935 ret = color( from( local ) ); 15936 ret[ cache ] = local; 15937 return ret; 15938 } else { 15939 return color( local ); 15940 } 15941 }; 15942 15943 // makes red() green() blue() alpha() hue() saturation() lightness() 15944 each( props, function( key, prop ) { 15945 // alpha is included in more than one space 15946 if ( color.fn[ key ] ) { 15947 return; 15948 } 15949 color.fn[ key ] = function( value ) { 15950 var vtype = jQuery.type( value ), 15951 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 15952 local = this[ fn ](), 15953 cur = local[ prop.idx ], 15954 match; 15955 15956 if ( vtype === "undefined" ) { 15957 return cur; 15958 } 15959 15960 if ( vtype === "function" ) { 15961 value = value.call( this, cur ); 15962 vtype = jQuery.type( value ); 15963 } 15964 if ( value == null && prop.empty ) { 15965 return this; 15966 } 15967 if ( vtype === "string" ) { 15968 match = rplusequals.exec( value ); 15969 if ( match ) { 15970 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 15971 } 15972 } 15973 local[ prop.idx ] = value; 15974 return this[ fn ]( local ); 15975 }; 15976 }); 15977}); 15978 15979// add cssHook and .fx.step function for each named hook. 15980// accept a space separated string of properties 15981color.hook = function( hook ) { 15982 var hooks = hook.split( " " ); 15983 each( hooks, function( i, hook ) { 15984 jQuery.cssHooks[ hook ] = { 15985 set: function( elem, value ) { 15986 var parsed, curElem, 15987 backgroundColor = ""; 15988 15989 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 15990 value = color( parsed || value ); 15991 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 15992 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 15993 while ( 15994 (backgroundColor === "" || backgroundColor === "transparent") && 15995 curElem && curElem.style 15996 ) { 15997 try { 15998 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 15999 curElem = curElem.parentNode; 16000 } catch ( e ) { 16001 } 16002 } 16003 16004 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 16005 backgroundColor : 16006 "_default" ); 16007 } 16008 16009 value = value.toRgbaString(); 16010 } 16011 try { 16012 elem.style[ hook ] = value; 16013 } catch( e ) { 16014 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 16015 } 16016 } 16017 }; 16018 jQuery.fx.step[ hook ] = function( fx ) { 16019 if ( !fx.colorInit ) { 16020 fx.start = color( fx.elem, hook ); 16021 fx.end = color( fx.end ); 16022 fx.colorInit = true; 16023 } 16024 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 16025 }; 16026 }); 16027 16028}; 16029 16030color.hook( stepHooks ); 16031 16032jQuery.cssHooks.borderColor = { 16033 expand: function( value ) { 16034 var expanded = {}; 16035 16036 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 16037 expanded[ "border" + part + "Color" ] = value; 16038 }); 16039 return expanded; 16040 } 16041}; 16042 16043// Basic color names only. 16044// Usage of any of the other color names requires adding yourself or including 16045// jquery.color.svg-names.js. 16046colors = jQuery.Color.names = { 16047 // 4.1. Basic color keywords 16048 aqua: "#00ffff", 16049 black: "#000000", 16050 blue: "#0000ff", 16051 fuchsia: "#ff00ff", 16052 gray: "#808080", 16053 green: "#008000", 16054 lime: "#00ff00", 16055 maroon: "#800000", 16056 navy: "#000080", 16057 olive: "#808000", 16058 purple: "#800080", 16059 red: "#ff0000", 16060 silver: "#c0c0c0", 16061 teal: "#008080", 16062 white: "#ffffff", 16063 yellow: "#ffff00", 16064 16065 // 4.2.3. "transparent" color keyword 16066 transparent: [ null, null, null, 0 ], 16067 16068 _default: "#ffffff" 16069}; 16070 16071})( jQuery ); 16072 16073 16074/******************************************************************************/ 16075/****************************** CLASS ANIMATIONS ******************************/ 16076/******************************************************************************/ 16077(function() { 16078 16079var classAnimationActions = [ "add", "remove", "toggle" ], 16080 shorthandStyles = { 16081 border: 1, 16082 borderBottom: 1, 16083 borderColor: 1, 16084 borderLeft: 1, 16085 borderRight: 1, 16086 borderTop: 1, 16087 borderWidth: 1, 16088 margin: 1, 16089 padding: 1 16090 }; 16091 16092$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 16093 $.fx.step[ prop ] = function( fx ) { 16094 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 16095 jQuery.style( fx.elem, prop, fx.end ); 16096 fx.setAttr = true; 16097 } 16098 }; 16099}); 16100 16101function getElementStyles( elem ) { 16102 var key, len, 16103 style = elem.ownerDocument.defaultView ? 16104 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 16105 elem.currentStyle, 16106 styles = {}; 16107 16108 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 16109 len = style.length; 16110 while ( len-- ) { 16111 key = style[ len ]; 16112 if ( typeof style[ key ] === "string" ) { 16113 styles[ $.camelCase( key ) ] = style[ key ]; 16114 } 16115 } 16116 // support: Opera, IE <9 16117 } else { 16118 for ( key in style ) { 16119 if ( typeof style[ key ] === "string" ) { 16120 styles[ key ] = style[ key ]; 16121 } 16122 } 16123 } 16124 16125 return styles; 16126} 16127 16128 16129function styleDifference( oldStyle, newStyle ) { 16130 var diff = {}, 16131 name, value; 16132 16133 for ( name in newStyle ) { 16134 value = newStyle[ name ]; 16135 if ( oldStyle[ name ] !== value ) { 16136 if ( !shorthandStyles[ name ] ) { 16137 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 16138 diff[ name ] = value; 16139 } 16140 } 16141 } 16142 } 16143 16144 return diff; 16145} 16146 16147// support: jQuery <1.8 16148if ( !$.fn.addBack ) { 16149 $.fn.addBack = function( selector ) { 16150 return this.add( selector == null ? 16151 this.prevObject : this.prevObject.filter( selector ) 16152 ); 16153 }; 16154} 16155 16156$.effects.animateClass = function( value, duration, easing, callback ) { 16157 var o = $.speed( duration, easing, callback ); 16158 16159 return this.queue( function() { 16160 var animated = $( this ), 16161 baseClass = animated.attr( "class" ) || "", 16162 applyClassChange, 16163 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 16164 16165 // map the animated objects to store the original styles. 16166 allAnimations = allAnimations.map(function() { 16167 var el = $( this ); 16168 return { 16169 el: el, 16170 start: getElementStyles( this ) 16171 }; 16172 }); 16173 16174 // apply class change 16175 applyClassChange = function() { 16176 $.each( classAnimationActions, function(i, action) { 16177 if ( value[ action ] ) { 16178 animated[ action + "Class" ]( value[ action ] ); 16179 } 16180 }); 16181 }; 16182 applyClassChange(); 16183 16184 // map all animated objects again - calculate new styles and diff 16185 allAnimations = allAnimations.map(function() { 16186 this.end = getElementStyles( this.el[ 0 ] ); 16187 this.diff = styleDifference( this.start, this.end ); 16188 return this; 16189 }); 16190 16191 // apply original class 16192 animated.attr( "class", baseClass ); 16193 16194 // map all animated objects again - this time collecting a promise 16195 allAnimations = allAnimations.map(function() { 16196 var styleInfo = this, 16197 dfd = $.Deferred(), 16198 opts = $.extend({}, o, { 16199 queue: false, 16200 complete: function() { 16201 dfd.resolve( styleInfo ); 16202 } 16203 }); 16204 16205 this.el.animate( this.diff, opts ); 16206 return dfd.promise(); 16207 }); 16208 16209 // once all animations have completed: 16210 $.when.apply( $, allAnimations.get() ).done(function() { 16211 16212 // set the final class 16213 applyClassChange(); 16214 16215 // for each animated element, 16216 // clear all css properties that were animated 16217 $.each( arguments, function() { 16218 var el = this.el; 16219 $.each( this.diff, function(key) { 16220 el.css( key, "" ); 16221 }); 16222 }); 16223 16224 // this is guarnteed to be there if you use jQuery.speed() 16225 // it also handles dequeuing the next anim... 16226 o.complete.call( animated[ 0 ] ); 16227 }); 16228 }); 16229}; 16230 16231$.fn.extend({ 16232 addClass: (function( orig ) { 16233 return function( classNames, speed, easing, callback ) { 16234 return speed ? 16235 $.effects.animateClass.call( this, 16236 { add: classNames }, speed, easing, callback ) : 16237 orig.apply( this, arguments ); 16238 }; 16239 })( $.fn.addClass ), 16240 16241 removeClass: (function( orig ) { 16242 return function( classNames, speed, easing, callback ) { 16243 return arguments.length > 1 ? 16244 $.effects.animateClass.call( this, 16245 { remove: classNames }, speed, easing, callback ) : 16246 orig.apply( this, arguments ); 16247 }; 16248 })( $.fn.removeClass ), 16249 16250 toggleClass: (function( orig ) { 16251 return function( classNames, force, speed, easing, callback ) { 16252 if ( typeof force === "boolean" || force === undefined ) { 16253 if ( !speed ) { 16254 // without speed parameter 16255 return orig.apply( this, arguments ); 16256 } else { 16257 return $.effects.animateClass.call( this, 16258 (force ? { add: classNames } : { remove: classNames }), 16259 speed, easing, callback ); 16260 } 16261 } else { 16262 // without force parameter 16263 return $.effects.animateClass.call( this, 16264 { toggle: classNames }, force, speed, easing ); 16265 } 16266 }; 16267 })( $.fn.toggleClass ), 16268 16269 switchClass: function( remove, add, speed, easing, callback) { 16270 return $.effects.animateClass.call( this, { 16271 add: add, 16272 remove: remove 16273 }, speed, easing, callback ); 16274 } 16275}); 16276 16277})(); 16278 16279/******************************************************************************/ 16280/*********************************** EFFECTS **********************************/ 16281/******************************************************************************/ 16282 16283(function() { 16284 16285$.extend( $.effects, { 16286 version: "1.10.3", 16287 16288 // Saves a set of properties in a data storage 16289 save: function( element, set ) { 16290 for( var i=0; i < set.length; i++ ) { 16291 if ( set[ i ] !== null ) { 16292 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 16293 } 16294 } 16295 }, 16296 16297 // Restores a set of previously saved properties from a data storage 16298 restore: function( element, set ) { 16299 var val, i; 16300 for( i=0; i < set.length; i++ ) { 16301 if ( set[ i ] !== null ) { 16302 val = element.data( dataSpace + set[ i ] ); 16303 // support: jQuery 1.6.2 16304 // http://bugs.jquery.com/ticket/9917 16305 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 16306 // We can't differentiate between "" and 0 here, so we just assume 16307 // empty string since it's likely to be a more common value... 16308 if ( val === undefined ) { 16309 val = ""; 16310 } 16311 element.css( set[ i ], val ); 16312 } 16313 } 16314 }, 16315 16316 setMode: function( el, mode ) { 16317 if (mode === "toggle") { 16318 mode = el.is( ":hidden" ) ? "show" : "hide"; 16319 } 16320 return mode; 16321 }, 16322 16323 // Translates a [top,left] array into a baseline value 16324 // this should be a little more flexible in the future to handle a string & hash 16325 getBaseline: function( origin, original ) { 16326 var y, x; 16327 switch ( origin[ 0 ] ) { 16328 case "top": y = 0; break; 16329 case "middle": y = 0.5; break; 16330 case "bottom": y = 1; break; 16331 default: y = origin[ 0 ] / original.height; 16332 } 16333 switch ( origin[ 1 ] ) { 16334 case "left": x = 0; break; 16335 case "center": x = 0.5; break; 16336 case "right": x = 1; break; 16337 default: x = origin[ 1 ] / original.width; 16338 } 16339 return { 16340 x: x, 16341 y: y 16342 }; 16343 }, 16344 16345 // Wraps the element around a wrapper that copies position properties 16346 createWrapper: function( element ) { 16347 16348 // if the element is already wrapped, return it 16349 if ( element.parent().is( ".ui-effects-wrapper" )) { 16350 return element.parent(); 16351 } 16352 16353 // wrap the element 16354 var props = { 16355 width: element.outerWidth(true), 16356 height: element.outerHeight(true), 16357 "float": element.css( "float" ) 16358 }, 16359 wrapper = $( "<div></div>" ) 16360 .addClass( "ui-effects-wrapper" ) 16361 .css({ 16362 fontSize: "100%", 16363 background: "transparent", 16364 border: "none", 16365 margin: 0, 16366 padding: 0 16367 }), 16368 // Store the size in case width/height are defined in % - Fixes #5245 16369 size = { 16370 width: element.width(), 16371 height: element.height() 16372 }, 16373 active = document.activeElement; 16374 16375 // support: Firefox 16376 // Firefox incorrectly exposes anonymous content 16377 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 16378 try { 16379 active.id; 16380 } catch( e ) { 16381 active = document.body; 16382 } 16383 16384 element.wrap( wrapper ); 16385 16386 // Fixes #7595 - Elements lose focus when wrapped. 16387 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 16388 $( active ).focus(); 16389 } 16390 16391 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 16392 16393 // transfer positioning properties to the wrapper 16394 if ( element.css( "position" ) === "static" ) { 16395 wrapper.css({ position: "relative" }); 16396 element.css({ position: "relative" }); 16397 } else { 16398 $.extend( props, { 16399 position: element.css( "position" ), 16400 zIndex: element.css( "z-index" ) 16401 }); 16402 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 16403 props[ pos ] = element.css( pos ); 16404 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 16405 props[ pos ] = "auto"; 16406 } 16407 }); 16408 element.css({ 16409 position: "relative", 16410 top: 0, 16411 left: 0, 16412 right: "auto", 16413 bottom: "auto" 16414 }); 16415 } 16416 element.css(size); 16417 16418 return wrapper.css( props ).show(); 16419 }, 16420 16421 removeWrapper: function( element ) { 16422 var active = document.activeElement; 16423 16424 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 16425 element.parent().replaceWith( element ); 16426 16427 // Fixes #7595 - Elements lose focus when wrapped. 16428 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 16429 $( active ).focus(); 16430 } 16431 } 16432 16433 16434 return element; 16435 }, 16436 16437 setTransition: function( element, list, factor, value ) { 16438 value = value || {}; 16439 $.each( list, function( i, x ) { 16440 var unit = element.cssUnit( x ); 16441 if ( unit[ 0 ] > 0 ) { 16442 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 16443 } 16444 }); 16445 return value; 16446 } 16447}); 16448 16449// return an effect options object for the given parameters: 16450function _normalizeArguments( effect, options, speed, callback ) { 16451 16452 // allow passing all options as the first parameter 16453 if ( $.isPlainObject( effect ) ) { 16454 options = effect; 16455 effect = effect.effect; 16456 } 16457 16458 // convert to an object 16459 effect = { effect: effect }; 16460 16461 // catch (effect, null, ...) 16462 if ( options == null ) { 16463 options = {}; 16464 } 16465 16466 // catch (effect, callback) 16467 if ( $.isFunction( options ) ) { 16468 callback = options; 16469 speed = null; 16470 options = {}; 16471 } 16472 16473 // catch (effect, speed, ?) 16474 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 16475 callback = speed; 16476 speed = options; 16477 options = {}; 16478 } 16479 16480 // catch (effect, options, callback) 16481 if ( $.isFunction( speed ) ) { 16482 callback = speed; 16483 speed = null; 16484 } 16485 16486 // add options to effect 16487 if ( options ) { 16488 $.extend( effect, options ); 16489 } 16490 16491 speed = speed || options.duration; 16492 effect.duration = $.fx.off ? 0 : 16493 typeof speed === "number" ? speed : 16494 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 16495 $.fx.speeds._default; 16496 16497 effect.complete = callback || options.complete; 16498 16499 return effect; 16500} 16501 16502function standardAnimationOption( option ) { 16503 // Valid standard speeds (nothing, number, named speed) 16504 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 16505 return true; 16506 } 16507 16508 // Invalid strings - treat as "normal" speed 16509 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 16510 return true; 16511 } 16512 16513 // Complete callback 16514 if ( $.isFunction( option ) ) { 16515 return true; 16516 } 16517 16518 // Options hash (but not naming an effect) 16519 if ( typeof option === "object" && !option.effect ) { 16520 return true; 16521 } 16522 16523 // Didn't match any standard API 16524 return false; 16525} 16526 16527$.fn.extend({ 16528 effect: function( /* effect, options, speed, callback */ ) { 16529 var args = _normalizeArguments.apply( this, arguments ), 16530 mode = args.mode, 16531 queue = args.queue, 16532 effectMethod = $.effects.effect[ args.effect ]; 16533 16534 if ( $.fx.off || !effectMethod ) { 16535 // delegate to the original method (e.g., .show()) if possible 16536 if ( mode ) { 16537 return this[ mode ]( args.duration, args.complete ); 16538 } else { 16539 return this.each( function() { 16540 if ( args.complete ) { 16541 args.complete.call( this ); 16542 } 16543 }); 16544 } 16545 } 16546 16547 function run( next ) { 16548 var elem = $( this ), 16549 complete = args.complete, 16550 mode = args.mode; 16551 16552 function done() { 16553 if ( $.isFunction( complete ) ) { 16554 complete.call( elem[0] ); 16555 } 16556 if ( $.isFunction( next ) ) { 16557 next(); 16558 } 16559 } 16560 16561 // If the element already has the correct final state, delegate to 16562 // the core methods so the internal tracking of "olddisplay" works. 16563 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 16564 elem[ mode ](); 16565 done(); 16566 } else { 16567 effectMethod.call( elem[0], args, done ); 16568 } 16569 } 16570 16571 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 16572 }, 16573 16574 show: (function( orig ) { 16575 return function( option ) { 16576 if ( standardAnimationOption( option ) ) { 16577 return orig.apply( this, arguments ); 16578 } else { 16579 var args = _normalizeArguments.apply( this, arguments ); 16580 args.mode = "show"; 16581 return this.effect.call( this, args ); 16582 } 16583 }; 16584 })( $.fn.show ), 16585 16586 hide: (function( orig ) { 16587 return function( option ) { 16588 if ( standardAnimationOption( option ) ) { 16589 return orig.apply( this, arguments ); 16590 } else { 16591 var args = _normalizeArguments.apply( this, arguments ); 16592 args.mode = "hide"; 16593 return this.effect.call( this, args ); 16594 } 16595 }; 16596 })( $.fn.hide ), 16597 16598 toggle: (function( orig ) { 16599 return function( option ) { 16600 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 16601 return orig.apply( this, arguments ); 16602 } else { 16603 var args = _normalizeArguments.apply( this, arguments ); 16604 args.mode = "toggle"; 16605 return this.effect.call( this, args ); 16606 } 16607 }; 16608 })( $.fn.toggle ), 16609 16610 // helper functions 16611 cssUnit: function(key) { 16612 var style = this.css( key ), 16613 val = []; 16614 16615 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 16616 if ( style.indexOf( unit ) > 0 ) { 16617 val = [ parseFloat( style ), unit ]; 16618 } 16619 }); 16620 return val; 16621 } 16622}); 16623 16624})(); 16625 16626/******************************************************************************/ 16627/*********************************** EASING ***********************************/ 16628/******************************************************************************/ 16629 16630(function() { 16631 16632// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 16633 16634var baseEasings = {}; 16635 16636$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 16637 baseEasings[ name ] = function( p ) { 16638 return Math.pow( p, i + 2 ); 16639 }; 16640}); 16641 16642$.extend( baseEasings, { 16643 Sine: function ( p ) { 16644 return 1 - Math.cos( p * Math.PI / 2 ); 16645 }, 16646 Circ: function ( p ) { 16647 return 1 - Math.sqrt( 1 - p * p ); 16648 }, 16649 Elastic: function( p ) { 16650 return p === 0 || p === 1 ? p : 16651 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 16652 }, 16653 Back: function( p ) { 16654 return p * p * ( 3 * p - 2 ); 16655 }, 16656 Bounce: function ( p ) { 16657 var pow2, 16658 bounce = 4; 16659 16660 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 16661 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 16662 } 16663}); 16664 16665$.each( baseEasings, function( name, easeIn ) { 16666 $.easing[ "easeIn" + name ] = easeIn; 16667 $.easing[ "easeOut" + name ] = function( p ) { 16668 return 1 - easeIn( 1 - p ); 16669 }; 16670 $.easing[ "easeInOut" + name ] = function( p ) { 16671 return p < 0.5 ? 16672 easeIn( p * 2 ) / 2 : 16673 1 - easeIn( p * -2 + 2 ) / 2; 16674 }; 16675}); 16676 16677})(); 16678 16679})(jQuery); 16680(function( $, undefined ) { 16681 16682var rvertical = /up|down|vertical/, 16683 rpositivemotion = /up|left|vertical|horizontal/; 16684 16685$.effects.effect.blind = function( o, done ) { 16686 // Create element 16687 var el = $( this ), 16688 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 16689 mode = $.effects.setMode( el, o.mode || "hide" ), 16690 direction = o.direction || "up", 16691 vertical = rvertical.test( direction ), 16692 ref = vertical ? "height" : "width", 16693 ref2 = vertical ? "top" : "left", 16694 motion = rpositivemotion.test( direction ), 16695 animation = {}, 16696 show = mode === "show", 16697 wrapper, distance, margin; 16698 16699 // if already wrapped, the wrapper's properties are my property. #6245 16700 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 16701 $.effects.save( el.parent(), props ); 16702 } else { 16703 $.effects.save( el, props ); 16704 } 16705 el.show(); 16706 wrapper = $.effects.createWrapper( el ).css({ 16707 overflow: "hidden" 16708 }); 16709 16710 distance = wrapper[ ref ](); 16711 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 16712 16713 animation[ ref ] = show ? distance : 0; 16714 if ( !motion ) { 16715 el 16716 .css( vertical ? "bottom" : "right", 0 ) 16717 .css( vertical ? "top" : "left", "auto" ) 16718 .css({ position: "absolute" }); 16719 16720 animation[ ref2 ] = show ? margin : distance + margin; 16721 } 16722 16723 // start at 0 if we are showing 16724 if ( show ) { 16725 wrapper.css( ref, 0 ); 16726 if ( ! motion ) { 16727 wrapper.css( ref2, margin + distance ); 16728 } 16729 } 16730 16731 // Animate 16732 wrapper.animate( animation, { 16733 duration: o.duration, 16734 easing: o.easing, 16735 queue: false, 16736 complete: function() { 16737 if ( mode === "hide" ) { 16738 el.hide(); 16739 } 16740 $.effects.restore( el, props ); 16741 $.effects.removeWrapper( el ); 16742 done(); 16743 } 16744 }); 16745 16746}; 16747 16748})(jQuery); 16749(function( $, undefined ) { 16750 16751$.effects.effect.bounce = function( o, done ) { 16752 var el = $( this ), 16753 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 16754 16755 // defaults: 16756 mode = $.effects.setMode( el, o.mode || "effect" ), 16757 hide = mode === "hide", 16758 show = mode === "show", 16759 direction = o.direction || "up", 16760 distance = o.distance, 16761 times = o.times || 5, 16762 16763 // number of internal animations 16764 anims = times * 2 + ( show || hide ? 1 : 0 ), 16765 speed = o.duration / anims, 16766 easing = o.easing, 16767 16768 // utility: 16769 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 16770 motion = ( direction === "up" || direction === "left" ), 16771 i, 16772 upAnim, 16773 downAnim, 16774 16775 // we will need to re-assemble the queue to stack our animations in place 16776 queue = el.queue(), 16777 queuelen = queue.length; 16778 16779 // Avoid touching opacity to prevent clearType and PNG issues in IE 16780 if ( show || hide ) { 16781 props.push( "opacity" ); 16782 } 16783 16784 $.effects.save( el, props ); 16785 el.show(); 16786 $.effects.createWrapper( el ); // Create Wrapper 16787 16788 // default distance for the BIGGEST bounce is the outer Distance / 3 16789 if ( !distance ) { 16790 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 16791 } 16792 16793 if ( show ) { 16794 downAnim = { opacity: 1 }; 16795 downAnim[ ref ] = 0; 16796 16797 // if we are showing, force opacity 0 and set the initial position 16798 // then do the "first" animation 16799 el.css( "opacity", 0 ) 16800 .css( ref, motion ? -distance * 2 : distance * 2 ) 16801 .animate( downAnim, speed, easing ); 16802 } 16803 16804 // start at the smallest distance if we are hiding 16805 if ( hide ) { 16806 distance = distance / Math.pow( 2, times - 1 ); 16807 } 16808 16809 downAnim = {}; 16810 downAnim[ ref ] = 0; 16811 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 16812 for ( i = 0; i < times; i++ ) { 16813 upAnim = {}; 16814 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 16815 16816 el.animate( upAnim, speed, easing ) 16817 .animate( downAnim, speed, easing ); 16818 16819 distance = hide ? distance * 2 : distance / 2; 16820 } 16821 16822 // Last Bounce when Hiding 16823 if ( hide ) { 16824 upAnim = { opacity: 0 }; 16825 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 16826 16827 el.animate( upAnim, speed, easing ); 16828 } 16829 16830 el.queue(function() { 16831 if ( hide ) { 16832 el.hide(); 16833 } 16834 $.effects.restore( el, props ); 16835 $.effects.removeWrapper( el ); 16836 done(); 16837 }); 16838 16839 // inject all the animations we just queued to be first in line (after "inprogress") 16840 if ( queuelen > 1) { 16841 queue.splice.apply( queue, 16842 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 16843 } 16844 el.dequeue(); 16845 16846}; 16847 16848})(jQuery); 16849(function( $, undefined ) { 16850 16851$.effects.effect.clip = function( o, done ) { 16852 // Create element 16853 var el = $( this ), 16854 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 16855 mode = $.effects.setMode( el, o.mode || "hide" ), 16856 show = mode === "show", 16857 direction = o.direction || "vertical", 16858 vert = direction === "vertical", 16859 size = vert ? "height" : "width", 16860 position = vert ? "top" : "left", 16861 animation = {}, 16862 wrapper, animate, distance; 16863 16864 // Save & Show 16865 $.effects.save( el, props ); 16866 el.show(); 16867 16868 // Create Wrapper 16869 wrapper = $.effects.createWrapper( el ).css({ 16870 overflow: "hidden" 16871 }); 16872 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 16873 distance = animate[ size ](); 16874 16875 // Shift 16876 if ( show ) { 16877 animate.css( size, 0 ); 16878 animate.css( position, distance / 2 ); 16879 } 16880 16881 // Create Animation Object: 16882 animation[ size ] = show ? distance : 0; 16883 animation[ position ] = show ? 0 : distance / 2; 16884 16885 // Animate 16886 animate.animate( animation, { 16887 queue: false, 16888 duration: o.duration, 16889 easing: o.easing, 16890 complete: function() { 16891 if ( !show ) { 16892 el.hide(); 16893 } 16894 $.effects.restore( el, props ); 16895 $.effects.removeWrapper( el ); 16896 done(); 16897 } 16898 }); 16899 16900}; 16901 16902})(jQuery); 16903(function( $, undefined ) { 16904 16905$.effects.effect.drop = function( o, done ) { 16906 16907 var el = $( this ), 16908 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 16909 mode = $.effects.setMode( el, o.mode || "hide" ), 16910 show = mode === "show", 16911 direction = o.direction || "left", 16912 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 16913 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 16914 animation = { 16915 opacity: show ? 1 : 0 16916 }, 16917 distance; 16918 16919 // Adjust 16920 $.effects.save( el, props ); 16921 el.show(); 16922 $.effects.createWrapper( el ); 16923 16924 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 16925 16926 if ( show ) { 16927 el 16928 .css( "opacity", 0 ) 16929 .css( ref, motion === "pos" ? -distance : distance ); 16930 } 16931 16932 // Animation 16933 animation[ ref ] = ( show ? 16934 ( motion === "pos" ? "+=" : "-=" ) : 16935 ( motion === "pos" ? "-=" : "+=" ) ) + 16936 distance; 16937 16938 // Animate 16939 el.animate( animation, { 16940 queue: false, 16941 duration: o.duration, 16942 easing: o.easing, 16943 complete: function() { 16944 if ( mode === "hide" ) { 16945 el.hide(); 16946 } 16947 $.effects.restore( el, props ); 16948 $.effects.removeWrapper( el ); 16949 done(); 16950 } 16951 }); 16952}; 16953 16954})(jQuery); 16955(function( $, undefined ) { 16956 16957$.effects.effect.explode = function( o, done ) { 16958 16959 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 16960 cells = rows, 16961 el = $( this ), 16962 mode = $.effects.setMode( el, o.mode || "hide" ), 16963 show = mode === "show", 16964 16965 // show and then visibility:hidden the element before calculating offset 16966 offset = el.show().css( "visibility", "hidden" ).offset(), 16967 16968 // width and height of a piece 16969 width = Math.ceil( el.outerWidth() / cells ), 16970 height = Math.ceil( el.outerHeight() / rows ), 16971 pieces = [], 16972 16973 // loop 16974 i, j, left, top, mx, my; 16975 16976 // children animate complete: 16977 function childComplete() { 16978 pieces.push( this ); 16979 if ( pieces.length === rows * cells ) { 16980 animComplete(); 16981 } 16982 } 16983 16984 // clone the element for each row and cell. 16985 for( i = 0; i < rows ; i++ ) { // ===> 16986 top = offset.top + i * height; 16987 my = i - ( rows - 1 ) / 2 ; 16988 16989 for( j = 0; j < cells ; j++ ) { // ||| 16990 left = offset.left + j * width; 16991 mx = j - ( cells - 1 ) / 2 ; 16992 16993 // Create a clone of the now hidden main element that will be absolute positioned 16994 // within a wrapper div off the -left and -top equal to size of our pieces 16995 el 16996 .clone() 16997 .appendTo( "body" ) 16998 .wrap( "<div></div>" ) 16999 .css({ 17000 position: "absolute", 17001 visibility: "visible", 17002 left: -j * width, 17003 top: -i * height 17004 }) 17005 17006 // select the wrapper - make it overflow: hidden and absolute positioned based on 17007 // where the original was located +left and +top equal to the size of pieces 17008 .parent() 17009 .addClass( "ui-effects-explode" ) 17010 .css({ 17011 position: "absolute", 17012 overflow: "hidden", 17013 width: width, 17014 height: height, 17015 left: left + ( show ? mx * width : 0 ), 17016 top: top + ( show ? my * height : 0 ), 17017 opacity: show ? 0 : 1 17018 }).animate({ 17019 left: left + ( show ? 0 : mx * width ), 17020 top: top + ( show ? 0 : my * height ), 17021 opacity: show ? 1 : 0 17022 }, o.duration || 500, o.easing, childComplete ); 17023 } 17024 } 17025 17026 function animComplete() { 17027 el.css({ 17028 visibility: "visible" 17029 }); 17030 $( pieces ).remove(); 17031 if ( !show ) { 17032 el.hide(); 17033 } 17034 done(); 17035 } 17036}; 17037 17038})(jQuery); 17039(function( $, undefined ) { 17040 17041$.effects.effect.fade = function( o, done ) { 17042 var el = $( this ), 17043 mode = $.effects.setMode( el, o.mode || "toggle" ); 17044 17045 el.animate({ 17046 opacity: mode 17047 }, { 17048 queue: false, 17049 duration: o.duration, 17050 easing: o.easing, 17051 complete: done 17052 }); 17053}; 17054 17055})( jQuery ); 17056(function( $, undefined ) { 17057 17058$.effects.effect.fold = function( o, done ) { 17059 17060 // Create element 17061 var el = $( this ), 17062 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 17063 mode = $.effects.setMode( el, o.mode || "hide" ), 17064 show = mode === "show", 17065 hide = mode === "hide", 17066 size = o.size || 15, 17067 percent = /([0-9]+)%/.exec( size ), 17068 horizFirst = !!o.horizFirst, 17069 widthFirst = show !== horizFirst, 17070 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 17071 duration = o.duration / 2, 17072 wrapper, distance, 17073 animation1 = {}, 17074 animation2 = {}; 17075 17076 $.effects.save( el, props ); 17077 el.show(); 17078 17079 // Create Wrapper 17080 wrapper = $.effects.createWrapper( el ).css({ 17081 overflow: "hidden" 17082 }); 17083 distance = widthFirst ? 17084 [ wrapper.width(), wrapper.height() ] : 17085 [ wrapper.height(), wrapper.width() ]; 17086 17087 if ( percent ) { 17088 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 17089 } 17090 if ( show ) { 17091 wrapper.css( horizFirst ? { 17092 height: 0, 17093 width: size 17094 } : { 17095 height: size, 17096 width: 0 17097 }); 17098 } 17099 17100 // Animation 17101 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 17102 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 17103 17104 // Animate 17105 wrapper 17106 .animate( animation1, duration, o.easing ) 17107 .animate( animation2, duration, o.easing, function() { 17108 if ( hide ) { 17109 el.hide(); 17110 } 17111 $.effects.restore( el, props ); 17112 $.effects.removeWrapper( el ); 17113 done(); 17114 }); 17115 17116}; 17117 17118})(jQuery); 17119(function( $, undefined ) { 17120 17121$.effects.effect.highlight = function( o, done ) { 17122 var elem = $( this ), 17123 props = [ "backgroundImage", "backgroundColor", "opacity" ], 17124 mode = $.effects.setMode( elem, o.mode || "show" ), 17125 animation = { 17126 backgroundColor: elem.css( "backgroundColor" ) 17127 }; 17128 17129 if (mode === "hide") { 17130 animation.opacity = 0; 17131 } 17132 17133 $.effects.save( elem, props ); 17134 17135 elem 17136 .show() 17137 .css({ 17138 backgroundImage: "none", 17139 backgroundColor: o.color || "#ffff99" 17140 }) 17141 .animate( animation, { 17142 queue: false, 17143 duration: o.duration, 17144 easing: o.easing, 17145 complete: function() { 17146 if ( mode === "hide" ) { 17147 elem.hide(); 17148 } 17149 $.effects.restore( elem, props ); 17150 done(); 17151 } 17152 }); 17153}; 17154 17155})(jQuery); 17156(function( $, undefined ) { 17157 17158$.effects.effect.pulsate = function( o, done ) { 17159 var elem = $( this ), 17160 mode = $.effects.setMode( elem, o.mode || "show" ), 17161 show = mode === "show", 17162 hide = mode === "hide", 17163 showhide = ( show || mode === "hide" ), 17164 17165 // showing or hiding leaves of the "last" animation 17166 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 17167 duration = o.duration / anims, 17168 animateTo = 0, 17169 queue = elem.queue(), 17170 queuelen = queue.length, 17171 i; 17172 17173 if ( show || !elem.is(":visible")) { 17174 elem.css( "opacity", 0 ).show(); 17175 animateTo = 1; 17176 } 17177 17178 // anims - 1 opacity "toggles" 17179 for ( i = 1; i < anims; i++ ) { 17180 elem.animate({ 17181 opacity: animateTo 17182 }, duration, o.easing ); 17183 animateTo = 1 - animateTo; 17184 } 17185 17186 elem.animate({ 17187 opacity: animateTo 17188 }, duration, o.easing); 17189 17190 elem.queue(function() { 17191 if ( hide ) { 17192 elem.hide(); 17193 } 17194 done(); 17195 }); 17196 17197 // We just queued up "anims" animations, we need to put them next in the queue 17198 if ( queuelen > 1 ) { 17199 queue.splice.apply( queue, 17200 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 17201 } 17202 elem.dequeue(); 17203}; 17204 17205})(jQuery); 17206(function( $, undefined ) { 17207 17208$.effects.effect.puff = function( o, done ) { 17209 var elem = $( this ), 17210 mode = $.effects.setMode( elem, o.mode || "hide" ), 17211 hide = mode === "hide", 17212 percent = parseInt( o.percent, 10 ) || 150, 17213 factor = percent / 100, 17214 original = { 17215 height: elem.height(), 17216 width: elem.width(), 17217 outerHeight: elem.outerHeight(), 17218 outerWidth: elem.outerWidth() 17219 }; 17220 17221 $.extend( o, { 17222 effect: "scale", 17223 queue: false, 17224 fade: true, 17225 mode: mode, 17226 complete: done, 17227 percent: hide ? percent : 100, 17228 from: hide ? 17229 original : 17230 { 17231 height: original.height * factor, 17232 width: original.width * factor, 17233 outerHeight: original.outerHeight * factor, 17234 outerWidth: original.outerWidth * factor 17235 } 17236 }); 17237 17238 elem.effect( o ); 17239}; 17240 17241$.effects.effect.scale = function( o, done ) { 17242 17243 // Create element 17244 var el = $( this ), 17245 options = $.extend( true, {}, o ), 17246 mode = $.effects.setMode( el, o.mode || "effect" ), 17247 percent = parseInt( o.percent, 10 ) || 17248 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 17249 direction = o.direction || "both", 17250 origin = o.origin, 17251 original = { 17252 height: el.height(), 17253 width: el.width(), 17254 outerHeight: el.outerHeight(), 17255 outerWidth: el.outerWidth() 17256 }, 17257 factor = { 17258 y: direction !== "horizontal" ? (percent / 100) : 1, 17259 x: direction !== "vertical" ? (percent / 100) : 1 17260 }; 17261 17262 // We are going to pass this effect to the size effect: 17263 options.effect = "size"; 17264 options.queue = false; 17265 options.complete = done; 17266 17267 // Set default origin and restore for show/hide 17268 if ( mode !== "effect" ) { 17269 options.origin = origin || ["middle","center"]; 17270 options.restore = true; 17271 } 17272 17273 options.from = o.from || ( mode === "show" ? { 17274 height: 0, 17275 width: 0, 17276 outerHeight: 0, 17277 outerWidth: 0 17278 } : original ); 17279 options.to = { 17280 height: original.height * factor.y, 17281 width: original.width * factor.x, 17282 outerHeight: original.outerHeight * factor.y, 17283 outerWidth: original.outerWidth * factor.x 17284 }; 17285 17286 // Fade option to support puff 17287 if ( options.fade ) { 17288 if ( mode === "show" ) { 17289 options.from.opacity = 0; 17290 options.to.opacity = 1; 17291 } 17292 if ( mode === "hide" ) { 17293 options.from.opacity = 1; 17294 options.to.opacity = 0; 17295 } 17296 } 17297 17298 // Animate 17299 el.effect( options ); 17300 17301}; 17302 17303$.effects.effect.size = function( o, done ) { 17304 17305 // Create element 17306 var original, baseline, factor, 17307 el = $( this ), 17308 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 17309 17310 // Always restore 17311 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 17312 17313 // Copy for children 17314 props2 = [ "width", "height", "overflow" ], 17315 cProps = [ "fontSize" ], 17316 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 17317 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 17318 17319 // Set options 17320 mode = $.effects.setMode( el, o.mode || "effect" ), 17321 restore = o.restore || mode !== "effect", 17322 scale = o.scale || "both", 17323 origin = o.origin || [ "middle", "center" ], 17324 position = el.css( "position" ), 17325 props = restore ? props0 : props1, 17326 zero = { 17327 height: 0, 17328 width: 0, 17329 outerHeight: 0, 17330 outerWidth: 0 17331 }; 17332 17333 if ( mode === "show" ) { 17334 el.show(); 17335 } 17336 original = { 17337 height: el.height(), 17338 width: el.width(), 17339 outerHeight: el.outerHeight(), 17340 outerWidth: el.outerWidth() 17341 }; 17342 17343 if ( o.mode === "toggle" && mode === "show" ) { 17344 el.from = o.to || zero; 17345 el.to = o.from || original; 17346 } else { 17347 el.from = o.from || ( mode === "show" ? zero : original ); 17348 el.to = o.to || ( mode === "hide" ? zero : original ); 17349 } 17350 17351 // Set scaling factor 17352 factor = { 17353 from: { 17354 y: el.from.height / original.height, 17355 x: el.from.width / original.width 17356 }, 17357 to: { 17358 y: el.to.height / original.height, 17359 x: el.to.width / original.width 17360 } 17361 }; 17362 17363 // Scale the css box 17364 if ( scale === "box" || scale === "both" ) { 17365 17366 // Vertical props scaling 17367 if ( factor.from.y !== factor.to.y ) { 17368 props = props.concat( vProps ); 17369 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 17370 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 17371 } 17372 17373 // Horizontal props scaling 17374 if ( factor.from.x !== factor.to.x ) { 17375 props = props.concat( hProps ); 17376 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 17377 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 17378 } 17379 } 17380 17381 // Scale the content 17382 if ( scale === "content" || scale === "both" ) { 17383 17384 // Vertical props scaling 17385 if ( factor.from.y !== factor.to.y ) { 17386 props = props.concat( cProps ).concat( props2 ); 17387 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 17388 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 17389 } 17390 } 17391 17392 $.effects.save( el, props ); 17393 el.show(); 17394 $.effects.createWrapper( el ); 17395 el.css( "overflow", "hidden" ).css( el.from ); 17396 17397 // Adjust 17398 if (origin) { // Calculate baseline shifts 17399 baseline = $.effects.getBaseline( origin, original ); 17400 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 17401 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 17402 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 17403 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 17404 } 17405 el.css( el.from ); // set top & left 17406 17407 // Animate 17408 if ( scale === "content" || scale === "both" ) { // Scale the children 17409 17410 // Add margins/font-size 17411 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 17412 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 17413 props2 = props0.concat(vProps).concat(hProps); 17414 17415 el.find( "*[width]" ).each( function(){ 17416 var child = $( this ), 17417 c_original = { 17418 height: child.height(), 17419 width: child.width(), 17420 outerHeight: child.outerHeight(), 17421 outerWidth: child.outerWidth() 17422 }; 17423 if (restore) { 17424 $.effects.save(child, props2); 17425 } 17426 17427 child.from = { 17428 height: c_original.height * factor.from.y, 17429 width: c_original.width * factor.from.x, 17430 outerHeight: c_original.outerHeight * factor.from.y, 17431 outerWidth: c_original.outerWidth * factor.from.x 17432 }; 17433 child.to = { 17434 height: c_original.height * factor.to.y, 17435 width: c_original.width * factor.to.x, 17436 outerHeight: c_original.height * factor.to.y, 17437 outerWidth: c_original.width * factor.to.x 17438 }; 17439 17440 // Vertical props scaling 17441 if ( factor.from.y !== factor.to.y ) { 17442 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 17443 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 17444 } 17445 17446 // Horizontal props scaling 17447 if ( factor.from.x !== factor.to.x ) { 17448 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 17449 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 17450 } 17451 17452 // Animate children 17453 child.css( child.from ); 17454 child.animate( child.to, o.duration, o.easing, function() { 17455 17456 // Restore children 17457 if ( restore ) { 17458 $.effects.restore( child, props2 ); 17459 } 17460 }); 17461 }); 17462 } 17463 17464 // Animate 17465 el.animate( el.to, { 17466 queue: false, 17467 duration: o.duration, 17468 easing: o.easing, 17469 complete: function() { 17470 if ( el.to.opacity === 0 ) { 17471 el.css( "opacity", el.from.opacity ); 17472 } 17473 if( mode === "hide" ) { 17474 el.hide(); 17475 } 17476 $.effects.restore( el, props ); 17477 if ( !restore ) { 17478 17479 // we need to calculate our new positioning based on the scaling 17480 if ( position === "static" ) { 17481 el.css({ 17482 position: "relative", 17483 top: el.to.top, 17484 left: el.to.left 17485 }); 17486 } else { 17487 $.each([ "top", "left" ], function( idx, pos ) { 17488 el.css( pos, function( _, str ) { 17489 var val = parseInt( str, 10 ), 17490 toRef = idx ? el.to.left : el.to.top; 17491 17492 // if original was "auto", recalculate the new value from wrapper 17493 if ( str === "auto" ) { 17494 return toRef + "px"; 17495 } 17496 17497 return val + toRef + "px"; 17498 }); 17499 }); 17500 } 17501 } 17502 17503 $.effects.removeWrapper( el ); 17504 done(); 17505 } 17506 }); 17507 17508}; 17509 17510})(jQuery); 17511(function( $, undefined ) { 17512 17513$.effects.effect.shake = function( o, done ) { 17514 17515 var el = $( this ), 17516 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 17517 mode = $.effects.setMode( el, o.mode || "effect" ), 17518 direction = o.direction || "left", 17519 distance = o.distance || 20, 17520 times = o.times || 3, 17521 anims = times * 2 + 1, 17522 speed = Math.round(o.duration/anims), 17523 ref = (direction === "up" || direction === "down") ? "top" : "left", 17524 positiveMotion = (direction === "up" || direction === "left"), 17525 animation = {}, 17526 animation1 = {}, 17527 animation2 = {}, 17528 i, 17529 17530 // we will need to re-assemble the queue to stack our animations in place 17531 queue = el.queue(), 17532 queuelen = queue.length; 17533 17534 $.effects.save( el, props ); 17535 el.show(); 17536 $.effects.createWrapper( el ); 17537 17538 // Animation 17539 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 17540 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 17541 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 17542 17543 // Animate 17544 el.animate( animation, speed, o.easing ); 17545 17546 // Shakes 17547 for ( i = 1; i < times; i++ ) { 17548 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 17549 } 17550 el 17551 .animate( animation1, speed, o.easing ) 17552 .animate( animation, speed / 2, o.easing ) 17553 .queue(function() { 17554 if ( mode === "hide" ) { 17555 el.hide(); 17556 } 17557 $.effects.restore( el, props ); 17558 $.effects.removeWrapper( el ); 17559 done(); 17560 }); 17561 17562 // inject all the animations we just queued to be first in line (after "inprogress") 17563 if ( queuelen > 1) { 17564 queue.splice.apply( queue, 17565 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 17566 } 17567 el.dequeue(); 17568 17569}; 17570 17571})(jQuery); 17572(function( $, undefined ) { 17573 17574$.effects.effect.slide = function( o, done ) { 17575 17576 // Create element 17577 var el = $( this ), 17578 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 17579 mode = $.effects.setMode( el, o.mode || "show" ), 17580 show = mode === "show", 17581 direction = o.direction || "left", 17582 ref = (direction === "up" || direction === "down") ? "top" : "left", 17583 positiveMotion = (direction === "up" || direction === "left"), 17584 distance, 17585 animation = {}; 17586 17587 // Adjust 17588 $.effects.save( el, props ); 17589 el.show(); 17590 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 17591 17592 $.effects.createWrapper( el ).css({ 17593 overflow: "hidden" 17594 }); 17595 17596 if ( show ) { 17597 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 17598 } 17599 17600 // Animation 17601 animation[ ref ] = ( show ? 17602 ( positiveMotion ? "+=" : "-=") : 17603 ( positiveMotion ? "-=" : "+=")) + 17604 distance; 17605 17606 // Animate 17607 el.animate( animation, { 17608 queue: false, 17609 duration: o.duration, 17610 easing: o.easing, 17611 complete: function() { 17612 if ( mode === "hide" ) { 17613 el.hide(); 17614 } 17615 $.effects.restore( el, props ); 17616 $.effects.removeWrapper( el ); 17617 done(); 17618 } 17619 }); 17620}; 17621 17622})(jQuery); 17623(function( $, undefined ) { 17624 17625$.effects.effect.transfer = function( o, done ) { 17626 var elem = $( this ), 17627 target = $( o.to ), 17628 targetFixed = target.css( "position" ) === "fixed", 17629 body = $("body"), 17630 fixTop = targetFixed ? body.scrollTop() : 0, 17631 fixLeft = targetFixed ? body.scrollLeft() : 0, 17632 endPosition = target.offset(), 17633 animation = { 17634 top: endPosition.top - fixTop , 17635 left: endPosition.left - fixLeft ,
17636 height: target.innerHeight(), 17637 width: target.innerWidth() 17638 }, 17639 startPosition = elem.offset(), 17640 transfer = $( "<div class='ui-effects-transfer'></div>" ) 17641 .appendTo( document.body ) 17642 .addClass( o.className ) 17643 .css({ 17644 top: startPosition.top - fixTop , 17645 left: startPosition.left - fixLeft , 17646 height: elem.innerHeight(), 17647 width: elem.innerWidth(), 17648 position: targetFixed ? "fixed" : "absolute" 17649 }) 17650 .animate( animation, o.duration, o.easing, function() { 17651 transfer.remove(); 17652 done(); 17653 }); 17654}; 17655 17656})(jQuery); 17657 17658/* End */ 17659; 17660; /* Start:"a:4:{s:4:"full";s:45:"/js/google_analitics_submit.js?17212255671066";s:6:"source";s:30:"/js/google_analitics_submit.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 17661 /****************************************************** 17662 GA СÐÐЫТÐЯ 17663 *********************************************************/ 17664$(document).ready(function() { 17665 //bottom form 17666 $( "#bottomform form" ).submit(function() { 17667 ga('send', 'pageview', 'bottomformsubmit.html'); 17668 }); 17669 17670 //header callback 17671 //link click 17672 $( ".link .popup" ).click(function() { 17673 ga('send', 'pageview', 'opencallback'); 17674 }); 17675 //submit form Ð»ÐµÐ¶Ð¸Ñ Ð² иÑÑ Ð¾Ð´Ð½Ð¸ÐºÐ°Ñ ÑоÑÐ¼Ñ 17676 17677 //ostalis voprosy 17678 //link click 17679 $( ".ask a" ).click(function() { 17680 _gaq.push(['_trackPageview', '/contentformopen.html']); 17681 }); 17682 //submit form Ð»ÐµÐ¶Ð¸Ñ Ð² иÑÑ Ð¾Ð´Ð½Ð¸ÐºÐ°Ñ ÑоÑÐ¼Ñ 17683 17684 //karlov form 17685 $( "#karlovform form" ).submit(function() { 17686 _gaq.push(['_trackPageview', '/Czechiasubmit.html']); 17687 }); 17688 17689 //European universities 17690 //link click 17691 $( ".information_goal" ).submit(function() { 17692 ga('send', 'event', 'submit', 'look_univer'); 17693 look_univer_submit.reachGoal(ym); 17694 }); 17695 17696 $(".popup.consult2").click(function() { 17697 ga('send', 'pageview', 'openconsult'); 17698 }); 17699 17700}); 17701/* End */ 17702; 17703; /* Start:"a:4:{s:4:"full";s:84:"/bitrix/templates/main_new/components/bitrix/menu/top_header/script.js?1721225566682";s:6:"source";s:70:"/bitrix/templates/main_new/components/bitrix/menu/top_header/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 17704var jshover = function() 17705{ 17706 var menuDiv = document.getElementById("horizontal-multilevel-menu") 17707 if (!menuDiv) 17708 return; 17709 17710 var sfEls = menuDiv.getElementsByTagName("li"); 17711 for (var i=0; i<sfEls.length; i++) 17712 { 17713 sfEls[i].onmouseover=function() 17714 { 17715 this.className+=" jshover"; 17716 } 17717 sfEls[i].onmouseout=function() 17718 { 17719 this.className=this.className.replace(new RegExp(" jshover\\b"), ""); 17720 } 17721 } 17722} 17723 17724if (window.attachEvent) 17725 window.attachEvent("onload", jshover); 17726 17727$(document).ready(function(){ 17728 $('.block').hover(function() { 17729 $(this).closest('li').find('.parent').addClass("hover"); 17730 }, function(){ 17731 $(this).closest('li').find('.parent').removeClass("hover"); 17732 }); 17733}); 17734/* End */ 17735; 17736; /* Start:"a:4:{s:4:"full";s:77:"/bitrix/templates/main_new/components/bitrix/menu/top/script.js?1721225566682";s:6:"source";s:63:"/bitrix/templates/main_new/components/bitrix/menu/top/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 17737var jshover = function() 17738{ 17739 var menuDiv = document.getElementById("horizontal-multilevel-menu") 17740 if (!menuDiv) 17741 return; 17742 17743 var sfEls = menuDiv.getElementsByTagName("li"); 17744 for (var i=0; i<sfEls.length; i++) 17745 { 17746 sfEls[i].onmouseover=function() 17747 { 17748 this.className+=" jshover"; 17749 } 17750 sfEls[i].onmouseout=function() 17751 { 17752 this.className=this.className.replace(new RegExp(" jshover\\b"), ""); 17753 } 17754 } 17755} 17756 17757if (window.attachEvent) 17758 window.attachEvent("onload", jshover); 17759 17760$(document).ready(function(){ 17761 $('.block').hover(function() { 17762 $(this).closest('li').find('.parent').addClass("hover"); 17763 }, function(){ 17764 $(this).closest('li').find('.parent').removeClass("hover"); 17765 }); 17766}); 17767/* End */ 17768; 17769; /* Start:"a:4:{s:4:"full";s:82:"/bitrix/templates/main_new/components/bitrix/menu/programs/script.js?1721225566682";s:6:"source";s:68:"/bitrix/templates/main_new/components/bitrix/menu/programs/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 17770var jshover = function() 17771{ 17772 var menuDiv = document.getElementById("horizontal-multilevel-menu") 17773 if (!menuDiv) 17774 return; 17775 17776 var sfEls = menuDiv.getElementsByTagName("li"); 17777 for (var i=0; i<sfEls.length; i++) 17778 { 17779 sfEls[i].onmouseover=function() 17780 { 17781 this.className+=" jshover"; 17782 } 17783 sfEls[i].onmouseout=function() 17784 {
17785 this.className=this.className.replace(new RegExp(" jshover\\b"), ""); 17786 } 17787 } 17788} 17789 17790if (window.attachEvent) 17791 window.attachEvent("onload", jshover); 17792 17793$(document).ready(function(){ 17794 $('.block').hover(function() { 17795 $(this).closest('li').find('.parent').addClass("hover"); 17796 }, function(){ 17797 $(this).closest('li').find('.parent').removeClass("hover"); 17798 }); 17799}); 17800/* End */ 17801; 17802; /* Start:"a:4:{s:4:"full";s:84:"/bitrix/templates/main_new/components/bitrix/menu/mobile-top/script.js?1721225566682";s:6:"source";s:70:"/bitrix/templates/main_new/components/bitrix/menu/mobile-top/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 17803var jshover = function() 17804{ 17805 var menuDiv = document.getElementById("horizontal-multilevel-menu") 17806 if (!menuDiv) 17807 return; 17808 17809 var sfEls = menuDiv.getElementsByTagName("li"); 17810 for (var i=0; i<sfEls.length; i++) 17811 { 17812 sfEls[i].onmouseover=function() 17813 { 17814 this.className+=" jshover"; 17815 } 17816 sfEls[i].onmouseout=function() 17817 { 17818 this.className=this.className.replace(new RegExp(" jshover\\b"), ""); 17819 } 17820 } 17821} 17822 17823if (window.attachEvent) 17824 window.attachEvent("onload", jshover); 17825 17826$(document).ready(function(){ 17827 $('.block').hover(function() { 17828 $(this).closest('li').find('.parent').addClass("hover"); 17829 }, function(){ 17830 $(this).closest('li').find('.parent').removeClass("hover"); 17831 }); 17832}); 17833/* End */ 17834; 17835; /* Start:"a:4:{s:4:"full";s:88:"/bitrix/templates/main_new/components/bitrix/menu/social_network/script.js?1721225566682";s:6:"source";s:74:"/bitrix/templates/main_new/components/bitrix/menu/social_network/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ 17836var jshover = function() 17837{ 17838 var menuDiv = document.getElementById("horizontal-multilevel-menu") 17839 if (!menuDiv) 17840 return; 17841 17842 var sfEls = menuDiv.getElementsByTagName("li"); 17843 for (var i=0; i<sfEls.length; i++) 17844 { 17845 sfEls[i].onmouseover=function() 17846 { 17847 this.className+=" jshover"; 17848 } 17849 sfEls[i].onmouseout=function() 17850 { 17851 this.className=this.className.replace(new RegExp(" jshover\\b"), ""); 17852 } 17853 } 17854} 17855 17856if (window.attachEvent) 17857 window.attachEvent("onload", jshover); 17858 17859$(document).ready(function(){ 17860 $('.block').hover(function() { 17861 $(this).closest('li').find('.parent').addClass("hover"); 17862 }, function(){ 17863 $(this).closest('li').find('.parent').removeClass("hover"); 17864 }); 17865}); 17866/* End */ 17867;;
17867 /* /js/script.js?172122556711515*/ 17868; /* /js/jquery.fancybox.js?172122556748706*/ 17869; /* /js/jquery.jcarousel.js?172122556736009*/ 17870; /* /js/jquery-ui-1.10.3.custom.js?1721225567416213*/ 17871; /* /js/google_analitics_submit.js?17212255671066*/ 17872; /* /bitrix/templates/main_new/components/bitrix/menu/top_header/script.js?1721225566682*/ 17873; /* /bitrix/templates/main_new/components/bitrix/menu/top/script.js?1721225566682*/ 17874; /* /bitrix/templates/main_new/components/bitrix/menu/programs/script.js?1721225566682*/ 17875; /* /bitrix/templates/main_new/components/bitrix/menu/mobile-top/script.js?1721225566682*/ 17876; /* /bitrix/templates/main_new/components/bitrix/menu/social_network/script.js?1721225566682*/
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.