1 2/* ========================================================== 3 * bootstrap-affix.js v2.2.1 4 * http://twitter.github.com/bootstrap/javascript.html#affix 5 * ========================================================== 6 * Copyright 2012 Twitter, Inc. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * ========================================================== */ 20 21 22!function ($) { 23 24 "use strict"; // jshint ;_; 25 26 27 /* AFFIX CLASS DEFINITION 28 * ====================== */ 29 30 var Affix = function (element, options) { 31 this.options = $.extend({}, $.fn.affix.defaults, options) 32 this.$window = $(window) 33 .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) 34 .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) 35 this.$element = $(element) 36 this.checkPosition() 37 } 38 39 Affix.prototype.checkPosition = function () { 40 if (!this.$element.is(':visible')) return 41 42 var scrollHeight = $(document).height() 43 , scrollTop = this.$window.scrollTop() 44 , position = this.$element.offset() 45 , offset = this.options.offset 46 , offsetBottom = offset.bottom 47 , offsetTop = offset.top 48 , reset = 'affix affix-top affix-bottom' 49 , affix 50 51 if (typeof offset != 'object') offsetBottom = offsetTop = offset 52 if (typeof offsetTop == 'function') offsetTop = offset.top() 53 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() 54 55 affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? 56 false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 57 'bottom' : offsetTop != null && scrollTop <= offsetTop ? 58 'top' : false 59 60 if (this.affixed === affix) return 61 62 this.affixed = affix 63 this.unpin = affix == 'bottom' ? position.top - scrollTop : null 64 65 this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) 66 } 67 68 69 /* AFFIX PLUGIN DEFINITION 70 * ======================= */ 71 72 $.fn.affix = function (option) { 73 return this.each(function () { 74 var $this = $(this) 75 , data = $this.data('affix') 76 , options = typeof option == 'object' && option 77 if (!data) $this.data('affix', (data = new Affix(this, options))) 78 if (typeof option == 'string') data[option]() 79 }) 80 } 81 82 $.fn.affix.Constructor = Affix 83 84 $.fn.affix.defaults = { 85 offset: 0 86 } 87 88 89 /* AFFIX DATA-API 90 * ============== */ 91 92 $(window).on('load', function () { 93 $('[data-spy="affix"]').each(function () { 94 var $spy = $(this) 95 , data = $spy.data() 96 97 data.offset = data.offset || {} 98 99 data.offsetBottom && (data.offset.bottom = data.offsetBottom) 100 data.offsetTop && (data.offset.top = data.offsetTop) 101 102 $spy.affix(data) 103 }) 104 }) 105 106 107}(window.jQuery); 108/* ========================================================== 109 * bootstrap-alert.js v2.2.1 110 * http://twitter.github.com/bootstrap/javascript.html#alerts 111 * ========================================================== 112 * Copyright 2012 Twitter, Inc. 113 * 114 * Licensed under the Apache License, Version 2.0 (the "License"); 115 * you may not use this file except in compliance with the License. 116 * You may obtain a copy of the License at 117 * 118 * http://www.apache.org/licenses/LICENSE-2.0 119 * 120 * Unless required by applicable law or agreed to in writing, software 121 * distributed under the License is distributed on an "AS IS" BASIS, 122 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123 * See the License for the specific language governing permissions and 124 * limitations under the License. 125 * ========================================================== */ 126 127 128!function ($) { 129 130 "use strict"; // jshint ;_; 131 132 133 /* ALERT CLASS DEFINITION 134 * ====================== */ 135 136 var dismiss = '[data-dismiss="alert"]' 137 , Alert = function (el) { 138 $(el).on('click', dismiss, this.close) 139 } 140 141 Alert.prototype.close = function (e) { 142 var $this = $(this) 143 , selector = $this.attr('data-target') 144 , $parent 145 146 if (!selector) { 147 selector = $this.attr('href') 148 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 149 } 150 151 $parent = $(selector) 152 153 e && e.preventDefault() 154 155 $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) 156 157 $parent.trigger(e = $.Event('close')) 158 159 if (e.isDefaultPrevented()) return 160 161 $parent.removeClass('in') 162 163 function removeElement() { 164 $parent 165 .trigger('closed') 166 .remove() 167 } 168 169 $.support.transition && $parent.hasClass('fade') ? 170 $parent.on($.support.transition.end, removeElement) : 171 removeElement() 172 } 173 174 175 /* ALERT PLUGIN DEFINITION 176 * ======================= */ 177 178 $.fn.alert = function (option) { 179 return this.each(function () { 180 var $this = $(this) 181 , data = $this.data('alert')
182 if (!data) $this.data('alert', (data = new Alert(this))) 183 if (typeof option == 'string') data[option].call($this) 184 }) 185 } 186 187 $.fn.alert.Constructor = Alert 188 189 190 /* ALERT DATA-API 191 * ============== */ 192 193 $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) 194 195}(window.jQuery); 196/* ============================================================ 197 * bootstrap-button.js v2.2.1 198 * http://twitter.github.com/bootstrap/javascript.html#buttons 199 * ============================================================ 200 * Copyright 2012 Twitter, Inc. 201 * 202 * Licensed under the Apache License, Version 2.0 (the "License"); 203 * you may not use this file except in compliance with the License. 204 * You may obtain a copy of the License at 205 * 206 * http://www.apache.org/licenses/LICENSE-2.0 207 * 208 * Unless required by applicable law or agreed to in writing, software 209 * distributed under the License is distributed on an "AS IS" BASIS, 210 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 211 * See the License for the specific language governing permissions and 212 * limitations under the License. 213 * ============================================================ */ 214 215 216!function ($) { 217 218 "use strict"; // jshint ;_; 219 220 221 /* BUTTON PUBLIC CLASS DEFINITION 222 * ============================== */ 223 224 var Button = function (element, options) { 225 this.$element = $(element) 226 this.options = $.extend({}, $.fn.button.defaults, options) 227 } 228 229 Button.prototype.setState = function (state) { 230 var d = 'disabled' 231 , $el = this.$element 232 , data = $el.data() 233 , val = $el.is('input') ? 'val' : 'html' 234 235 state = state + 'Text' 236 data.resetText || $el.data('resetText', $el[val]()) 237 238 $el[val](data[state] || this.options[state]) 239 240 // push to event loop to allow forms to submit 241 setTimeout(function () { 242 state == 'loadingText' ? 243 $el.addClass(d).attr(d, d) : 244 $el.removeClass(d).removeAttr(d) 245 }, 0) 246 } 247 248 Button.prototype.toggle = function () { 249 var $parent = this.$element.closest('[data-toggle="buttons-radio"]') 250 251 $parent && $parent 252 .find('.active') 253 .removeClass('active') 254 255 this.$element.toggleClass('active') 256 } 257 258 259 /* BUTTON PLUGIN DEFINITION 260 * ======================== */ 261 262 $.fn.button = function (option) { 263 return this.each(function () { 264 var $this = $(this) 265 , data = $this.data('button') 266 , options = typeof option == 'object' && option 267 if (!data) $this.data('button', (data = new Button(this, options))) 268 if (option == 'toggle') data.toggle() 269 else if (option) data.setState(option) 270 }) 271 } 272 273 $.fn.button.defaults = { 274 loadingText: 'loading...' 275 } 276 277 $.fn.button.Constructor = Button 278 279 280 /* BUTTON DATA-API 281 * =============== */ 282 283 $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { 284 var $btn = $(e.target) 285 if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 286 $btn.button('toggle') 287 }) 288 289}(window.jQuery); 290/* ========================================================== 291 * bootstrap-carousel.js v2.2.1 292 * http://twitter.github.com/bootstrap/javascript.html#carousel 293 * ========================================================== 294 * Copyright 2012 Twitter, Inc. 295 * 296 * Licensed under the Apache License, Version 2.0 (the "License"); 297 * you may not use this file except in compliance with the License. 298 * You may obtain a copy of the License at 299 * 300 * http://www.apache.org/licenses/LICENSE-2.0 301 * 302 * Unless required by applicable law or agreed to in writing, software 303 * distributed under the License is distributed on an "AS IS" BASIS, 304 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 305 * See the License for the specific language governing permissions and 306 * limitations under the License. 307 * ========================================================== */ 308 309 310!function ($) { 311 312 "use strict"; // jshint ;_; 313 314 315 /* CAROUSEL CLASS DEFINITION 316 * ========================= */ 317 318 var Carousel = function (element, options) { 319 this.$element = $(element) 320 this.options = options 321 this.options.slide && this.slide(this.options.slide) 322 this.options.pause == 'hover' && this.$element 323 .on('mouseenter', $.proxy(this.pause, this)) 324 .on('mouseleave', $.proxy(this.cycle, this)) 325 } 326 327 Carousel.prototype = { 328 329 cycle: function (e) { 330 if (!e) this.paused = false 331 this.options.interval 332 && !this.paused 333 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 334 return this 335 } 336 337 , to: function (pos) { 338 var $active = this.$element.find('.item.active') 339 , children = $active.parent().children() 340 , activePos = children.index($active) 341 , that = this 342 343 if (pos > (children.length - 1) || pos < 0) return 344 345 if (this.sliding) { 346 return this.$element.one('slid', function () { 347 that.to(pos) 348 }) 349 } 350 351 if (activePos == pos) { 352 return this.pause().cycle() 353 } 354 355 return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos])) 356 } 357 358 , pause: function (e) { 359 if (!e) this.paused = true 360 if (this.$element.find('.next, .prev').length && $.support.transition.end) { 361 this.$element.trigger($.support.transition.end) 362 this.cycle() 363 } 364 clearInterval(this.interval) 365 this.interval = null 366 return this 367 } 368 369 , next: function () { 370 if (this.sliding) return 371 return this.slide('next') 372 } 373 374 , prev: function () { 375 if (this.sliding) return 376 return this.slide('prev') 377 } 378 379 , slide: function (type, next) { 380 var $active = this.$element.find('.item.active') 381 , $next = next || $active[type]() 382 , isCycling = this.interval 383 , direction = type == 'next' ? 'left' : 'right' 384 , fallback = type == 'next' ? 'first' : 'last' 385 , that = this 386 , e 387 388 this.sliding = true 389 390 isCycling && this.pause() 391 392 $next = $next.length ? $next : this.$element.find('.item')[fallback]() 393 394 e = $.Event('slide', { 395 relatedTarget: $next[0] 396 }) 397 398 if ($next.hasClass('active')) return 399
400 if ($.support.transition && this.$element.hasClass('slide')) { 401 this.$element.trigger(e) 402 if (e.isDefaultPrevented()) return 403 $next.addClass(type) 404 $next[0].offsetWidth // force reflow 405 $active.addClass(direction) 406 $next.addClass(direction) 407 this.$element.one($.support.transition.end, function () { 408 $next.removeClass([type, direction].join(' ')).addClass('active') 409 $active.removeClass(['active', direction].join(' ')) 410 that.sliding = false 411 setTimeout(function () { that.$element.trigger('slid') }, 0) 412 }) 413 } else { 414 this.$element.trigger(e) 415 if (e.isDefaultPrevented()) return 416 $active.removeClass('active') 417 $next.addClass('active') 418 this.sliding = false 419 this.$element.trigger('slid') 420 } 421 422 isCycling && this.cycle() 423 424 return this 425 } 426 427 } 428 429 430 /* CAROUSEL PLUGIN DEFINITION 431 * ========================== */ 432 433 $.fn.carousel = function (option) { 434 return this.each(function () { 435 var $this = $(this) 436 , data = $this.data('carousel') 437 , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) 438 , action = typeof option == 'string' ? option : options.slide 439 if (!data) $this.data('carousel', (data = new Carousel(this, options))) 440 if (typeof option == 'number') data.to(option) 441 else if (action) data[action]() 442 else if (options.interval) data.cycle() 443 }) 444 } 445 446 $.fn.carousel.defaults = { 447 interval: 5000 448 , pause: 'hover' 449 } 450 451 $.fn.carousel.Constructor = Carousel 452 453 454 /* CAROUSEL DATA-API 455 * ================= */ 456 457 $(document).on('click.carousel.data-api', '[data-slide]', function (e) { 458 var $this = $(this), href 459 , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 460 , options = $.extend({}, $target.data(), $this.data()) 461 $target.carousel(options) 462 e.preventDefault() 463 }) 464 465}(window.jQuery); 466/* ============================================================= 467 * bootstrap-collapse.js v2.2.1 468 * http://twitter.github.com/bootstrap/javascript.html#collapse 469 * ============================================================= 470 * Copyright 2012 Twitter, Inc. 471 * 472 * Licensed under the Apache License, Version 2.0 (the "License"); 473 * you may not use this file except in compliance with the License. 474 * You may obtain a copy of the License at 475 * 476 * http://www.apache.org/licenses/LICENSE-2.0 477 * 478 * Unless required by applicable law or agreed to in writing, software 479 * distributed under the License is distributed on an "AS IS" BASIS, 480 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 481 * See the License for the specific language governing permissions and 482 * limitations under the License. 483 * ============================================================ */ 484 485 486!function ($) { 487 488 "use strict"; // jshint ;_; 489 490 491 /* COLLAPSE PUBLIC CLASS DEFINITION 492 * ================================ */ 493 494 var Collapse = function (element, options) { 495 this.$element = $(element) 496 this.options = $.extend({}, $.fn.collapse.defaults, options) 497 498 if (this.options.parent) { 499 this.$parent = $(this.options.parent) 500 } 501 502 this.options.toggle && this.toggle() 503 } 504 505 Collapse.prototype = { 506 507 constructor: Collapse 508 509 , dimension: function () { 510 var hasWidth = this.$element.hasClass('width') 511 return hasWidth ? 'width' : 'height' 512 } 513 514 , show: function () { 515 var dimension 516 , scroll 517 , actives 518 , hasData 519 520 if (this.transitioning) return 521 522 dimension = this.dimension() 523 scroll = $.camelCase(['scroll', dimension].join('-')) 524 actives = this.$parent && this.$parent.find('> .accordion-group > .in') 525 526 if (actives && actives.length) { 527 hasData = actives.data('collapse') 528 if (hasData && hasData.transitioning) return 529 actives.collapse('hide') 530 hasData || actives.data('collapse', null) 531 } 532 533 this.$element[dimension](0) 534 this.transition('addClass', $.Event('show'), 'shown') 535 $.support.transition && this.$element[dimension](this.$element[0][scroll]) 536 } 537 538 , hide: function () { 539 var dimension 540 if (this.transitioning) return 541 dimension = this.dimension() 542 this.reset(this.$element[dimension]()) 543 this.transition('removeClass', $.Event('hide'), 'hidden') 544 this.$element[dimension](0) 545 } 546 547 , reset: function (size) { 548 var dimension = this.dimension() 549 550 this.$element 551 .removeClass('collapse') 552 [dimension](size || 'auto') 553 [0].offsetWidth 554 555 this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') 556 557 return this 558 } 559 560 , transition: function (method, startEvent, completeEvent) { 561 var that = this 562 , complete = function () { 563 if (startEvent.type == 'show') that.reset() 564 that.transitioning = 0 565 that.$element.trigger(completeEvent) 566 } 567 568 this.$element.trigger(startEvent) 569 570 if (startEvent.isDefaultPrevented()) return 571 572 this.transitioning = 1 573 574 this.$element[method]('in') 575 576 $.support.transition && this.$element.hasClass('collapse') ? 577 this.$element.one($.support.transition.end, complete) : 578 complete() 579 } 580 581 , toggle: function () { 582 this[this.$element.hasClass('in') ? 'hide' : 'show']() 583 } 584 585 } 586 587 588 /* COLLAPSIBLE PLUGIN DEFINITION 589 * ============================== */ 590 591 $.fn.collapse = function (option) { 592 return this.each(function () { 593 var $this = $(this) 594 , data = $this.data('collapse') 595 , options = typeof option == 'object' && option 596 if (!data) $this.data('collapse', (data = new Collapse(this, options))) 597 if (typeof option == 'string') data[option]() 598 }) 599 } 600 601 $.fn.collapse.defaults = { 602 toggle: true 603 } 604 605 $.fn.collapse.Constructor = Collapse 606 607 608 /* COLLAPSIBLE DATA-API 609 * ==================== */ 610 611 $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { 612 var $this = $(this), href 613 , target = $this.attr('data-target') 614 || e.preventDefault() 615 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 616 , option = $(target).data('collapse') ? 'toggle' : $this.data() 617 $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 618 $(target).collapse(option) 619 }) 620 621}(window.jQuery); 622/* ============================================================ 623 * bootstrap-dropdown.js v2.2.1 624 * http://twitter.github.com/bootstrap/javascript.html#dropdowns 625 * ============================================================ 626 * Copyright 2012 Twitter, Inc. 627 * 628 * Licensed under the Apache License, Version 2.0 (the "License");
629 * you may not use this file except in compliance with the License. 630 * You may obtain a copy of the License at 631 * 632 * http://www.apache.org/licenses/LICENSE-2.0 633 * 634 * Unless required by applicable law or agreed to in writing, software 635 * distributed under the License is distributed on an "AS IS" BASIS, 636 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 637 * See the License for the specific language governing permissions and 638 * limitations under the License. 639 * ============================================================ */ 640 641 642!function ($) { 643 644 "use strict"; // jshint ;_; 645 646 647 /* DROPDOWN CLASS DEFINITION 648 * ========================= */ 649 650 var toggle = '[data-toggle=dropdown]' 651 , Dropdown = function (element) { 652 var $el = $(element).on('click.dropdown.data-api', this.toggle) 653 $('html').on('click.dropdown.data-api', function () { 654 $el.parent().removeClass('open') 655 }) 656 } 657 658 Dropdown.prototype = { 659 660 constructor: Dropdown 661 662 , toggle: function (e) { 663 var $this = $(this) 664 , $parent 665 , isActive 666 667 if ($this.is('.disabled, :disabled')) return 668 669 $parent = getParent($this) 670 671 isActive = $parent.hasClass('open') 672 673 clearMenus() 674 675 if (!isActive) { 676 $parent.toggleClass('open') 677 $this.focus() 678 } 679 680 return false 681 } 682 683 , keydown: function (e) { 684 var $this 685 , $items 686 , $active 687 , $parent 688 , isActive 689 , index 690 691 if (!/(38|40|27)/.test(e.keyCode)) return 692 693 $this = $(this) 694 695 e.preventDefault() 696 e.stopPropagation() 697 698 if ($this.is('.disabled, :disabled')) return 699 700 $parent = getParent($this) 701 702 isActive = $parent.hasClass('open') 703 704 if (!isActive || (isActive && e.keyCode == 27)) return $this.click() 705 706 $items = $('[role=menu] li:not(.divider) a', $parent) 707 708 if (!$items.length) return 709 710 index = $items.index($items.filter(':focus')) 711 712 if (e.keyCode == 38 && index > 0) index-- // up 713 if (e.keyCode == 40 && index < $items.length - 1) index++ // down 714 if (!~index) index = 0 715 716 $items 717 .eq(index) 718 .focus() 719 } 720 721 } 722 723 function clearMenus() { 724 $(toggle).each(function () { 725 getParent($(this)).removeClass('open') 726 }) 727 } 728 729 function getParent($this) { 730 var selector = $this.attr('data-target') 731 , $parent 732 733 if (!selector) { 734 selector = $this.attr('href') 735 selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 736 } 737 738 $parent = $(selector) 739 $parent.length || ($parent = $this.parent()) 740 741 return $parent 742 } 743 744 745 /* DROPDOWN PLUGIN DEFINITION 746 * ========================== */ 747 748 $.fn.dropdown = function (option) { 749 return this.each(function () { 750 var $this = $(this) 751 , data = $this.data('dropdown') 752 if (!data) $this.data('dropdown', (data = new Dropdown(this))) 753 if (typeof option == 'string') data[option].call($this) 754 }) 755 } 756 757 $.fn.dropdown.Constructor = Dropdown 758 759 760 /* APPLY TO STANDARD DROPDOWN ELEMENTS 761 * =================================== */ 762 763 $(document) 764 .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus) 765 .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) 766 .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle) 767 .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) 768 769}(window.jQuery); 770/* ========================================================= 771 * bootstrap-modal.js v2.2.1 772 * http://twitter.github.com/bootstrap/javascript.html#modals 773 * ========================================================= 774 * Copyright 2012 Twitter, Inc. 775 * 776 * Licensed under the Apache License, Version 2.0 (the "License"); 777 * you may not use this file except in compliance with the License. 778 * You may obtain a copy of the License at 779 * 780 * http://www.apache.org/licenses/LICENSE-2.0 781 * 782 * Unless required by applicable law or agreed to in writing, softw
782are 783 * distributed under the License is distributed on an "AS IS" BASIS, 784 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 785 * See the License for the specific language governing permissions and 786 * limitations under the License. 787 * ========================================================= */ 788 789 790!function ($) { 791 792 "use strict"; // jshint ;_; 793 794 795 /* MODAL CLASS DEFINITION 796 * ====================== */ 797 798 var Modal = function (element, options) { 799 this.options = options 800 this.$element = $(element) 801 .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) 802 this.options.remote && this.$element.find('.modal-body').load(this.options.remote) 803 } 804 805 Modal.prototype = { 806 807 constructor: Modal 808 809 , toggle: function () { 810 return this[!this.isShown ? 'show' : 'hide']() 811 } 812 813 , show: function () { 814 var that = this 815 , e = $.Event('show') 816 817 this.$element.trigger(e) 818 819 if (this.isShown || e.isDefaultPrevented()) return 820 821 this.isShown = true 822 823 this.escape() 824 825 this.backdrop(function () { 826 var transition = $.support.transition && that.$element.hasClass('fade') 827 828 if (!that.$element.parent().length) { 829 that.$element.appendTo(document.body) //don't move modals dom position 830 } 831 832 that.$element 833 .show() 834 835 if (transition) { 836 that.$element[0].offsetWidth // force reflow 837 } 838 839 that.$element 840 .addClass('in') 841 .attr('aria-hidden', false) 842 843 that.enforceFocus() 844 845 transition ? 846 that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) : 847 that.$element.focus().trigger('shown') 848 849 }) 850 } 851 852 , hide: function (e) { 853 e && e.preventDefault() 854 855 var that = this 856 857 e = $.Event('hide') 858 859 this.$element.trigger(e) 860 861 if (!this.isShown || e.isDefaultPrevented()) return 862 863 this.isShown = false 864 865 this.escape() 866 867 $(document).off('focusin.modal') 868 869 this.$element 870 .removeClass('in') 871 .attr('aria-hidden', true) 872 873 $.support.transition && this.$element.hasClass('fade') ? 874 this.hideWithTransition() : 875 this.hideModal() 876 } 877 878 , enforceFocus: function () { 879 var that = this 880 $(document).on('focusin.modal', function (e) { 881 if (that.$element[0] !== e.target && !that.$element.has(e.target).length) { 882 that.$element.focus() 883 } 884 }) 885 } 886 887 , escape: function () { 888 var that = this 889 if (this.isShown && this.options.keyboard) { 890 this.$element.on('keyup.dismiss.modal', function ( e ) { 891 e.which == 27 && that.hide() 892 }) 893 } else if (!this.isShown) { 894 this.$element.off('keyup.dismiss.modal') 895 } 896 } 897 898 , hideWithTransition: function () { 899 var that = this 900 , timeout = setTimeout(function () { 901 that.$element.off($.support.transition.end) 902 that.hideModal() 903 }, 500) 904 905 this.$element.one($.support.transition.end, function () { 906 clearTimeout(timeout) 907 that.hideModal() 908 }) 909 } 910 911 , hideModal: function (that) { 912 this.$element 913 .hide() 914 .trigger('hidden') 915 916 this.backdrop() 917 } 918 919 , removeBackdrop: function () { 920 this.$backdrop.remove() 921 this.$backdrop = null 922 } 923 924 , backdrop: function (callback) { 925 var that = this 926 , animate = this.$element.hasClass('fade') ? 'fade' : '' 927 928 if (this.isShown && this.options.backdrop) { 929 var doAnimate = $.support.transition && animate 930 931 this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') 932 .appendTo(document.body) 933 934 this.$backdrop.click( 935 this.options.backdrop == 'static' ? 936 $.proxy(this.$element[0].focus, this.$element[0]) 937 : $.proxy(this.hide, this) 938 ) 939 940 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow 941 942 this.$backdrop.addClass('in') 943 944 doAnimate ? 945 this.$backdrop.one($.support.transition.end, callback) : 946 callback() 947 948 } else if (!this.isShown && this.$backdrop) { 949 this.$backdrop.removeClass('in') 950 951 $.support.transition && this.$element.hasClass('fade')? 952 this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) : 953 this.removeBackdrop() 954 955 } else if (callback) { 956 callback() 957 } 958 } 959 } 960 961 962 /* MODAL PLUGIN DEFINITION 963 * ======================= */ 964 965 $.fn.modal = function (option) { 966 return this.each(function () { 967 var $this = $(this) 968 , data = $this.data('modal') 969 , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option) 970 if (!data) $this.data('modal', (data = new Modal(this, options))) 971 if (typeof option == 'string') data[option]() 972 else if (options.show) data.show() 973 }) 974 } 975 976 $.fn.modal.defaults = { 977 backdrop: true 978 , keyboard: true 979 , show: true 980 } 981 982 $.fn.modal.Constructor = Modal 983 984 985 /* MODAL DATA-API 986 * ============== */ 987 988 $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) { 989 var $this = $(this) 990 , href = $this.attr('href') 991 , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7 992 , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data()) 993 994 e.preventDefault() 995 996 $target 997 .modal(option) 998 .one('hide', function () { 999 $this.focus() 1000 }) 1001 }) 1002 1003}(window.jQuery); 1004 1005/* =========================================================== 1006 * bootstrap-tooltip.js v2.2.1 1007 * http://twitter.github.com/bootstrap/javascript.html#tooltips 1008 * Inspired by the original jQuery.tipsy by Jason Frame 1009 * =========================================================== 1010 * Copyright 2012 Twitter, Inc. 1011 * 1012 * Licensed under the Apache License, Version 2.0 (the "License");
1013 * you may not use this file except in compliance with the License. 1014 * You may obtain a copy of the License at 1015 * 1016 * http://www.apache.org/licenses/LICENSE-2.0 1017 * 1018 * Unless required by applicable law or agreed to in writing, software 1019 * distributed under the License is distributed on an "AS IS" BASIS, 1020 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1021 * See the License for the specific language governing permissions and 1022 * limitations under the License. 1023 * ========================================================== */ 1024 1025 1026!function ($) { 1027 1028 "use strict"; // jshint ;_; 1029 1030 1031 /* TOOLTIP PUBLIC CLASS DEFINITION 1032 * =============================== */ 1033 1034 var Tooltip = function (element, options) { 1035 this.init('tooltip', element, options) 1036 } 1037 1038 Tooltip.prototype = { 1039 1040 constructor: Tooltip 1041 1042 , init: function (type, element, options) { 1043 var eventIn 1044 , eventOut 1045 1046 this.type = type 1047 this.$element = $(element) 1048 this.options = this.getOptions(options) 1049 this.enabled = true 1050 1051 if (this.options.trigger == 'click') { 1052 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 1053 } else if (this.options.trigger != 'manual') { 1054 eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus' 1055 eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur' 1056 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 1057 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 1058 } 1059 1060 this.options.selector ? 1061 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 1062 this.fixTitle() 1063 } 1064 1065 , getOptions: function (options) { 1066 options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data()) 1067 1068 if (options.delay && typeof options.delay == 'number') { 1069 options.delay = { 1070 show: options.delay 1071 , hide: options.delay 1072 } 1073 } 1074 1075 return options 1076 } 1077 1078 , enter: function (e) { 1079 var self = $(e.currentTarget)[this.type](this._options).data(this.type) 1080 1081 if (!self.options.delay || !self.options.delay.show) return self.show() 1082 1083 clearTimeout(this.timeout) 1084 self.hoverState = 'in' 1085 this.timeout = setTimeout(function() { 1086 if (self.hoverState == 'in') self.show() 1087 }, self.options.delay.show) 1088 } 1089 1090 , leave: function (e) { 1091 var self = $(e.currentTarget)[this.type](this._options).data(this.type) 1092 1093 if (this.timeout) clearTimeout(this.timeout) 1094 if (!self.options.delay || !self.options.delay.hide) return self.hide() 1095 1096 self.hoverState = 'out' 1097 this.timeout = setTimeout(function() { 1098 if (self.hoverState == 'out') self.hide() 1099 }, self.options.delay.hide) 1100 } 1101 1102 , show: function () { 1103 var $tip 1104 , inside 1105 , pos 1106 , actualWidth 1107 , actualHeight 1108 , placement 1109 , tp 1110 1111 if (this.hasContent() && this.enabled) { 1112 $tip = this.tip() 1113 this.setContent() 1114 1115 if (this.options.animation) { 1116 $tip.addClass('fade') 1117 } 1118 1119 placement = typeof this.options.placement == 'function' ? 1120 this.options.placement.call(this, $tip[0], this.$element[0]) : 1121 this.options.placement 1122 1123 inside = /in/.test(placement) 1124 1125 $tip 1126 .detach() 1127 .css({ top: 0, left: 0, display: 'block' }) 1128 .insertAfter(this.$element) 1129 1130 pos = this.getPosition(inside) 1131 1132 actualWidth = $tip[0].offsetWidth 1133 actualHeight = $tip[0].offsetHeight 1134 1135 switch (inside ? placement.split(' ')[1] : placement) { 1136 case 'bottom': 1137 tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} 1138 break 1139 case 'top': 1140 tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} 1141 break 1142 case 'left': 1143 tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} 1144 break 1145 case 'right': 1146 tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} 1147 break 1148 } 1149 1150 $tip 1151 .offset(tp) 1152 .addClass(placement) 1153 .addClass('in') 1154 } 1155 } 1156 1157 , setContent: function () { 1158 var $tip = this.tip() 1159 , title = this.getTitle() 1160 1161 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 1162 $tip.removeClass('fade in top bottom left right') 1163 } 1164 1165 , hide: function () { 1166 var that = this 1167 , $tip = this.tip() 1168 1169 $tip.removeClass('in') 1170 1171 function removeWithAnimation() { 1172 var timeout = setTimeout(function () {
1173 $tip.off($.support.transition.end).detach() 1174 }, 500) 1175 1176 $tip.one($.support.transition.end, function () { 1177 clearTimeout(timeout) 1178 $tip.detach() 1179 }) 1180 } 1181 1182 $.support.transition && this.$tip.hasClass('fade') ? 1183 removeWithAnimation() : 1184 $tip.detach() 1185 1186 return this 1187 } 1188 1189 , fixTitle: function () { 1190 var $e = this.$element 1191 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 1192 $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title') 1193 } 1194 } 1195 1196 , hasContent: function () { 1197 return this.getTitle() 1198 } 1199 1200 , getPosition: function (inside) { 1201 return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), { 1202 width: this.$element[0].offsetWidth 1203 , height: this.$element[0].offsetHeight 1204 }) 1205 } 1206 1207 , getTitle: function () { 1208 var title 1209 , $e = this.$element 1210 , o = this.options 1211 1212 title = $e.attr('data-original-title') 1213 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 1214 1215 return title 1216 } 1217 1218 , tip: function () { 1219 return this.$tip = this.$tip || $(this.options.template) 1220 } 1221 1222 , validate: function () { 1223 if (!this.$element[0].parentNode) { 1224 this.hide() 1225 this.$element = null 1226 this.options = null 1227 } 1228 } 1229 1230 , enable: function () { 1231 this.enabled = true 1232 } 1233 1234 , disable: function () { 1235 this.enabled = false 1236 } 1237 1238 , toggleEnabled: function () { 1239 this.enabled = !this.enabled 1240 } 1241 1242 , toggle: function (e) { 1243 var self = $(e.currentTarget)[this.type](this._options).data(this.type) 1244 self[self.tip().hasClass('in') ? 'hide' : 'show']() 1245 } 1246 1247 , destroy: function () { 1248 this.hide().$element.off('.' + this.type).removeData(this.type) 1249 } 1250 1251 } 1252 1253 1254 /* TOOLTIP PLUGIN DEFINITION 1255 * ========================= */ 1256 1257 $.fn.tooltip = function ( option ) { 1258 return this.each(function () { 1259 var $this = $(this) 1260 , data = $this.data('tooltip') 1261 , options = typeof option == 'object' && option 1262 if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) 1263 if (typeof option == 'string') data[option]() 1264 }) 1265 } 1266 1267 $.fn.tooltip.Constructor = Tooltip 1268 1269 $.fn.tooltip.defaults = { 1270 animation: true 1271 , placement: 'top' 1272 , selector: false 1273 , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' 1274 , trigger: 'hover' 1275 , title: '' 1276 , delay: 0 1277 , html: false 1278 } 1279 1280}(window.jQuery); 1281/* =========================================================== 1282 * bootstrap-popover.js v2.2.1 1283 * http://twitter.github.com/bootstrap/javascript.html#popovers 1284 * =========================================================== 1285 * Copyright 2012 Twitter, Inc. 1286 * 1287 * Licensed under the Apache License, Version 2.0 (the "License"); 1288 * you may not use this file except in compliance with the License. 1289 * You may obtain a copy of the License at 1290 * 1291 * http://www.apache.org/licenses/LICENSE-2.0 1292 * 1293 * Unless required by applicable law or agreed to in writing, software 1294 * distributed under the License is distributed on an "AS IS" BASIS, 1295 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1296 * See the License for the specific language governing permissions and 1297 * limitations under the License. 1298 * =========================================================== */ 1299 1300 1301!function ($) { 1302 1303 "use strict"; // jshint ;_; 1304 1305 1306 /* POPOVER PUBLIC CLASS DEFINITION 1307 * =============================== */ 1308 1309 var Popover = function (element, options) { 1310 this.init('popover', element, options) 1311 } 1312 1313 1314 /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js 1315 ========================================== */ 1316 1317 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { 1318 1319 constructor: Popover 1320 1321 , setContent: function () { 1322 var $tip = this.tip() 1323 , title = this.getTitle() 1324 , content = this.getContent() 1325 1326 $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) 1327 $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content) 1328 1329 $tip.removeClass('fade top bottom left right in') 1330 } 1331 1332 , hasContent: function () { 1333 return this.getTitle() || this.getContent() 1334 } 1335 1336 , getContent: function () { 1337 var content 1338 , $e = this.$element 1339 , o = this.options 1340 1341 content = $e.attr('data-content') 1342 || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) 1343 1344 return content 1345 } 1346 1347 , tip: function () { 1348 if (!this.$tip) { 1349 this.$tip = $(this.options.template) 1350 } 1351 return this.$tip 1352 } 1353 1354 , destroy: function () { 1355 this.hide().$element.off('.' + this.type).removeData(this.type) 1356 } 1357 1358 }) 1359 1360 1361 /* POPOVER PLUGIN DEFINITION 1362 * ======================= */ 1363 1364 $.fn.popover = function (option) { 1365 return this.each(function () { 1366 var $this = $(this) 1367 , data = $this.data('popover') 1368 , options = typeof option == 'object' && option 1369 if (!data) $this.data('popover', (data = new Popover(this, options))) 1370 if (typeof option == 'string') data[option]() 1371 }) 1372 } 1373 1374 $.fn.popover.Constructor = Popover 1375 1376 $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { 1377 placement: 'right' 1378 , trigger: 'click' 1379 , content: '' 1380 , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>' 1381 }) 1382 1383}(window.jQuery); 1384/* ============================================================= 1385 * bootstrap-scrollspy.js v2.2.1 1386 * http://twitter.github.com/bootstrap/javascript.html#scrollspy 1387 * ============================================================= 1388 * Copyright 2012 Twitter, Inc. 1389 * 1390 * Licensed under the Apache License, Version 2.0 (the "License");
1391 * you may not use this file except in compliance with the License. 1392 * You may obtain a copy of the License at 1393 * 1394 * http://www.apache.org/licenses/LICENSE-2.0 1395 * 1396 * Unless required by applicable law or agreed to in writing, software 1397 * distributed under the License is distributed on an "AS IS" BASIS, 1398 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1399 * See the License for the specific language governing permissions and 1400 * limitations under the License. 1401 * ============================================================== */ 1402 1403 1404!function ($) { 1405 1406 "use strict"; // jshint ;_; 1407 1408 1409 /* SCROLLSPY CLASS DEFINITION 1410 * ========================== */ 1411 1412 function ScrollSpy(element, options) { 1413 var process = $.proxy(this.process, this) 1414 , $element = $(element).is('body') ? $(window) : $(element) 1415 , href 1416 this.options = $.extend({}, $.fn.scrollspy.defaults, options) 1417 this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process) 1418 this.selector = (this.options.target 1419 || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 1420 || '') + ' .nav li > a' 1421 this.$body = $('body') 1422 this.refresh() 1423 this.process() 1424 } 1425 1426 ScrollSpy.prototype = { 1427 1428 constructor: ScrollSpy 1429 1430 , refresh: function () { 1431 var self = this 1432 , $targets 1433 1434 this.offsets = $([]) 1435 this.targets = $([]) 1436 1437 $targets = this.$body 1438 .find(this.selector) 1439 .map(function () { 1440 var $el = $(this) 1441 , href = $el.data('target') || $el.attr('href') 1442 , $href = /^#\w/.test(href) && $(href) 1443 return ( $href 1444 && $href.length 1445 && [[ $href.position().top, href ]] ) || null 1446 }) 1447 .sort(function (a, b) { return a[0] - b[0] }) 1448 .each(function () { 1449 self.offsets.push(this[0]) 1450 self.targets.push(this[1]) 1451 }) 1452 } 1453 1454 , process: function () { 1455 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset 1456 , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight 1457 , maxScroll = scrollHeight - this.$scrollElement.height() 1458 , offsets = this.offsets 1459 , targets = this.targets 1460 , activeTarget = this.activeTarget 1461 , i 1462 1463 if (scrollTop >= maxScroll) { 1464 return activeTarget != (i = targets.last()[0]) 1465 && this.activate ( i ) 1466 } 1467 1468 for (i = offsets.length; i--;) { 1469 activeTarget != targets[i] 1470 && scrollTop >= offsets[i] 1471 && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) 1472 && this.activate( targets[i] ) 1473 } 1474 } 1475 1476 , activate: function (target) { 1477 var active 1478 , selector 1479 1480 this.activeTarget = target 1481 1482 $(this.selector) 1483 .parent('.active') 1484 .removeClass('active') 1485 1486 selector = this.selector 1487 + '[data-target="' + target + '"],' 1488 + this.selector + '[href="' + target + '"]' 1489 1490 active = $(selector) 1491 .parent('li') 1492 .addClass('active') 1493 1494 if (active.parent('.dropdown-menu').length) { 1495 active = active.closest('li.dropdown').addClass('active') 1496 } 1497 1498 active.trigger('activate') 1499 } 1500 1501 } 1502 1503 1504 /* SCROLLSPY PLUGIN DEFINITION 1505 * =========================== */ 1506 1507 $.fn.scrollspy = function (option) { 1508 return this.each(function () { 1509 var $this = $(this) 1510 , data = $this.data('scrollspy') 1511 , options = typeof option == 'object' && option 1512 if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options))) 1513 if (typeof option == 'string') data[option]() 1514 }) 1515 } 1516 1517 $.fn.scrollspy.Constructor = ScrollSpy 1518 1519 $.fn.scrollspy.defaults = { 1520 offset: 10 1521 } 1522 1523 1524 /* SCROLLSPY DATA-API 1525 * ================== */ 1526 1527 $(window).on('load', function () { 1528 $('[data-spy="scroll"]').each(function () { 1529 var $spy = $(this) 1530 $spy.scrollspy($spy.data()) 1531 }) 1532 }) 1533 1534}(window.jQuery); 1535/* ======================================================== 1536 * bootstrap-tab.js v2.2.1 1537 * http://twitter.github.com/bootstrap/javascript.html#tabs 1538 * ======================================================== 1539 * Copyright 2012 Twitter, Inc. 1540 * 1541 * Licensed under the Apache License, Version 2.0 (the "License");
1542 * you may not use this file except in compliance with the License. 1543 * You may obtain a copy of the License at 1544 * 1545 * http://www.apache.org/licenses/LICENSE-2.0 1546 * 1547 * Unless required by applicable law or agreed to in writing, software 1548 * distributed under the License is distributed on an "AS IS" BASIS, 1549 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1550 * See the License for the specific language governing permissions and 1551 * limitations under the License. 1552 * ======================================================== */ 1553 1554 1555!function ($) { 1556 1557 "use strict"; // jshint ;_; 1558 1559 1560 /* TAB CLASS DEFINITION 1561 * ==================== */ 1562 1563 var Tab = function (element) { 1564 this.element = $(element) 1565 } 1566 1567 Tab.prototype = { 1568 1569 constructor: Tab 1570 1571 , show: function () { 1572 var $this = this.element 1573 , $ul = $this.closest('ul:not(.dropdown-menu)') 1574 , selector = $this.attr('data-target') 1575 , previous 1576 , $target 1577 , e 1578 1579 if (!selector) { 1580 selector = $this.attr('href') 1581 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 1582 } 1583 1584 if ( $this.parent('li').hasClass('active') ) return 1585 1586 previous = $ul.find('.active:last a')[0] 1587 1588 e = $.Event('show', { 1589 relatedTarget: previous 1590 }) 1591 1592 $this.trigger(e) 1593 1594 if (e.isDefaultPrevented()) return 1595 1596 $target = $(selector) 1597 1598 this.activate($this.parent('li'), $ul) 1599 this.activate($target, $target.parent(), function () { 1600 $this.trigger({ 1601 type: 'shown' 1602 , relatedTarget: previous 1603 }) 1604 }) 1605 } 1606 1607 , activate: function ( element, container, callback) { 1608 var $active = container.find('> .active') 1609 , transition = callback 1610 && $.support.transition 1611 && $active.hasClass('fade') 1612 1613 function next() { 1614 $active 1615 .removeClass('active') 1616 .find('> .dropdown-menu > .active') 1617 .removeClass('active') 1618 1619 element.addClass('active') 1620 1621 if (transition) { 1622 element[0].offsetWidth // reflow for transition 1623 element.addClass('in') 1624 } else { 1625 element.removeClass('fade') 1626 } 1627 1628 if ( element.parent('.dropdown-menu') ) { 1629 element.closest('li.dropdown').addClass('active') 1630 } 1631 1632 callback && callback() 1633 } 1634 1635 transition ? 1636 $active.one($.support.transition.end, next) : 1637 next() 1638 1639 $active.removeClass('in') 1640 } 1641 } 1642 1643 1644 /* TAB PLUGIN DEFINITION 1645 * ===================== */ 1646 1647 $.fn.tab = function ( option ) { 1648 return this.each(function () { 1649 var $this = $(this) 1650 , data = $this.data('tab') 1651 if (!data) $this.data('tab', (data = new Tab(this))) 1652 if (typeof option == 'string') data[option]() 1653 }) 1654 } 1655 1656 $.fn.tab.Constructor = Tab 1657 1658 1659 /* TAB DATA-API 1660 * ============ */ 1661 1662 $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 1663 e.preventDefault() 1664 $(this).tab('show') 1665 }) 1666 1667}(window.jQuery); 1668/* =================================================== 1669 * bootstrap-transition.js v2.2.1 1670 * http://twitter.github.com/bootstrap/javascript.html#transitions 1671 * =================================================== 1672 * Copyright 2012 Twitter, Inc. 1673 * 1674 * Licensed under the Apache License, Version 2.0 (the "License"); 1675 * you may not use this file except in compliance with the License. 1676 * You may obtain a copy of the License at 1677 * 1678 * http://www.apache.org/licenses/LICENSE-2.0 1679 * 1680 * Unless required by applicable law or agreed to in writing, software 1681 * distributed under the License is distributed on an "AS IS" BASIS, 1682 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1683 * See the License for the specific language governing permissions and 1684 * limitations under the License. 1685 * ========================================================== */ 1686 1687 1688!function ($) { 1689 1690 "use strict"; // jshint ;_; 1691 1692 1693 /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) 1694 * ======================================================= */ 1695 1696 $(function () { 1697 1698 $.support.transition = (function () { 1699 1700 var transitionEnd = (function () { 1701 1702 var el = document.createElement('bootstrap') 1703 , transEndEventNames = { 1704 'WebkitTransition' : 'webkitTransitionEnd' 1705 , 'MozTransition' : 'transitionend' 1706 , 'OTransition' : 'oTransitionEnd otransitionend' 1707 , 'transition' : 'transitionend' 1708 } 1709 , name 1710 1711 for (name in transEndEventNames){ 1712 if (el.style[name] !== undefined) { 1713 return transEndEventNames[name] 1714 } 1715 } 1716 1717 }()) 1718 1719 return transitionEnd && { 1720 end: transitionEnd 1721 } 1722 1723 })() 1724 1725 }) 1726 1727}(window.jQuery); 1728/* ============================================================= 1729 * bootstrap-typeahead.js v2.2.1 1730 * http://twitter.github.com/bootstrap/javascript.html#typeahead 1731 * ============================================================= 1732 * Copyright 2012 Twitter, Inc. 1733 * 1734 * Licensed under the Apache License, Version 2.0 (the "License");
vendor: 7,222 bytes, lines 1735-2029
1735 * you may not use this file except in compliance with the License. 1736 * You may obtain a copy of the License at 1737 * 1738 * http://www.apache.org/licenses/LICENSE-2.0 1739 * 1740 * Unless required by applicable law or agreed to in writing, software 1741 * distributed under the License is distributed on an "AS IS" BASIS, 1742 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1743 * See the License for the specific language governing permissions and 1744 * limitations under the License. 1745 * ============================================================ */ 1746 1747 1748!function($){ 1749 1750 "use strict"; // jshint ;_; 1751 1752 1753 /* TYPEAHEAD PUBLIC CLASS DEFINITION 1754 * ================================= */ 1755 1756 var Typeahead = function (element, options) { 1757 this.$element = $(element) 1758 this.options = $.extend({}, $.fn.typeahead.defaults, options) 1759 this.matcher = this.options.matcher || this.matcher 1760 this.sorter = this.options.sorter || this.sorter 1761 this.highlighter = this.options.highlighter || this.highlighter 1762 this.updater = this.options.updater || this.updater 1763 this.$menu = $(this.options.menu).appendTo('body') 1764 this.source = this.options.source 1765 this.shown = false 1766 this.listen() 1767 } 1768 1769 Typeahead.prototype = { 1770 1771 constructor: Typeahead 1772 1773 , select: function () { 1774 var val = this.$menu.find('.active').attr('data-value') 1775 this.$element 1776 .val(this.updater(val)) 1777 .change() 1778 return this.hide() 1779 } 1780 1781 , updater: function (item) { 1782 return item 1783 } 1784 1785 , show: function () { 1786 var pos = $.extend({}, this.$element.offset(), { 1787 height: this.$element[0].offsetHeight 1788 }) 1789 1790 this.$menu.css({ 1791 top: pos.top + pos.height 1792 , left: pos.left 1793 }) 1794 1795 this.$menu.show() 1796 this.shown = true 1797 return this 1798 } 1799 1800 , hide: function () { 1801 this.$menu.hide() 1802 this.shown = false 1803 return this 1804 } 1805 1806 , lookup: function (event) { 1807 var items 1808 1809 this.query = this.$element.val() 1810 1811 if (!this.query || this.query.length < this.options.minLength) { 1812 return this.shown ? this.hide() : this 1813 } 1814 1815 items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source 1816 1817 return items ? this.process(items) : this 1818 } 1819 1820 , process: function (items) { 1821 var that = this 1822 1823 items = $.grep(items, function (item) { 1824 return that.matcher(item) 1825 }) 1826 1827 items = this.sorter(items) 1828 1829 if (!items.length) { 1830 return this.shown ? this.hide() : this 1831 } 1832 1833 return this.render(items.slice(0, this.options.items)).show() 1834 } 1835 1836 , matcher: function (item) { 1837 return ~item.toLowerCase().indexOf(this.query.toLowerCase()) 1838 } 1839 1840 , sorter: function (items) { 1841 var beginswith = [] 1842 , caseSensitive = [] 1843 , caseInsensitive = [] 1844 , item 1845 1846 while (item = items.shift()) { 1847 if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item) 1848 else if (~item.indexOf(this.query)) caseSensitive.push(item) 1849 else caseInsensitive.push(item) 1850 } 1851 1852 return beginswith.concat(caseSensitive, caseInsensitive) 1853 } 1854 1855 , highlighter: function (item) { 1856 var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&') 1857 return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) { 1858 return '<strong>' + match + '</strong>' 1859 }) 1860 } 1861 1862 , render: function (items) { 1863 var that = this 1864 1865 items = $(items).map(function (i, item) { 1866 i = $(that.options.item).attr('data-value', item) 1867 i.find('a').html(that.highlighter(item)) 1868 return i[0] 1869 }) 1870 1871 items.first().addClass('active') 1872 this.$menu.html(items) 1873 return this 1874 } 1875 1876 , next: function (event) { 1877 var active = this.$menu.find('.active').removeClass('active') 1878 , next = active.next() 1879 1880 if (!next.length) { 1881 next = $(this.$menu.find('li')[0]) 1882 } 1883 1884 next.addClass('active') 1885 } 1886 1887 , prev: function (event) { 1888 var active = this.$menu.find('.active').removeClass('active') 1889 , prev = active.prev() 1890 1891 if (!prev.length) { 1892 prev = this.$menu.find('li').last() 1893 } 1894 1895 prev.addClass('active') 1896 } 1897 1898 , listen: function () { 1899 this.$element 1900 .on('blur', $.proxy(this.blur, this)) 1901 .on('keypress', $.proxy(this.keypress, this)) 1902 .on('keyup', $.proxy(this.keyup, this)) 1903 1904 if (this.eventSupported('keydown')) { 1905 this.$element.on('keydown', $.proxy(this.keydown, this)) 1906 } 1907 1908 this.$menu 1909 .on('click', $.proxy(this.click, this)) 1910 .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) 1911 } 1912 1913 , eventSupported: function(eventName) { 1914 var isSupported = eventName in this.$element 1915 if (!isSupported) { 1916 this.$element.setAttribute(eventName, 'return;') 1917 isSupported = typeof this.$element[eventName] === 'function' 1918 } 1919 return isSupported 1920 } 1921 1922 , move: function (e) { 1923 if (!this.shown) return 1924 1925 switch(e.keyCode) { 1926 case 9: // tab 1927 case 13: // enter 1928 case 27: // escape 1929 e.preventDefault() 1930 break 1931 1932 case 38: // up arrow 1933 e.preventDefault() 1934 this.prev() 1935 break 1936 1937 case 40: // down arrow 1938 e.preventDefault() 1939 this.next() 1940 break 1941 } 1942 1943 e.stopPropagation() 1944 } 1945 1946 , keydown: function (e) { 1947 this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27]) 1948 this.move(e) 1949 } 1950 1951 , keypress: function (e) { 1952 if (this.suppressKeyPressRepeat) return 1953 this.move(e) 1954 } 1955 1956 , keyup: function (e) { 1957 switch(e.keyCode) { 1958 case 40: // down arrow 1959 case 38: // up arrow 1960 case 16: // shift 1961 case 17: // ctrl 1962 case 18: // alt 1963 break 1964 1965 case 9: // tab 1966 case 13: // enter 1967 if (!this.shown) return 1968 this.select() 1969 break 1970 1971 case 27: // escape 1972 if (!this.shown) return 1973 this.hide() 1974 break 1975 1976 default: 1977 this.lookup() 1978 } 1979 1980 e.stopPropagation() 1981 e.preventDefault() 1982 } 1983 1984 , blur: function (e) { 1985 var that = this 1986 setTimeout(function () { that.hide() }, 150) 1987 } 1988 1989 , click: function (e) { 1990 e.stopPropagation() 1991 e.preventDefault() 1992 this.select() 1993 } 1994 1995 , mouseenter: function (e) { 1996 this.$menu.find('.active').removeClass('active') 1997 $(e.currentTarget).addClass('active') 1998 } 1999 2000 } 2001 2002 2003 /* TYPEAHEAD PLUGIN DEFINITION 2004 * =========================== */ 2005 2006 $.fn.typeahead = function (option) { 2007 return this.each(function () { 2008 var $this = $(this) 2009 , data = $this.data('typeahead') 2010 , options = typeof option == 'object' && option 2011 if (!data) $this.data('typeahead', (data = new Typeahead(this, options))) 2012 if (typeof option == 'string') data[option]() 2013 }) 2014 } 2015 2016 $.fn.typeahead.defaults = { 2017 source: [] 2018 , items: 8 2019 , menu: '<ul class="typeahead dropdown-menu"></ul>' 2020 , item: '<li><a href="#"></a></li>' 2021 , minLength: 1 2022 } 2023 2024 $.fn.typeahead.Constructor = Typeahead 2025 2026 2027 /* TYPEAHEAD DATA-API 2028 * ================== */ 2029
2030 $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { 2031 var $this = $(this) 2032 if ($this.data('typeahead')) return 2033 e.preventDefault() 2034 $this.typeahead($this.data()) 2035 }) 2036 2037}(window.jQuery); 2038 2039/*! 2040 * jQuery Migrate - v1.2.1 - 2013-05-08 2041 * https://github.com/jquery/jquery-migrate 2042 * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT 2043 */ 2044(function( jQuery, window, undefined ) { 2045// See http://bugs.jquery.com/ticket/13335 2046// "use strict"; 2047 2048 2049var warnedAbout = {}; 2050 2051// List of warnings already given; public read only 2052jQuery.migrateWarnings = []; 2053 2054// Set to true to prevent console output; migrateWarnings still maintained 2055// jQuery.migrateMute = false; 2056 2057// Show a message on the console so devs know we're active 2058if ( !jQuery.migrateMute && window.console && window.console.log ) { 2059 window.console.log("JQMIGRATE: Logging is active"); 2060} 2061 2062// Set to false to disable traces that appear with warnings 2063if ( jQuery.migrateTrace === undefined ) { 2064 jQuery.migrateTrace = true; 2065} 2066 2067// Forget any warnings we've already given; public 2068jQuery.migrateReset = function() { 2069 warnedAbout = {}; 2070 jQuery.migrateWarnings.length = 0; 2071}; 2072 2073function migrateWarn( msg) { 2074 var console = window.console; 2075 if ( !warnedAbout[ msg ] ) { 2076 warnedAbout[ msg ] = true; 2077 jQuery.migrateWarnings.push( msg ); 2078 if ( console && console.warn && !jQuery.migrateMute ) { 2079 console.warn( "JQMIGRATE: " + msg ); 2080 if ( jQuery.migrateTrace && console.trace ) { 2081 console.trace(); 2082 } 2083 } 2084 } 2085} 2086 2087function migrateWarnProp( obj, prop, value, msg ) { 2088 if ( Object.defineProperty ) { 2089 // On ES5 browsers (non-oldIE), warn if the code tries to get prop; 2090 // allow property to be overwritten in case some other plugin wants it 2091 try { 2092 Object.defineProperty( obj, prop, { 2093 configurable: true, 2094 enumerable: true, 2095 get: function() { 2096 migrateWarn( msg ); 2097 return value; 2098 }, 2099 set: function( newValue ) { 2100 migrateWarn( msg ); 2101 value = newValue; 2102 } 2103 }); 2104 return; 2105 } catch( err ) { 2106 // IE8 is a dope about Object.defineProperty, can't warn there 2107 } 2108 } 2109 2110 // Non-ES5 (or broken) browser; just set the property 2111 jQuery._definePropertyBroken = true; 2112 obj[ prop ] = value; 2113} 2114 2115if ( document.compatMode === "BackCompat" ) { 2116 // jQuery has never supported or tested Quirks Mode 2117 migrateWarn( "jQuery is not compatible with Quirks Mode" ); 2118} 2119 2120 2121var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn, 2122 oldAttr = jQuery.attr, 2123 valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get || 2124 function() { return null; }, 2125 valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set || 2126 function() { return undefined; }, 2127 rnoType = /^(?:input|button)$/i, 2128 rnoAttrNodeType = /^[238]$/, 2129 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, 2130 ruseDefault = /^(?:checked|selected)$/i; 2131 2132// jQuery.attrFn 2133migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" ); 2134 2135jQuery.attr = function( elem, name, value, pass ) { 2136 var lowerName = name.toLowerCase(), 2137 nType = elem && elem.nodeType; 2138 2139 if ( pass ) { 2140 // Since pass is used internally, we only warn for new jQuery 2141 // versions where there isn't a pass arg in the formal params 2142 if ( oldAttr.length < 4 ) { 2143 migrateWarn("jQuery.fn.attr( props, pass ) is deprecated"); 2144 } 2145 if ( elem && !rnoAttrNodeType.test( nType ) && 2146 (attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) { 2147 return jQuery( elem )[ name ]( value ); 2148 } 2149 } 2150 2151 // Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking 2152 // for disconnected elements we don't warn on $( "<button>", { type: "button" } ). 2153 if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) { 2154 migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8"); 2155 } 2156 2157 // Restore boolHook for boolean property/attribute synchronization 2158 if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) { 2159 jQuery.attrHooks[ lowerName ] = { 2160 get: function( elem, name ) { 2161 // Align boolean attributes with corresponding properties 2162 // Fall back to attribute presence where some booleans are not supported 2163 var attrNode, 2164 property = jQuery.prop( elem, name ); 2165 return property === true || typeof property !== "boolean" && 2166 ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? 2167 2168 name.toLowerCase() : 2169 undefined; 2170 },
2171 set: function( elem, value, name ) { 2172 var propName; 2173 if ( value === false ) { 2174 // Remove boolean attributes when set to false 2175 jQuery.removeAttr( elem, name ); 2176 } else { 2177 // value is true since we know at this point it's type boolean and not false 2178 // Set boolean attributes to the same name and set the DOM property 2179 propName = jQuery.propFix[ name ] || name; 2180 if ( propName in elem ) { 2181 // Only set the IDL specifically if it already exists on the element 2182 elem[ propName ] = true; 2183 } 2184 2185 elem.setAttribute( name, name.toLowerCase() ); 2186 } 2187 return name; 2188 } 2189 }; 2190 2191 // Warn only for attributes that can remain distinct from their properties post-1.9 2192 if ( ruseDefault.test( lowerName ) ) { 2193 migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" ); 2194 } 2195 } 2196 2197 return oldAttr.call( jQuery, elem, name, value ); 2198}; 2199 2200// attrHooks: value 2201jQuery.attrHooks.value = { 2202 get: function( elem, name ) { 2203 var nodeName = ( elem.nodeName || "" ).toLowerCase(); 2204 if ( nodeName === "button" ) { 2205 return valueAttrGet.apply( this, arguments ); 2206 } 2207 if ( nodeName !== "input" && nodeName !== "option" ) { 2208 migrateWarn("jQuery.fn.attr('value') no longer gets properties"); 2209 } 2210 return name in elem ? 2211 elem.value : 2212 null; 2213 }, 2214 set: function( elem, value ) { 2215 var nodeName = ( elem.nodeName || "" ).toLowerCase(); 2216 if ( nodeName === "button" ) { 2217 return valueAttrSet.apply( this, arguments ); 2218 } 2219 if ( nodeName !== "input" && nodeName !== "option" ) { 2220 migrateWarn("jQuery.fn.attr('value', val) no longer sets properties"); 2221 } 2222 // Does not return so that setAttribute is also used 2223 elem.value = value; 2224 } 2225}; 2226 2227 2228var matched, browser, 2229 oldInit = jQuery.fn.init, 2230 oldParseJSON = jQuery.parseJSON, 2231 // Note: XSS check is done below after string is trimmed 2232 rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/; 2233 2234// $(html) "looks like html" rule change 2235jQuery.fn.init = function( selector, context, rootjQuery ) { 2236 var match; 2237 2238 if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) && 2239 (match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) { 2240 // This is an HTML string according to the "old" rules; is it still? 2241 if ( selector.charAt( 0 ) !== "<" ) { 2242 migrateWarn("$(html) HTML strings must start with '<' character"); 2243 } 2244 if ( match[ 3 ] ) { 2245 migrateWarn("$(html) HTML text after last tag is ignored"); 2246 } 2247 // Consistently reject any HTML-like string starting with a hash (#9521) 2248 // Note that this may break jQuery 1.6.x code that otherwise would work. 2249 if ( match[ 0 ].charAt( 0 ) === "#" ) { 2250 migrateWarn("HTML string cannot start with a '#' character"); 2251 jQuery.error("JQMIGRATE: Invalid selector string (XSS)"); 2252 } 2253 // Now process using loose rules; let pre-1.8 play too 2254 if ( context && context.context ) { 2255 // jQuery object as context; parseHTML expects a DOM object 2256 context = context.context; 2257 } 2258 if ( jQuery.parseHTML ) { 2259 return oldInit.call( this, jQuery.parseHTML( match[ 2 ], context, true ), 2260 context, rootjQuery ); 2261 } 2262 } 2263 return oldInit.apply( this, arguments ); 2264}; 2265jQuery.fn.init.prototype = jQuery.fn; 2266 2267// Let $.parseJSON(falsy_value) return null 2268jQuery.parseJSON = function( json ) { 2269 if ( !json && json !== null ) { 2270 migrateWarn("jQuery.parseJSON requires a valid JSON string"); 2271 return null; 2272 } 2273 return oldParseJSON.apply( this, arguments ); 2274}; 2275 2276jQuery.uaMatch = function( ua ) { 2277 ua = ua.toLowerCase(); 2278 2279 var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || 2280 /(webkit)[ \/]([\w.]+)/.exec( ua ) || 2281 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || 2282 /(msie) ([\w.]+)/.exec( ua ) || 2283 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || 2284 []; 2285 2286 return { 2287 browser: match[ 1 ] || "", 2288 version: match[ 2 ] || "0" 2289 }; 2290}; 2291 2292// Don't clobber any existing jQuery.browser in case it's different 2293if ( !jQuery.browser ) { 2294 matched = jQuery.uaMatch( navigator.userAgent ); 2295 browser = {}; 2296 2297 if ( matched.browser ) { 2298 browser[ matched.browser ] = true; 2299 browser.version = matched.version; 2300 } 2301 2302 // Chrome is Webkit, but Webkit is also Safari. 2303 if ( browser.chrome ) { 2304 browser.webkit = true; 2305 } else if ( browser.webkit ) { 2306 browser.safari = true; 2307 } 2308 2309 jQuery.browser = browser; 2310} 2311 2312// Warn if the code tries to get jQuery.browser 2313migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" ); 2314 2315jQuery.sub = function() { 2316 function jQuerySub( selector, context ) { 2317 return new jQuerySub.fn.init( selector, context ); 2318 } 2319 jQuery.extend( true, jQuerySub, this ); 2320 jQuerySub.superclass = this; 2321 jQuerySub.fn = jQuerySub.prototype = this(); 2322 jQuerySub.fn.constructor = jQuerySub; 2323 jQuerySub.sub = this.sub; 2324 jQuerySub.fn.init = function init( selector, context ) { 2325 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { 2326 context = jQuerySub( context ); 2327 } 2328 2329 return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); 2330 }; 2331 jQuerySub.fn.init.prototype = jQuerySub.fn; 2332 var rootjQuerySub = jQuerySub(document); 2333 migrateWarn( "jQuery.sub() is deprecated" ); 2334 return jQuerySub; 2335}; 2336 2337 2338// Ensure that $.ajax gets the new parseJSON defined in core.js 2339jQuery.ajaxSetup({ 2340 converters: { 2341 "text json": jQuery.parseJSON 2342 } 2343}); 2344 2345 2346var oldFnData = jQuery.fn.data; 2347 2348jQuery.fn.data = function( name ) { 2349 var ret, evt, 2350 elem = this[0]; 2351 2352 // Handles 1.7 which has this behavior and 1.8 which doesn't 2353 if ( elem && name === "events" && arguments.length === 1 ) { 2354 ret = jQuery.data( elem, name ); 2355 evt = jQuery._data( elem, name ); 2356 if ( ( ret === undefined || ret === evt ) && evt !== undefined ) { 2357 migrateWarn("Use of jQuery.fn.data('events') is deprecated"); 2358 return evt; 2359 } 2360 } 2361 return oldFnData.apply( this, arguments ); 2362};
2363 2364 2365var rscriptType = /\/(java|ecma)script/i, 2366 oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack; 2367 2368jQuery.fn.andSelf = function() { 2369 migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()"); 2370 return oldSelf.apply( this, arguments ); 2371}; 2372 2373// Since jQuery.clean is used internally on older versions, we only shim if it's missing 2374if ( !jQuery.clean ) { 2375 jQuery.clean = function( elems, context, fragment, scripts ) { 2376 // Set context per 1.8 logic 2377 context = context || document; 2378 context = !context.nodeType && context[0] || context; 2379 context = context.ownerDocument || context; 2380 2381 migrateWarn("jQuery.clean() is deprecated"); 2382 2383 var i, elem, handleScript, jsTags, 2384 ret = []; 2385 2386 jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes ); 2387 2388 // Complex logic lifted directly from jQuery 1.8 2389 if ( fragment ) { 2390 // Special handling of each script element 2391 handleScript = function( elem ) { 2392 // Check if we consider it executable 2393 if ( !elem.type || rscriptType.test( elem.type ) ) { 2394 // Detach the script and store it in the scripts array (if provided) or the fragment 2395 // Return truthy to indicate that it has been handled 2396 return scripts ? 2397 scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : 2398 fragment.appendChild( elem ); 2399 } 2400 }; 2401 2402 for ( i = 0; (elem = ret[i]) != null; i++ ) { 2403 // Check if we're done after handling an executable script 2404 if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { 2405 // Append to fragment and handle embedded scripts 2406 fragment.appendChild( elem ); 2407 if ( typeof elem.getElementsByTagName !== "undefined" ) { 2408 // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration 2409 jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); 2410 2411 // Splice the scripts into ret after their former ancestor and advance our index beyond them 2412 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); 2413 i += jsTags.length; 2414 } 2415 } 2416 } 2417 } 2418 2419 return ret; 2420 }; 2421} 2422 2423var eventAdd = jQuery.event.add, 2424 eventRemove = jQuery.event.remove, 2425 eventTrigger = jQuery.event.trigger, 2426 oldToggle = jQuery.fn.toggle, 2427 oldLive = jQuery.fn.live, 2428 oldDie = jQuery.fn.die, 2429 ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess", 2430 rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ), 2431 rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, 2432 hoverHack = function( events ) { 2433 if ( typeof( events ) !== "string" || jQuery.event.special.hover ) { 2434 return events; 2435 } 2436 if ( rhoverHack.test( events ) ) { 2437 migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'"); 2438 } 2439 return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); 2440 }; 2441 2442// Event props removed in 1.9, put them back if needed; no practical way to warn them 2443if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) { 2444 jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" ); 2445} 2446 2447// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7 2448if ( jQuery.event.dispatch ) { 2449 migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" ); 2450} 2451 2452// Support for 'hover' pseudo-event and ajax event warnings 2453jQuery.event.add = function( elem, types, handler, data, selector ){ 2454 if ( elem !== document && rajaxEvent.test( types ) ) { 2455 migrateWarn( "AJAX events should be attached to document: " + types ); 2456 } 2457 eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector ); 2458}; 2459jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){ 2460 eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes ); 2461};
2462 2463jQuery.fn.error = function() { 2464 var args = Array.prototype.slice.call( arguments, 0); 2465 migrateWarn("jQuery.fn.error() is deprecated"); 2466 args.splice( 0, 0, "error" ); 2467 if ( arguments.length ) { 2468 return this.bind.apply( this, args ); 2469 } 2470 // error event should not bubble to window, although it does pre-1.7 2471 this.triggerHandler.apply( this, args ); 2472 return this; 2473}; 2474 2475jQuery.fn.toggle = function( fn, fn2 ) { 2476 2477 // Don't mess with animation or css toggles 2478 if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) { 2479 return oldToggle.apply( this, arguments ); 2480 } 2481 migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated"); 2482 2483 // Save reference to arguments for access in closure 2484 var args = arguments, 2485 guid = fn.guid || jQuery.guid++, 2486 i = 0, 2487 toggler = function( event ) { 2488 // Figure out which function to execute 2489 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; 2490 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 2491 2492 // Make sure that clicks stop 2493 event.preventDefault(); 2494 2495 // and execute the function 2496 return args[ lastToggle ].apply( this, arguments ) || false; 2497 }; 2498 2499 // link all the functions, so any of them can unbind this click handler 2500 toggler.guid = guid; 2501 while ( i < args.length ) { 2502 args[ i++ ].guid = guid; 2503 } 2504 2505 return this.click( toggler ); 2506}; 2507 2508jQuery.fn.live = function( types, data, fn ) { 2509 migrateWarn("jQuery.fn.live() is deprecated"); 2510 if ( oldLive ) { 2511 return oldLive.apply( this, arguments ); 2512 } 2513 jQuery( this.context ).on( types, this.selector, data, fn ); 2514 return this; 2515}; 2516 2517jQuery.fn.die = function( types, fn ) { 2518 migrateWarn("jQuery.fn.die() is deprecated"); 2519 if ( oldDie ) { 2520 return oldDie.apply( this, arguments ); 2521 } 2522 jQuery( this.context ).off( types, this.selector || "**", fn ); 2523 return this; 2524}; 2525 2526// Turn global events into document-triggered events 2527jQuery.event.trigger = function( event, data, elem, onlyHandlers ){ 2528 if ( !elem && !rajaxEvent.test( event ) ) { 2529 migrateWarn( "Global events are undocumented and deprecated" ); 2530 } 2531 return eventTrigger.call( this, event, data, elem || document, onlyHandlers ); 2532}; 2533jQuery.each( ajaxEvents.split("|"), 2534 function( _, name ) { 2535 jQuery.event.special[ name ] = { 2536 setup: function() { 2537 var elem = this; 2538 2539 // The document needs no shimming; must be !== for oldIE 2540 if ( elem !== document ) { 2541 jQuery.event.add( document, name + "." + jQuery.guid, function() { 2542 jQuery.event.trigger( name, null, elem, true ); 2543 }); 2544 jQuery._data( this, name, jQuery.guid++ ); 2545 } 2546 return false; 2547 }, 2548 teardown: function() { 2549 if ( this !== document ) { 2550 jQuery.event.remove( document, name + "." + jQuery._data( this, name ) ); 2551 } 2552 return false; 2553 } 2554 }; 2555 } 2556); 2557 2558 2559})( jQuery, window ); 2560 2561/* 2562 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 2563 * 2564 * Uses the built in easing capabilities added In jQuery 1.1 2565 * to offer multiple easing options 2566 * 2567 * TERMS OF USE - jQuery Easing 2568 * 2569 * Open source under the BSD License. 2570 * 2571 * Copyright © 2008 George McGinley Smith 2572 * All rights reserved. 2573 * 2574 * Redistribution and use in source and binary forms, with or without modification, 2575 * are permitted provided that the following conditions are met: 2576 * 2577 * Redistributions of source code must retain the above copyright notice, this list of 2578 * conditions and the following disclaimer. 2579 * Redistributions in binary form must reproduce the above copyright notice, this list 2580 * of conditions and the following disclaimer in the documentation and/or other materials 2581 * provided with the distribution. 2582 * 2583 * Neither the name of the author nor the names of contributors may be used to endorse 2584 * or promote products derived from this software without specific prior written permission. 2585 * 2586 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 2587 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2588 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2589 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
vendor: 5,692 bytes, lines 2590-2736
2590 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 2591 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2592 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2593 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 2594 * OF THE POSSIBILITY OF SUCH DAMAGE. 2595 * 2596*/ 2597 2598// t: current time, b: begInnIng value, c: change In value, d: duration 2599jQuery.easing['jswing'] = jQuery.easing['swing']; 2600 2601jQuery.extend( jQuery.easing, 2602{ 2603 def: 'easeOutQuad', 2604 swing: function (x, t, b, c, d) { 2605 //alert(jQuery.easing.default); 2606 return jQuery.easing[jQuery.easing.def](x, t, b, c, d); 2607 }, 2608 easeInQuad: function (x, t, b, c, d) { 2609 return c*(t/=d)*t + b; 2610 }, 2611 easeOutQuad: function (x, t, b, c, d) { 2612 return -c *(t/=d)*(t-2) + b; 2613 }, 2614 easeInOutQuad: function (x, t, b, c, d) { 2615 if ((t/=d/2) < 1) return c/2*t*t + b; 2616 return -c/2 * ((--t)*(t-2) - 1) + b; 2617 }, 2618 easeInCubic: function (x, t, b, c, d) { 2619 return c*(t/=d)*t*t + b; 2620 }, 2621 easeOutCubic: function (x, t, b, c, d) { 2622 return c*((t=t/d-1)*t*t + 1) + b; 2623 }, 2624 easeInOutCubic: function (x, t, b, c, d) { 2625 if ((t/=d/2) < 1) return c/2*t*t*t + b; 2626 return c/2*((t-=2)*t*t + 2) + b; 2627 }, 2628 easeInQuart: function (x, t, b, c, d) { 2629 return c*(t/=d)*t*t*t + b; 2630 }, 2631 easeOutQuart: function (x, t, b, c, d) { 2632 return -c * ((t=t/d-1)*t*t*t - 1) + b; 2633 }, 2634 easeInOutQuart: function (x, t, b, c, d) { 2635 if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 2636 return -c/2 * ((t-=2)*t*t*t - 2) + b; 2637 }, 2638 easeInQuint: function (x, t, b, c, d) { 2639 return c*(t/=d)*t*t*t*t + b; 2640 }, 2641 easeOutQuint: function (x, t, b, c, d) { 2642 return c*((t=t/d-1)*t*t*t*t + 1) + b; 2643 }, 2644 easeInOutQuint: function (x, t, b, c, d) { 2645 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 2646 return c/2*((t-=2)*t*t*t*t + 2) + b; 2647 }, 2648 easeInSine: function (x, t, b, c, d) { 2649 return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 2650 }, 2651 easeOutSine: function (x, t, b, c, d) { 2652 return c * Math.sin(t/d * (Math.PI/2)) + b; 2653 }, 2654 easeInOutSine: function (x, t, b, c, d) { 2655 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 2656 }, 2657 easeInExpo: function (x, t, b, c, d) { 2658 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 2659 }, 2660 easeOutExpo: function (x, t, b, c, d) { 2661 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 2662 }, 2663 2664 easeInOutExpo: function (x, t, b, c, d) { 2665 if (t==0) return b; 2666 if (t==d) return b+c; 2667 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 2668 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 2669 }, 2670 easeInCirc: function (x, t, b, c, d) { 2671 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 2672 }, 2673 easeOutCirc: function (x, t, b, c, d) { 2674 return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 2675 }, 2676 easeInOutCirc: function (x, t, b, c, d) { 2677 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 2678 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 2679 }, 2680 easeInElastic: function (x, t, b, c, d) { 2681 var s=1.70158;var p=0;var a=c; 2682 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 2683 if (a < Math.abs(c)) { a=c; var s=p/4; } 2684 else var s = p/(2*Math.PI) * Math.asin (c/a); 2685 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 2686 }, 2687 easeOutElastic: function (x, t, b, c, d) { 2688 var s=1.70158;var p=0;var a=c; 2689 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 2690 if (a < Math.abs(c)) { a=c; var s=p/4; } 2691 else var s = p/(2*Math.PI) * Math.asin (c/a); 2692 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 2693 }, 2694 easeInOutElastic: function (x, t, b, c, d) { 2695 var s=1.70158;var p=0;var a=c; 2696 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 2697 if (a < Math.abs(c)) { a=c; var s=p/4; } 2698 else var s = p/(2*Math.PI) * Math.asin (c/a); 2699 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 2700 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 2701 }, 2702 easeInBack: function (x, t, b, c, d, s) { 2703 if (s == undefined) s = 1.70158; 2704 return c*(t/=d)*t*((s+1)*t - s) + b; 2705 }, 2706 easeOutBack: function (x, t, b, c, d, s) { 2707 if (s == undefined) s = 1.70158; 2708 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 2709 }, 2710 easeInOutBack: function (x, t, b, c, d, s) { 2711 if (s == undefined) s = 1.70158; 2712 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 2713 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 2714 }, 2715 easeInBounce: function (x, t, b, c, d) { 2716 return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; 2717 }, 2718 easeOutBounce: function (x, t, b, c, d) { 2719 if ((t/=d) < (1/2.75)) { 2720 return c*(7.5625*t*t) + b; 2721 } else if (t < (2/2.75)) { 2722 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 2723 } else if (t < (2.5/2.75)) { 2724 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 2725 } else { 2726 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 2727 } 2728 }, 2729 easeInOutBounce: function (x, t, b, c, d) { 2730 if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; 2731 return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; 2732 } 2733}); 2734 2735/* 2736 *
2737 * TERMS OF USE - EASING EQUATIONS 2738 * 2739 * Open source under the BSD License. 2740 * 2741 * Copyright © 2001 Robert Penner 2742 * All rights reserved. 2743 * 2744 * Redistribution and use in source and binary forms, with or without modification, 2745 * are permitted provided that the following conditions are met: 2746 * 2747 * Redistributions of source code must retain the above copyright notice, this list of 2748 * conditions and the following disclaimer. 2749 * Redistributions in binary form must reproduce the above copyright notice, this list 2750 * of conditions and the following disclaimer in the documentation and/or other materials 2751 * provided with the distribution. 2752 * 2753 * Neither the name of the author nor the names of contributors may be used to endorse 2754 * or promote products derived from this software without specific prior written permission. 2755 * 2756 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 2757 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2758 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2759 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2760 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 2761 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2762 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2763 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 2764 * OF THE POSSIBILITY OF SUCH DAMAGE. 2765 * 2766 */ 2767/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 2768 * Licensed under the MIT License (LICENSE.txt). 2769 * 2770 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 2771 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 2772 * Thanks to: Seamus Leahy for adding deltaX and deltaY 2773 * 2774 * Version: 3.0.6 2775 * 2776 * Requires: 1.2.2+ 2777 */ 2778(function(a){function d(b){var c=b||window.event,d=[].slice.call(arguments,1),e=0,f=!0,g=0,h=0;return b=a.event.fix(c),b.type="mousewheel",c.wheelDelta&&(e=c.wheelDelta/120),c.detail&&(e=-c.detail/3),h=e,c.axis!==undefined&&c.axis===c.HORIZONTAL_AXIS&&(h=0,g=-1*e),c.wheelDeltaY!==undefined&&(h=c.wheelDeltaY/120),c.wheelDeltaX!==undefined&&(g=-1*c.wheelDeltaX/120),d.unshift(b,e,g,h),(a.event.dispatch||a.event.handle).apply(this,d)}var b=["DOMMouseScroll","mousewheel"];if(a.event.fixHooks)for(var c=b.length;c;)a.event.fixHooks[b[--c]]=a.event.mouseHooks;a.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=b.length;a;)this.addEventListener(b[--a],d,!1);else this.onmousewheel=d},teardown:function(){if(this.removeEventListener)for(var a=b.length;a;)this.removeEventListener(b[--a],d,!1);else this.onmousewheel=null}},a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery); 2779 2780/** 2781 * Rhinoslider 1.05 2782 * http://rhinoslider.com/ 2783 * 2784 * Copyright 2013: Sebastian Pontow, Rene Maas (http://renemaas.de/) 2785 * Dual licensed under the MIT or GPL Version 2 licenses. 2786 * http://rhinoslider.com/license/ 2787 */ 2788 2789(function($,window,undefined){$.extend($.easing,{def:'out',out:function(none,currentTime,startValue,endValue,totalTime){return-endValue*(currentTime/=totalTime)*(currentTime-2)+startValue;},kick:function(none,currentTime,startValue,endValue,totalTime){if((currentTime/=totalTime/2)<1){return endValue/2*Math.pow(2,10*(currentTime-1))+startValue;} 2790return endValue/2*(-Math.pow(2,-10*--currentTime)+2)+startValue;},shuffle:function(none,currentTime,startValue,endValue,totalTime){if((currentTime/=totalTime/2)<1){return endValue/2*currentTime*currentTime*currentTime*currentTime*currentTime+startValue;} 2791return endValue/2*((currentTime-=2)*currentTime*currentTime*currentTime*currentTime+2)+startValue;}});var rhinoSlider=function(element,opts){var 2792settings=$.extend({},$.fn.rhinoslider.defaults,opts),$slider=$(element),effects=$.fn.rhinoslider.effects,preparations=$.fn.rhinoslider.preparations,vars={isPlaying:false,intervalAutoPlay:false,active:'',next:'',container:'',items:'',buttons:[],prefix:'rhino-',playedArray:[],playedCounter:0,original:element};settings.callBeforeInit();var
2793setUpSettings=function(settings){settings.controlsPrevNext=String(settings.controlsPrevNext)=='true'?true:false;settings.controlsKeyboard=String(settings.controlsKeyboard)=='true'?true:false;settings.controlsMousewheel=String(settings.controlsMousewheel)=='true'?true:false;settings.controlsPlayPause=String(settings.controlsPlayPause)=='true'?true:false;settings.pauseOnHover=String(settings.pauseOnHover)=='true'?true:false;settings.animateActive=String(settings.animateActive)=='true'?true:false;settings.autoPlay=String(settings.autoPlay)=='true'?true:false;settings.cycled=String(settings.cycled)=='true'?true:false;settings.showTime=parseInt(settings.showTime,10);settings.effectTime=parseInt(settings.effectTime,10);settings.controlFadeTime=parseInt(settings.controlFadeTime,10);settings.captionsFadeTime=parseInt(settings.captionsFadeTime,10);tmpShiftValue=settings.shiftValue;tmpParts=settings.parts;settings.shiftValue=[];settings.parts=[];return settings;},init=function($slider,settings,vars){settings=setUpSettings(settings);
2793$slider.wrap('<div class="'+vars.prefix+'container">');vars.container=$slider.parent('.'+vars.prefix+'container');vars.isPlaying=settings.autoPlay;var buttons='';if(settings.controlsPrevNext){vars.container.addClass(vars.prefix+'controls-prev-next');buttons='<a class="'+vars.prefix+'prev '+vars.prefix+'btn">'+settings.prevText+'</a><a class="'+vars.prefix+'next '+vars.prefix+'btn">'+settings.nextText+'</a>';vars.container.append(buttons);vars.buttons.prev=vars.container.find('.'+vars.prefix+'prev');vars.buttons.next=vars.container.find('.'+vars.prefix+'next');vars.buttons.prev.click(function(){prev($slider,settings);if(settings.autoPlay){pause();}});vars.buttons.next.click(function(){next($slider,settings);if(settings.autoPlay){pause();}});} 2794if(settings.controlsPlayPause){vars.container.addClass(vars.prefix+'controls-play-pause');buttons=settings.autoPlay?'<a class="'+vars.prefix+'toggle '+vars.prefix+'pause '+vars.prefix+'btn">'+settings.pauseText+'</a>':'<a class="'+vars.prefix+'toggle '+vars.prefix+'play '+vars.prefix+'btn">'+settings.playText+'</a>';vars.container.append(buttons);vars.buttons.play=vars.container.find('.'+vars.prefix+'toggle');vars.buttons.play.click(function(){if(vars.isPlaying===false){play();}else{pause();}});} 2795vars.container.find('.'+vars.prefix+'btn').css({position:'absolute',display:'block',cursor:'pointer'});if(settings.showControls!=='always'){var allControls=vars.container.find('.'+vars.prefix+'btn');allControls.stop(true,true).fadeOut(0);if(settings.showControls==='hover'){vars.container.mouseenter(function(){allControls.stop(true,true).fadeIn(settings.controlFadeTime);}).mouseleave(function(){allControls.delay(200).fadeOut(settings.controlFadeTime);});}} 2796if(settings.showControls!=='never'){vars.container.addClass(vars.prefix+'show-controls');} 2797vars.items=$slider.children();vars.items.addClass(vars.prefix+'item');vars.items.first().addClass(vars.prefix+'active');var sliderStyles=settings.styles.split(','),style;$.each(sliderStyles,function(i,cssAttribute){style=$.trim(cssAttribute);vars.container.css(style,$slider.css(style));$slider.css(style,' ');switch(style){case'width':case'height':$slider.css(style,'100%');break;}});if(vars.container.css('position')=='static'){vars.container.css('position','relative');} 2798$slider.css({top:'auto',left:'auto',position:'relative'});vars.items.css({margin:0,width:$slider.css('width'),height:$slider.css('height'),position:'absolute',top:0,left:0,zIndex:0,opacity:0,overflow:'hidden'});vars.items.each(function(i){$(this).attr('id',vars.prefix+'item'+i);});if(settings.showBullets!=='never'){vars.container.addClass(vars.prefix+'show-bullets');var navi='<ol class="'+vars.prefix+'bullets">';vars.items.each(function(i){var $item=$(this);var id=vars.prefix+'item'+i;navi=navi+'<li><a id="'+id+'-bullet" class="'+vars.prefix+'bullet">'+parseInt(i+1,10)+'</a></li>';});navi=navi+'</ol>';vars.container.append(navi);vars.navigation=vars.container.find('.'+vars.prefix+'bullets');vars.buttons.bullets=vars.navigation.find('.'+vars.prefix+'bullet');vars.buttons.bullets.first().addClass(vars.prefix+'active-bullet '+vars.prefix+'first-bullet');vars.buttons.bullets.last().addClass(vars.prefix+'last-bullet');vars.buttons.bullets.click(function(){var itemID=$(this).attr('id').replace('-bullet','');var $next=vars.container.find('#'+itemID);var curID=parseInt(vars.navigation.find('.'+vars.prefix+'active-bullet').attr('id').replace('-bullet','').replace(vars.prefix+'item',''),10);var nextID=parseInt(itemID.replace(vars.prefix+'item',''),10);if(curID<nextID){next($slider,settings,$next);}else if(curID>nextID){prev($slider,settings,$next);}else{return false;} 2799if(settings.autoPlay){pause();}});} 2800if(settings.showBullets==='hover'){vars.navigation.hide();vars.container.mouseenter(function(){vars.navigation.stop(true,true).fadeIn(settings.controlFadeTime);}).mouseleave(function(){vars.navigation.delay(200).fadeOut(settings.controlFadeTime);});} 2801if(settings.showCaptions!=='never'){vars.container.addClass(vars.prefix+'show-captions');vars.items.each(function(){var $item=$(this);if($item.children('.'+vars.prefix+'caption').length==0){if($item.children('img').length>0){var title=$.trim($item.children('img:first').attr('title'));if(undefined!=title||''==title){$item.append('<div class="'+vars.prefix+'caption">'+title+'</div>');$item.children('.'+vars.prefix+'caption:empty').remove();}}}});if(settings.showCaptions==='hover'){$('.'+vars.prefix+'caption').hide();vars.container.mouseenter(function(){vars.active.find('.'+vars.prefix+'caption').stop(true,true).fadeTo(settings.captionFadeTime,settings.captionsOpacity);}).mouseleave(function(){vars.active.find('.'+vars.prefix+'caption').delay(200).fadeOut(settings.captionFadeTime);});}else if(settings.showCaptions==='always'){$('.'+vars.prefix+'caption').fadeTo(0,settings.captionsOpacity);}} 2802vars.items.each(function(){$(this).children('img').removeAttr('title');});if(settings.autoPlay){vars.intervalAutoPlay=setInterval(function(){next($slider,settings);},settings.showTime);}else{vars.intervalAutoPlay=false;}
2803if(settings.pauseOnHover){vars.container.addClass(vars.prefix+'pause-on-hover');$slider.mouseenter(function(){if(vars.isPlaying){clearInterval(vars.intervalAutoPlay);if(settings.controlsPlayPause){vars.buttons.play.text(settings.playText).removeClass(vars.prefix+'pause').addClass(vars.prefix+'play');}}}).mouseleave(function(){if(vars.isPlaying){vars.intervalAutoPlay=setInterval(function(){next($slider,settings);},settings.showTime);if(settings.controlsPlayPause){vars.buttons.play.text(settings.pauseText).removeClass(vars.prefix+'play').addClass(vars.prefix+'pause');}}});} 2804if(settings.controlsKeyboard){vars.container.addClass(vars.prefix+'controls-keyboard');$(document).keyup(function(e){switch(e.keyCode){case 37:pause();prev($slider,settings);break;case 39:pause();next($slider,settings);break;case 80:if(vars.isPlaying===false){play();}else{pause();} 2805break;}});} 2806if(settings.controlsMousewheel){vars.container.addClass(vars.prefix+'controls-mousewheel');if(!$.isFunction($.fn.mousewheel)){alert('$.fn.mousewheel is not a function. Please check that you have the mousewheel-plugin installed properly.');}else{$slider.mousewheel(function(e,delta){e.preventDefault();if(vars.container.hasClass('inProgress')){return false;} 2807var dir=delta>0?'up':'down';if(dir==='up'){pause();prev($slider,settings);}else{pause();next($slider,settings);}});}} 2808vars.active=$slider.find('.'+vars.prefix+'active');vars.active.css({zIndex:1,opacity:1});if(!settings.cycled){vars.items.each(function(){var $item=$(this);if($item.is(':first-child')){$item.addClass(vars.prefix+'firstItem');} 2809if($item.is(':last-child')){$item.addClass(vars.prefix+'lastItem');}});if(vars.active.is(':first-child')&&settings.controlsPrevNext){vars.buttons.prev.addClass('disabled');} 2810if(vars.active.is(':last-child')){if(settings.controlsPrevNext){vars.buttons.next.addClass('disabled');pause();} 2811if(settings.autoPlay){vars.buttons.play.addClass('disabled');}}} 2812if(preparations[settings.effect]==undefined){console.log('Effect for '+settings.effect+' not found.');}else{preparations[settings.effect]($slider,settings,vars);} 2813$slider.data('slider:vars',vars);settings.callBackInit();},isFirst=function($item){return $item.is(':first-child');},isLast=function($item){return $item.is(':last-child');},pause=function(){var vars=$slider.data('slider:vars');clearInterval(vars.intervalAutoPlay);vars.isPlaying=false;if(settings.controlsPlayPause){vars.buttons.play.text(settings.playText).removeClass(vars.prefix+'pause').addClass(vars.prefix+'play');} 2814settings.callBackPause();},play=function(){var vars=$slider.data('slider:vars');vars.intervalAutoPlay=setInterval(function(){next($slider,settings);},settings.showTime);vars.isPlaying=true;if(settings.controlsPlayPause){vars.buttons.play.text(settings.pauseText).removeClass(vars.prefix+'play').addClass(vars.prefix+'pause');} 2815settings.callBackPlay();},prev=function($slider,settings,$next){var vars=$slider.data('slider:vars');if(!settings.cycled&&isFirst(vars.active)){return false;} 2816settings.callBeforePrev();if(vars.container.hasClass('inProgress')){return false;} 2817vars.container.addClass('inProgress');if(!$next){if(settings.randomOrder){var nextID=getRandom(vars);vars.next=vars.container.find('#'+nextID);}else{vars.next=vars.items.first().hasClass(vars.prefix+'active')?vars.items.last():vars.active.prev();}}else{vars.next=$next;} 2818if(vars.next.hasClass(vars.prefix+'active')){return false;} 2819if(settings.showCaptions!=='never'){$('.'+vars.prefix+'caption').stop(true,true).fadeOut(settings.captionsFadeTime);} 2820if(settings.showBullets!=='never'&&settings.changeBullets=='before'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');} 2821setTimeout(function(){var params=[];params.settings=settings;params.animateActive=settings.animateActive;params.direction=settings.slidePrevDirection;if(effects[settings.effect]==undefined){console.log('Preparations for '+settings.effect+' not found.');}else{effects[settings.effect]($slider,params,resetElements);} 2822setTimeout(function(){if(settings.showBullets!=='never'&&settings.changeBullets=='after'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');} 2823settings.callBackPrev();},settings.effectTime);},settings.captionsFadeTime);if(settings.showBullets!=='never'&&settings.changeBullets=='after'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');}},next=function($slider,settings,$next){var vars=$slider.data('slider:vars');if(!settings.cycled&&isLast(vars.active)){return false;} 2824settings.callBeforeNext();if(vars.container.hasClass('inProgress')){return false;} 2825vars.container.addClass('inProgress');if(!$next){if(settings.randomOrder){var nextID=getRandom(vars);vars.next=vars.container.find('#'+nextID);}
2825else{vars.next=vars.items.last().hasClass(vars.prefix+'active')?vars.items.first():vars.active.next();}}else{vars.next=$next;} 2826if(vars.next.hasClass(vars.prefix+'active')){return false;} 2827if(settings.showCaptions!=='never'){$('.'+vars.prefix+'caption').stop(true,true).fadeOut(settings.captionsFadeTime);} 2828if(settings.showBullets!=='never'&&settings.changeBullets=='before'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');} 2829setTimeout(function(){var params=[];params.settings=settings;params.animateActive=settings.animateActive;params.direction=settings.slideNextDirection;if(effects[settings.effect]==undefined){console.log('Preparations for '+settings.effect+' not found.');}else{effects[settings.effect]($slider,params,resetElements);} 2830setTimeout(function(){if(settings.showBullets!=='never'&&settings.changeBullets=='after'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');} 2831settings.callBackNext();},settings.effectTime);},settings.captionsFadeTime);},getRandom=function(vars){var curID=vars.active.attr('id');var itemCount=vars.items.length;var nextID=vars.prefix+'item'+parseInt((Math.random()*itemCount),10);var nextKey=nextID.replace(vars.prefix+'item','');if(vars.playedCounter>=itemCount){vars.playedCounter=0;vars.playedArray=[];} 2832if(curID==nextID||vars.playedArray[nextKey]===true){return getRandom(vars);}else{vars.playedArray[nextKey]=true;vars.playedCounter++;return nextID;}},resetElements=function($slider,settings){var vars=$slider.data('slider:vars');vars.next.addClass(vars.prefix+'active').css({zIndex:1,top:0,left:0,width:'100%',height:'100%',margin:0,opacity:1});vars.active.css({zIndex:0,top:0,left:0,margin:0,opacity:0}).removeClass(vars.prefix+'active');settings.additionalResets();if(!settings.cycled){if(settings.controlsPrevNext){if(isFirst(vars.next)){vars.buttons.prev.addClass('disabled');}else{vars.buttons.prev.removeClass('disabled');} 2833if(isLast(vars.next)){vars.buttons.next.addClass('disabled');pause();}else{vars.buttons.next.removeClass('disabled');}} 2834if(settings.controlsPlayPause){if(isLast(vars.next)){vars.buttons.play.addClass('disabled');pause();}else{vars.buttons.play.removeClass('disabled');}}} 2835if(settings.showBullets!=='never'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');} 2836vars.active=vars.next;if(settings.showCaptions!=='never'){vars.active.find('.'+vars.prefix+'caption').stop(true,true).fadeTo(settings.captionsFadeTime,settings.captionsOpacity);} 2837vars.container.removeClass('inProgress');};this.pause=function(){pause();};this.play=function(){play();};this.prev=function($next){prev($slider,settings,$next);};this.next=function($next){next($slider,settings,$next);};this.uninit=function(){pause();vars.container.before($(element).data('slider:original'));$slider.data('slider:vars',null);vars.container.remove();$(element).data('rhinoslider',null);};init($slider,settings,vars);};$.fn.rhinoslider=function(opts){return this.each(function(){var element=$(this);if(element.data('rhinoslider')){return element.data('rhinoslider');} 2838element.data('slider:original',element.clone());var rhinoslider=new rhinoSlider(this,opts);element.data('rhinoslider',rhinoslider);});};$.fn.rhinoslider.defaults={effect:'slide',easing:'swing',randomOrder:false,controlsMousewheel:true,controlsKeyboard:true,controlsPrevNext:true,controlsPlayPause:true,pauseOnHover:true,animateActive:true,autoPlay:false,cycled:true,showTime:3000,effectTime:1000,controlFadeTime:650,captionsFadeTime:250,captionsOpacity:0.7,partDelay:100,shiftValue:'150',parts:'5,3',showCaptions:'never',showBullets:'hover',changeBullets:'after',showControls:'hover',slidePrevDirection:'toLeft',slideNextDirection:'toRight',prevText:'prev',nextText:'next',playText:'play',pauseText:'pause',styles:'position,top,right,bottom,left,margin-top,margin-right,margin-bottom,margin-left,width,height',callBeforeInit:function(){return false;},callBackInit:function(){return false;},callBeforeNext:function(){return false;},callBeforePrev:function(){return false;},callBackNext:function(){return false;},callBackPrev:function(){return false;},callBackPlay:function(){return false;},callBackPause:function(){return false;},additionalResets:function(){return false;}};$.fn.rhinoslider.effects={fade:function($slider,params,callback){var vars=$slider.data('slider:vars');var settings=params.settings;if(settings.animateActive){vars.active.animate({opacity:0}
vendor: 4,925 bytes, lines 2838-2989
2838,settings.effectTime);} 2839vars.next.css({zIndex:2}).animate({opacity:1},settings.effectTime,settings.easing,function(){callback($slider,settings);});}};$.fn.rhinoslider.preparations={fade:function($slider,settings,vars){}};})(jQuery,window); 2840/*! jQuery UI - v1.9.1 - 2012-10-25 2841* http://jqueryui.com 2842* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.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, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js 2843* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ 2844 2845(function( $, undefined ) { 2846 2847var uuid = 0, 2848 runiqueId = /^ui-id-\d+$/; 2849 2850// prevent duplicate loading 2851// this is only a problem because we proxy existing functions 2852// and we don't want to double proxy them 2853$.ui = $.ui || {}; 2854if ( $.ui.version ) { 2855 return; 2856} 2857 2858$.extend( $.ui, { 2859 version: "1.9.1", 2860 2861 keyCode: { 2862 BACKSPACE: 8, 2863 COMMA: 188, 2864 DELETE: 46, 2865 DOWN: 40, 2866 END: 35, 2867 ENTER: 13, 2868 ESCAPE: 27, 2869 HOME: 36, 2870 LEFT: 37, 2871 NUMPAD_ADD: 107, 2872 NUMPAD_DECIMAL: 110, 2873 NUMPAD_DIVIDE: 111, 2874 NUMPAD_ENTER: 108, 2875 NUMPAD_MULTIPLY: 106, 2876 NUMPAD_SUBTRACT: 109, 2877 PAGE_DOWN: 34, 2878 PAGE_UP: 33, 2879 PERIOD: 190, 2880 RIGHT: 39, 2881 SPACE: 32, 2882 TAB: 9, 2883 UP: 38 2884 } 2885}); 2886 2887// plugins 2888$.fn.extend({ 2889 _focus: $.fn.focus, 2890 focus: function( delay, fn ) { 2891 return typeof delay === "number" ? 2892 this.each(function() { 2893 var elem = this; 2894 setTimeout(function() { 2895 $( elem ).focus(); 2896 if ( fn ) { 2897 fn.call( elem ); 2898 } 2899 }, delay ); 2900 }) : 2901 this._focus.apply( this, arguments ); 2902 }, 2903 2904 scrollParent: function() { 2905 var scrollParent; 2906 if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { 2907 scrollParent = this.parents().filter(function() { 2908 return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); 2909 }).eq(0); 2910 } else { 2911 scrollParent = this.parents().filter(function() { 2912 return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); 2913 }).eq(0); 2914 } 2915 2916 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; 2917 }, 2918 2919 zIndex: function( zIndex ) { 2920 if ( zIndex !== undefined ) { 2921 return this.css( "zIndex", zIndex ); 2922 } 2923 2924 if ( this.length ) { 2925 var elem = $( this[ 0 ] ), position, value; 2926 while ( elem.length && elem[ 0 ] !== document ) { 2927 // Ignore z-index if position is set to a value where z-index is ignored by the browser 2928 // This makes behavior of this function consistent across browsers 2929 // WebKit always returns auto if the element is positioned 2930 position = elem.css( "position" ); 2931 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 2932 // IE returns 0 when zIndex is not specified 2933 // other browsers return a string 2934 // we ignore the case of nested elements with an explicit value of 0 2935 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 2936 value = parseInt( elem.css( "zIndex" ), 10 ); 2937 if ( !isNaN( value ) && value !== 0 ) { 2938 return value; 2939 } 2940 } 2941 elem = elem.parent(); 2942 } 2943 } 2944 2945 return 0; 2946 }, 2947 2948 uniqueId: function() { 2949 return this.each(function() { 2950 if ( !this.id ) { 2951 this.id = "ui-id-" + (++uuid); 2952 } 2953 }); 2954 }, 2955 2956 removeUniqueId: function() { 2957 return this.each(function() { 2958 if ( runiqueId.test( this.id ) ) { 2959 $( this ).removeAttr( "id" ); 2960 } 2961 }); 2962 } 2963}); 2964 2965// support: jQuery <1.8 2966if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { 2967 $.each( [ "Width", "Height" ], function( i, name ) { 2968 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], 2969 type = name.toLowerCase(), 2970 orig = { 2971 innerWidth: $.fn.innerWidth, 2972 innerHeight: $.fn.innerHeight, 2973 outerWidth: $.fn.outerWidth, 2974 outerHeight: $.fn.outerHeight 2975 }; 2976 2977 function reduce( elem, size, border, margin ) { 2978 $.each( side, function() { 2979 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; 2980 if ( border ) { 2981 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; 2982 } 2983 if ( margin ) { 2984 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; 2985 } 2986 }); 2987 return size; 2988 } 2989
2990 $.fn[ "inner" + name ] = function( size ) { 2991 if ( size === undefined ) { 2992 return orig[ "inner" + name ].call( this ); 2993 } 2994 2995 return this.each(function() { 2996 $( this ).css( type, reduce( this, size ) + "px" ); 2997 }); 2998 }; 2999 3000 $.fn[ "outer" + name] = function( size, margin ) { 3001 if ( typeof size !== "number" ) { 3002 return orig[ "outer" + name ].call( this, size ); 3003 } 3004 3005 return this.each(function() { 3006 $( this).css( type, reduce( this, size, true, margin ) + "px" ); 3007 }); 3008 }; 3009 }); 3010} 3011 3012// selectors 3013function focusable( element, isTabIndexNotNaN ) { 3014 var map, mapName, img, 3015 nodeName = element.nodeName.toLowerCase(); 3016 if ( "area" === nodeName ) { 3017 map = element.parentNode; 3018 mapName = map.name; 3019 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 3020 return false; 3021 } 3022 img = $( "img[usemap=#" + mapName + "]" )[0]; 3023 return !!img && visible( img ); 3024 } 3025 return ( /input|select|textarea|button|object/.test( nodeName ) ? 3026 !element.disabled : 3027 "a" === nodeName ? 3028 element.href || isTabIndexNotNaN : 3029 isTabIndexNotNaN) && 3030 // the element and all of its ancestors must be visible 3031 visible( element ); 3032} 3033 3034function visible( element ) { 3035 return $.expr.filters.visible( element ) && 3036 !$( element ).parents().andSelf().filter(function() { 3037 return $.css( this, "visibility" ) === "hidden"; 3038 }).length; 3039} 3040 3041$.extend( $.expr[ ":" ], { 3042 data: $.expr.createPseudo ? 3043 $.expr.createPseudo(function( dataName ) { 3044 return function( elem ) { 3045 return !!$.data( elem, dataName ); 3046 }; 3047 }) : 3048 // support: jQuery <1.8 3049 function( elem, i, match ) { 3050 return !!$.data( elem, match[ 3 ] ); 3051 }, 3052 3053 focusable: function( element ) { 3054 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); 3055 }, 3056 3057 tabbable: function( element ) { 3058 var tabIndex = $.attr( element, "tabindex" ), 3059 isTabIndexNaN = isNaN( tabIndex ); 3060 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); 3061 } 3062}); 3063 3064// support 3065$(function() { 3066 var body = document.body, 3067 div = body.appendChild( div = document.createElement( "div" ) ); 3068 3069 // access offsetHeight before setting the style to prevent a layout bug 3070 // in IE 9 which causes the element to continue to take up space even 3071 // after it is removed from the DOM (#8026) 3072 div.offsetHeight; 3073 3074 $.extend( div.style, { 3075 minHeight: "100px", 3076 height: "auto", 3077 padding: 0, 3078 borderWidth: 0 3079 }); 3080 3081 $.support.minHeight = div.offsetHeight === 100; 3082 $.support.selectstart = "onselectstart" in div; 3083 3084 // set display to none to avoid a layout bug in IE 3085 // http://dev.jquery.com/ticket/4014 3086 body.removeChild( div ).style.display = "none"; 3087}); 3088 3089 3090 3091 3092 3093// deprecated 3094 3095(function() { 3096 var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || []; 3097 $.ui.ie = uaMatch.length ? true : false; 3098 $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6; 3099})(); 3100 3101$.fn.extend({ 3102 disableSelection: function() { 3103 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + 3104 ".ui-disableSelection", function( event ) { 3105 event.preventDefault(); 3106 }); 3107 }, 3108 3109 enableSelection: function() { 3110 return this.unbind( ".ui-disableSelection" ); 3111 } 3112}); 3113 3114$.extend( $.ui, { 3115 // $.ui.plugin is deprecated. Use the proxy pattern instead. 3116 plugin: { 3117 add: function( module, option, set ) { 3118 var i, 3119 proto = $.ui[ module ].prototype; 3120 for ( i in set ) { 3121 proto.plugins[ i ] = proto.plugins[ i ] || []; 3122 proto.plugins[ i ].push( [ option, set[ i ] ] ); 3123 } 3124 }, 3125 call: function( instance, name, args ) { 3126 var i, 3127 set = instance.plugins[ name ]; 3128 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { 3129 return; 3130 } 3131 3132 for ( i = 0; i < set.length; i++ ) { 3133 if ( instance.options[ set[ i ][ 0 ] ] ) { 3134 set[ i ][ 1 ].apply( instance.element, args ); 3135 } 3136 } 3137 } 3138 }, 3139 3140 contains: $.contains, 3141 3142 // only used by resizable 3143 hasScroll: function( el, a ) { 3144 3145 //If overflow is hidden, the element might have extra content, but the user wants to hide it 3146 if ( $( el ).css( "overflow" ) === "hidden") { 3147 return false; 3148 } 3149 3150 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 3151 has = false;
3152 3153 if ( el[ scroll ] > 0 ) { 3154 return true; 3155 } 3156 3157 // TODO: determine which cases actually cause this to happen 3158 // if the element doesn't have the scroll set, see if it's possible to 3159 // set the scroll 3160 el[ scroll ] = 1; 3161 has = ( el[ scroll ] > 0 ); 3162 el[ scroll ] = 0; 3163 return has; 3164 }, 3165 3166 // these are odd functions, fix the API or move into individual plugins 3167 isOverAxis: function( x, reference, size ) { 3168 //Determines when x coordinate is over "b" element axis 3169 return ( x > reference ) && ( x < ( reference + size ) ); 3170 }, 3171 isOver: function( y, x, top, left, height, width ) { 3172 //Determines when x, y coordinates is over "b" element 3173 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); 3174 } 3175}); 3176 3177})( jQuery ); 3178 3179(function( $, undefined ) { 3180 3181var uuid = 0, 3182 slice = Array.prototype.slice, 3183 _cleanData = $.cleanData; 3184$.cleanData = function( elems ) { 3185 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 3186 try { 3187 $( elem ).triggerHandler( "remove" ); 3188 // http://bugs.jquery.com/ticket/8235 3189 } catch( e ) {} 3190 } 3191 _cleanData( elems ); 3192}; 3193 3194$.widget = function( name, base, prototype ) { 3195 var fullName, existingConstructor, constructor, basePrototype, 3196 namespace = name.split( "." )[ 0 ]; 3197 3198 name = name.split( "." )[ 1 ]; 3199 fullName = namespace + "-" + name; 3200 3201 if ( !prototype ) { 3202 prototype = base; 3203 base = $.Widget; 3204 } 3205 3206 // create selector for plugin 3207 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 3208 return !!$.data( elem, fullName ); 3209 }; 3210 3211 $[ namespace ] = $[ namespace ] || {}; 3212 existingConstructor = $[ namespace ][ name ]; 3213 constructor = $[ namespace ][ name ] = function( options, element ) { 3214 // allow instantiation without "new" keyword 3215 if ( !this._createWidget ) { 3216 return new constructor( options, element ); 3217 } 3218 3219 // allow instantiation without initializing for simple inheritance 3220 // must use "new" keyword (the code above always passes args) 3221 if ( arguments.length ) { 3222 this._createWidget( options, element ); 3223 } 3224 }; 3225 // extend with the existing constructor to carry over any static properties 3226 $.extend( constructor, existingConstructor, { 3227 version: prototype.version, 3228 // copy the object used to create the prototype in case we need to 3229 // redefine the widget later 3230 _proto: $.extend( {}, prototype ), 3231 // track widgets that inherit from this widget in case this widget is 3232 // redefined after a widget inherits from it 3233 _childConstructors: [] 3234 }); 3235 3236 basePrototype = new base(); 3237 // we need to make the options hash a property directly on the new instance 3238 // otherwise we'll modify the options hash on the prototype that we're 3239 // inheriting from 3240 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 3241 $.each( prototype, function( prop, value ) { 3242 if ( $.isFunction( value ) ) { 3243 prototype[ prop ] = (function() { 3244 var _super = function() { 3245 return base.prototype[ prop ].apply( this, arguments ); 3246 }, 3247 _superApply = function( args ) { 3248 return base.prototype[ prop ].apply( this, args ); 3249 }; 3250 return function() { 3251 var __super = this._super, 3252 __superApply = this._superApply, 3253 returnValue; 3254 3255 this._super = _super; 3256 this._superApply = _superApply; 3257 3258 returnValue = value.apply( this, arguments ); 3259 3260 this._super = __super; 3261 this._superApply = __superApply; 3262 3263 return returnValue; 3264 }; 3265 })(); 3266 } 3267 }); 3268 constructor.prototype = $.widget.extend( basePrototype, { 3269 // TODO: remove support for widgetEventPrefix 3270 // always use the name + a colon as the prefix, e.g., draggable:start 3271 // don't prefix for widgets that aren't DOM-based 3272 widgetEventPrefix: basePrototype.widgetEventPrefix || name 3273 }, prototype, { 3274 constructor: constructor, 3275 namespace: namespace, 3276 widgetName: name, 3277 // TODO remove widgetBaseClass, see #8155 3278 widgetBaseClass: fullName, 3279 widgetFullName: fullName 3280 }); 3281 3282 // If this widget is being redefined then we need to find all widgets that 3283 // are inheriting from it and redefine all of them so that they inherit from 3284 // the new version of this widget. We're essentially trying to replace one 3285 // level in the prototype chain.
vendor: 10,899 bytes, lines 3286-3666
3286 if ( existingConstructor ) { 3287 $.each( existingConstructor._childConstructors, function( i, child ) { 3288 var childPrototype = child.prototype; 3289 3290 // redefine the child widget using the same prototype that was 3291 // originally used, but inherit from the new version of the base 3292 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 3293 }); 3294 // remove the list of existing child constructors from the old constructor 3295 // so the old child constructors can be garbage collected 3296 delete existingConstructor._childConstructors; 3297 } else { 3298 base._childConstructors.push( constructor ); 3299 } 3300 3301 $.widget.bridge( name, constructor ); 3302}; 3303 3304$.widget.extend = function( target ) { 3305 var input = slice.call( arguments, 1 ), 3306 inputIndex = 0, 3307 inputLength = input.length, 3308 key, 3309 value; 3310 for ( ; inputIndex < inputLength; inputIndex++ ) { 3311 for ( key in input[ inputIndex ] ) { 3312 value = input[ inputIndex ][ key ]; 3313 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 3314 // Clone objects 3315 if ( $.isPlainObject( value ) ) { 3316 target[ key ] = $.isPlainObject( target[ key ] ) ? 3317 $.widget.extend( {}, target[ key ], value ) : 3318 // Don't extend strings, arrays, etc. with objects 3319 $.widget.extend( {}, value ); 3320 // Copy everything else by reference 3321 } else { 3322 target[ key ] = value; 3323 } 3324 } 3325 } 3326 } 3327 return target; 3328}; 3329 3330$.widget.bridge = function( name, object ) { 3331 var fullName = object.prototype.widgetFullName; 3332 $.fn[ name ] = function( options ) { 3333 var isMethodCall = typeof options === "string", 3334 args = slice.call( arguments, 1 ), 3335 returnValue = this; 3336 3337 // allow multiple hashes to be passed on init 3338 options = !isMethodCall && args.length ? 3339 $.widget.extend.apply( null, [ options ].concat(args) ) : 3340 options; 3341 3342 if ( isMethodCall ) { 3343 this.each(function() { 3344 var methodValue, 3345 instance = $.data( this, fullName ); 3346 if ( !instance ) { 3347 return $.error( "cannot call methods on " + name + " prior to initialization; " + 3348 "attempted to call method '" + options + "'" ); 3349 } 3350 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 3351 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 3352 } 3353 methodValue = instance[ options ].apply( instance, args ); 3354 if ( methodValue !== instance && methodValue !== undefined ) { 3355 returnValue = methodValue && methodValue.jquery ? 3356 returnValue.pushStack( methodValue.get() ) : 3357 methodValue; 3358 return false; 3359 } 3360 }); 3361 } else { 3362 this.each(function() { 3363 var instance = $.data( this, fullName ); 3364 if ( instance ) { 3365 instance.option( options || {} )._init(); 3366 } else { 3367 new object( options, this ); 3368 } 3369 }); 3370 } 3371 3372 return returnValue; 3373 }; 3374}; 3375 3376$.Widget = function( /* options, element */ ) {}; 3377$.Widget._childConstructors = []; 3378 3379$.Widget.prototype = { 3380 widgetName: "widget", 3381 widgetEventPrefix: "", 3382 defaultElement: "<div>", 3383 options: { 3384 disabled: false, 3385 3386 // callbacks 3387 create: null 3388 }, 3389 _createWidget: function( options, element ) { 3390 element = $( element || this.defaultElement || this )[ 0 ]; 3391 this.element = $( element ); 3392 this.uuid = uuid++; 3393 this.eventNamespace = "." + this.widgetName + this.uuid; 3394 this.options = $.widget.extend( {}, 3395 this.options, 3396 this._getCreateOptions(), 3397 options ); 3398 3399 this.bindings = $(); 3400 this.hoverable = $(); 3401 this.focusable = $(); 3402 3403 if ( element !== this ) { 3404 // 1.9 BC for #7810 3405 // TODO remove dual storage 3406 $.data( element, this.widgetName, this ); 3407 $.data( element, this.widgetFullName, this ); 3408 this._on( this.element, { 3409 remove: function( event ) { 3410 if ( event.target === element ) { 3411 this.destroy(); 3412 } 3413 } 3414 }); 3415 this.document = $( element.style ? 3416 // element within the document 3417 element.ownerDocument : 3418 // element is window or document 3419 element.document || element ); 3420 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 3421 } 3422 3423 this._create(); 3424 this._trigger( "create", null, this._getCreateEventData() ); 3425 this._init(); 3426 }, 3427 _getCreateOptions: $.noop, 3428 _getCreateEventData: $.noop, 3429 _create: $.noop, 3430 _init: $.noop, 3431 3432 destroy: function() { 3433 this._destroy(); 3434 // we can probably remove the unbind calls in 2.0 3435 // all event bindings should go through this._on() 3436 this.element 3437 .unbind( this.eventNamespace ) 3438 // 1.9 BC for #7810 3439 // TODO remove dual storage 3440 .removeData( this.widgetName ) 3441 .removeData( this.widgetFullName ) 3442 // support: jquery <1.6.3 3443 // http://bugs.jquery.com/ticket/9413 3444 .removeData( $.camelCase( this.widgetFullName ) ); 3445 this.widget() 3446 .unbind( this.eventNamespace ) 3447 .removeAttr( "aria-disabled" ) 3448 .removeClass( 3449 this.widgetFullName + "-disabled " + 3450 "ui-state-disabled" ); 3451 3452 // clean up events and states 3453 this.bindings.unbind( this.eventNamespace ); 3454 this.hoverable.removeClass( "ui-state-hover" ); 3455 this.focusable.removeClass( "ui-state-focus" ); 3456 }, 3457 _destroy: $.noop, 3458 3459 widget: function() { 3460 return this.element; 3461 }, 3462 3463 option: function( key, value ) { 3464 var options = key, 3465 parts, 3466 curOption, 3467 i; 3468 3469 if ( arguments.length === 0 ) { 3470 // don't return a reference to the internal hash 3471 return $.widget.extend( {}, this.options ); 3472 } 3473 3474 if ( typeof key === "string" ) { 3475 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 3476 options = {}; 3477 parts = key.split( "." ); 3478 key = parts.shift(); 3479 if ( parts.length ) { 3480 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 3481 for ( i = 0; i < parts.length - 1; i++ ) { 3482 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 3483 curOption = curOption[ parts[ i ] ]; 3484 } 3485 key = parts.pop(); 3486 if ( value === undefined ) { 3487 return curOption[ key ] === undefined ? null : curOption[ key ]; 3488 } 3489 curOption[ key ] = value; 3490 } else { 3491 if ( value === undefined ) { 3492 return this.options[ key ] === undefined ? null : this.options[ key ]; 3493 } 3494 options[ key ] = value; 3495 } 3496 } 3497 3498 this._setOptions( options ); 3499 3500 return this; 3501 }, 3502 _setOptions: function( options ) { 3503 var key; 3504 3505 for ( key in options ) { 3506 this._setOption( key, options[ key ] ); 3507 } 3508 3509 return this; 3510 }, 3511 _setOption: function( key, value ) { 3512 this.options[ key ] = value; 3513 3514 if ( key === "disabled" ) { 3515 this.widget() 3516 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 3517 .attr( "aria-disabled", value ); 3518 this.hoverable.removeClass( "ui-state-hover" ); 3519 this.focusable.removeClass( "ui-state-focus" ); 3520 } 3521 3522 return this; 3523 }, 3524 3525 enable: function() { 3526 return this._setOption( "disabled", false ); 3527 }, 3528 disable: function() { 3529 return this._setOption( "disabled", true ); 3530 }, 3531 3532 _on: function( element, handlers ) { 3533 var delegateElement, 3534 instance = this; 3535 // no element argument, shuffle and use this.element 3536 if ( !handlers ) { 3537 handlers = element; 3538 element = this.element; 3539 delegateElement = this.widget(); 3540 } else { 3541 // accept selectors, DOM elements 3542 element = delegateElement = $( element ); 3543 this.bindings = this.bindings.add( element ); 3544 } 3545 3546 $.each( handlers, function( event, handler ) { 3547 function handlerProxy() { 3548 // allow widgets to customize the disabled handling 3549 // - disabled as an array instead of boolean 3550 // - disabled class as method for disabling individual parts 3551 if ( instance.options.disabled === true || 3552 $( this ).hasClass( "ui-state-disabled" ) ) { 3553 return; 3554 } 3555 return ( typeof handler === "string" ? instance[ handler ] : handler ) 3556 .apply( instance, arguments ); 3557 } 3558 3559 // copy the guid so direct unbinding works 3560 if ( typeof handler !== "string" ) { 3561 handlerProxy.guid = handler.guid = 3562 handler.guid || handlerProxy.guid || $.guid++; 3563 } 3564 3565 var match = event.match( /^(\w+)\s*(.*)$/ ), 3566 eventName = match[1] + instance.eventNamespace, 3567 selector = match[2]; 3568 if ( selector ) { 3569 delegateElement.delegate( selector, eventName, handlerProxy ); 3570 } else { 3571 element.bind( eventName, handlerProxy ); 3572 } 3573 }); 3574 }, 3575 3576 _off: function( element, eventName ) { 3577 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 3578 element.unbind( eventName ).undelegate( eventName ); 3579 }, 3580 3581 _delay: function( handler, delay ) { 3582 function handlerProxy() { 3583 return ( typeof handler === "string" ? instance[ handler ] : handler ) 3584 .apply( instance, arguments ); 3585 } 3586 var instance = this; 3587 return setTimeout( handlerProxy, delay || 0 ); 3588 }, 3589 3590 _hoverable: function( element ) { 3591 this.hoverable = this.hoverable.add( element ); 3592 this._on( element, { 3593 mouseenter: function( event ) { 3594 $( event.currentTarget ).addClass( "ui-state-hover" ); 3595 }, 3596 mouseleave: function( event ) { 3597 $( event.currentTarget ).removeClass( "ui-state-hover" ); 3598 } 3599 }); 3600 }, 3601 3602 _focusable: function( element ) { 3603 this.focusable = this.focusable.add( element ); 3604 this._on( element, { 3605 focusin: function( event ) { 3606 $( event.currentTarget ).addClass( "ui-state-focus" ); 3607 }, 3608 focusout: function( event ) { 3609 $( event.currentTarget ).removeClass( "ui-state-focus" ); 3610 } 3611 }); 3612 }, 3613 3614 _trigger: function( type, event, data ) { 3615 var prop, orig, 3616 callback = this.options[ type ]; 3617 3618 data = data || {}; 3619 event = $.Event( event ); 3620 event.type = ( type === this.widgetEventPrefix ? 3621 type : 3622 this.widgetEventPrefix + type ).toLowerCase(); 3623 // the original event may come from any element 3624 // so we need to reset the target on the new event 3625 event.target = this.element[ 0 ]; 3626 3627 // copy original event properties over to the new event 3628 orig = event.originalEvent; 3629 if ( orig ) { 3630 for ( prop in orig ) { 3631 if ( !( prop in event ) ) { 3632 event[ prop ] = orig[ prop ]; 3633 } 3634 } 3635 } 3636 3637 this.element.trigger( event, data ); 3638 return !( $.isFunction( callback ) && 3639 callback.apply( this.element[0], [ event ].concat( data ) ) === false || 3640 event.isDefaultPrevented() ); 3641 } 3642}; 3643 3644$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 3645 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 3646 if ( typeof options === "string" ) { 3647 options = { effect: options }; 3648 } 3649 var hasOptions, 3650 effectName = !options ? 3651 method : 3652 options === true || typeof options === "number" ? 3653 defaultEffect : 3654 options.effect || defaultEffect; 3655 options = options || {}; 3656 if ( typeof options === "number" ) { 3657 options = { duration: options }; 3658 } 3659 hasOptions = !$.isEmptyObject( options ); 3660 options.complete = callback; 3661 if ( options.delay ) { 3662 element.delay( options.delay ); 3663 } 3664 if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { 3665 element[ method ]( options ); 3666 } else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,171 bytes, lines 3667-3822
3667 element[ effectName ]( options.duration, options.easing, callback ); 3668 } else { 3669 element.queue(function( next ) { 3670 $( this )[ method ](); 3671 if ( callback ) { 3672 callback.call( element[ 0 ] ); 3673 } 3674 next(); 3675 }); 3676 } 3677 }; 3678}); 3679 3680// DEPRECATED 3681if ( $.uiBackCompat !== false ) { 3682 $.Widget.prototype._getCreateOptions = function() { 3683 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; 3684 }; 3685} 3686 3687})( jQuery ); 3688 3689(function( $, undefined ) { 3690 3691var mouseHandled = false; 3692$( document ).mouseup( function( e ) { 3693 mouseHandled = false; 3694}); 3695 3696$.widget("ui.mouse", { 3697 version: "1.9.1", 3698 options: { 3699 cancel: 'input,textarea,button,select,option', 3700 distance: 1, 3701 delay: 0 3702 }, 3703 _mouseInit: function() { 3704 var that = this; 3705 3706 this.element 3707 .bind('mousedown.'+this.widgetName, function(event) { 3708 return that._mouseDown(event); 3709 }) 3710 .bind('click.'+this.widgetName, function(event) { 3711 if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { 3712 $.removeData(event.target, that.widgetName + '.preventClickEvent'); 3713 event.stopImmediatePropagation(); 3714 return false; 3715 } 3716 }); 3717 3718 this.started = false; 3719 }, 3720 3721 // TODO: make sure destroying one instance of mouse doesn't mess with 3722 // other instances of mouse 3723 _mouseDestroy: function() { 3724 this.element.unbind('.'+this.widgetName); 3725 if ( this._mouseMoveDelegate ) { 3726 $(document) 3727 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 3728 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 3729 } 3730 }, 3731 3732 _mouseDown: function(event) { 3733 // don't let more than one widget handle mouseStart 3734 if( mouseHandled ) { return; } 3735 3736 // we may have missed mouseup (out of window) 3737 (this._mouseStarted && this._mouseUp(event)); 3738 3739 this._mouseDownEvent = event; 3740 3741 var that = this, 3742 btnIsLeft = (event.which === 1), 3743 // event.target.nodeName works around a bug in IE 8 with 3744 // disabled inputs (#7620) 3745 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); 3746 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { 3747 return true; 3748 } 3749 3750 this.mouseDelayMet = !this.options.delay; 3751 if (!this.mouseDelayMet) { 3752 this._mouseDelayTimer = setTimeout(function() { 3753 that.mouseDelayMet = true; 3754 }, this.options.delay); 3755 } 3756 3757 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 3758 this._mouseStarted = (this._mouseStart(event) !== false); 3759 if (!this._mouseStarted) { 3760 event.preventDefault(); 3761 return true; 3762 } 3763 } 3764 3765 // Click event may never have fired (Gecko & Opera) 3766 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { 3767 $.removeData(event.target, this.widgetName + '.preventClickEvent'); 3768 } 3769 3770 // these delegates are required to keep context 3771 this._mouseMoveDelegate = function(event) { 3772 return that._mouseMove(event); 3773 }; 3774 this._mouseUpDelegate = function(event) { 3775 return that._mouseUp(event); 3776 }; 3777 $(document) 3778 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 3779 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); 3780 3781 event.preventDefault(); 3782 3783 mouseHandled = true; 3784 return true; 3785 }, 3786 3787 _mouseMove: function(event) { 3788 // IE mouseup check - mouseup happened when mouse was out of window 3789 if ($.ui.ie && !(document.documentMode >= 9) && !event.button) { 3790 return this._mouseUp(event); 3791 } 3792 3793 if (this._mouseStarted) { 3794 this._mouseDrag(event); 3795 return event.preventDefault(); 3796 } 3797 3798 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 3799 this._mouseStarted = 3800 (this._mouseStart(this._mouseDownEvent, event) !== false); 3801 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 3802 } 3803 3804 return !this._mouseStarted; 3805 }, 3806 3807 _mouseUp: function(event) { 3808 $(document) 3809 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) 3810 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); 3811 3812 if (this._mouseStarted) { 3813 this._mouseStarted = false; 3814 3815 if (event.target === this._mouseDownEvent.target) { 3816 $.data(event.target, this.widgetName + '.preventClickEvent', true); 3817 } 3818 3819 this._mouseStop(event); 3820 } 3821 3822 return false;
3823 }, 3824 3825 _mouseDistanceMet: function(event) { 3826 return (Math.max( 3827 Math.abs(this._mouseDownEvent.pageX - event.pageX), 3828 Math.abs(this._mouseDownEvent.pageY - event.pageY) 3829 ) >= this.options.distance 3830 ); 3831 }, 3832 3833 _mouseDelayMet: function(event) { 3834 return this.mouseDelayMet; 3835 }, 3836 3837 // These are placeholder methods, to be overriden by extending plugin 3838 _mouseStart: function(event) {}, 3839 _mouseDrag: function(event) {}, 3840 _mouseStop: function(event) {}, 3841 _mouseCapture: function(event) { return true; } 3842}); 3843 3844})(jQuery); 3845 3846(function( $, undefined ) { 3847 3848$.widget("ui.draggable", $.ui.mouse, { 3849 version: "1.9.1", 3850 widgetEventPrefix: "drag", 3851 options: { 3852 addClasses: true, 3853 appendTo: "parent", 3854 axis: false, 3855 connectToSortable: false, 3856 containment: false, 3857 cursor: "auto", 3858 cursorAt: false, 3859 grid: false, 3860 handle: false, 3861 helper: "original", 3862 iframeFix: false, 3863 opacity: false, 3864 refreshPositions: false, 3865 revert: false, 3866 revertDuration: 500, 3867 scope: "default", 3868 scroll: true, 3869 scrollSensitivity: 20, 3870 scrollSpeed: 20, 3871 snap: false, 3872 snapMode: "both", 3873 snapTolerance: 20, 3874 stack: false, 3875 zIndex: false 3876 }, 3877 _create: function() { 3878 3879 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) 3880 this.element[0].style.position = 'relative'; 3881 3882 (this.options.addClasses && this.element.addClass("ui-draggable")); 3883 (this.options.disabled && this.element.addClass("ui-draggable-disabled")); 3884 3885 this._mouseInit(); 3886 3887 }, 3888 3889 _destroy: function() { 3890 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); 3891 this._mouseDestroy(); 3892 }, 3893 3894 _mouseCapture: function(event) { 3895 3896 var o = this.options; 3897 3898 // among others, prevent a drag on a resizable-handle 3899 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) 3900 return false; 3901 3902 //Quit if we're not on a valid handle 3903 this.handle = this._getHandle(event); 3904 if (!this.handle) 3905 return false; 3906 3907 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { 3908 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>') 3909 .css({ 3910 width: this.offsetWidth+"px", height: this.offsetHeight+"px", 3911 position: "absolute", opacity: "0.001", zIndex: 1000 3912 }) 3913 .css($(this).offset()) 3914 .appendTo("body"); 3915 }); 3916 3917 return true; 3918 3919 }, 3920 3921 _mouseStart: function(event) { 3922 3923 var o = this.options; 3924 3925 //Create and append the visible helper 3926 this.helper = this._createHelper(event); 3927 3928 this.helper.addClass("ui-draggable-dragging"); 3929 3930 //Cache the helper size 3931 this._cacheHelperProportions(); 3932 3933 //If ddmanager is used for droppables, set the global draggable 3934 if($.ui.ddmanager) 3935 $.ui.ddmanager.current = this; 3936 3937 /* 3938 * - Position generation - 3939 * This block generates everything position related - it's the core of draggables. 3940 */ 3941 3942 //Cache the margins of the original element 3943 this._cacheMargins(); 3944 3945 //Store the helper's css position 3946 this.cssPosition = this.helper.css("position"); 3947 this.scrollParent = this.helper.scrollParent(); 3948 3949 //The element's absolute position on the page minus margins 3950 this.offset = this.positionAbs = this.element.offset(); 3951 this.offset = { 3952 top: this.offset.top - this.margins.top, 3953 left: this.offset.left - this.margins.left 3954 }; 3955 3956 $.extend(this.offset, { 3957 click: { //Where the click happened, relative to the element 3958 left: event.pageX - this.offset.left, 3959 top: event.pageY - this.offset.top 3960 }, 3961 parent: this._getParentOffset(), 3962 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 3963 }); 3964 3965 //Generate the original position 3966 this.originalPosition = this.position = this._generatePosition(event); 3967 this.originalPageX = event.pageX; 3968 this.originalPageY = event.pageY; 3969 3970 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 3971 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 3972 3973 //Set a containment if given in the options 3974 if(o.containment) 3975 this._setContainment(); 3976 3977 //Trigger event + callbacks 3978 if(this._trigger("start", event) === false) { 3979 this._clear(); 3980 return false;
3981 } 3982 3983 //Recache the helper size 3984 this._cacheHelperProportions(); 3985 3986 //Prepare the droppable offsets 3987 if ($.ui.ddmanager && !o.dropBehaviour) 3988 $.ui.ddmanager.prepareOffsets(this, event); 3989 3990 3991 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 3992 3993 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 3994 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); 3995 3996 return true; 3997 }, 3998 3999 _mouseDrag: function(event, noPropagation) { 4000 4001 //Compute the helpers position 4002 this.position = this._generatePosition(event); 4003 this.positionAbs = this._convertPositionTo("absolute"); 4004 4005 //Call plugins and callbacks and use the resulting position if something is returned 4006 if (!noPropagation) { 4007 var ui = this._uiHash(); 4008 if(this._trigger('drag', event, ui) === false) { 4009 this._mouseUp({}); 4010 return false; 4011 } 4012 this.position = ui.position; 4013 } 4014 4015 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 4016 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 4017 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 4018 4019 return false; 4020 }, 4021 4022 _mouseStop: function(event) { 4023 4024 //If we are using droppables, inform the manager about the drop 4025 var dropped = false; 4026 if ($.ui.ddmanager && !this.options.dropBehaviour) 4027 dropped = $.ui.ddmanager.drop(this, event); 4028 4029 //if a drop comes from outside (a sortable) 4030 if(this.dropped) { 4031 dropped = this.dropped; 4032 this.dropped = false; 4033 } 4034 4035 //if the original element is no longer in the DOM don't bother to continue (see #8269) 4036 var element = this.element[0], elementInDom = false;
4037 while ( element && (element = element.parentNode) ) { 4038 if (element == document ) { 4039 elementInDom = true; 4040 } 4041 } 4042 if ( !elementInDom && this.options.helper === "original" ) 4043 return false; 4044 4045 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))) { 4046 var that = this; 4047 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { 4048 if(that._trigger("stop", event) !== false) { 4049 that._clear(); 4050 } 4051 }); 4052 } else { 4053 if(this._trigger("stop", event) !== false) { 4054 this._clear(); 4055 } 4056 } 4057 4058 return false; 4059 }, 4060 4061 _mouseUp: function(event) { 4062 //Remove frame helpers 4063 $("div.ui-draggable-iframeFix").each(function() { 4064 this.parentNode.removeChild(this); 4065 }); 4066 4067 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) 4068 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); 4069 4070 return $.ui.mouse.prototype._mouseUp.call(this, event); 4071 }, 4072 4073 cancel: function() { 4074 4075 if(this.helper.is(".ui-draggable-dragging")) { 4076 this._mouseUp({}); 4077 } else { 4078 this._clear(); 4079 } 4080 4081 return this; 4082 4083 }, 4084 4085 _getHandle: function(event) { 4086 4087 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; 4088 $(this.options.handle, this.element) 4089 .find("*") 4090 .andSelf() 4091 .each(function() { 4092 if(this == event.target) handle = true; 4093 }); 4094 4095 return handle; 4096 4097 }, 4098 4099 _createHelper: function(event) { 4100 4101 var o = this.options; 4102 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); 4103 4104 if(!helper.parents('body').length) 4105 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); 4106 4107 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) 4108 helper.css("position", "absolute"); 4109 4110 return helper; 4111 4112 }, 4113 4114 _adjustOffsetFromHelper: function(obj) { 4115 if (typeof obj == 'string') { 4116 obj = obj.split(' '); 4117 } 4118 if ($.isArray(obj)) { 4119 obj = {left: +obj[0], top: +obj[1] || 0}; 4120 } 4121 if ('left' in obj) { 4122 this.offset.click.left = obj.left + this.margins.left; 4123 } 4124 if ('right' in obj) { 4125 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 4126 } 4127 if ('top' in obj) { 4128 this.offset.click.top = obj.top + this.margins.top; 4129 } 4130 if ('bottom' in obj) { 4131 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 4132 } 4133 }, 4134 4135 _getParentOffset: function() { 4136 4137 //Get the offsetParent and cache its position 4138 this.offsetParent = this.helper.offsetParent(); 4139 var po = this.offsetParent.offset(); 4140 4141 // This is a special case where we need to modify a offset calculated on start, since the following happened: 4142 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 4143 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 4144 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 4145 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 4146 po.left += this.scrollParent.scrollLeft(); 4147 po.top += this.scrollParent.scrollTop(); 4148 } 4149 4150 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 4151 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 4152 po = { top: 0, left: 0 }; 4153 4154 return { 4155 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 4156 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 4157 }; 4158 4159 }, 4160 4161 _getRelativeOffset: function() { 4162 4163 if(this.cssPosition == "relative") { 4164 var p = this.element.position(); 4165 return { 4166 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 4167 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 4168 }; 4169 } else { 4170 return { top: 0, left: 0 }; 4171 } 4172 4173 }, 4174 4175 _cacheMargins: function() { 4176 this.margins = { 4177 left: (parseInt(this.element.css("marginLeft"),10) || 0), 4178 top: (parseInt(this.element.css("marginTop"),10) || 0), 4179 right: (parseInt(this.element.css("marginRight"),10) || 0), 4180 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) 4181 }; 4182 }, 4183 4184 _cacheHelperProportions: function() { 4185 this.helperProportions = { 4186 width: this.helper.outerWidth(), 4187 height: this.helper.outerHeight() 4188 }; 4189 }, 4190 4191 _setContainment: function() { 4192 4193 var o = this.options; 4194 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 4195 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 4196 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 4197 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, 4198 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 4199 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 4200 ]; 4201 4202 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { 4203 var c = $(o.containment); 4204 var ce = c[0]; if(!ce) return; 4205 var co = c.offset(); 4206 var over = ($(ce).css("overflow") != 'hidden'); 4207 4208 this.containment = [ 4209 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
4210 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), 4211 (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 - this.margins.right, 4212 (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 - this.margins.bottom 4213 ]; 4214 this.relative_container = c; 4215 4216 } else if(o.containment.constructor == Array) { 4217 this.containment = o.containment; 4218 } 4219 4220 }, 4221 4222 _convertPositionTo: function(d, pos) { 4223 4224 if(!pos) pos = this.position; 4225 var mod = d == "absolute" ? 1 : -1; 4226 var o = this.options, 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); 4227 4228 return { 4229 top: ( 4230 pos.top // The absolute mouse position 4231 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4232 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 4233 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 4234 ), 4235 left: ( 4236 pos.left // The absolute mouse position 4237 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 4238 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 4239 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 4240 ) 4241 }; 4242 4243 }, 4244 4245 _generatePosition: function(event) { 4246 4247 var o = this.options, 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); 4248 var pageX = event.pageX; 4249 var pageY = event.pageY; 4250 4251 /* 4252 * - Position constraining - 4253 * Constrain the position to a mix of grid, containment. 4254 */ 4255 4256 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 4257 var containment; 4258 if(this.containment) { 4259 if (this.relative_container){ 4260 var co = this.relative_container.offset(); 4261 containment = [ this.containment[0] + co.left, 4262 this.containment[1] + co.top, 4263 this.containment[2] + co.left, 4264 this.containment[3] + co.top ]; 4265 } 4266 else { 4267 containment = this.containment; 4268 } 4269 4270 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; 4271 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; 4272 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; 4273 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; 4274 } 4275 4276 if(o.grid) { 4277 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) 4278 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; 4279 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; 4280 4281 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; 4282 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; 4283 } 4284 4285 } 4286 4287 return { 4288 top: ( 4289 pageY // The absolute mouse position 4290 - this.offset.click.top // Click offset (relative to the element) 4291 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 4292 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 4293 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 4294 ), 4295 left: ( 4296 pageX // The absolute mouse position 4297 - this.offset.click.left // Click offset (relative to the element) 4298 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 4299 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 4300 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 4301 ) 4302 }; 4303 4304 }, 4305 4306 _clear: function() { 4307 this.helper.removeClass("ui-draggable-dragging"); 4308 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); 4309 //if($.ui.ddmanager) $.ui.ddmanager.current = null; 4310 this.helper = null; 4311 this.cancelHelperRemoval = false;
4312 }, 4313 4314 // From now on bulk stuff - mainly helpers 4315 4316 _trigger: function(type, event, ui) { 4317 ui = ui || this._uiHash(); 4318 $.ui.plugin.call(this, type, [event, ui]); 4319 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins 4320 return $.Widget.prototype._trigger.call(this, type, event, ui); 4321 }, 4322 4323 plugins: {}, 4324 4325 _uiHash: function(event) { 4326 return { 4327 helper: this.helper, 4328 position: this.position, 4329 originalPosition: this.originalPosition, 4330 offset: this.positionAbs 4331 }; 4332 } 4333 4334}); 4335 4336$.ui.plugin.add("draggable", "connectToSortable", { 4337 start: function(event, ui) { 4338 4339 var inst = $(this).data("draggable"), o = inst.options, 4340 uiSortable = $.extend({}, ui, { item: inst.element }); 4341 inst.sortables = []; 4342 $(o.connectToSortable).each(function() { 4343 var sortable = $.data(this, 'sortable'); 4344 if (sortable && !sortable.options.disabled) { 4345 inst.sortables.push({ 4346 instance: sortable, 4347 shouldRevert: sortable.options.revert 4348 }); 4349 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). 4350 sortable._trigger("activate", event, uiSortable); 4351 } 4352 }); 4353 4354 }, 4355 stop: function(event, ui) { 4356 4357 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper 4358 var inst = $(this).data("draggable"), 4359 uiSortable = $.extend({}, ui, { item: inst.element }); 4360 4361 $.each(inst.sortables, function() { 4362 if(this.instance.isOver) { 4363 4364 this.instance.isOver = 0; 4365 4366 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance 4367 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) 4368 4369 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' 4370 if(this.shouldRevert) this.instance.options.revert = true; 4371 4372 //Trigger the stop of the sortable 4373 this.instance._mouseStop(event); 4374 4375 this.instance.options.helper = this.instance.options._helper; 4376 4377 //If the helper has been the original item, restore properties in the sortable 4378 if(inst.options.helper == 'original') 4379 this.instance.currentItem.css({ top: 'auto', left: 'auto' }); 4380 4381 } else { 4382 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance 4383 this.instance._trigger("deactivate", event, uiSortable); 4384 } 4385 4386 }); 4387 4388 }, 4389 drag: function(event, ui) { 4390 4391 var inst = $(this).data("draggable"), that = this; 4392 4393 var checkPos = function(o) { 4394 var dyClick = this.offset.click.top, dxClick = this.offset.click.left; 4395 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; 4396 var itemHeight = o.height, itemWidth = o.width; 4397 var itemTop = o.top, itemLeft = o.left; 4398 4399 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); 4400 }; 4401 4402 $.each(inst.sortables, function(i) { 4403 4404 var innermostIntersecting = false; 4405 var thisSortable = this; 4406 //Copy over some variables to allow calling the sortable's native _intersectsWith 4407 this.instance.positionAbs = inst.positionAbs; 4408 this.instance.helperProportions = inst.helperProportions; 4409 this.instance.offset.click = inst.offset.click; 4410 4411 if(this.instance._intersectsWith(this.instance.containerCache)) { 4412 innermostIntersecting = true; 4413 $.each(inst.sortables, function () { 4414 this.instance.positionAbs = inst.positionAbs; 4415 this.instance.helperProportions = inst.helperProportions; 4416 this.instance.offset.click = inst.offset.click; 4417 if (this != thisSortable 4418 && this.instance._intersectsWith(this.instance.containerCache) 4419 && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])) 4420 innermostIntersecting = false; 4421 return innermostIntersecting; 4422 }); 4423 } 4424 4425 4426 if(innermostIntersecting) { 4427 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once 4428 if(!this.instance.isOver) { 4429 4430 this.instance.isOver = 1; 4431 //Now we fake the start of dragging for the sortable instance, 4432 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem 4433 //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) 4434 this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); 4435 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it 4436 this.instance.options.helper = function() { return ui.helper[0]; }; 4437 4438 event.target = this.instance.currentItem[0]; 4439 this.instance._mouseCapture(event, true); 4440 this.instance._mouseStart(event, true, true); 4441
4442 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes 4443 this.instance.offset.click.top = inst.offset.click.top; 4444 this.instance.offset.click.left = inst.offset.click.left; 4445 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; 4446 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; 4447 4448 inst._trigger("toSortable", event); 4449 inst.dropped = this.instance.element; //draggable revert needs that 4450 //hack so receive/update callbacks work (mostly) 4451 inst.currentItem = inst.element; 4452 this.instance.fromOutside = inst; 4453 4454 } 4455 4456 //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 4457 if(this.instance.currentItem) this.instance._mouseDrag(event); 4458 4459 } else { 4460 4461 //If it doesn't intersect with the sortable, and it intersected before, 4462 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval 4463 if(this.instance.isOver) { 4464 4465 this.instance.isOver = 0; 4466 this.instance.cancelHelperRemoval = true; 4467 4468 //Prevent reverting on this forced stop 4469 this.instance.options.revert = false; 4470 4471 // The out event needs to be triggered independently 4472 this.instance._trigger('out', event, this.instance._uiHash(this.instance)); 4473 4474 this.instance._mouseStop(event, true); 4475 this.instance.options.helper = this.instance.options._helper; 4476 4477 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size 4478 this.instance.currentItem.remove(); 4479 if(this.instance.placeholder) this.instance.placeholder.remove(); 4480 4481 inst._trigger("fromSortable", event); 4482 inst.dropped = false; //draggable revert needs that 4483 } 4484 4485 }; 4486 4487 }); 4488 4489 } 4490}); 4491 4492$.ui.plugin.add("draggable", "cursor", { 4493 start: function(event, ui) { 4494 var t = $('body'), o = $(this).data('draggable').options; 4495 if (t.css("cursor")) o._cursor = t.css("cursor"); 4496 t.css("cursor", o.cursor); 4497 }, 4498 stop: function(event, ui) { 4499 var o = $(this).data('draggable').options; 4500 if (o._cursor) $('body').css("cursor", o._cursor); 4501 } 4502}); 4503 4504$.ui.plugin.add("draggable", "opacity", { 4505 start: function(event, ui) { 4506 var t = $(ui.helper), o = $(this).data('draggable').options; 4507 if(t.css("opacity")) o._opacity = t.css("opacity"); 4508 t.css('opacity', o.opacity); 4509 }, 4510 stop: function(event, ui) { 4511 var o = $(this).data('draggable').options; 4512 if(o._opacity) $(ui.helper).css('opacity', o._opacity); 4513 } 4514}); 4515 4516$.ui.plugin.add("draggable", "scroll", { 4517 start: function(event, ui) { 4518 var i = $(this).data("draggable"); 4519 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); 4520 }, 4521 drag: function(event, ui) { 4522 4523 var i = $(this).data("draggable"), o = i.options, scrolled = false; 4524 4525 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { 4526 4527 if(!o.axis || o.axis != 'x') { 4528 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 4529 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; 4530 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) 4531 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; 4532 } 4533 4534 if(!o.axis || o.axis != 'y') { 4535 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 4536 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; 4537 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) 4538 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; 4539 } 4540 4541 } else { 4542 4543 if(!o.axis || o.axis != 'x') { 4544 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 4545 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 4546 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 4547 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 4548 } 4549 4550 if(!o.axis || o.axis != 'y') { 4551 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 4552 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 4553 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 4554 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 4555 } 4556 4557 } 4558 4559 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 4560 $.ui.ddmanager.prepareOffsets(i, event); 4561 4562 } 4563}); 4564 4565$.ui.plugin.add("draggable", "snap", { 4566 start: function(event, ui) { 4567 4568 var i = $(this).data("draggable"), o = i.options; 4569 i.snapElements = []; 4570 4571 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { 4572 var $t = $(this); var $o = $t.offset(); 4573 if(this != i.element[0]) i.snapElements.push({ 4574 item: this, 4575 width: $t.outerWidth(), height: $t.outerHeight(), 4576 top: $o.top, left: $o.left 4577 }); 4578 }); 4579 4580 }, 4581 drag: function(event, ui) { 4582 4583 var inst = $(this).data("draggable"), o = inst.options; 4584 var d = o.snapTolerance; 4585 4586 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 4587 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 4588 4589 for (var i = inst.snapElements.length - 1; i >= 0; i--){ 4590 4591 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, 4592 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; 4593 4594 //Yes, I know, this is insane ;) 4595 if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { 4596 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 4597 inst.snapElements[i].snapping = false;
4598 continue; 4599 } 4600 4601 if(o.snapMode != 'inner') { 4602 var ts = Math.abs(t - y2) <= d; 4603 var bs = Math.abs(b - y1) <= d; 4604 var ls = Math.abs(l - x2) <= d; 4605 var rs = Math.abs(r - x1) <= d; 4606 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 4607 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; 4608 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; 4609 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; 4610 } 4611 4612 var first = (ts || bs || ls || rs); 4613 4614 if(o.snapMode != 'outer') { 4615 var ts = Math.abs(t - y1) <= d; 4616 var bs = Math.abs(b - y2) <= d; 4617 var ls = Math.abs(l - x1) <= d; 4618 var rs = Math.abs(r - x2) <= d; 4619 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; 4620 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; 4621 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; 4622 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; 4623 } 4624 4625 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) 4626 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); 4627 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); 4628 4629 }; 4630 4631 } 4632}); 4633 4634$.ui.plugin.add("draggable", "stack", { 4635 start: function(event, ui) { 4636 4637 var o = $(this).data("draggable").options; 4638 4639 var group = $.makeArray($(o.stack)).sort(function(a,b) { 4640 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); 4641 }); 4642 if (!group.length) { return; } 4643 4644 var min = parseInt(group[0].style.zIndex) || 0; 4645 $(group).each(function(i) { 4646 this.style.zIndex = min + i; 4647 }); 4648 4649 this[0].style.zIndex = min + group.length; 4650 4651 } 4652}); 4653 4654$.ui.plugin.add("draggable", "zIndex", { 4655 start: function(event, ui) { 4656 var t = $(ui.helper), o = $(this).data("draggable").options; 4657 if(t.css("zIndex")) o._zIndex = t.css("zIndex"); 4658 t.css('zIndex', o.zIndex); 4659 }, 4660 stop: function(event, ui) { 4661 var o = $(this).data("draggable").options; 4662 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); 4663 } 4664}); 4665 4666})(jQuery); 4667 4668(function( $, undefined ) { 4669 4670$.widget("ui.droppable", { 4671 version: "1.9.1", 4672 widgetEventPrefix: "drop", 4673 options: { 4674 accept: '*', 4675 activeClass: false, 4676 addClasses: true, 4677 greedy: false, 4678 hoverClass: false, 4679 scope: 'default', 4680 tolerance: 'intersect' 4681 }, 4682 _create: function() { 4683 4684 var o = this.options, accept = o.accept; 4685 this.isover = 0; this.isout = 1; 4686 4687 this.accept = $.isFunction(accept) ? accept : function(d) { 4688 return d.is(accept); 4689 }; 4690 4691 //Store the droppable's proportions 4692 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; 4693 4694 // Add the reference and positions to the manager 4695 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; 4696 $.ui.ddmanager.droppables[o.scope].push(this); 4697 4698 (o.addClasses && this.element.addClass("ui-droppable")); 4699 4700 }, 4701 4702 _destroy: function() { 4703 var drop = $.ui.ddmanager.droppables[this.options.scope]; 4704 for ( var i = 0; i < drop.length; i++ ) 4705 if ( drop[i] == this ) 4706 drop.splice(i, 1); 4707 4708 this.element.removeClass("ui-droppable ui-droppable-disabled"); 4709 }, 4710 4711 _setOption: function(key, value) { 4712 4713 if(key == 'accept') { 4714 this.accept = $.isFunction(value) ? value : function(d) { 4715 return d.is(value); 4716 }; 4717 } 4718 $.Widget.prototype._setOption.apply(this, arguments); 4719 }, 4720 4721 _activate: function(event) { 4722 var draggable = $.ui.ddmanager.current; 4723 if(this.options.activeClass) this.element.addClass(this.options.activeClass); 4724 (draggable && this._trigger('activate', event, this.ui(draggable))); 4725 }, 4726 4727 _deactivate: function(event) { 4728 var draggable = $.ui.ddmanager.current; 4729 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 4730 (draggable && this._trigger('deactivate', event, this.ui(draggable))); 4731 }, 4732 4733 _over: function(event) { 4734 4735 var draggable = $.ui.ddmanager.current; 4736 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 4737 4738 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 4739 if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); 4740 this._trigger('over', event, this.ui(draggable)); 4741 } 4742 4743 }, 4744 4745 _out: function(event) { 4746 4747 var draggable = $.ui.ddmanager.current; 4748 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 4749 4750 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 4751 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 4752 this._trigger('out', event, this.ui(draggable)); 4753 } 4754 4755 }, 4756 4757 _drop: function(event,custom) { 4758 4759 var draggable = custom || $.ui.ddmanager.current; 4760 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element 4761 4762 var childrenIntersection = false;
4763 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { 4764 var inst = $.data(this, 'droppable'); 4765 if( 4766 inst.options.greedy 4767 && !inst.options.disabled 4768 && inst.options.scope == draggable.options.scope 4769 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) 4770 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) 4771 ) { childrenIntersection = true; return false; } 4772 }); 4773 if(childrenIntersection) return false; 4774 4775 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 4776 if(this.options.activeClass) this.element.removeClass(this.options.activeClass); 4777 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 4778 this._trigger('drop', event, this.ui(draggable)); 4779 return this.element; 4780 } 4781 4782 return false; 4783 4784 }, 4785 4786 ui: function(c) { 4787 return { 4788 draggable: (c.currentItem || c.element), 4789 helper: c.helper, 4790 position: c.position, 4791 offset: c.positionAbs 4792 }; 4793 } 4794 4795}); 4796 4797$.ui.intersect = function(draggable, droppable, toleranceMode) { 4798 4799 if (!droppable.offset) return false; 4800 4801 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, 4802 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; 4803 var l = droppable.offset.left, r = l + droppable.proportions.width, 4804 t = droppable.offset.top, b = t + droppable.proportions.height; 4805 4806 switch (toleranceMode) { 4807 case 'fit': 4808 return (l <= x1 && x2 <= r 4809 && t <= y1 && y2 <= b); 4810 break; 4811 case 'intersect': 4812 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half 4813 && x2 - (draggable.helperProportions.width / 2) < r // Left Half 4814 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half 4815 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half 4816 break; 4817 case 'pointer': 4818 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), 4819 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), 4820 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); 4821 return isOver; 4822 break; 4823 case 'touch': 4824 return ( 4825 (y1 >= t && y1 <= b) || // Top edge touching 4826 (y2 >= t && y2 <= b) || // Bottom edge touching 4827 (y1 < t && y2 > b) // Surrounded vertically 4828 ) && ( 4829 (x1 >= l && x1 <= r) || // Left edge touching 4830 (x2 >= l && x2 <= r) || // Right edge touching 4831 (x1 < l && x2 > r) // Surrounded horizontally 4832 ); 4833 break; 4834 default: 4835 return false; 4836 break; 4837 } 4838 4839}; 4840 4841/* 4842 This manager tracks offsets of draggables and droppables 4843*/ 4844$.ui.ddmanager = { 4845 current: null, 4846 droppables: { 'default': [] }, 4847 prepareOffsets: function(t, event) { 4848 4849 var m = $.ui.ddmanager.droppables[t.options.scope] || []; 4850 var type = event ? event.type : null; // workaround for #2317 4851 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); 4852 4853 droppablesLoop: for (var i = 0; i < m.length; i++) { 4854 4855 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted 4856 for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item 4857 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue 4858 4859 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables 4860 4861 m[i].offset = m[i].element.offset(); 4862 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; 4863 4864 } 4865 4866 }, 4867 drop: function(draggable, event) { 4868 4869 var dropped = false; 4870 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 4871 4872 if(!this.options) return; 4873 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) 4874 dropped = this._drop.call(this, event) || dropped; 4875 4876 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { 4877 this.isout = 1; this.isover = 0; 4878 this._deactivate.call(this, event); 4879 } 4880 4881 }); 4882 return dropped; 4883 4884 }, 4885 dragStart: function( draggable, event ) { 4886 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) 4887 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
4888 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 4889 }); 4890 }, 4891 drag: function(draggable, event) { 4892 4893 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 4894 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 4895 4896 //Run through all droppables and check their positions based on specific tolerance options 4897 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { 4898 4899 if(this.options.disabled || this.greedyChild || !this.visible) return; 4900 var intersects = $.ui.intersect(draggable, this, this.options.tolerance); 4901 4902 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); 4903 if(!c) return; 4904 4905 var parentInstance; 4906 if (this.options.greedy) { 4907 // find droppable parents with same scope 4908 var scope = this.options.scope; 4909 var parent = this.element.parents(':data(droppable)').filter(function () { 4910 return $.data(this, 'droppable').options.scope === scope; 4911 }); 4912 4913 if (parent.length) { 4914 parentInstance = $.data(parent[0], 'droppable'); 4915 parentInstance.greedyChild = (c == 'isover' ? 1 : 0); 4916 } 4917 } 4918 4919 // we just moved into a greedy child 4920 if (parentInstance && c == 'isover') { 4921 parentInstance['isover'] = 0; 4922 parentInstance['isout'] = 1; 4923 parentInstance._out.call(parentInstance, event); 4924 } 4925 4926 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; 4927 this[c == "isover" ? "_over" : "_out"].call(this, event); 4928 4929 // we just moved out of a greedy child 4930 if (parentInstance && c == 'isout') { 4931 parentInstance['isout'] = 0; 4932 parentInstance['isover'] = 1; 4933 parentInstance._over.call(parentInstance, event); 4934 } 4935 }); 4936 4937 }, 4938 dragStop: function( draggable, event ) { 4939 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); 4940 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) 4941 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); 4942 } 4943}; 4944 4945})(jQuery); 4946 4947(function( $, undefined ) { 4948 4949$.widget("ui.resizable", $.ui.mouse, { 4950 version: "1.9.1", 4951 widgetEventPrefix: "resize", 4952 options: { 4953 alsoResize: false, 4954 animate: false, 4955 animateDuration: "slow", 4956 animateEasing: "swing", 4957 aspectRatio: false, 4958 autoHide: false, 4959 containment: false, 4960 ghost: false, 4961 grid: false, 4962 handles: "e,s,se", 4963 helper: false, 4964 maxHeight: null, 4965 maxWidth: null, 4966 minHeight: 10, 4967 minWidth: 10, 4968 zIndex: 1000 4969 }, 4970 _create: function() { 4971 4972 var that = this, o = this.options; 4973 this.element.addClass("ui-resizable"); 4974 4975 $.extend(this, { 4976 _aspectRatio: !!(o.aspectRatio), 4977 aspectRatio: o.aspectRatio, 4978 originalElement: this.element, 4979 _proportionallyResizeElements: [], 4980 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null 4981 }); 4982 4983 //Wrap the element if it cannot hold child nodes 4984 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 4985 4986 //Create a wrapper element and set the wrapper to the new current internal element 4987 this.element.wrap( 4988 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({ 4989 position: this.element.css('position'), 4990 width: this.element.outerWidth(), 4991 height: this.element.outerHeight(), 4992 top: this.element.css('top'), 4993 left: this.element.css('left') 4994 }) 4995 ); 4996 4997 //Overwrite the original this.element 4998 this.element = this.element.parent().data( 4999 "resizable", this.element.data('resizable') 5000 ); 5001 5002 this.elementIsWrapper = true; 5003 5004 //Move margins to the wrapper 5005 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); 5006 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 5007 5008 //Prevent Safari textarea resize 5009 this.originalResizeStyle = this.originalElement.css('resize'); 5010 this.originalElement.css('resize', 'none'); 5011 5012 //Push the actual element to our proportionallyResize internal array 5013 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); 5014 5015 // avoid IE jump (hard set the margin) 5016 this.originalElement.css({ margin: this.originalElement.css('margin') }); 5017 5018 // fix handlers offset 5019 this._proportionallyResize(); 5020 5021 } 5022 5023 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' }); 5024 if(this.handles.constructor == String) { 5025 5026 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; 5027 var n = this.handles.split(","); this.handles = {}; 5028 5029 for(var i = 0; i < n.length; i++) { 5030 5031 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; 5032 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); 5033 5034 // Apply zIndex to all handles - see #7960 5035 axis.css({ zIndex: o.zIndex }); 5036 5037 //TODO : What's going on here? 5038 if ('se' == handle) { 5039 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); 5040 }; 5041 5042 //Insert into internal handles object and append to element 5043 this.handles[handle] = '.ui-resizable-'+handle; 5044 this.element.append(axis); 5045 } 5046 5047 } 5048 5049 this._renderAxis = function(target) { 5050 5051 target = target || this.element; 5052 5053 for(var i in this.handles) { 5054 5055 if(this.handles[i].constructor == String) 5056 this.handles[i] = $(this.handles[i], this.element).show(); 5057 5058 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) 5059 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 5060 5061 var axis = $(this.handles[i], this.element), padWrapper = 0; 5062 5063 //Checking the correct pad and border 5064 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 5065 5066 //The padding type i have to apply... 5067 var padPos = [ 'padding',
5068 /ne|nw|n/.test(i) ? 'Top' : 5069 /se|sw|s/.test(i) ? 'Bottom' : 5070 /^e$/.test(i) ? 'Right' : 'Left' ].join(""); 5071 5072 target.css(padPos, padWrapper); 5073 5074 this._proportionallyResize(); 5075 5076 } 5077 5078 //TODO: What's that good for? There's not anything to be executed left 5079 if(!$(this.handles[i]).length) 5080 continue; 5081 5082 } 5083 }; 5084 5085 //TODO: make renderAxis a prototype function 5086 this._renderAxis(this.element); 5087 5088 this._handles = $('.ui-resizable-handle', this.element) 5089 .disableSelection(); 5090 5091 //Matching axis name 5092 this._handles.mouseover(function() { 5093 if (!that.resizing) { 5094 if (this.className) 5095 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); 5096 //Axis, default = se 5097 that.axis = axis && axis[1] ? axis[1] : 'se'; 5098 } 5099 }); 5100 5101 //If we want to auto hide the elements 5102 if (o.autoHide) { 5103 this._handles.hide(); 5104 $(this.element) 5105 .addClass("ui-resizable-autohide") 5106 .mouseenter(function() { 5107 if (o.disabled) return; 5108 $(this).removeClass("ui-resizable-autohide"); 5109 that._handles.show(); 5110 }) 5111 .mouseleave(function(){ 5112 if (o.disabled) return; 5113 if (!that.resizing) { 5114 $(this).addClass("ui-resizable-autohide"); 5115 that._handles.hide(); 5116 } 5117 }); 5118 } 5119 5120 //Initialize the mouse interaction 5121 this._mouseInit(); 5122 5123 }, 5124 5125 _destroy: function() { 5126 5127 this._mouseDestroy(); 5128 5129 var _destroy = function(exp) { 5130 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") 5131 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); 5132 }; 5133 5134 //TODO: Unwrap at same DOM position 5135 if (this.elementIsWrapper) { 5136 _destroy(this.element); 5137 var wrapper = this.element; 5138 this.originalElement.css({ 5139 position: wrapper.css('position'), 5140 width: wrapper.outerWidth(), 5141 height: wrapper.outerHeight(), 5142 top: wrapper.css('top'), 5143 left: wrapper.css('left') 5144 }).insertAfter( wrapper ); 5145 wrapper.remove(); 5146 } 5147 5148 this.originalElement.css('resize', this.originalResizeStyle); 5149 _destroy(this.originalElement); 5150 5151 return this; 5152 }, 5153 5154 _mouseCapture: function(event) { 5155 var handle = false; 5156 for (var i in this.handles) { 5157 if ($(this.handles[i])[0] == event.target) { 5158 handle = true; 5159 } 5160 } 5161 5162 return !this.options.disabled && handle; 5163 }, 5164 5165 _mouseStart: function(event) { 5166 5167 var o = this.options, iniPos = this.element.position(), el = this.element; 5168 5169 this.resizing = true; 5170 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; 5171 5172 // bugfix for http://dev.jquery.com/ticket/1749 5173 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { 5174 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); 5175 } 5176 5177 this._renderProxy(); 5178 5179 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); 5180 5181 if (o.containment) { 5182 curleft += $(o.containment).scrollLeft() || 0; 5183 curtop += $(o.containment).scrollTop() || 0; 5184 } 5185 5186 //Store needed variables 5187 this.offset = this.helper.offset(); 5188 this.position = { left: curleft, top: curtop }; 5189 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 5190 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; 5191 this.originalPosition = { left: curleft, top: curtop }; 5192 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; 5193 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 5194 5195 //Aspect Ratio 5196 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 5197 5198 var cursor = $('.ui-resizable-' + this.axis).css('cursor'); 5199 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); 5200 5201 el.addClass("ui-resizable-resizing"); 5202 this._propagate("start", event); 5203 return true; 5204 }, 5205 5206 _mouseDrag: function(event) { 5207 5208 //Increase performance, avoid regex 5209 var el = this.helper, o = this.options, props = {}, 5210 that = this, smp = this.originalMousePosition, a = this.axis; 5211 5212 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; 5213 var trigger = this._change[a]; 5214 if (!trigger) return false;
5215 5216 // Calculate the attrs that will be change 5217 var data = trigger.apply(this, [event, dx, dy]); 5218 5219 // Put this in the mouseDrag handler since the user can start pressing shift while resizing 5220 this._updateVirtualBoundaries(event.shiftKey); 5221 if (this._aspectRatio || event.shiftKey) 5222 data = this._updateRatio(data, event); 5223 5224 data = this._respectSize(data, event); 5225 5226 // plugins callbacks need to be called first 5227 this._propagate("resize", event); 5228 5229 el.css({ 5230 top: this.position.top + "px", left: this.position.left + "px", 5231 width: this.size.width + "px", height: this.size.height + "px" 5232 }); 5233 5234 if (!this._helper && this._proportionallyResizeElements.length) 5235 this._proportionallyResize(); 5236 5237 this._updateCache(data); 5238 5239 // calling the user callback at the end 5240 this._trigger('resize', event, this.ui()); 5241 5242 return false; 5243 }, 5244 5245 _mouseStop: function(event) { 5246 5247 this.resizing = false; 5248 var o = this.options, that = this; 5249 5250 if(this._helper) { 5251 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 5252 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 5253 soffsetw = ista ? 0 : that.sizeDiff.width; 5254 5255 var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, 5256 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 5257 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 5258 5259 if (!o.animate) 5260 this.element.css($.extend(s, { top: top, left: left })); 5261 5262 that.helper.height(that.size.height); 5263 that.helper.width(that.size.width); 5264 5265 if (this._helper && !o.animate) this._proportionallyResize(); 5266 } 5267 5268 $('body').css('cursor', 'auto'); 5269 5270 this.element.removeClass("ui-resizable-resizing"); 5271 5272 this._propagate("stop", event); 5273 5274 if (this._helper) this.helper.remove(); 5275 return false; 5276 5277 }, 5278 5279 _updateVirtualBoundaries: function(forceAspectRatio) { 5280 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; 5281 5282 b = { 5283 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, 5284 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, 5285 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, 5286 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity 5287 }; 5288 5289 if(this._aspectRatio || forceAspectRatio) { 5290 // We want to create an enclosing box whose aspect ration is the requested one 5291 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension 5292 pMinWidth = b.minHeight * this.aspectRatio; 5293 pMinHeight = b.minWidth / this.aspectRatio; 5294 pMaxWidth = b.maxHeight * this.aspectRatio; 5295 pMaxHeight = b.maxWidth / this.aspectRatio; 5296 5297 if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; 5298 if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; 5299 if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; 5300 if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; 5301 } 5302 this._vBoundaries = b; 5303 }, 5304 5305 _updateCache: function(data) { 5306 var o = this.options; 5307 this.offset = this.helper.offset(); 5308 if (isNumber(data.left)) this.position.left = data.left; 5309 if (isNumber(data.top)) this.position.top = data.top; 5310 if (isNumber(data.height)) this.size.height = data.height; 5311 if (isNumber(data.width)) this.size.width = data.width; 5312 }, 5313 5314 _updateRatio: function(data, event) { 5315 5316 var o = this.options, cpos = this.position, csize = this.size, a = this.axis; 5317 5318 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); 5319 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); 5320 5321 if (a == 'sw') { 5322 data.left = cpos.left + (csize.width - data.width); 5323 data.top = null; 5324 } 5325 if (a == 'nw') { 5326 data.top = cpos.top + (csize.height - data.height); 5327 data.left = cpos.left + (csize.width - data.width); 5328 } 5329 5330 return data; 5331 }, 5332 5333 _respectSize: function(data, event) { 5334 5335 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, 5336 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), 5337 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); 5338 5339 if (isminw) data.width = o.minWidth; 5340 if (isminh) data.height = o.minHeight; 5341 if (ismaxw) data.width = o.maxWidth; 5342 if (ismaxh) data.height = o.maxHeight; 5343 5344 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; 5345 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 5346 5347 if (isminw && cw) data.left = dw - o.minWidth; 5348 if (ismaxw && cw) data.left = dw - o.maxWidth; 5349 if (isminh && ch) data.top = dh - o.minHeight; 5350 if (ismaxh && ch) data.top = dh - o.maxHeight; 5351 5352 // fixing jump error on top/left - bug #2330 5353 var isNotwh = !data.width && !data.height; 5354 if (isNotwh && !data.left && data.top) data.top = null; 5355 else if (isNotwh && !data.top && data.left) data.left = null; 5356 5357 return data; 5358 }, 5359 5360 _proportionallyResize: function() { 5361 5362 var o = this.options; 5363 if (!this._proportionallyResizeElements.length) return; 5364 var element = this.helper || this.element; 5365 5366 for (var i=0; i < this._proportionallyResizeElements.length; i++) { 5367 5368 var prel = this._proportionallyResizeElements[i]; 5369 5370 if (!this.borderDif) { 5371 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], 5372 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; 5373 5374 this.borderDif = $.map(b, function(v, i) { 5375 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; 5376 return border + padding; 5377 }); 5378 } 5379 5380 prel.css({ 5381 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, 5382 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 5383 }); 5384 5385 }; 5386 5387 }, 5388 5389 _renderProxy: function() { 5390 5391 var el = this.element, o = this.options; 5392 this.elementOffset = el.offset(); 5393 5394 if(this._helper) { 5395 5396 this.helper = this.helper || $('<div style="overflow:hidden;"></div>'); 5397 5398 // fix ie6 offset TODO: This seems broken 5399 var ie6offset = ($.ui.ie6 ? 1 : 0), 5400 pxyoffset = ( $.ui.ie6 ? 2 : -1 ); 5401 5402 this.helper.addClass(this._helper).css({ 5403 width: this.element.outerWidth() + pxyoffset, 5404 height: this.element.outerHeight() + pxyoffset, 5405 position: 'absolute', 5406 left: this.elementOffset.left - ie6offset +'px', 5407 top: this.elementOffset.top - ie6offset +'px', 5408 zIndex: ++o.zIndex //TODO: Don't modify option 5409 }); 5410 5411 this.helper 5412 .appendTo("body") 5413 .disableSelection(); 5414 5415 } else { 5416 this.helper = this.element; 5417 } 5418 5419 }, 5420 5421 _change: { 5422 e: function(event, dx, dy) { 5423 return { width: this.originalSize.width + dx }; 5424 }, 5425 w: function(event, dx, dy) { 5426 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 5427 return { left: sp.left + dx, width: cs.width - dx }; 5428 }, 5429 n: function(event, dx, dy) { 5430 var o = this.options, cs = this.originalSize, sp = this.originalPosition; 5431 return { top: sp.top + dy, height: cs.height - dy }; 5432 }, 5433 s: function(event, dx, dy) { 5434 return { height: this.originalSize.height + dy }; 5435 }, 5436 se: function(event, dx, dy) { 5437 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 5438 }, 5439 sw: function(event, dx, dy) { 5440 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 5441 }, 5442 ne: function(event, dx, dy) { 5443 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); 5444 }, 5445 nw: function(event, dx, dy) { 5446 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); 5447 } 5448 }, 5449 5450 _propagate: function(n, event) { 5451 $.ui.plugin.call(this, n, [event, this.ui()]); 5452 (n != "resize" && this._trigger(n, event, this.ui())); 5453 }, 5454 5455 plugins: {}, 5456 5457 ui: function() { 5458 return { 5459 originalElement: this.originalElement, 5460 element: this.element, 5461 helper: this.helper, 5462 position: this.position, 5463 size: this.size, 5464 originalSize: this.originalSize, 5465 originalPosition: this.originalPosition 5466 }; 5467 } 5468 5469}); 5470 5471/* 5472 * Resizable Extensions 5473 */ 5474 5475$.ui.plugin.add("resizable", "alsoResize", { 5476 5477 start: function (event, ui) { 5478 var that = $(this).data("resizable"), o = that.options; 5479 5480 var _store = function (exp) { 5481 $(exp).each(function() { 5482 var el = $(this); 5483 el.data("resizable-alsoresize", { 5484 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), 5485 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) 5486 }); 5487 }); 5488 }; 5489 5490 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { 5491 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } 5492 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } 5493 }else{ 5494 _store(o.alsoResize); 5495 } 5496 }, 5497 5498 resize: function (event, ui) { 5499 var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; 5500 5501 var delta = { 5502 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, 5503 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 5504 }, 5505 5506 _alsoResize = function (exp, c) { 5507 $(exp).each(function() { 5508 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 5509 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; 5510
5511 $.each(css, function (i, prop) { 5512 var sum = (start[prop]||0) + (delta[prop]||0); 5513 if (sum && sum >= 0) 5514 style[prop] = sum || null; 5515 }); 5516 5517 el.css(style); 5518 }); 5519 }; 5520 5521 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { 5522 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); 5523 }else{ 5524 _alsoResize(o.alsoResize); 5525 } 5526 }, 5527 5528 stop: function (event, ui) { 5529 $(this).removeData("resizable-alsoresize"); 5530 } 5531}); 5532 5533$.ui.plugin.add("resizable", "animate", { 5534 5535 stop: function(event, ui) { 5536 var that = $(this).data("resizable"), o = that.options; 5537 5538 var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), 5539 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, 5540 soffsetw = ista ? 0 : that.sizeDiff.width; 5541 5542 var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, 5543 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, 5544 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; 5545 5546 that.element.animate( 5547 $.extend(style, top && left ? { top: top, left: left } : {}), { 5548 duration: o.animateDuration, 5549 easing: o.animateEasing, 5550 step: function() { 5551 5552 var data = { 5553 width: parseInt(that.element.css('width'), 10), 5554 height: parseInt(that.element.css('height'), 10), 5555 top: parseInt(that.element.css('top'), 10), 5556 left: parseInt(that.element.css('left'), 10) 5557 }; 5558 5559 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); 5560 5561 // propagating resize, and updating values for each animation step 5562 that._updateCache(data); 5563 that._propagate("resize", event); 5564 5565 } 5566 } 5567 ); 5568 } 5569 5570}); 5571 5572$.ui.plugin.add("resizable", "containment", { 5573 5574 start: function(event, ui) { 5575 var that = $(this).data("resizable"), o = that.options, el = that.element; 5576 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; 5577 if (!ce) return; 5578 5579 that.containerElement = $(ce); 5580 5581 if (/document/.test(oc) || oc == document) { 5582 that.containerOffset = { left: 0, top: 0 }; 5583 that.containerPosition = { left: 0, top: 0 }; 5584 5585 that.parentData = { 5586 element: $(document), left: 0, top: 0, 5587 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight 5588 }; 5589 } 5590 5591 // i'm a node, so compute top, left, right, bottom 5592 else { 5593 var element = $(ce), p = []; 5594 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); 5595 5596 that.containerOffset = element.offset(); 5597 that.containerPosition = element.position(); 5598 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; 5599 5600 var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, 5601 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); 5602 5603 that.parentData = { 5604 element: ce, left: co.left, top: co.top, width: width, height: height 5605 }; 5606 } 5607 }, 5608 5609 resize: function(event, ui) { 5610 var that = $(this).data("resizable"), o = that.options, 5611 ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, 5612 pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement; 5613 5614 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; 5615 5616 if (cp.left < (that._helper ? co.left : 0)) { 5617 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); 5618 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 5619 that.position.left = o.helper ? co.left : 0; 5620 } 5621 5622 if (cp.top < (that._helper ? co.top : 0)) { 5623 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); 5624 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 5625 that.position.top = that._helper ? co.top : 0; 5626 } 5627 5628 that.offset.left = that.parentData.left+that.position.left; 5629 that.offset.top = that.parentData.top+that.position.top; 5630 5631 var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ), 5632 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); 5633 5634 var isParent = that.containerElement.get(0) == that.element.parent().get(0), 5635 isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); 5636 5637 if(isParent && isOffsetRelative) woset -= that.parentData.left; 5638 5639 if (woset + that.size.width >= that.parentData.width) { 5640 that.size.width = that.parentData.width - woset; 5641 if (pRatio) that.size.height = that.size.width / that.aspectRatio; 5642 } 5643 5644 if (hoset + that.size.height >= that.parentData.height) { 5645 that.size.height = that.parentData.height - hoset; 5646 if (pRatio) that.size.width = that.size.height * that.aspectRatio; 5647 } 5648 }, 5649 5650 stop: function(event, ui){ 5651 var that = $(this).data("resizable"), o = that.options, cp = that.position, 5652 co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; 5653 5654 var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; 5655
5656 if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) 5657 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 5658 5659 if (that._helper && !o.animate && (/static/).test(ce.css('position'))) 5660 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 5661 5662 } 5663}); 5664 5665$.ui.plugin.add("resizable", "ghost", { 5666 5667 start: function(event, ui) { 5668 5669 var that = $(this).data("resizable"), o = that.options, cs = that.size; 5670 5671 that.ghost = that.originalElement.clone(); 5672 that.ghost 5673 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) 5674 .addClass('ui-resizable-ghost') 5675 .addClass(typeof o.ghost == 'string' ? o.ghost : ''); 5676 5677 that.ghost.appendTo(that.helper); 5678 5679 }, 5680 5681 resize: function(event, ui){ 5682 var that = $(this).data("resizable"), o = that.options; 5683 if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width }); 5684 }, 5685 5686 stop: function(event, ui){ 5687 var that = $(this).data("resizable"), o = that.options; 5688 if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); 5689 } 5690 5691}); 5692 5693$.ui.plugin.add("resizable", "grid", { 5694 5695 resize: function(event, ui) { 5696 var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey; 5697 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; 5698 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); 5699 5700 if (/^(se|s|e)$/.test(a)) { 5701 that.size.width = os.width + ox; 5702 that.size.height = os.height + oy; 5703 } 5704 else if (/^(ne)$/.test(a)) { 5705 that.size.width = os.width + ox; 5706 that.size.height = os.height + oy; 5707 that.position.top = op.top - oy; 5708 } 5709 else if (/^(sw)$/.test(a)) { 5710 that.size.width = os.width + ox; 5711 that.size.height = os.height + oy; 5712 that.position.left = op.left - ox; 5713 } 5714 else { 5715 that.size.width = os.width + ox; 5716 that.size.height = os.height + oy; 5717 that.position.top = op.top - oy; 5718 that.position.left = op.left - ox; 5719 } 5720 } 5721 5722}); 5723 5724var num = function(v) { 5725 return parseInt(v, 10) || 0; 5726}; 5727 5728var isNumber = function(value) { 5729 return !isNaN(parseInt(value, 10)); 5730}; 5731 5732})(jQuery); 5733 5734(function( $, undefined ) { 5735 5736$.widget("ui.selectable", $.ui.mouse, { 5737 version: "1.9.1", 5738 options: { 5739 appendTo: 'body', 5740 autoRefresh: true, 5741 distance: 0, 5742 filter: '*', 5743 tolerance: 'touch' 5744 }, 5745 _create: function() { 5746 var that = this; 5747 5748 this.element.addClass("ui-selectable"); 5749 5750 this.dragged = false; 5751 5752 // cache selectee children based on filter 5753 var selectees; 5754 this.refresh = function() { 5755 selectees = $(that.options.filter, that.element[0]); 5756 selectees.addClass("ui-selectee"); 5757 selectees.each(function() { 5758 var $this = $(this); 5759 var pos = $this.offset(); 5760 $.data(this, "selectable-item", { 5761 element: this, 5762 $element: $this, 5763 left: pos.left, 5764 top: pos.top, 5765 right: pos.left + $this.outerWidth(), 5766 bottom: pos.top + $this.outerHeight(), 5767 startselected: false, 5768 selected: $this.hasClass('ui-selected'), 5769 selecting: $this.hasClass('ui-selecting'), 5770 unselecting: $this.hasClass('ui-unselecting') 5771 }); 5772 }); 5773 }; 5774 this.refresh(); 5775 5776 this.selectees = selectees.addClass("ui-selectee"); 5777 5778 this._mouseInit(); 5779 5780 this.helper = $("<div class='ui-selectable-helper'></div>"); 5781 }, 5782 5783 _destroy: function() { 5784 this.selectees 5785 .removeClass("ui-selectee") 5786 .removeData("selectable-item"); 5787 this.element 5788 .removeClass("ui-selectable ui-selectable-disabled"); 5789 this._mouseDestroy(); 5790 }, 5791 5792 _mouseStart: function(event) { 5793 var that = this; 5794 5795 this.opos = [event.pageX, event.pageY]; 5796 5797 if (this.options.disabled) 5798 return; 5799 5800 var options = this.options; 5801 5802 this.selectees = $(options.filter, this.element[0]); 5803 5804 this._trigger("start", event); 5805 5806 $(options.appendTo).append(this.helper); 5807 // position helper (lasso) 5808 this.helper.css({ 5809 "left": event.clientX, 5810 "top": event.clientY, 5811 "width": 0, 5812 "height": 0 5813 }); 5814 5815 if (options.autoRefresh) { 5816 this.refresh(); 5817 } 5818 5819 this.selectees.filter('.ui-selected').each(function() { 5820 var selectee = $.data(this, "selectable-item"); 5821 selectee.startselected = true; 5822 if (!event.metaKey && !event.ctrlKey) { 5823 selectee.$element.removeClass('ui-selected'); 5824 selectee.selected = false;
5825 selectee.$element.addClass('ui-unselecting'); 5826 selectee.unselecting = true; 5827 // selectable UNSELECTING callback 5828 that._trigger("unselecting", event, { 5829 unselecting: selectee.element 5830 }); 5831 } 5832 }); 5833 5834 $(event.target).parents().andSelf().each(function() { 5835 var selectee = $.data(this, "selectable-item"); 5836 if (selectee) { 5837 var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected'); 5838 selectee.$element 5839 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") 5840 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); 5841 selectee.unselecting = !doSelect; 5842 selectee.selecting = doSelect; 5843 selectee.selected = doSelect; 5844 // selectable (UN)SELECTING callback 5845 if (doSelect) { 5846 that._trigger("selecting", event, { 5847 selecting: selectee.element 5848 }); 5849 } else { 5850 that._trigger("unselecting", event, { 5851 unselecting: selectee.element 5852 }); 5853 } 5854 return false; 5855 } 5856 }); 5857 5858 }, 5859 5860 _mouseDrag: function(event) { 5861 var that = this; 5862 this.dragged = true; 5863 5864 if (this.options.disabled) 5865 return; 5866 5867 var options = this.options; 5868 5869 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; 5870 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } 5871 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } 5872 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); 5873 5874 this.selectees.each(function() { 5875 var selectee = $.data(this, "selectable-item"); 5876 //prevent helper from being selected if appendTo: selectable 5877 if (!selectee || selectee.element == that.element[0]) 5878 return; 5879 var hit = false; 5880 if (options.tolerance == 'touch') { 5881 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); 5882 } else if (options.tolerance == 'fit') { 5883 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); 5884 } 5885 5886 if (hit) { 5887 // SELECT 5888 if (selectee.selected) { 5889 selectee.$element.removeClass('ui-selected'); 5890 selectee.selected = false; 5891 } 5892 if (selectee.unselecting) { 5893 selectee.$element.removeClass('ui-unselecting'); 5894 selectee.unselecting = false; 5895 } 5896 if (!selectee.selecting) { 5897 selectee.$element.addClass('ui-selecting'); 5898 selectee.selecting = true; 5899 // selectable SELECTING callback 5900 that._trigger("selecting", event, { 5901 selecting: selectee.element 5902 }); 5903 } 5904 } else { 5905 // UNSELECT 5906 if (selectee.selecting) { 5907 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { 5908 selectee.$element.removeClass('ui-selecting'); 5909 selectee.selecting = false; 5910 selectee.$element.addClass('ui-selected'); 5911 selectee.selected = true; 5912 } else { 5913 selectee.$element.removeClass('ui-selecting'); 5914 selectee.selecting = false; 5915 if (selectee.startselected) { 5916 selectee.$element.addClass('ui-unselecting'); 5917 selectee.unselecting = true; 5918 } 5919 // selectable UNSELECTING callback 5920 that._trigger("unselecting", event, { 5921 unselecting: selectee.element 5922 }); 5923 } 5924 } 5925 if (selectee.selected) { 5926 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { 5927 selectee.$element.removeClass('ui-selected'); 5928 selectee.selected = false; 5929 5930 selectee.$element.addClass('ui-unselecting'); 5931 selectee.unselecting = true; 5932 // selectable UNSELECTING callback 5933 that._trigger("unselecting", event, { 5934 unselecting: selectee.element 5935 }); 5936 } 5937 } 5938 } 5939 }); 5940 5941 return false; 5942 }, 5943 5944 _mouseStop: function(event) { 5945 var that = this; 5946 5947 this.dragged = false; 5948 5949 var options = this.options; 5950 5951 $('.ui-unselecting', this.element[0]).each(function() { 5952 var selectee = $.data(this, "selectable-item"); 5953 selectee.$element.removeClass('ui-unselecting'); 5954 selectee.unselecting = false; 5955 selectee.startselected = false; 5956 that._trigger("unselected", event, { 5957 unselected: selectee.element 5958 }); 5959 }); 5960 $('.ui-selecting', this.element[0]).each(function() { 5961 var selectee = $.data(this, "selectable-item"); 5962 selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); 5963 selectee.selecting = false;
5964 selectee.selected = true; 5965 selectee.startselected = true; 5966 that._trigger("selected", event, { 5967 selected: selectee.element 5968 }); 5969 }); 5970 this._trigger("stop", event); 5971 5972 this.helper.remove(); 5973 5974 return false; 5975 } 5976 5977}); 5978 5979})(jQuery); 5980 5981(function( $, undefined ) { 5982 5983$.widget("ui.sortable", $.ui.mouse, { 5984 version: "1.9.1", 5985 widgetEventPrefix: "sort", 5986 ready: false, 5987 options: { 5988 appendTo: "parent", 5989 axis: false, 5990 connectWith: false, 5991 containment: false, 5992 cursor: 'auto', 5993 cursorAt: false, 5994 dropOnEmpty: true, 5995 forcePlaceholderSize: false, 5996 forceHelperSize: false, 5997 grid: false, 5998 handle: false, 5999 helper: "original", 6000 items: '> *', 6001 opacity: false, 6002 placeholder: false, 6003 revert: false, 6004 scroll: true, 6005 scrollSensitivity: 20, 6006 scrollSpeed: 20, 6007 scope: "default", 6008 tolerance: "intersect", 6009 zIndex: 1000 6010 }, 6011 _create: function() { 6012 6013 var o = this.options; 6014 this.containerCache = {}; 6015 this.element.addClass("ui-sortable"); 6016 6017 //Get the items 6018 this.refresh(); 6019 6020 //Let's determine if the items are being displayed horizontally 6021 this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; 6022 6023 //Let's determine the parent's offset 6024 this.offset = this.element.offset(); 6025 6026 //Initialize mouse events for interaction 6027 this._mouseInit(); 6028 6029 //We're ready to go 6030 this.ready = true 6031 6032 }, 6033 6034 _destroy: function() { 6035 this.element 6036 .removeClass("ui-sortable ui-sortable-disabled"); 6037 this._mouseDestroy(); 6038 6039 for ( var i = this.items.length - 1; i >= 0; i-- ) 6040 this.items[i].item.removeData(this.widgetName + "-item"); 6041 6042 return this; 6043 }, 6044 6045 _setOption: function(key, value){ 6046 if ( key === "disabled" ) { 6047 this.options[ key ] = value; 6048 6049 this.widget().toggleClass( "ui-sortable-disabled", !!value ); 6050 } else { 6051 // Don't call widget base _setOption for disable as it adds ui-state-disabled class 6052 $.Widget.prototype._setOption.apply(this, arguments); 6053 } 6054 }, 6055 6056 _mouseCapture: function(event, overrideHandle) { 6057 var that = this; 6058 6059 if (this.reverting) { 6060 return false; 6061 } 6062 6063 if(this.options.disabled || this.options.type == 'static') return false; 6064 6065 //We have to refresh the items data once first 6066 this._refreshItems(event); 6067 6068 //Find out if the clicked node (or one of its parents) is a actual item in this.items 6069 var currentItem = null, nodes = $(event.target).parents().each(function() { 6070 if($.data(this, that.widgetName + '-item') == that) { 6071 currentItem = $(this); 6072 return false; 6073 } 6074 }); 6075 if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target); 6076 6077 if(!currentItem) return false; 6078 if(this.options.handle && !overrideHandle) { 6079 var validHandle = false; 6080 6081 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); 6082 if(!validHandle) return false; 6083 } 6084 6085 this.currentItem = currentItem; 6086 this._removeCurrentsFromItems(); 6087 return true; 6088 6089 }, 6090 6091 _mouseStart: function(event, overrideHandle, noActivation) { 6092 6093 var o = this.options; 6094 this.currentContainer = this; 6095 6096 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture 6097 this.refreshPositions(); 6098 6099 //Create and append the visible helper 6100 this.helper = this._createHelper(event); 6101 6102 //Cache the helper size 6103 this._cacheHelperProportions(); 6104 6105 /* 6106 * - Position generation - 6107 * This block generates everything position related - it's the core of draggables. 6108 */ 6109 6110 //Cache the margins of the original element 6111 this._cacheMargins(); 6112 6113 //Get the next scrolling parent 6114 this.scrollParent = this.helper.scrollParent(); 6115 6116 //The element's absolute position on the page minus margins 6117 this.offset = this.currentItem.offset(); 6118 this.offset = { 6119 top: this.offset.top - this.margins.top, 6120 left: this.offset.left - this.margins.left 6121 }; 6122 6123 $.extend(this.offset, { 6124 click: { //Where the click happened, relative to the element 6125 left: event.pageX - this.offset.left, 6126 top: event.pageY - this.offset.top 6127 }, 6128 parent: this._getParentOffset(), 6129 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 6130 }); 6131 6132 // Only after we got the offset, we can change the helper's position to absolute 6133 // TODO: Still need to figure out a way to make relative sorting possible 6134 this.helper.css("position", "absolute"); 6135 this.cssPosition = this.helper.css("position"); 6136 6137 //Generate the original position 6138 this.originalPosition = this._generatePosition(event); 6139 this.originalPageX = event.pageX; 6140 this.originalPageY = event.pageY; 6141 6142 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied 6143 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 6144 6145 //Cache the former DOM position 6146 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; 6147 6148 //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 6149 if(this.helper[0] != this.currentItem[0]) { 6150 this.currentItem.hide(); 6151 } 6152 6153 //Create the placeholder 6154 this._createPlaceholder(); 6155 6156 //Set a containment if given in the options 6157 if(o.containment) 6158 this._setContainment(); 6159 6160 if(o.cursor) { // cursor option 6161 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); 6162 $('body').css("cursor", o.cursor); 6163 } 6164 6165 if(o.opacity) { // opacity option 6166 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); 6167 this.helper.css("opacity", o.opacity); 6168 } 6169 6170 if(o.zIndex) { // zIndex option 6171 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); 6172 this.helper.css("zIndex", o.zIndex); 6173 } 6174 6175 //Prepare scrolling 6176 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') 6177 this.overflowOffset = this.scrollParent.offset(); 6178 6179 //Call callbacks 6180 this._trigger("start", event, this._uiHash()); 6181 6182 //Recache the helper size 6183 if(!this._preserveHelperProportions) 6184 this._cacheHelperProportions(); 6185 6186 6187 //Post 'activate' events to possible containers 6188 if(!noActivation) { 6189 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); } 6190 } 6191 6192 //Prepare possible droppables 6193 if($.ui.ddmanager) 6194 $.ui.ddmanager.current = this; 6195 6196 if ($.ui.ddmanager && !o.dropBehaviour) 6197 $.ui.ddmanager.prepareOffsets(this, event); 6198 6199 this.dragging = true; 6200 6201 this.helper.addClass("ui-sortable-helper"); 6202 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position 6203 return true; 6204 6205 }, 6206 6207 _mouseDrag: function(event) { 6208 6209 //Compute the helpers position 6210 this.position = this._generatePosition(event); 6211 this.positionAbs = this._convertPositionTo("absolute"); 6212 6213 if (!this.lastPositionAbs) { 6214 this.lastPositionAbs = this.positionAbs; 6215 } 6216 6217 //Do scrolling 6218 if(this.options.scroll) { 6219 var o = this.options, scrolled = false;
6220 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { 6221 6222 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) 6223 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; 6224 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) 6225 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; 6226 6227 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) 6228 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; 6229 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) 6230 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; 6231 6232 } else { 6233 6234 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) 6235 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); 6236 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) 6237 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); 6238 6239 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) 6240 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); 6241 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) 6242 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); 6243 6244 } 6245 6246 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) 6247 $.ui.ddmanager.prepareOffsets(this, event); 6248 } 6249 6250 //Regenerate the absolute position used for position checks 6251 this.positionAbs = this._convertPositionTo("absolute"); 6252 6253 //Set the helper position 6254 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; 6255 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; 6256 6257 //Rearrange 6258 for (var i = this.items.length - 1; i >= 0; i--) { 6259 6260 //Cache variables and intersection, continue if no intersection 6261 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); 6262 if (!intersection) continue; 6263 6264 // Only put the placeholder inside the current Container, skip all 6265 // items form other containers. This works because when moving 6266 // an item from one container to another the 6267 // currentContainer is switched before the placeholder is moved. 6268 // 6269 // Without this moving items in "sub-sortables" can cause the placeholder to jitter 6270 // beetween the outer and inner container. 6271 if (item.instance !== this.currentContainer) continue; 6272 6273 if (itemElement != this.currentItem[0] //cannot intersect with itself 6274 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before 6275 && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked 6276 && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true) 6277 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container 6278 ) { 6279 6280 this.direction = intersection == 1 ? "down" : "up"; 6281 6282 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { 6283 this._rearrange(event, item); 6284 } else { 6285 break; 6286 } 6287 6288 this._trigger("change", event, this._uiHash()); 6289 break; 6290 } 6291 } 6292 6293 //Post events to containers 6294 this._contactContainers(event); 6295 6296 //Interconnect with droppables 6297 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 6298 6299 //Call callbacks 6300 this._trigger('sort', event, this._uiHash()); 6301 6302 this.lastPositionAbs = this.positionAbs; 6303 return false; 6304 6305 }, 6306 6307 _mouseStop: function(event, noPropagation) { 6308 6309 if(!event) return; 6310 6311 //If we are using droppables, inform the manager about the drop 6312 if ($.ui.ddmanager && !this.options.dropBehaviour) 6313 $.ui.ddmanager.drop(this, event); 6314 6315 if(this.options.revert) { 6316 var that = this; 6317 var cur = this.placeholder.offset(); 6318 6319 this.reverting = true; 6320 6321 $(this.helper).animate({ 6322 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), 6323 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) 6324 }, parseInt(this.options.revert, 10) || 500, function() { 6325 that._clear(event); 6326 }); 6327 } else { 6328 this._clear(event, noPropagation); 6329 } 6330 6331 return false;
6332 6333 }, 6334 6335 cancel: function() { 6336 6337 if(this.dragging) { 6338 6339 this._mouseUp({ target: null }); 6340 6341 if(this.options.helper == "original") 6342 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 6343 else 6344 this.currentItem.show(); 6345 6346 //Post deactivating events to containers 6347 for (var i = this.containers.length - 1; i >= 0; i--){ 6348 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); 6349 if(this.containers[i].containerCache.over) { 6350 this.containers[i]._trigger("out", null, this._uiHash(this)); 6351 this.containers[i].containerCache.over = 0; 6352 } 6353 } 6354 6355 } 6356 6357 if (this.placeholder) { 6358 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 6359 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 6360 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); 6361 6362 $.extend(this, { 6363 helper: null, 6364 dragging: false, 6365 reverting: false, 6366 _noFinalSort: null 6367 }); 6368 6369 if(this.domPosition.prev) { 6370 $(this.domPosition.prev).after(this.currentItem); 6371 } else { 6372 $(this.domPosition.parent).prepend(this.currentItem); 6373 } 6374 } 6375 6376 return this; 6377 6378 }, 6379 6380 serialize: function(o) { 6381 6382 var items = this._getItemsAsjQuery(o && o.connected); 6383 var str = []; o = o || {}; 6384 6385 $(items).each(function() { 6386 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); 6387 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); 6388 }); 6389 6390 if(!str.length && o.key) { 6391 str.push(o.key + '='); 6392 } 6393 6394 return str.join('&'); 6395 6396 }, 6397 6398 toArray: function(o) { 6399 6400 var items = this._getItemsAsjQuery(o && o.connected); 6401 var ret = []; o = o || {}; 6402 6403 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); 6404 return ret; 6405 6406 }, 6407 6408 /* Be careful with the following core functions */ 6409 _intersectsWith: function(item) { 6410 6411 var x1 = this.positionAbs.left, 6412 x2 = x1 + this.helperProportions.width, 6413 y1 = this.positionAbs.top, 6414 y2 = y1 + this.helperProportions.height; 6415 6416 var l = item.left, 6417 r = l + item.width, 6418 t = item.top, 6419 b = t + item.height; 6420 6421 var dyClick = this.offset.click.top, 6422 dxClick = this.offset.click.left; 6423 6424 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; 6425 6426 if( this.options.tolerance == "pointer" 6427 || this.options.forcePointerForContainers 6428 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) 6429 ) { 6430 return isOverElement; 6431 } else { 6432 6433 return (l < x1 + (this.helperProportions.width / 2) // Right Half 6434 && x2 - (this.helperProportions.width / 2) < r // Left Half 6435 && t < y1 + (this.helperProportions.height / 2) // Bottom Half 6436 && y2 - (this.helperProportions.height / 2) < b ); // Top Half 6437 6438 } 6439 }, 6440 6441 _intersectsWithPointer: function(item) { 6442 6443 var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), 6444 isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), 6445 isOverElement = isOverElementHeight && isOverElementWidth, 6446 verticalDirection = this._getDragVerticalDirection(), 6447 horizontalDirection = this._getDragHorizontalDirection(); 6448 6449 if (!isOverElement) 6450 return false; 6451 6452 return this.floating ? 6453 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) 6454 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); 6455 6456 }, 6457 6458 _intersectsWithSides: function(item) { 6459 6460 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), 6461 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), 6462 verticalDirection = this._getDragVerticalDirection(), 6463 horizontalDirection = this._getDragHorizontalDirection(); 6464 6465 if (this.floating && horizontalDirection) { 6466 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); 6467 } else { 6468 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); 6469 } 6470 6471 }, 6472 6473 _getDragVerticalDirection: function() { 6474 var delta = this.positionAbs.top - this.lastPositionAbs.top; 6475 return delta != 0 && (delta > 0 ? "down" : "up"); 6476 }, 6477 6478 _getDragHorizontalDirection: function() { 6479 var delta = this.positionAbs.left - this.lastPositionAbs.left; 6480 return delta != 0 && (delta > 0 ? "right" : "left"); 6481 }, 6482 6483 refresh: function(event) { 6484 this._refreshItems(event); 6485 this.refreshPositions(); 6486 return this; 6487 }, 6488 6489 _connectWith: function() { 6490 var options = this.options; 6491 return options.connectWith.constructor == String
6492 ? [options.connectWith] 6493 : options.connectWith; 6494 }, 6495 6496 _getItemsAsjQuery: function(connected) { 6497 6498 var items = []; 6499 var queries = []; 6500 var connectWith = this._connectWith(); 6501 6502 if(connectWith && connected) { 6503 for (var i = connectWith.length - 1; i >= 0; i--){ 6504 var cur = $(connectWith[i]); 6505 for (var j = cur.length - 1; j >= 0; j--){ 6506 var inst = $.data(cur[j], this.widgetName); 6507 if(inst && inst != this && !inst.options.disabled) { 6508 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]); 6509 } 6510 }; 6511 }; 6512 } 6513 6514 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]); 6515 6516 for (var i = queries.length - 1; i >= 0; i--){ 6517 queries[i][0].each(function() { 6518 items.push(this); 6519 }); 6520 }; 6521 6522 return $(items); 6523 6524 }, 6525 6526 _removeCurrentsFromItems: function() { 6527 6528 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); 6529 6530 this.items = $.grep(this.items, function (item) { 6531 for (var j=0; j < list.length; j++) { 6532 if(list[j] == item.item[0]) 6533 return false; 6534 }; 6535 return true; 6536 }); 6537 6538 }, 6539 6540 _refreshItems: function(event) { 6541 6542 this.items = []; 6543 this.containers = [this]; 6544 var items = this.items; 6545 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; 6546 var connectWith = this._connectWith(); 6547 6548 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down 6549 for (var i = connectWith.length - 1; i >= 0; i--){ 6550 var cur = $(connectWith[i]); 6551 for (var j = cur.length - 1; j >= 0; j--){ 6552 var inst = $.data(cur[j], this.widgetName); 6553 if(inst && inst != this && !inst.options.disabled) { 6554 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); 6555 this.containers.push(inst); 6556 } 6557 }; 6558 }; 6559 } 6560 6561 for (var i = queries.length - 1; i >= 0; i--) { 6562 var targetData = queries[i][1]; 6563 var _queries = queries[i][0]; 6564 6565 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { 6566 var item = $(_queries[j]); 6567 6568 item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager) 6569 6570 items.push({ 6571 item: item, 6572 instance: targetData, 6573 width: 0, height: 0, 6574 left: 0, top: 0 6575 }); 6576 }; 6577 }; 6578 6579 }, 6580 6581 refreshPositions: function(fast) { 6582 6583 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change 6584 if(this.offsetParent && this.helper) { 6585 this.offset.parent = this._getParentOffset(); 6586 } 6587 6588 for (var i = this.items.length - 1; i >= 0; i--){ 6589 var item = this.items[i]; 6590 6591 //We ignore calculating positions of all connected containers when we're not over them 6592 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) 6593 continue; 6594 6595 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; 6596 6597 if (!fast) { 6598 item.width = t.outerWidth(); 6599 item.height = t.outerHeight(); 6600 } 6601 6602 var p = t.offset(); 6603 item.left = p.left; 6604 item.top = p.top; 6605 }; 6606 6607 if(this.options.custom && this.options.custom.refreshContainers
6607) { 6608 this.options.custom.refreshContainers.call(this); 6609 } else { 6610 for (var i = this.containers.length - 1; i >= 0; i--){ 6611 var p = this.containers[i].element.offset(); 6612 this.containers[i].containerCache.left = p.left; 6613 this.containers[i].containerCache.top = p.top; 6614 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); 6615 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); 6616 }; 6617 } 6618 6619 return this; 6620 }, 6621 6622 _createPlaceholder: function(that) { 6623 that = that || this; 6624 var o = that.options; 6625 6626 if(!o.placeholder || o.placeholder.constructor == String) { 6627 var className = o.placeholder; 6628 o.placeholder = { 6629 element: function() { 6630 6631 var el = $(document.createElement(that.currentItem[0].nodeName)) 6632 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") 6633 .removeClass("ui-sortable-helper")[0]; 6634 6635 if(!className) 6636 el.style.visibility = "hidden"; 6637 6638 return el; 6639 }, 6640 update: function(container, p) { 6641 6642 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that 6643 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified 6644 if(className && !o.forcePlaceholderSize) return; 6645 6646 //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
6647 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }; 6648 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }; 6649 } 6650 }; 6651 } 6652 6653 //Create the placeholder 6654 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); 6655 6656 //Append it after the actual current item 6657 that.currentItem.after(that.placeholder); 6658 6659 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 6660 o.placeholder.update(that, that.placeholder); 6661 6662 }, 6663 6664 _contactContainers: function(event) { 6665 6666 // get innermost container that intersects with item 6667 var innermostContainer = null, innermostIndex = null; 6668 6669 6670 for (var i = this.containers.length - 1; i >= 0; i--){ 6671 6672 // never consider a container that's located within the item itself 6673 if($.contains(this.currentItem[0], this.containers[i].element[0])) 6674 continue; 6675 6676 if(this._intersectsWith(this.containers[i].containerCache)) { 6677 6678 // if we've already found a container and it's more "inner" than this, then continue 6679 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) 6680 continue; 6681 6682 innermostContainer = this.containers[i]; 6683 innermostIndex = i; 6684 6685 } else { 6686 // container doesn't intersect. trigger "out" event if necessary 6687 if(this.containers[i].containerCache.over) { 6688 this.containers[i]._trigger("out", event, this._uiHash(this)); 6689 this.containers[i].containerCache.over = 0; 6690 } 6691 } 6692 6693 } 6694 6695 // if no intersecting containers found, return 6696 if(!innermostContainer) return; 6697 6698 // move the item into the container if it's not there already 6699 if(this.containers.length === 1) { 6700 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 6701 this.containers[innermostIndex].containerCache.over = 1; 6702 } else { 6703 6704 //When entering a new container, we will find the item with the least distance and append our item near it 6705 var dist = 10000; var itemWithLeastDistance = null; 6706 var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top'; 6707 var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height'; 6708 var base = this.positionAbs[posProperty] + this.offset.click[posProperty]; 6709 for (var j = this.items.length - 1; j >= 0; j--) { 6710 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 6711 if(this.items[j].item[0] == this.currentItem[0]) continue; 6712 var cur = this.items[j].item.offset()[posProperty]; 6713 var nearBottom = false; 6714 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ 6715 nearBottom = true; 6716 cur += this.items[j][sizeProperty]; 6717 } 6718 6719 if(Math.abs(cur - base) < dist) { 6720 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 6721 this.direction = nearBottom ? "up": "down"; 6722 } 6723 } 6724 6725 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 6726 return; 6727 6728 this.currentContainer = this.containers[innermostIndex]; 6729 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 6730 this._trigger("change", event, this._uiHash()); 6731 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 6732 6733 //Update the placeholder 6734 this.options.placeholder.update(this.currentContainer, this.placeholder); 6735 6736 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 6737 this.containers[innermostIndex].containerCache.over = 1; 6738 } 6739 6740 6741 }, 6742 6743 _createHelper: function(event) { 6744 6745 var o = this.options; 6746 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); 6747 6748 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already 6749 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); 6750 6751 if(helper[0] == this.currentItem[0]) 6752 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
6752: this.currentItem.css("left") }; 6753 6754 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); 6755 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); 6756 6757 return helper; 6758 6759 }, 6760 6761 _adjustOffsetFromHelper: function(obj) { 6762 if (typeof obj == 'string') { 6763 obj = obj.split(' '); 6764 } 6765 if ($.isArray(obj)) { 6766 obj = {left: +obj[0], top: +obj[1] || 0}; 6767 } 6768 if ('left' in obj) { 6769 this.offset.click.left = obj.left + this.margins.left; 6770 } 6771 if ('right' in obj) { 6772 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 6773 } 6774 if ('top' in obj) { 6775 this.offset.click.top = obj.top + this.margins.top; 6776 } 6777 if ('bottom' in obj) { 6778 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 6779 } 6780 }, 6781 6782 _getParentOffset: function() { 6783 6784 6785 //Get the offsetParent and cache its position 6786 this.offsetParent = this.helper.offsetParent(); 6787 var po = this.offsetParent.offset(); 6788 6789 // This is a special case where we need to modify a offset calculated on start, since the following happened: 6790 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent 6791 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that 6792 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag 6793 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { 6794 po.left += this.scrollParent.scrollLeft(); 6795 po.top += this.scrollParent.scrollTop(); 6796 } 6797 6798 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information 6799 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix 6800 po = { top: 0, left: 0 }; 6801 6802 return { 6803 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), 6804 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) 6805 }; 6806 6807 }, 6808 6809 _getRelativeOffset: function() { 6810 6811 if(this.cssPosition == "relative") { 6812 var p = this.currentItem.position(); 6813 return { 6814 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), 6815 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() 6816 }; 6817 } else { 6818 return { top: 0, left: 0 }; 6819 } 6820 6821 }, 6822 6823 _cacheMargins: function() { 6824 this.margins = { 6825 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), 6826 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) 6827 }; 6828 }, 6829 6830 _cacheHelperProportions: function() { 6831 this.helperProportions = { 6832 width: this.helper.outerWidth(), 6833 height: this.helper.outerHeight() 6834 }; 6835 }, 6836 6837 _setContainment: function() { 6838 6839 var o = this.options; 6840 if(o.containment == 'parent') o.containment = this.helper[0].parentNode; 6841 if(o.containment == 'document' || o.containment == 'window') this.containment = [ 6842 0 - this.offset.relative.left - this.offset.parent.left, 6843 0 - this.offset.relative.top - this.offset.parent.top, 6844 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, 6845 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top 6846 ]; 6847 6848 if(!(/^(document|window|parent)$/).test(o.containment)) { 6849 var ce = $(o.containment)[0]; 6850 var co = $(o.containment).offset(); 6851 var over = ($(ce).css("overflow") != 'hidden'); 6852 6853 this.containment = [ 6854 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, 6855 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, 6856 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, 6857 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
685710) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top 6858 ]; 6859 } 6860 6861 }, 6862 6863 _convertPositionTo: function(d, pos) { 6864 6865 if(!pos) pos = this.position; 6866 var mod = d == "absolute" ? 1 : -1; 6867 var o = this.options, 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); 6868 6869 return { 6870 top: ( 6871 pos.top // The absolute mouse position 6872 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent 6873 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) 6874 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) 6875 ), 6876 left: ( 6877 pos.left // The absolute mouse position 6878 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent 6879 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) 6880 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) 6881 ) 6882 }; 6883 6884 }, 6885 6886 _generatePosition: function(event) { 6887 6888 var o = this.options, 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); 6889 6890 // This is another very weird special case that only happens for relative elements: 6891 // 1. If the css position is relative 6892 // 2. and the scroll parent is the document or similar to the offset parent 6893 // we have to refresh the relative offset during the scroll so there are no jumps 6894 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { 6895 this.offset.relative = this._getRelativeOffset(); 6896 } 6897 6898 var pageX = event.pageX; 6899 var pageY = event.pageY; 6900 6901 /* 6902 * - Position constraining - 6903 * Constrain the position to a mix of grid, containment. 6904 */ 6905 6906 if(this.originalPosition) { //If we are not dragging yet, we won't check for options 6907 6908 if(this.containment) { 6909 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; 6910 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; 6911 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; 6912 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; 6913 } 6914 6915 if(o.grid) { 6916 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 6917 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; 6918 6919 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 6920 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; 6921 } 6922 6923 } 6924 6925 return { 6926 top: ( 6927 pageY // The absolute mouse position 6928 - this.offset.click.top // Click offset (relative to the element) 6929 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent 6930 - this.offset.parent.top // The offsetParent's offset without borders (offset + border) 6931 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) 6932 ), 6933 left: ( 6934 pageX // The absolute mouse position 6935 - this.offset.click.left // Click offset (relative to the element) 6936 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent 6937 - this.offset.parent.left // The offsetParent's offset without borders (offset + border) 6938 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) 6939 ) 6940 }; 6941 6942 }, 6943 6944 _rearrange: function(event, i, a, hardRefresh) { 6945 6946 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)); 6947 6948 //Various things done here to improve the performance: 6949 // 1. we create a setTimeout, that calls refreshPositions 6950 // 2. on the instance, we have a counter variable, that get's higher after every append 6951 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 6952 // 4. this lets only the last addition to the timeout stack through 6953 this.counter = this.counter ? ++this.counter : 1; 6954 var counter = this.counter; 6955 6956 this._delay(function() {
6957 if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 6958 }); 6959 6960 }, 6961 6962 _clear: function(event, noPropagation) { 6963 6964 this.reverting = false; 6965 // We delay all events that have to be triggered to after the point where the placeholder has been removed and 6966 // everything else normalized again 6967 var delayedTriggers = []; 6968 6969 // We first have to update the dom position of the actual currentItem 6970 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) 6971 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); 6972 this._noFinalSort = null; 6973 6974 if(this.helper[0] == this.currentItem[0]) { 6975 for(var i in this._storedCSS) { 6976 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; 6977 } 6978 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); 6979 } else { 6980 this.currentItem.show(); 6981 } 6982 6983 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); 6984 if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed 6985 6986 // Check if the items Container has Changed and trigger appropriate 6987 // events. 6988 if (this !== this.currentContainer) { 6989 if(!noPropagation) { 6990 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); 6991 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 6992 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); 6993 } 6994 } 6995 6996 6997 //Post events to containers 6998 for (var i = this.containers.length - 1; i >= 0; i--){ 6999 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 7000 if(this.containers[i].containerCache.over) { 7001 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); 7002 this.containers[i].containerCache.over = 0; 7003 } 7004 } 7005 7006 //Do what was originally in plugins 7007 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor 7008 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity 7009 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index 7010 7011 this.dragging = false; 7012 if(this.cancelHelperRemoval) { 7013 if(!noPropagation) { 7014 this._trigger("beforeStop", event, this._uiHash()); 7015 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 7016 this._trigger("stop", event, this._uiHash()); 7017 } 7018 7019 this.fromOutside = false;
7020 return false; 7021 } 7022 7023 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); 7024 7025 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! 7026 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); 7027 7028 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; 7029 7030 if(!noPropagation) { 7031 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events 7032 this._trigger("stop", event, this._uiHash()); 7033 } 7034 7035 this.fromOutside = false; 7036 return true; 7037 7038 }, 7039 7040 _trigger: function() { 7041 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { 7042 this.cancel(); 7043 } 7044 }, 7045 7046 _uiHash: function(_inst) { 7047 var inst = _inst || this; 7048 return { 7049 helper: inst.helper, 7050 placeholder: inst.placeholder || $([]), 7051 position: inst.position, 7052 originalPosition: inst.originalPosition, 7053 offset: inst.positionAbs, 7054 item: inst.currentItem, 7055 sender: _inst ? _inst.element : null 7056 }; 7057 } 7058 7059}); 7060 7061})(jQuery); 7062 7063;(jQuery.effects || (function($, undefined) { 7064 7065var backCompat = $.uiBackCompat !== false, 7066 // prefix used for storing data on .data() 7067 dataSpace = "ui-effects-"; 7068 7069$.effects = { 7070 effect: {} 7071}; 7072 7073/*! 7074 * jQuery Color Animations v2.0.0 7075 * http://jquery.com/ 7076 * 7077 * Copyright 2012 jQuery Foundation and other contributors 7078 * Released under the MIT license. 7079 * http://jquery.org/license 7080 * 7081 * Date: Mon Aug 13 13:41:02 2012 -0500 7082 */ 7083(function( jQuery, undefined ) { 7084 7085 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "), 7086 7087 // plusequals test for += 100 -= 100 7088 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 7089 // a set of RE's that can match strings and generate color tuples. 7090 stringParsers = [{ 7091 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 7092 parse: function( execResult ) { 7093 return [ 7094 execResult[ 1 ], 7095 execResult[ 2 ], 7096 execResult[ 3 ], 7097 execResult[ 4 ] 7098 ]; 7099 } 7100 }, { 7101 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 7102 parse: function( execResult ) { 7103 return [ 7104 execResult[ 1 ] * 2.55, 7105 execResult[ 2 ] * 2.55, 7106 execResult[ 3 ] * 2.55, 7107 execResult[ 4 ] 7108 ]; 7109 } 7110 }, { 7111 // this regex ignores A-F because it's compared against an already lowercased string 7112 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 7113 parse: function( execResult ) { 7114 return [ 7115 parseInt( execResult[ 1 ], 16 ), 7116 parseInt( execResult[ 2 ], 16 ), 7117 parseInt( execResult[ 3 ], 16 ) 7118 ]; 7119 } 7120 }, { 7121 // this regex ignores A-F because it's compared against an already lowercased string 7122 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 7123 parse: function( execResult ) { 7124 return [ 7125 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 7126 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 7127 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 7128 ]; 7129 } 7130 }, { 7131 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 7132 space: "hsla", 7133 parse: function( execResult ) { 7134 return [ 7135 execResult[ 1 ], 7136 execResult[ 2 ] / 100, 7137 execResult[ 3 ] / 100, 7138 execResult[ 4 ] 7139 ]; 7140 } 7141 }], 7142 7143 // jQuery.Color( ) 7144 color = jQuery.Color = function( color, green, blue, alpha ) { 7145 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 7146 }, 7147 spaces = { 7148 rgba: { 7149 props: { 7150 red: { 7151 idx: 0, 7152 type: "byte" 7153 }, 7154 green: { 7155 idx: 1, 7156 type: "byte" 7157 }, 7158 blue: { 7159 idx: 2, 7160 type: "byte" 7161 } 7162 } 7163 }, 7164 7165 hsla: { 7166 props: { 7167 hue: { 7168 idx: 0, 7169 type: "degrees" 7170 }, 7171 saturation: { 7172 idx: 1, 7173 type: "percent" 7174 }, 7175 lightness: { 7176 idx: 2, 7177 type: "percent" 7178 } 7179 } 7180 } 7181 }, 7182 propTypes = { 7183 "byte": { 7184 floor: true, 7185 max: 255 7186 }, 7187 "percent": { 7188 max: 1 7189 }, 7190 "degrees": { 7191 mod: 360, 7192 floor: true 7193 } 7194 }, 7195 support = color.support = {}, 7196 7197 // element for support tests 7198 supportElem = jQuery( "<p>" )[ 0 ], 7199 7200 // colors = jQuery.Color.names 7201 colors, 7202 7203 // local aliases of functions called often 7204 each = jQuery.each; 7205
vendor: 23,788 bytes, lines 7206-8157
7206// determine rgba support immediately 7207supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 7208support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 7209 7210// define cache name and alpha properties 7211// for rgba and hsla spaces 7212each( spaces, function( spaceName, space ) { 7213 space.cache = "_" + spaceName; 7214 space.props.alpha = { 7215 idx: 3, 7216 type: "percent", 7217 def: 1 7218 }; 7219}); 7220 7221function clamp( value, prop, allowEmpty ) { 7222 var type = propTypes[ prop.type ] || {}; 7223 7224 if ( value == null ) { 7225 return (allowEmpty || !prop.def) ? null : prop.def; 7226 } 7227 7228 // ~~ is an short way of doing floor for positive numbers 7229 value = type.floor ? ~~value : parseFloat( value ); 7230 7231 // IE will pass in empty strings as value for alpha, 7232 // which will hit this case 7233 if ( isNaN( value ) ) { 7234 return prop.def; 7235 } 7236 7237 if ( type.mod ) { 7238 // we add mod before modding to make sure that negatives values 7239 // get converted properly: -10 -> 350 7240 return (value + type.mod) % type.mod; 7241 } 7242 7243 // for now all property types without mod have min and max 7244 return 0 > value ? 0 : type.max < value ? type.max : value; 7245} 7246 7247function stringParse( string ) { 7248 var inst = color(), 7249 rgba = inst._rgba = []; 7250 7251 string = string.toLowerCase(); 7252 7253 each( stringParsers, function( i, parser ) { 7254 var parsed, 7255 match = parser.re.exec( string ), 7256 values = match && parser.parse( match ), 7257 spaceName = parser.space || "rgba"; 7258 7259 if ( values ) { 7260 parsed = inst[ spaceName ]( values ); 7261 7262 // if this was an rgba parse the assignment might happen twice 7263 // oh well.... 7264 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 7265 rgba = inst._rgba = parsed._rgba; 7266 7267 // exit each( stringParsers ) here because we matched 7268 return false; 7269 } 7270 }); 7271 7272 // Found a stringParser that handled it 7273 if ( rgba.length ) { 7274 7275 // if this came from a parsed string, force "transparent" when alpha is 0 7276 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 7277 if ( rgba.join() === "0,0,0,0" ) { 7278 jQuery.extend( rgba, colors.transparent ); 7279 } 7280 return inst; 7281 } 7282 7283 // named colors 7284 return colors[ string ]; 7285} 7286 7287color.fn = jQuery.extend( color.prototype, { 7288 parse: function( red, green, blue, alpha ) { 7289 if ( red === undefined ) { 7290 this._rgba = [ null, null, null, null ]; 7291 return this; 7292 } 7293 if ( red.jquery || red.nodeType ) { 7294 red = jQuery( red ).css( green ); 7295 green = undefined; 7296 } 7297 7298 var inst = this, 7299 type = jQuery.type( red ), 7300 rgba = this._rgba = []; 7301 7302 // more than 1 argument specified - assume ( red, green, blue, alpha ) 7303 if ( green !== undefined ) { 7304 red = [ red, green, blue, alpha ]; 7305 type = "array"; 7306 } 7307 7308 if ( type === "string" ) { 7309 return this.parse( stringParse( red ) || colors._default ); 7310 } 7311 7312 if ( type === "array" ) { 7313 each( spaces.rgba.props, function( key, prop ) { 7314 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 7315 }); 7316 return this; 7317 } 7318 7319 if ( type === "object" ) { 7320 if ( red instanceof color ) { 7321 each( spaces, function( spaceName, space ) { 7322 if ( red[ space.cache ] ) { 7323 inst[ space.cache ] = red[ space.cache ].slice(); 7324 } 7325 }); 7326 } else { 7327 each( spaces, function( spaceName, space ) { 7328 var cache = space.cache; 7329 each( space.props, function( key, prop ) { 7330 7331 // if the cache doesn't exist, and we know how to convert 7332 if ( !inst[ cache ] && space.to ) { 7333 7334 // if the value was null, we don't need to copy it 7335 // if the key was alpha, we don't need to copy it either 7336 if ( key === "alpha" || red[ key ] == null ) { 7337 return; 7338 } 7339 inst[ cache ] = space.to( inst._rgba ); 7340 } 7341 7342 // this is the only case where we allow nulls for ALL properties. 7343 // call clamp with alwaysAllowEmpty 7344 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 7345 }); 7346 7347 // everything defined but alpha? 7348 if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 7349 // use the default of 1 7350 inst[ cache ][ 3 ] = 1; 7351 if ( space.from ) { 7352 inst._rgba = space.from( inst[ cache ] ); 7353 } 7354 } 7355 }); 7356 } 7357 return this; 7358 } 7359 }, 7360 is: function( compare ) { 7361 var is = color( compare ), 7362 same = true, 7363 inst = this; 7364 7365 each( spaces, function( _, space ) { 7366 var localCache, 7367 isCache = is[ space.cache ]; 7368 if (isCache) { 7369 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 7370 each( space.props, function( _, prop ) { 7371 if ( isCache[ prop.idx ] != null ) { 7372 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 7373 return same; 7374 } 7375 }); 7376 } 7377 return same; 7378 }); 7379 return same; 7380 }, 7381 _space: function() { 7382 var used = [], 7383 inst = this; 7384 each( spaces, function( spaceName, space ) { 7385 if ( inst[ space.cache ] ) { 7386 used.push( spaceName ); 7387 } 7388 }); 7389 return used.pop(); 7390 }, 7391 transition: function( other, distance ) { 7392 var end = color( other ), 7393 spaceName = end._space(), 7394 space = spaces[ spaceName ], 7395 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 7396 start = startColor[ space.cache ] || space.to( startColor._rgba ), 7397 result = start.slice(); 7398 7399 end = end[ space.cache ]; 7400 each( space.props, function( key, prop ) { 7401 var index = prop.idx, 7402 startValue = start[ index ], 7403 endValue = end[ index ], 7404 type = propTypes[ prop.type ] || {}; 7405 7406 // if null, don't override start value 7407 if ( endValue === null ) { 7408 return; 7409 } 7410 // if null - use end 7411 if ( startValue === null ) { 7412 result[ index ] = endValue; 7413 } else { 7414 if ( type.mod ) { 7415 if ( endValue - startValue > type.mod / 2 ) { 7416 startValue += type.mod; 7417 } else if ( startValue - endValue > type.mod / 2 ) { 7418 startValue -= type.mod; 7419 } 7420 } 7421 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 7422 } 7423 }); 7424 return this[ spaceName ]( result ); 7425 }, 7426 blend: function( opaque ) { 7427 // if we are already opaque - return ourself 7428 if ( this._rgba[ 3 ] === 1 ) { 7429 return this; 7430 } 7431 7432 var rgb = this._rgba.slice(), 7433 a = rgb.pop(), 7434 blend = color( opaque )._rgba; 7435 7436 return color( jQuery.map( rgb, function( v, i ) { 7437 return ( 1 - a ) * blend[ i ] + a * v; 7438 })); 7439 }, 7440 toRgbaString: function() { 7441 var prefix = "rgba(", 7442 rgba = jQuery.map( this._rgba, function( v, i ) { 7443 return v == null ? ( i > 2 ? 1 : 0 ) : v; 7444 }); 7445 7446 if ( rgba[ 3 ] === 1 ) { 7447 rgba.pop(); 7448 prefix = "rgb("; 7449 } 7450 7451 return prefix + rgba.join() + ")"; 7452 }, 7453 toHslaString: function() { 7454 var prefix = "hsla(", 7455 hsla = jQuery.map( this.hsla(), function( v, i ) { 7456 if ( v == null ) { 7457 v = i > 2 ? 1 : 0; 7458 } 7459 7460 // catch 1 and 2 7461 if ( i && i < 3 ) { 7462 v = Math.round( v * 100 ) + "%"; 7463 } 7464 return v; 7465 }); 7466 7467 if ( hsla[ 3 ] === 1 ) { 7468 hsla.pop(); 7469 prefix = "hsl("; 7470 } 7471 return prefix + hsla.join() + ")"; 7472 }, 7473 toHexString: function( includeAlpha ) { 7474 var rgba = this._rgba.slice(), 7475 alpha = rgba.pop(); 7476 7477 if ( includeAlpha ) { 7478 rgba.push( ~~( alpha * 255 ) ); 7479 } 7480 7481 return "#" + jQuery.map( rgba, function( v ) { 7482 7483 // default to 0 when nulls exist 7484 v = ( v || 0 ).toString( 16 ); 7485 return v.length === 1 ? "0" + v : v; 7486 }).join(""); 7487 }, 7488 toString: function() { 7489 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 7490 } 7491}); 7492color.fn.parse.prototype = color.fn; 7493 7494// hsla conversions adapted from: 7495// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 7496 7497function hue2rgb( p, q, h ) { 7498 h = ( h + 1 ) % 1; 7499 if ( h * 6 < 1 ) { 7500 return p + (q - p) * h * 6; 7501 } 7502 if ( h * 2 < 1) { 7503 return q; 7504 } 7505 if ( h * 3 < 2 ) { 7506 return p + (q - p) * ((2/3) - h) * 6; 7507 } 7508 return p; 7509} 7510 7511spaces.hsla.to = function ( rgba ) { 7512 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 7513 return [ null, null, null, rgba[ 3 ] ]; 7514 } 7515 var r = rgba[ 0 ] / 255, 7516 g = rgba[ 1 ] / 255, 7517 b = rgba[ 2 ] / 255, 7518 a = rgba[ 3 ], 7519 max = Math.max( r, g, b ), 7520 min = Math.min( r, g, b ), 7521 diff = max - min, 7522 add = max + min, 7523 l = add * 0.5, 7524 h, s; 7525 7526 if ( min === max ) { 7527 h = 0; 7528 } else if ( r === max ) { 7529 h = ( 60 * ( g - b ) / diff ) + 360; 7530 } else if ( g === max ) { 7531 h = ( 60 * ( b - r ) / diff ) + 120; 7532 } else { 7533 h = ( 60 * ( r - g ) / diff ) + 240; 7534 } 7535 7536 if ( l === 0 || l === 1 ) { 7537 s = l; 7538 } else if ( l <= 0.5 ) { 7539 s = diff / add; 7540 } else { 7541 s = diff / ( 2 - add ); 7542 } 7543 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 7544}; 7545 7546spaces.hsla.from = function ( hsla ) { 7547 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 7548 return [ null, null, null, hsla[ 3 ] ]; 7549 } 7550 var h = hsla[ 0 ] / 360, 7551 s = hsla[ 1 ], 7552 l = hsla[ 2 ], 7553 a = hsla[ 3 ], 7554 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 7555 p = 2 * l - q; 7556 7557 return [ 7558 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 7559 Math.round( hue2rgb( p, q, h ) * 255 ), 7560 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 7561 a 7562 ]; 7563}; 7564 7565 7566each( spaces, function( spaceName, space ) { 7567 var props = space.props, 7568 cache = space.cache, 7569 to = space.to, 7570 from = space.from; 7571 7572 // makes rgba() and hsla() 7573 color.fn[ spaceName ] = function( value ) { 7574 7575 // generate a cache for this space if it doesn't exist 7576 if ( to && !this[ cache ] ) { 7577 this[ cache ] = to( this._rgba ); 7578 } 7579 if ( value === undefined ) { 7580 return this[ cache ].slice(); 7581 } 7582 7583 var ret, 7584 type = jQuery.type( value ), 7585 arr = ( type === "array" || type === "object" ) ? value : arguments, 7586 local = this[ cache ].slice(); 7587 7588 each( props, function( key, prop ) { 7589 var val = arr[ type === "object" ? key : prop.idx ]; 7590 if ( val == null ) { 7591 val = local[ prop.idx ]; 7592 } 7593 local[ prop.idx ] = clamp( val, prop ); 7594 }); 7595 7596 if ( from ) { 7597 ret = color( from( local ) ); 7598 ret[ cache ] = local; 7599 return ret; 7600 } else { 7601 return color( local ); 7602 } 7603 }; 7604 7605 // makes red() green() blue() alpha() hue() saturation() lightness() 7606 each( props, function( key, prop ) { 7607 // alpha is included in more than one space 7608 if ( color.fn[ key ] ) { 7609 return; 7610 } 7611 color.fn[ key ] = function( value ) { 7612 var vtype = jQuery.type( value ), 7613 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 7614 local = this[ fn ](), 7615 cur = local[ prop.idx ], 7616 match; 7617 7618 if ( vtype === "undefined" ) { 7619 return cur; 7620 } 7621 7622 if ( vtype === "function" ) { 7623 value = value.call( this, cur ); 7624 vtype = jQuery.type( value ); 7625 } 7626 if ( value == null && prop.empty ) { 7627 return this; 7628 } 7629 if ( vtype === "string" ) { 7630 match = rplusequals.exec( value ); 7631 if ( match ) { 7632 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 7633 } 7634 } 7635 local[ prop.idx ] = value; 7636 return this[ fn ]( local ); 7637 }; 7638 }); 7639}); 7640 7641// add .fx.step functions 7642each( stepHooks, function( i, hook ) { 7643 jQuery.cssHooks[ hook ] = { 7644 set: function( elem, value ) { 7645 var parsed, curElem, 7646 backgroundColor = ""; 7647 7648 if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { 7649 value = color( parsed || value ); 7650 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 7651 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 7652 while ( 7653 (backgroundColor === "" || backgroundColor === "transparent") && 7654 curElem && curElem.style 7655 ) { 7656 try { 7657 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 7658 curElem = curElem.parentNode; 7659 } catch ( e ) { 7660 } 7661 } 7662 7663 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 7664 backgroundColor : 7665 "_default" ); 7666 } 7667 7668 value = value.toRgbaString(); 7669 } 7670 try { 7671 elem.style[ hook ] = value; 7672 } catch( error ) { 7673 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 7674 } 7675 } 7676 }; 7677 jQuery.fx.step[ hook ] = function( fx ) { 7678 if ( !fx.colorInit ) { 7679 fx.start = color( fx.elem, hook ); 7680 fx.end = color( fx.end ); 7681 fx.colorInit = true; 7682 } 7683 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 7684 }; 7685}); 7686 7687jQuery.cssHooks.borderColor = { 7688 expand: function( value ) { 7689 var expanded = {}; 7690 7691 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 7692 expanded[ "border" + part + "Color" ] = value; 7693 }); 7694 return expanded; 7695 } 7696}; 7697 7698// Basic color names only. 7699// Usage of any of the other color names requires adding yourself or including 7700// jquery.color.svg-names.js. 7701colors = jQuery.Color.names = { 7702 // 4.1. Basic color keywords 7703 aqua: "#00ffff", 7704 black: "#000000", 7705 blue: "#0000ff", 7706 fuchsia: "#ff00ff", 7707 gray: "#808080", 7708 green: "#008000", 7709 lime: "#00ff00", 7710 maroon: "#800000", 7711 navy: "#000080", 7712 olive: "#808000", 7713 purple: "#800080", 7714 red: "#ff0000", 7715 silver: "#c0c0c0", 7716 teal: "#008080", 7717 white: "#ffffff", 7718 yellow: "#ffff00", 7719 7720 // 4.2.3. "transparent" color keyword 7721 transparent: [ null, null, null, 0 ], 7722 7723 _default: "#ffffff" 7724}; 7725 7726})( jQuery ); 7727 7728 7729 7730/******************************************************************************/ 7731/****************************** CLASS ANIMATIONS ******************************/ 7732/******************************************************************************/ 7733(function() { 7734 7735var classAnimationActions = [ "add", "remove", "toggle" ], 7736 shorthandStyles = { 7737 border: 1, 7738 borderBottom: 1, 7739 borderColor: 1, 7740 borderLeft: 1, 7741 borderRight: 1, 7742 borderTop: 1, 7743 borderWidth: 1, 7744 margin: 1, 7745 padding: 1 7746 }; 7747 7748$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { 7749 $.fx.step[ prop ] = function( fx ) { 7750 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 7751 jQuery.style( fx.elem, prop, fx.end ); 7752 fx.setAttr = true; 7753 } 7754 }; 7755}); 7756 7757function getElementStyles() { 7758 var style = this.ownerDocument.defaultView ? 7759 this.ownerDocument.defaultView.getComputedStyle( this, null ) : 7760 this.currentStyle, 7761 newStyle = {}, 7762 key, 7763 len; 7764 7765 // webkit enumerates style porperties 7766 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 7767 len = style.length; 7768 while ( len-- ) { 7769 key = style[ len ]; 7770 if ( typeof style[ key ] === "string" ) { 7771 newStyle[ $.camelCase( key ) ] = style[ key ]; 7772 } 7773 } 7774 } else { 7775 for ( key in style ) { 7776 if ( typeof style[ key ] === "string" ) { 7777 newStyle[ key ] = style[ key ]; 7778 } 7779 } 7780 } 7781 7782 return newStyle; 7783} 7784 7785 7786function styleDifference( oldStyle, newStyle ) { 7787 var diff = {}, 7788 name, value; 7789 7790 for ( name in newStyle ) { 7791 value = newStyle[ name ]; 7792 if ( oldStyle[ name ] !== value ) { 7793 if ( !shorthandStyles[ name ] ) { 7794 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 7795 diff[ name ] = value; 7796 } 7797 } 7798 } 7799 } 7800 7801 return diff; 7802} 7803 7804$.effects.animateClass = function( value, duration, easing, callback ) { 7805 var o = $.speed( duration, easing, callback ); 7806 7807 return this.queue( function() { 7808 var animated = $( this ), 7809 baseClass = animated.attr( "class" ) || "", 7810 applyClassChange, 7811 allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; 7812 7813 // map the animated objects to store the original styles. 7814 allAnimations = allAnimations.map(function() { 7815 var el = $( this ); 7816 return { 7817 el: el, 7818 start: getElementStyles.call( this ) 7819 }; 7820 }); 7821 7822 // apply class change 7823 applyClassChange = function() { 7824 $.each( classAnimationActions, function(i, action) { 7825 if ( value[ action ] ) { 7826 animated[ action + "Class" ]( value[ action ] ); 7827 } 7828 }); 7829 }; 7830 applyClassChange(); 7831 7832 // map all animated objects again - calculate new styles and diff 7833 allAnimations = allAnimations.map(function() { 7834 this.end = getElementStyles.call( this.el[ 0 ] ); 7835 this.diff = styleDifference( this.start, this.end ); 7836 return this; 7837 }); 7838 7839 // apply original class 7840 animated.attr( "class", baseClass ); 7841 7842 // map all animated objects again - this time collecting a promise 7843 allAnimations = allAnimations.map(function() { 7844 var styleInfo = this, 7845 dfd = $.Deferred(), 7846 opts = jQuery.extend({}, o, { 7847 queue: false, 7848 complete: function() { 7849 dfd.resolve( styleInfo ); 7850 } 7851 }); 7852 7853 this.el.animate( this.diff, opts ); 7854 return dfd.promise(); 7855 }); 7856 7857 // once all animations have completed: 7858 $.when.apply( $, allAnimations.get() ).done(function() { 7859 7860 // set the final class 7861 applyClassChange(); 7862 7863 // for each animated element, 7864 // clear all css properties that were animated 7865 $.each( arguments, function() { 7866 var el = this.el; 7867 $.each( this.diff, function(key) { 7868 el.css( key, '' ); 7869 }); 7870 }); 7871 7872 // this is guarnteed to be there if you use jQuery.speed() 7873 // it also handles dequeuing the next anim... 7874 o.complete.call( animated[ 0 ] ); 7875 }); 7876 }); 7877}; 7878 7879$.fn.extend({ 7880 _addClass: $.fn.addClass, 7881 addClass: function( classNames, speed, easing, callback ) { 7882 return speed ? 7883 $.effects.animateClass.call( this, 7884 { add: classNames }, speed, easing, callback ) : 7885 this._addClass( classNames ); 7886 }, 7887 7888 _removeClass: $.fn.removeClass, 7889 removeClass: function( classNames, speed, easing, callback ) { 7890 return speed ? 7891 $.effects.animateClass.call( this, 7892 { remove: classNames }, speed, easing, callback ) : 7893 this._removeClass( classNames ); 7894 }, 7895 7896 _toggleClass: $.fn.toggleClass, 7897 toggleClass: function( classNames, force, speed, easing, callback ) { 7898 if ( typeof force === "boolean" || force === undefined ) { 7899 if ( !speed ) { 7900 // without speed parameter 7901 return this._toggleClass( classNames, force ); 7902 } else { 7903 return $.effects.animateClass.call( this, 7904 (force ? { add: classNames } : { remove: classNames }), 7905 speed, easing, callback ); 7906 } 7907 } else { 7908 // without force parameter 7909 return $.effects.animateClass.call( this, 7910 { toggle: classNames }, force, speed, easing ); 7911 } 7912 }, 7913 7914 switchClass: function( remove, add, speed, easing, callback) { 7915 return $.effects.animateClass.call( this, { 7916 add: add, 7917 remove: remove 7918 }, speed, easing, callback ); 7919 } 7920}); 7921 7922})(); 7923 7924/******************************************************************************/ 7925/*********************************** EFFECTS **********************************/ 7926/******************************************************************************/ 7927 7928(function() { 7929 7930$.extend( $.effects, { 7931 version: "1.9.1", 7932 7933 // Saves a set of properties in a data storage 7934 save: function( element, set ) { 7935 for( var i=0; i < set.length; i++ ) { 7936 if ( set[ i ] !== null ) { 7937 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 7938 } 7939 } 7940 }, 7941 7942 // Restores a set of previously saved properties from a data storage 7943 restore: function( element, set ) { 7944 var val, i; 7945 for( i=0; i < set.length; i++ ) { 7946 if ( set[ i ] !== null ) { 7947 val = element.data( dataSpace + set[ i ] ); 7948 // support: jQuery 1.6.2 7949 // http://bugs.jquery.com/ticket/9917 7950 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. 7951 // We can't differentiate between "" and 0 here, so we just assume 7952 // empty string since it's likely to be a more common value... 7953 if ( val === undefined ) { 7954 val = ""; 7955 } 7956 element.css( set[ i ], val ); 7957 } 7958 } 7959 }, 7960 7961 setMode: function( el, mode ) { 7962 if (mode === "toggle") { 7963 mode = el.is( ":hidden" ) ? "show" : "hide"; 7964 } 7965 return mode; 7966 }, 7967 7968 // Translates a [top,left] array into a baseline value 7969 // this should be a little more flexible in the future to handle a string & hash 7970 getBaseline: function( origin, original ) { 7971 var y, x; 7972 switch ( origin[ 0 ] ) { 7973 case "top": y = 0; break; 7974 case "middle": y = 0.5; break; 7975 case "bottom": y = 1; break; 7976 default: y = origin[ 0 ] / original.height; 7977 } 7978 switch ( origin[ 1 ] ) { 7979 case "left": x = 0; break; 7980 case "center": x = 0.5; break; 7981 case "right": x = 1; break; 7982 default: x = origin[ 1 ] / original.width; 7983 } 7984 return { 7985 x: x, 7986 y: y 7987 }; 7988 }, 7989 7990 // Wraps the element around a wrapper that copies position properties 7991 createWrapper: function( element ) { 7992 7993 // if the element is already wrapped, return it 7994 if ( element.parent().is( ".ui-effects-wrapper" )) { 7995 return element.parent(); 7996 } 7997 7998 // wrap the element 7999 var props = { 8000 width: element.outerWidth(true), 8001 height: element.outerHeight(true), 8002 "float": element.css( "float" ) 8003 }, 8004 wrapper = $( "<div></div>" ) 8005 .addClass( "ui-effects-wrapper" ) 8006 .css({ 8007 fontSize: "100%", 8008 background: "transparent", 8009 border: "none", 8010 margin: 0, 8011 padding: 0 8012 }), 8013 // Store the size in case width/height are defined in % - Fixes #5245 8014 size = { 8015 width: element.width(), 8016 height: element.height() 8017 }, 8018 active = document.activeElement; 8019 8020 // support: Firefox 8021 // Firefox incorrectly exposes anonymous content 8022 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 8023 try { 8024 active.id; 8025 } catch( e ) { 8026 active = document.body; 8027 } 8028 8029 element.wrap( wrapper ); 8030 8031 // Fixes #7595 - Elements lose focus when wrapped. 8032 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 8033 $( active ).focus(); 8034 } 8035 8036 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element 8037 8038 // transfer positioning properties to the wrapper 8039 if ( element.css( "position" ) === "static" ) { 8040 wrapper.css({ position: "relative" }); 8041 element.css({ position: "relative" }); 8042 } else { 8043 $.extend( props, { 8044 position: element.css( "position" ), 8045 zIndex: element.css( "z-index" ) 8046 }); 8047 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { 8048 props[ pos ] = element.css( pos ); 8049 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 8050 props[ pos ] = "auto"; 8051 } 8052 }); 8053 element.css({ 8054 position: "relative", 8055 top: 0, 8056 left: 0, 8057 right: "auto", 8058 bottom: "auto" 8059 }); 8060 } 8061 element.css(size); 8062 8063 return wrapper.css( props ).show(); 8064 }, 8065 8066 removeWrapper: function( element ) { 8067 var active = document.activeElement; 8068 8069 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 8070 element.parent().replaceWith( element ); 8071 8072 // Fixes #7595 - Elements lose focus when wrapped. 8073 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 8074 $( active ).focus(); 8075 } 8076 } 8077 8078 8079 return element; 8080 }, 8081 8082 setTransition: function( element, list, factor, value ) { 8083 value = value || {}; 8084 $.each( list, function( i, x ) { 8085 var unit = element.cssUnit( x ); 8086 if ( unit[ 0 ] > 0 ) { 8087 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 8088 } 8089 }); 8090 return value; 8091 } 8092}); 8093 8094// return an effect options object for the given parameters: 8095function _normalizeArguments( effect, options, speed, callback ) { 8096 8097 // allow passing all options as the first parameter 8098 if ( $.isPlainObject( effect ) ) { 8099 options = effect; 8100 effect = effect.effect; 8101 } 8102 8103 // convert to an object 8104 effect = { effect: effect }; 8105 8106 // catch (effect, null, ...) 8107 if ( options == null ) { 8108 options = {}; 8109 } 8110 8111 // catch (effect, callback) 8112 if ( $.isFunction( options ) ) { 8113 callback = options; 8114 speed = null; 8115 options = {}; 8116 } 8117 8118 // catch (effect, speed, ?) 8119 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 8120 callback = speed; 8121 speed = options; 8122 options = {}; 8123 } 8124 8125 // catch (effect, options, callback) 8126 if ( $.isFunction( speed ) ) { 8127 callback = speed; 8128 speed = null; 8129 } 8130 8131 // add options to effect 8132 if ( options ) { 8133 $.extend( effect, options ); 8134 } 8135 8136 speed = speed || options.duration; 8137 effect.duration = $.fx.off ? 0 : 8138 typeof speed === "number" ? speed : 8139 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 8140 $.fx.speeds._default; 8141 8142 effect.complete = callback || options.complete; 8143 8144 return effect; 8145} 8146 8147function standardSpeed( speed ) { 8148 // valid standard speeds 8149 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { 8150 return true; 8151 } 8152 8153 // invalid strings - treat as "normal" speed 8154 if ( typeof speed === "string" && !$.effects.effect[ speed ] ) { 8155 // TODO: remove in 2.0 (#7115) 8156 if ( backCompat && $.effects[ speed ] ) { 8157 return false;
8158 } 8159 return true; 8160 } 8161 8162 return false; 8163} 8164 8165$.fn.extend({ 8166 effect: function( /* effect, options, speed, callback */ ) { 8167 var args = _normalizeArguments.apply( this, arguments ), 8168 mode = args.mode, 8169 queue = args.queue, 8170 effectMethod = $.effects.effect[ args.effect ], 8171 8172 // DEPRECATED: remove in 2.0 (#7115) 8173 oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ]; 8174 8175 if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { 8176 // delegate to the original method (e.g., .show()) if possible 8177 if ( mode ) { 8178 return this[ mode ]( args.duration, args.complete ); 8179 } else { 8180 return this.each( function() { 8181 if ( args.complete ) { 8182 args.complete.call( this ); 8183 } 8184 }); 8185 } 8186 } 8187 8188 function run( next ) { 8189 var elem = $( this ), 8190 complete = args.complete, 8191 mode = args.mode; 8192 8193 function done() { 8194 if ( $.isFunction( complete ) ) { 8195 complete.call( elem[0] ); 8196 } 8197 if ( $.isFunction( next ) ) { 8198 next(); 8199 } 8200 } 8201 8202 // if the element is hiddden and mode is hide, 8203 // or element is visible and mode is show 8204 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 8205 done(); 8206 } else { 8207 effectMethod.call( elem[0], args, done ); 8208 } 8209 } 8210 8211 // TODO: remove this check in 2.0, effectMethod will always be true 8212 if ( effectMethod ) { 8213 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); 8214 } else { 8215 // DEPRECATED: remove in 2.0 (#7115) 8216 return oldEffectMethod.call(this, { 8217 options: args, 8218 duration: args.duration, 8219 callback: args.complete, 8220 mode: args.mode 8221 }); 8222 } 8223 }, 8224 8225 _show: $.fn.show, 8226 show: function( speed ) { 8227 if ( standardSpeed( speed ) ) { 8228 return this._show.apply( this, arguments ); 8229 } else { 8230 var args = _normalizeArguments.apply( this, arguments ); 8231 args.mode = "show"; 8232 return this.effect.call( this, args ); 8233 } 8234 }, 8235 8236 _hide: $.fn.hide, 8237 hide: function( speed ) { 8238 if ( standardSpeed( speed ) ) { 8239 return this._hide.apply( this, arguments ); 8240 } else { 8241 var args = _normalizeArguments.apply( this, arguments ); 8242 args.mode = "hide"; 8243 return this.effect.call( this, args ); 8244 } 8245 }, 8246 8247 // jQuery core overloads toggle and creates _toggle 8248 __toggle: $.fn.toggle, 8249 toggle: function( speed ) { 8250 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { 8251 return this.__toggle.apply( this, arguments ); 8252 } else { 8253 var args = _normalizeArguments.apply( this, arguments ); 8254 args.mode = "toggle"; 8255 return this.effect.call( this, args ); 8256 } 8257 }, 8258 8259 // helper functions 8260 cssUnit: function(key) { 8261 var style = this.css( key ), 8262 val = []; 8263 8264 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 8265 if ( style.indexOf( unit ) > 0 ) { 8266 val = [ parseFloat( style ), unit ]; 8267 } 8268 }); 8269 return val; 8270 } 8271}); 8272 8273})(); 8274 8275/******************************************************************************/ 8276/*********************************** EASING ***********************************/ 8277/******************************************************************************/ 8278 8279(function() { 8280 8281// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 8282 8283var baseEasings = {}; 8284 8285$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 8286 baseEasings[ name ] = function( p ) { 8287 return Math.pow( p, i + 2 ); 8288 }; 8289}); 8290 8291$.extend( baseEasings, { 8292 Sine: function ( p ) { 8293 return 1 - Math.cos( p * Math.PI / 2 ); 8294 }, 8295 Circ: function ( p ) { 8296 return 1 - Math.sqrt( 1 - p * p ); 8297 }, 8298 Elastic: function( p ) { 8299 return p === 0 || p === 1 ? p : 8300 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); 8301 }, 8302 Back: function( p ) { 8303 return p * p * ( 3 * p - 2 ); 8304 }, 8305 Bounce: function ( p ) { 8306 var pow2, 8307 bounce = 4; 8308 8309 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 8310 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 8311 } 8312}); 8313 8314$.each( baseEasings, function( name, easeIn ) { 8315 $.easing[ "easeIn" + name ] = easeIn; 8316 $.easing[ "easeOut" + name ] = function( p ) { 8317 return 1 - easeIn( 1 - p ); 8318 };
8319 $.easing[ "easeInOut" + name ] = function( p ) { 8320 return p < 0.5 ? 8321 easeIn( p * 2 ) / 2 : 8322 1 - easeIn( p * -2 + 2 ) / 2; 8323 }; 8324}); 8325 8326})(); 8327 8328})(jQuery)); 8329 8330(function( $, undefined ) { 8331 8332var uid = 0, 8333 hideProps = {}, 8334 showProps = {}; 8335 8336hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = 8337 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; 8338showProps.height = showProps.paddingTop = showProps.paddingBottom = 8339 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; 8340 8341$.widget( "ui.accordion", { 8342 version: "1.9.1", 8343 options: { 8344 active: 0, 8345 animate: {}, 8346 collapsible: false, 8347 event: "click", 8348 header: "> li > :first-child,> :not(li):even", 8349 heightStyle: "auto", 8350 icons: { 8351 activeHeader: "ui-icon-triangle-1-s", 8352 header: "ui-icon-triangle-1-e" 8353 }, 8354 8355 // callbacks 8356 activate: null, 8357 beforeActivate: null 8358 }, 8359 8360 _create: function() { 8361 var accordionId = this.accordionId = "ui-accordion-" + 8362 (this.element.attr( "id" ) || ++uid), 8363 options = this.options; 8364 8365 this.prevShow = this.prevHide = $(); 8366 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ); 8367 8368 this.headers = this.element.find( options.header ) 8369 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); 8370 this._hoverable( this.headers ); 8371 this._focusable( this.headers ); 8372 8373 this.headers.next() 8374 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) 8375 .hide(); 8376 8377 // don't allow collapsible: false and active: false / null 8378 if ( !options.collapsible && (options.active === false || options.active == null) ) { 8379 options.active = 0; 8380 } 8381 // handle negative values 8382 if ( options.active < 0 ) { 8383 options.active += this.headers.length; 8384 } 8385 this.active = this._findActive( options.active ) 8386 .addClass( "ui-accordion-header-active ui-state-active" ) 8387 .toggleClass( "ui-corner-all ui-corner-top" ); 8388 this.active.next() 8389 .addClass( "ui-accordion-content-active" ) 8390 .show(); 8391 8392 this._createIcons(); 8393 this.refresh(); 8394 8395 // ARIA 8396 this.element.attr( "role", "tablist" ); 8397 8398 this.headers 8399 .attr( "role", "tab" ) 8400 .each(function( i ) { 8401 var header = $( this ), 8402 headerId = header.attr( "id" ), 8403 panel = header.next(), 8404 panelId = panel.attr( "id" ); 8405 if ( !headerId ) { 8406 headerId = accordionId + "-header-" + i; 8407 header.attr( "id", headerId ); 8408 } 8409 if ( !panelId ) { 8410 panelId = accordionId + "-panel-" + i; 8411 panel.attr( "id", panelId ); 8412 } 8413 header.attr( "aria-controls", panelId ); 8414 panel.attr( "aria-labelledby", headerId ); 8415 }) 8416 .next() 8417 .attr( "role", "tabpanel" ); 8418 8419 this.headers 8420 .not( this.active ) 8421 .attr({ 8422 "aria-selected": "false", 8423 tabIndex: -1 8424 }) 8425 .next() 8426 .attr({ 8427 "aria-expanded": "false", 8428 "aria-hidden": "true" 8429 }) 8430 .hide(); 8431 8432 // make sure at least one header is in the tab order 8433 if ( !this.active.length ) { 8434 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 8435 } else { 8436 this.active.attr({ 8437 "aria-selected": "true", 8438 tabIndex: 0 8439 }) 8440 .next() 8441 .attr({ 8442 "aria-expanded": "true", 8443 "aria-hidden": "false" 8444 }); 8445 } 8446 8447 this._on( this.headers, { keydown: "_keydown" }); 8448 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); 8449 this._setupEvents( options.event ); 8450 }, 8451 8452 _getCreateEventData: function() { 8453 return { 8454 header: this.active, 8455 content: !this.active.length ? $() : this.active.next() 8456 }; 8457 }, 8458 8459 _createIcons: function() { 8460 var icons = this.options.icons; 8461 if ( icons ) { 8462 $( "<span>" ) 8463 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) 8464 .prependTo( this.headers ); 8465 this.active.children( ".ui-accordion-header-icon" ) 8466 .removeClass( icons.header ) 8467 .addClass( icons.activeHeader ); 8468 this.headers.addClass( "ui-accordion-icons" ); 8469 } 8470 }, 8471 8472 _destroyIcons: function() { 8473 this.headers 8474 .removeClass( "ui-accordion-icons" ) 8475 .children( ".ui-accordion-header-icon" ) 8476 .remove(); 8477 }, 8478 8479 _destroy: function() { 8480 var contents; 8481 8482 // clean up main element 8483 this.element 8484 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) 8485 .removeAttr( "role" ); 8486 8487 // clean up headers 8488 this.headers 8489 .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" ) 8490 .removeAttr( "role" ) 8491 .removeAttr( "aria-selected" ) 8492 .removeAttr( "aria-controls" ) 8493 .removeAttr( "tabIndex" ) 8494 .each(function() { 8495 if ( /^ui-accordion/.test( this.id ) ) { 8496 this.removeAttribute( "id" ); 8497 } 8498 }); 8499 this._destroyIcons(); 8500 8501 // clean up content panels 8502 contents = this.headers.next() 8503 .css( "display", "" ) 8504 .removeAttr( "role" ) 8505 .removeAttr( "aria-expanded" ) 8506 .removeAttr( "aria-hidden" ) 8507 .removeAttr( "aria-labelledby" ) 8508 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) 8509 .each(function() { 8510 if ( /^ui-accordion/.test( this.id ) ) { 8511 this.removeAttribute( "id" ); 8512 } 8513 }); 8514 if ( this.options.heightStyle !== "content" ) { 8515 contents.css( "height", "" ); 8516 } 8517 }, 8518 8519 _setOption: function( key, value ) { 8520 if ( key === "active" ) { 8521 // _activate() will handle invalid values and update this.options 8522 this._activate( value ); 8523 return; 8524 } 8525 8526 if ( key === "event" ) { 8527 if ( this.options.event ) { 8528 this._off( this.headers, this.options.event ); 8529 } 8530 this._setupEvents( value ); 8531 } 8532 8533 this._super( key, value ); 8534 8535 // setting collapsible: false while collapsed; open first panel 8536 if ( key === "collapsible" && !value && this.options.active === false ) { 8537 this._activate( 0 ); 8538 } 8539 8540 if ( key === "icons" ) { 8541 this._destroyIcons(); 8542 if ( value ) { 8543 this._createIcons(); 8544 } 8545 } 8546 8547 // #5332 - opacity doesn't cascade to positioned elements in IE 8548 // so we need to add the disabled class to the headers and panels 8549 if ( key === "disabled" ) { 8550 this.headers.add( this.headers.next() ) 8551 .toggleClass( "ui-state-disabled", !!value ); 8552 } 8553 }, 8554 8555 _keydown: function( event ) { 8556 if ( event.altKey || event.ctrlKey ) { 8557 return; 8558 } 8559 8560 var keyCode = $.ui.keyCode, 8561 length = this.headers.length, 8562 currentIndex = this.headers.index( event.target ), 8563 toFocus = false;
vendor: 4,217 bytes, lines 8564-8719
8564 8565 switch ( event.keyCode ) { 8566 case keyCode.RIGHT: 8567 case keyCode.DOWN: 8568 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 8569 break; 8570 case keyCode.LEFT: 8571 case keyCode.UP: 8572 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 8573 break; 8574 case keyCode.SPACE: 8575 case keyCode.ENTER: 8576 this._eventHandler( event ); 8577 break; 8578 case keyCode.HOME: 8579 toFocus = this.headers[ 0 ]; 8580 break; 8581 case keyCode.END: 8582 toFocus = this.headers[ length - 1 ]; 8583 break; 8584 } 8585 8586 if ( toFocus ) { 8587 $( event.target ).attr( "tabIndex", -1 ); 8588 $( toFocus ).attr( "tabIndex", 0 ); 8589 toFocus.focus(); 8590 event.preventDefault(); 8591 } 8592 }, 8593 8594 _panelKeyDown : function( event ) { 8595 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 8596 $( event.currentTarget ).prev().focus(); 8597 } 8598 }, 8599 8600 refresh: function() { 8601 var maxHeight, overflow, 8602 heightStyle = this.options.heightStyle, 8603 parent = this.element.parent(); 8604 8605 8606 if ( heightStyle === "fill" ) { 8607 // IE 6 treats height like minHeight, so we need to turn off overflow 8608 // in order to get a reliable height 8609 // we use the minHeight support test because we assume that only 8610 // browsers that don't support minHeight will treat height as minHeight 8611 if ( !$.support.minHeight ) { 8612 overflow = parent.css( "overflow" ); 8613 parent.css( "overflow", "hidden"); 8614 } 8615 maxHeight = parent.height(); 8616 this.element.siblings( ":visible" ).each(function() { 8617 var elem = $( this ), 8618 position = elem.css( "position" ); 8619 8620 if ( position === "absolute" || position === "fixed" ) { 8621 return; 8622 } 8623 maxHeight -= elem.outerHeight( true ); 8624 }); 8625 if ( overflow ) { 8626 parent.css( "overflow", overflow ); 8627 } 8628 8629 this.headers.each(function() { 8630 maxHeight -= $( this ).outerHeight( true ); 8631 }); 8632 8633 this.headers.next() 8634 .each(function() { 8635 $( this ).height( Math.max( 0, maxHeight - 8636 $( this ).innerHeight() + $( this ).height() ) ); 8637 }) 8638 .css( "overflow", "auto" ); 8639 } else if ( heightStyle === "auto" ) { 8640 maxHeight = 0; 8641 this.headers.next() 8642 .each(function() { 8643 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 8644 }) 8645 .height( maxHeight ); 8646 } 8647 }, 8648 8649 _activate: function( index ) { 8650 var active = this._findActive( index )[ 0 ]; 8651 8652 // trying to activate the already active panel 8653 if ( active === this.active[ 0 ] ) { 8654 return; 8655 } 8656 8657 // trying to collapse, simulate a click on the currently active header 8658 active = active || this.active[ 0 ]; 8659 8660 this._eventHandler({ 8661 target: active, 8662 currentTarget: active, 8663 preventDefault: $.noop 8664 }); 8665 }, 8666 8667 _findActive: function( selector ) { 8668 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 8669 }, 8670 8671 _setupEvents: function( event ) { 8672 var events = {}; 8673 if ( !event ) { 8674 return; 8675 } 8676 $.each( event.split(" "), function( index, eventName ) { 8677 events[ eventName ] = "_eventHandler"; 8678 }); 8679 this._on( this.headers, events ); 8680 }, 8681 8682 _eventHandler: function( event ) { 8683 var options = this.options, 8684 active = this.active, 8685 clicked = $( event.currentTarget ), 8686 clickedIsActive = clicked[ 0 ] === active[ 0 ], 8687 collapsing = clickedIsActive && options.collapsible, 8688 toShow = collapsing ? $() : clicked.next(), 8689 toHide = active.next(), 8690 eventData = { 8691 oldHeader: active, 8692 oldPanel: toHide, 8693 newHeader: collapsing ? $() : clicked, 8694 newPanel: toShow 8695 }; 8696 8697 event.preventDefault(); 8698 8699 if ( 8700 // click on active header, but not collapsible 8701 ( clickedIsActive && !options.collapsible ) || 8702 // allow canceling activation 8703 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 8704 return; 8705 } 8706 8707 options.active = collapsing ? false : this.headers.index( clicked ); 8708 8709 // when the call to ._toggle() comes after the class changes 8710 // it causes a very odd bug in IE 8 (see #6720) 8711 this.active = clickedIsActive ? $() : clicked; 8712 this._toggle( eventData ); 8713 8714 // switch classes 8715 // corner classes on the previously active header stay after the animation 8716 active.removeClass( "ui-accordion-header-active ui-state-active" ); 8717 if ( options.icons ) { 8718 active.children( ".ui-accordion-header-icon" ) 8719 .removeClass( options.icons.activeHeader )
8720 .addClass( options.icons.header ); 8721 } 8722 8723 if ( !clickedIsActive ) { 8724 clicked 8725 .removeClass( "ui-corner-all" ) 8726 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); 8727 if ( options.icons ) { 8728 clicked.children( ".ui-accordion-header-icon" ) 8729 .removeClass( options.icons.header ) 8730 .addClass( options.icons.activeHeader ); 8731 } 8732 8733 clicked 8734 .next() 8735 .addClass( "ui-accordion-content-active" ); 8736 } 8737 }, 8738 8739 _toggle: function( data ) { 8740 var toShow = data.newPanel, 8741 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 8742 8743 // handle activating a panel during the animation for another activation 8744 this.prevShow.add( this.prevHide ).stop( true, true ); 8745 this.prevShow = toShow; 8746 this.prevHide = toHide; 8747 8748 if ( this.options.animate ) { 8749 this._animate( toShow, toHide, data ); 8750 } else { 8751 toHide.hide(); 8752 toShow.show(); 8753 this._toggleComplete( data ); 8754 } 8755 8756 toHide.attr({ 8757 "aria-expanded": "false", 8758 "aria-hidden": "true" 8759 }); 8760 toHide.prev().attr( "aria-selected", "false" ); 8761 // if we're switching panels, remove the old header from the tab order 8762 // if we're opening from collapsed state, remove the previous header from the tab order 8763 // if we're collapsing, then keep the collapsing header in the tab order 8764 if ( toShow.length && toHide.length ) { 8765 toHide.prev().attr( "tabIndex", -1 ); 8766 } else if ( toShow.length ) { 8767 this.headers.filter(function() { 8768 return $( this ).attr( "tabIndex" ) === 0; 8769 }) 8770 .attr( "tabIndex", -1 ); 8771 } 8772 8773 toShow 8774 .attr({ 8775 "aria-expanded": "true", 8776 "aria-hidden": "false" 8777 }) 8778 .prev() 8779 .attr({ 8780 "aria-selected": "true", 8781 tabIndex: 0 8782 }); 8783 }, 8784 8785 _animate: function( toShow, toHide, data ) { 8786 var total, easing, duration, 8787 that = this, 8788 adjust = 0, 8789 down = toShow.length && 8790 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 8791 animate = this.options.animate || {}, 8792 options = down && animate.down || animate, 8793 complete = function() { 8794 that._toggleComplete( data ); 8795 }; 8796 8797 if ( typeof options === "number" ) { 8798 duration = options; 8799 } 8800 if ( typeof options === "string" ) { 8801 easing = options; 8802 } 8803 // fall back from options to animation in case of partial down settings 8804 easing = easing || options.easing || animate.easing; 8805 duration = duration || options.duration || animate.duration; 8806 8807 if ( !toHide.length ) { 8808 return toShow.animate( showProps, duration, easing, complete ); 8809 } 8810 if ( !toShow.length ) { 8811 return toHide.animate( hideProps, duration, easing, complete ); 8812 } 8813 8814 total = toShow.show().outerHeight(); 8815 toHide.animate( hideProps, { 8816 duration: duration, 8817 easing: easing, 8818 step: function( now, fx ) { 8819 fx.now = Math.round( now ); 8820 } 8821 }); 8822 toShow 8823 .hide() 8824 .animate( showProps, { 8825 duration: duration, 8826 easing: easing, 8827 complete: complete, 8828 step: function( now, fx ) { 8829 fx.now = Math.round( now ); 8830 if ( fx.prop !== "height" ) { 8831 adjust += fx.now; 8832 } else if ( that.options.heightStyle !== "content" ) { 8833 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 8834 adjust = 0; 8835 } 8836 } 8837 }); 8838 }, 8839 8840 _toggleComplete: function( data ) { 8841 var toHide = data.oldPanel; 8842 8843 toHide 8844 .removeClass( "ui-accordion-content-active" ) 8845 .prev() 8846 .removeClass( "ui-corner-top" ) 8847 .addClass( "ui-corner-all" ); 8848 8849 // Work around for rendering bug in IE (#5421) 8850 if ( toHide.length ) { 8851 toHide.parent()[0].className = toHide.parent()[0].className; 8852 } 8853 8854 this._trigger( "activate", null, data ); 8855 } 8856}); 8857 8858 8859 8860// DEPRECATED 8861if ( $.uiBackCompat !== false ) { 8862 // navigation options 8863 (function( $, prototype ) { 8864 $.extend( prototype.options, { 8865 navigation: false, 8866 navigationFilter: function() { 8867 return this.href.toLowerCase() === location.href.toLowerCase(); 8868 } 8869 }); 8870 8871 var _create = prototype._create; 8872 prototype._create = function() { 8873 if ( this.options.navigation ) { 8874 var that = this, 8875 headers = this.element.find( this.options.header ), 8876 content = headers.next(), 8877 current = headers.add( content ) 8878 .find( "a" ) 8879 .filter( this.options.navigationFilter ) 8880 [ 0 ]; 8881 if ( current ) { 8882 headers.add( content ).each( function( index ) { 8883 if ( $.contains( this, current ) ) { 8884 that.options.active = Math.floor( index / 2 ); 8885 return false;
8886 } 8887 }); 8888 } 8889 } 8890 _create.call( this ); 8891 }; 8892 }( jQuery, jQuery.ui.accordion.prototype ) ); 8893 8894 // height options 8895 (function( $, prototype ) { 8896 $.extend( prototype.options, { 8897 heightStyle: null, // remove default so we fall back to old values 8898 autoHeight: true, // use heightStyle: "auto" 8899 clearStyle: false, // use heightStyle: "content" 8900 fillSpace: false // use heightStyle: "fill" 8901 }); 8902 8903 var _create = prototype._create, 8904 _setOption = prototype._setOption; 8905 8906 $.extend( prototype, { 8907 _create: function() { 8908 this.options.heightStyle = this.options.heightStyle || 8909 this._mergeHeightStyle(); 8910 8911 _create.call( this ); 8912 }, 8913 8914 _setOption: function( key ) { 8915 if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { 8916 this.options.heightStyle = this._mergeHeightStyle(); 8917 } 8918 _setOption.apply( this, arguments ); 8919 }, 8920 8921 _mergeHeightStyle: function() { 8922 var options = this.options; 8923 8924 if ( options.fillSpace ) { 8925 return "fill"; 8926 } 8927 8928 if ( options.clearStyle ) { 8929 return "content"; 8930 } 8931 8932 if ( options.autoHeight ) { 8933 return "auto"; 8934 } 8935 } 8936 }); 8937 }( jQuery, jQuery.ui.accordion.prototype ) ); 8938 8939 // icon options 8940 (function( $, prototype ) { 8941 $.extend( prototype.options.icons, { 8942 activeHeader: null, // remove default so we fall back to old values 8943 headerSelected: "ui-icon-triangle-1-s" 8944 }); 8945 8946 var _createIcons = prototype._createIcons; 8947 prototype._createIcons = function() { 8948 if ( this.options.icons ) { 8949 this.options.icons.activeHeader = this.options.icons.activeHeader || 8950 this.options.icons.headerSelected; 8951 } 8952 _createIcons.call( this ); 8953 }; 8954 }( jQuery, jQuery.ui.accordion.prototype ) ); 8955 8956 // expanded active option, activate method 8957 (function( $, prototype ) { 8958 prototype.activate = prototype._activate; 8959 8960 var _findActive = prototype._findActive; 8961 prototype._findActive = function( index ) { 8962 if ( index === -1 ) { 8963 index = false; 8964 } 8965 if ( index && typeof index !== "number" ) { 8966 index = this.headers.index( this.headers.filter( index ) ); 8967 if ( index === -1 ) { 8968 index = false; 8969 } 8970 } 8971 return _findActive.call( this, index ); 8972 }; 8973 }( jQuery, jQuery.ui.accordion.prototype ) ); 8974 8975 // resize method 8976 jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; 8977 8978 // change events 8979 (function( $, prototype ) { 8980 $.extend( prototype.options, { 8981 change: null, 8982 changestart: null 8983 }); 8984 8985 var _trigger = prototype._trigger; 8986 prototype._trigger = function( type, event, data ) { 8987 var ret = _trigger.apply( this, arguments ); 8988 if ( !ret ) { 8989 return false; 8990 } 8991 8992 if ( type === "beforeActivate" ) { 8993 ret = _trigger.call( this, "changestart", event, { 8994 oldHeader: data.oldHeader, 8995 oldContent: data.oldPanel, 8996 newHeader: data.newHeader, 8997 newContent: data.newPanel 8998 }); 8999 } else if ( type === "activate" ) { 9000 ret = _trigger.call( this, "change", event, { 9001 oldHeader: data.oldHeader, 9002 oldContent: data.oldPanel, 9003 newHeader: data.newHeader, 9004 newContent: data.newPanel 9005 }); 9006 } 9007 return ret; 9008 }; 9009 }( jQuery, jQuery.ui.accordion.prototype ) ); 9010 9011 // animated option 9012 // NOTE: this only provides support for "slide", "bounceslide", and easings 9013 // not the full $.ui.accordion.animations API 9014 (function( $, prototype ) { 9015 $.extend( prototype.options, { 9016 animate: null, 9017 animated: "slide" 9018 }); 9019 9020 var _create = prototype._create; 9021 prototype._create = function() { 9022 var options = this.options; 9023 if ( options.animate === null ) { 9024 if ( !options.animated ) { 9025 options.animate = false; 9026 } else if ( options.animated === "slide" ) { 9027 options.animate = 300; 9028 } else if ( options.animated === "bounceslide" ) { 9029 options.animate = { 9030 duration: 200, 9031 down: { 9032 easing: "easeOutBounce", 9033 duration: 1000 9034 } 9035 }; 9036 } else { 9037 options.animate = options.animated; 9038 } 9039 } 9040 9041 _create.call( this ); 9042 }; 9043 }( jQuery, jQuery.ui.accordion.prototype ) ); 9044} 9045 9046})( jQuery ); 9047 9048(function( $, undefined ) { 9049 9050// used to prevent race conditions with remote data sources 9051var requestIndex = 0; 9052 9053$.widget( "ui.autocomplete", { 9054 version: "1.9.1", 9055 defaultElement: "<input>", 9056 options: { 9057 appendTo: "body", 9058 autoFocus: false, 9059 delay: 300, 9060 minLength: 1, 9061 position: { 9062 my: "left top", 9063 at: "left bottom", 9064 collision: "none" 9065 }, 9066 source: null, 9067 9068 // callbacks 9069 change: null, 9070 close: null, 9071 focus: null, 9072 open: null, 9073 response: null, 9074 search: null, 9075 select: null 9076 }, 9077 9078 pending: 0, 9079 9080 _create: function() { 9081 // Some browsers only repeat keydown events, not keypress events, 9082 // so we use the suppressKeyPress flag to determine if we've already 9083 // handled the keydown event. #7269 9084 // Unfortunately the code for & in keypress is the same as the up arrow, 9085 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 9086 // events when we know the keydown event was used to modify the 9087 // search term. #7799 9088 var suppressKeyPress, suppressKeyPressRepeat, suppressInput; 9089 9090 this.isMultiLine = this._isMultiLine(); 9091 this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; 9092 this.isNewMenu = true; 9093 9094 this.element 9095 .addClass( "ui-autocomplete-input" ) 9096 .attr( "autocomplete", "off" ); 9097 9098 this._on( this.element, { 9099 keydown: function( event ) { 9100 if ( this.element.prop( "readOnly" ) ) { 9101 suppressKeyPress = true; 9102 suppressInput = true; 9103 suppressKeyPressRepeat = true; 9104 return; 9105 } 9106 9107 suppressKeyPress = false;
vendor: 4,280 bytes, lines 9108-9259
9108 suppressInput = false; 9109 suppressKeyPressRepeat = false; 9110 var keyCode = $.ui.keyCode; 9111 switch( event.keyCode ) { 9112 case keyCode.PAGE_UP: 9113 suppressKeyPress = true; 9114 this._move( "previousPage", event ); 9115 break; 9116 case keyCode.PAGE_DOWN: 9117 suppressKeyPress = true; 9118 this._move( "nextPage", event ); 9119 break; 9120 case keyCode.UP: 9121 suppressKeyPress = true; 9122 this._keyEvent( "previous", event ); 9123 break; 9124 case keyCode.DOWN: 9125 suppressKeyPress = true; 9126 this._keyEvent( "next", event ); 9127 break; 9128 case keyCode.ENTER: 9129 case keyCode.NUMPAD_ENTER: 9130 // when menu is open and has focus 9131 if ( this.menu.active ) { 9132 // #6055 - Opera still allows the keypress to occur 9133 // which causes forms to submit 9134 suppressKeyPress = true; 9135 event.preventDefault(); 9136 this.menu.select( event ); 9137 } 9138 break; 9139 case keyCode.TAB: 9140 if ( this.menu.active ) { 9141 this.menu.select( event ); 9142 } 9143 break; 9144 case keyCode.ESCAPE: 9145 if ( this.menu.element.is( ":visible" ) ) { 9146 this._value( this.term ); 9147 this.close( event ); 9148 // Different browsers have different default behavior for escape 9149 // Single press can mean undo or clear 9150 // Double press in IE means clear the whole form 9151 event.preventDefault(); 9152 } 9153 break; 9154 default: 9155 suppressKeyPressRepeat = true; 9156 // search timeout should be triggered before the input value is changed 9157 this._searchTimeout( event ); 9158 break; 9159 } 9160 }, 9161 keypress: function( event ) { 9162 if ( suppressKeyPress ) { 9163 suppressKeyPress = false; 9164 event.preventDefault(); 9165 return; 9166 } 9167 if ( suppressKeyPressRepeat ) { 9168 return; 9169 } 9170 9171 // replicate some key handlers to allow them to repeat in Firefox and Opera 9172 var keyCode = $.ui.keyCode; 9173 switch( event.keyCode ) { 9174 case keyCode.PAGE_UP: 9175 this._move( "previousPage", event ); 9176 break; 9177 case keyCode.PAGE_DOWN: 9178 this._move( "nextPage", event ); 9179 break; 9180 case keyCode.UP: 9181 this._keyEvent( "previous", event ); 9182 break; 9183 case keyCode.DOWN: 9184 this._keyEvent( "next", event ); 9185 break; 9186 } 9187 }, 9188 input: function( event ) { 9189 if ( suppressInput ) { 9190 suppressInput = false; 9191 event.preventDefault(); 9192 return; 9193 } 9194 this._searchTimeout( event ); 9195 }, 9196 focus: function() { 9197 this.selectedItem = null; 9198 this.previous = this._value(); 9199 }, 9200 blur: function( event ) { 9201 if ( this.cancelBlur ) { 9202 delete this.cancelBlur; 9203 return; 9204 } 9205 9206 clearTimeout( this.searching ); 9207 this.close( event ); 9208 this._change( event ); 9209 } 9210 }); 9211 9212 this._initSource(); 9213 this.menu = $( "<ul>" ) 9214 .addClass( "ui-autocomplete" ) 9215 .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] ) 9216 .menu({ 9217 // custom key handling for now 9218 input: $(), 9219 // disable ARIA support, the live region takes care of that 9220 role: null 9221 }) 9222 .zIndex( this.element.zIndex() + 1 ) 9223 .hide() 9224 .data( "menu" ); 9225 9226 this._on( this.menu.element, { 9227 mousedown: function( event ) { 9228 // prevent moving focus out of the text field 9229 event.preventDefault(); 9230 9231 // IE doesn't prevent moving focus even with event.preventDefault() 9232 // so we set a flag to know when we should ignore the blur event 9233 this.cancelBlur = true; 9234 this._delay(function() { 9235 delete this.cancelBlur; 9236 }); 9237 9238 // clicking on the scrollbar causes focus to shift to the body 9239 // but we can't detect a mouseup or a click immediately afterward 9240 // so we have to track the next mousedown and close the menu if 9241 // the user clicks somewhere outside of the autocomplete 9242 var menuElement = this.menu.element[ 0 ]; 9243 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { 9244 this._delay(function() { 9245 var that = this; 9246 this.document.one( "mousedown", function( event ) { 9247 if ( event.target !== that.element[ 0 ] && 9248 event.target !== menuElement && 9249 !$.contains( menuElement, event.target ) ) { 9250 that.close(); 9251 } 9252 }); 9253 }); 9254 } 9255 }, 9256 menufocus: function( event, ui ) { 9257 // #7024 - Prevent accidental activation of menu items in Firefox 9258 if ( this.isNewMenu ) { 9259 this.isNewMenu = false;
9260 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 9261 this.menu.blur(); 9262 9263 this.document.one( "mousemove", function() { 9264 $( event.target ).trigger( event.originalEvent ); 9265 }); 9266 9267 return; 9268 } 9269 } 9270 9271 // back compat for _renderItem using item.autocomplete, via #7810 9272 // TODO remove the fallback, see #8156 9273 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ); 9274 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 9275 // use value to match what will end up in the input, if it was a key event 9276 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 9277 this._value( item.value ); 9278 } 9279 } else { 9280 // Normally the input is populated with the item's value as the 9281 // menu is navigated, causing screen readers to notice a change and 9282 // announce the item. Since the focus event was canceled, this doesn't 9283 // happen, so we update the live region so that screen readers can 9284 // still notice the change and announce it. 9285 this.liveRegion.text( item.value ); 9286 } 9287 }, 9288 menuselect: function( event, ui ) { 9289 // back compat for _renderItem using item.autocomplete, via #7810 9290 // TODO remove the fallback, see #8156 9291 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ), 9292 previous = this.previous; 9293 9294 // only trigger when focus was lost (click on menu) 9295 if ( this.element[0] !== this.document[0].activeElement ) { 9296 this.element.focus(); 9297 this.previous = previous; 9298 // #6109 - IE triggers two focus events and the second 9299 // is asynchronous, so we need to reset the previous 9300 // term synchronously and asynchronously :-( 9301 this._delay(function() { 9302 this.previous = previous; 9303 this.selectedItem = item; 9304 }); 9305 } 9306 9307 if ( false !== this._trigger( "select", event, { item: item } ) ) { 9308 this._value( item.value ); 9309 } 9310 // reset the term after the select event 9311 // this allows custom select handling to work properly 9312 this.term = this._value(); 9313 9314 this.close( event ); 9315 this.selectedItem = item; 9316 } 9317 }); 9318 9319 this.liveRegion = $( "<span>", { 9320 role: "status", 9321 "aria-live": "polite" 9322 }) 9323 .addClass( "ui-helper-hidden-accessible" ) 9324 .insertAfter( this.element ); 9325 9326 if ( $.fn.bgiframe ) { 9327 this.menu.element.bgiframe(); 9328 } 9329 9330 // turning off autocomplete prevents the browser from remembering the 9331 // value when navigating through history, so we re-enable autocomplete 9332 // if the page is unloaded before the widget is destroyed. #7790 9333 this._on( this.window, { 9334 beforeunload: function() { 9335 this.element.removeAttr( "autocomplete" ); 9336 } 9337 }); 9338 }, 9339 9340 _destroy: function() { 9341 clearTimeout( this.searching ); 9342 this.element 9343 .removeClass( "ui-autocomplete-input" ) 9344 .removeAttr( "autocomplete" ); 9345 this.menu.element.remove(); 9346 this.liveRegion.remove(); 9347 }, 9348 9349 _setOption: function( key, value ) { 9350 this._super( key, value ); 9351 if ( key === "source" ) { 9352 this._initSource(); 9353 } 9354 if ( key === "appendTo" ) { 9355 this.menu.element.appendTo( this.document.find( value || "body" )[0] ); 9356 } 9357 if ( key === "disabled" && value && this.xhr ) { 9358 this.xhr.abort(); 9359 } 9360 }, 9361 9362 _isMultiLine: function() { 9363 // Textareas are always multi-line 9364 if ( this.element.is( "textarea" ) ) { 9365 return true; 9366 } 9367 // Inputs are always single-line, even if inside a contentEditable element 9368 // IE also treats inputs as contentEditable 9369 if ( this.element.is( "input" ) ) { 9370 return false; 9371 } 9372 // All other element types are determined by whether or not they're contentEditable 9373 return this.element.prop( "isContentEditable" ); 9374 }, 9375 9376 _initSource: function() { 9377 var array, url, 9378 that = this; 9379 if ( $.isArray(this.options.source) ) { 9380 array = this.options.source; 9381 this.source = function( request, response ) { 9382 response( $.ui.autocomplete.filter( array, request.term ) ); 9383 }; 9384 } else if ( typeof this.options.source === "string" ) { 9385 url = this.options.source; 9386 this.source = function( request, response ) { 9387 if ( that.xhr ) { 9388 that.xhr.abort(); 9389 } 9390 that.xhr = $.ajax({ 9391 url: url, 9392 data: request, 9393 dataType: "json", 9394 success: function( data ) { 9395 response( data ); 9396 }, 9397 error: function() { 9398 response( [] ); 9399 } 9400 }); 9401 }; 9402 } else { 9403 this.source = this.options.source; 9404 } 9405 }, 9406 9407 _searchTimeout: function( event ) { 9408 clearTimeout( this.searching ); 9409 this.searching = this._delay(function() { 9410 // only search if the value has changed
vendor: 12,812 bytes, lines 9411-9886
9411 if ( this.term !== this._value() ) { 9412 this.selectedItem = null; 9413 this.search( null, event ); 9414 } 9415 }, this.options.delay ); 9416 }, 9417 9418 search: function( value, event ) { 9419 value = value != null ? value : this._value(); 9420 9421 // always save the actual value, not the one passed as an argument 9422 this.term = this._value(); 9423 9424 if ( value.length < this.options.minLength ) { 9425 return this.close( event ); 9426 } 9427 9428 if ( this._trigger( "search", event ) === false ) { 9429 return; 9430 } 9431 9432 return this._search( value ); 9433 }, 9434 9435 _search: function( value ) { 9436 this.pending++; 9437 this.element.addClass( "ui-autocomplete-loading" ); 9438 this.cancelSearch = false; 9439 9440 this.source( { term: value }, this._response() ); 9441 }, 9442 9443 _response: function() { 9444 var that = this, 9445 index = ++requestIndex; 9446 9447 return function( content ) { 9448 if ( index === requestIndex ) { 9449 that.__response( content ); 9450 } 9451 9452 that.pending--; 9453 if ( !that.pending ) { 9454 that.element.removeClass( "ui-autocomplete-loading" ); 9455 } 9456 }; 9457 }, 9458 9459 __response: function( content ) { 9460 if ( content ) { 9461 content = this._normalize( content ); 9462 } 9463 this._trigger( "response", null, { content: content } ); 9464 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 9465 this._suggest( content ); 9466 this._trigger( "open" ); 9467 } else { 9468 // use ._close() instead of .close() so we don't cancel future searches 9469 this._close(); 9470 } 9471 }, 9472 9473 close: function( event ) { 9474 this.cancelSearch = true; 9475 this._close( event ); 9476 }, 9477 9478 _close: function( event ) { 9479 if ( this.menu.element.is( ":visible" ) ) { 9480 this.menu.element.hide(); 9481 this.menu.blur(); 9482 this.isNewMenu = true; 9483 this._trigger( "close", event ); 9484 } 9485 }, 9486 9487 _change: function( event ) { 9488 if ( this.previous !== this._value() ) { 9489 this._trigger( "change", event, { item: this.selectedItem } ); 9490 } 9491 }, 9492 9493 _normalize: function( items ) { 9494 // assume all items have the right format when the first item is complete 9495 if ( items.length && items[0].label && items[0].value ) { 9496 return items; 9497 } 9498 return $.map( items, function( item ) { 9499 if ( typeof item === "string" ) { 9500 return { 9501 label: item, 9502 value: item 9503 }; 9504 } 9505 return $.extend({ 9506 label: item.label || item.value, 9507 value: item.value || item.label 9508 }, item ); 9509 }); 9510 }, 9511 9512 _suggest: function( items ) { 9513 var ul = this.menu.element 9514 .empty() 9515 .zIndex( this.element.zIndex() + 1 ); 9516 this._renderMenu( ul, items ); 9517 this.menu.refresh(); 9518 9519 // size and position menu 9520 ul.show(); 9521 this._resizeMenu(); 9522 ul.position( $.extend({ 9523 of: this.element 9524 }, this.options.position )); 9525 9526 if ( this.options.autoFocus ) { 9527 this.menu.next(); 9528 } 9529 }, 9530 9531 _resizeMenu: function() { 9532 var ul = this.menu.element; 9533 ul.outerWidth( Math.max( 9534 // Firefox wraps long text (possibly a rounding bug) 9535 // so we add 1px to avoid the wrapping (#7513) 9536 ul.width( "" ).outerWidth() + 1, 9537 this.element.outerWidth() 9538 ) ); 9539 }, 9540 9541 _renderMenu: function( ul, items ) { 9542 var that = this; 9543 $.each( items, function( index, item ) { 9544 that._renderItemData( ul, item ); 9545 }); 9546 }, 9547 9548 _renderItemData: function( ul, item ) { 9549 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 9550 }, 9551 9552 _renderItem: function( ul, item ) { 9553 return $( "<li>" ) 9554 .append( $( "<a>" ).text( item.label ) ) 9555 .appendTo( ul ); 9556 }, 9557 9558 _move: function( direction, event ) { 9559 if ( !this.menu.element.is( ":visible" ) ) { 9560 this.search( null, event ); 9561 return; 9562 } 9563 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 9564 this.menu.isLastItem() && /^next/.test( direction ) ) { 9565 this._value( this.term ); 9566 this.menu.blur(); 9567 return; 9568 } 9569 this.menu[ direction ]( event ); 9570 }, 9571 9572 widget: function() { 9573 return this.menu.element; 9574 }, 9575 9576 _value: function() { 9577 return this.valueMethod.apply( this.element, arguments ); 9578 }, 9579 9580 _keyEvent: function( keyEvent, event ) { 9581 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 9582 this._move( keyEvent, event ); 9583 9584 // prevents moving cursor to beginning/end of the text field in some browsers 9585 event.preventDefault(); 9586 } 9587 } 9588}); 9589 9590$.extend( $.ui.autocomplete, { 9591 escapeRegex: function( value ) { 9592 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 9593 }, 9594 filter: function(array, term) { 9595 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); 9596 return $.grep( array, function(value) { 9597 return matcher.test( value.label || value.value || value ); 9598 }); 9599 } 9600}); 9601 9602 9603// live region extension, adding a `messages` option 9604// NOTE: This is an experimental API. We are still investigating 9605// a full solution for string manipulation and internationalization. 9606$.widget( "ui.autocomplete", $.ui.autocomplete, { 9607 options: { 9608 messages: { 9609 noResults: "No search results.", 9610 results: function( amount ) { 9611 return amount + ( amount > 1 ? " results are" : " result is" ) + 9612 " available, use up and down arrow keys to navigate."; 9613 } 9614 } 9615 }, 9616 9617 __response: function( content ) { 9618 var message; 9619 this._superApply( arguments ); 9620 if ( this.options.disabled || this.cancelSearch ) { 9621 return; 9622 } 9623 if ( content && content.length ) { 9624 message = this.options.messages.results( content.length ); 9625 } else { 9626 message = this.options.messages.noResults; 9627 } 9628 this.liveRegion.text( message ); 9629 } 9630}); 9631 9632 9633}( jQuery )); 9634 9635(function( $, undefined ) { 9636 9637var lastActive, startXPos, startYPos, clickDragged, 9638 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", 9639 stateClasses = "ui-state-hover ui-state-active ", 9640 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", 9641 formResetHandler = function() { 9642 var buttons = $( this ).find( ":ui-button" ); 9643 setTimeout(function() { 9644 buttons.button( "refresh" ); 9645 }, 1 ); 9646 }, 9647 radioGroup = function( radio ) { 9648 var name = radio.name, 9649 form = radio.form, 9650 radios = $( [] ); 9651 if ( name ) { 9652 if ( form ) { 9653 radios = $( form ).find( "[name='" + name + "']" ); 9654 } else { 9655 radios = $( "[name='" + name + "']", radio.ownerDocument ) 9656 .filter(function() { 9657 return !this.form; 9658 }); 9659 } 9660 } 9661 return radios; 9662 }; 9663 9664$.widget( "ui.button", { 9665 version: "1.9.1", 9666 defaultElement: "<button>", 9667 options: { 9668 disabled: null, 9669 text: true, 9670 label: null, 9671 icons: { 9672 primary: null, 9673 secondary: null 9674 } 9675 }, 9676 _create: function() { 9677 this.element.closest( "form" ) 9678 .unbind( "reset" + this.eventNamespace ) 9679 .bind( "reset" + this.eventNamespace, formResetHandler ); 9680 9681 if ( typeof this.options.disabled !== "boolean" ) { 9682 this.options.disabled = !!this.element.prop( "disabled" ); 9683 } else { 9684 this.element.prop( "disabled", this.options.disabled ); 9685 } 9686 9687 this._determineButtonType(); 9688 this.hasTitle = !!this.buttonElement.attr( "title" ); 9689 9690 var that = this, 9691 options = this.options, 9692 toggleButton = this.type === "checkbox" || this.type === "radio", 9693 hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ), 9694 focusClass = "ui-state-focus"; 9695 9696 if ( options.label === null ) { 9697 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); 9698 } 9699 9700 this.buttonElement 9701 .addClass( baseClasses ) 9702 .attr( "role", "button" ) 9703 .bind( "mouseenter" + this.eventNamespace, function() { 9704 if ( options.disabled ) { 9705 return; 9706 } 9707 $( this ).addClass( "ui-state-hover" ); 9708 if ( this === lastActive ) { 9709 $( this ).addClass( "ui-state-active" ); 9710 } 9711 }) 9712 .bind( "mouseleave" + this.eventNamespace, function() { 9713 if ( options.disabled ) { 9714 return; 9715 } 9716 $( this ).removeClass( hoverClass ); 9717 }) 9718 .bind( "click" + this.eventNamespace, function( event ) { 9719 if ( options.disabled ) { 9720 event.preventDefault(); 9721 event.stopImmediatePropagation(); 9722 } 9723 }); 9724 9725 this.element 9726 .bind( "focus" + this.eventNamespace, function() { 9727 // no need to check disabled, focus won't be triggered anyway 9728 that.buttonElement.addClass( focusClass ); 9729 }) 9730 .bind( "blur" + this.eventNamespace, function() { 9731 that.buttonElement.removeClass( focusClass ); 9732 }); 9733 9734 if ( toggleButton ) { 9735 this.element.bind( "change" + this.eventNamespace, function() { 9736 if ( clickDragged ) { 9737 return; 9738 } 9739 that.refresh(); 9740 }); 9741 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag 9742 // prevents issue where button state changes but checkbox/radio checked state 9743 // does not in Firefox (see ticket #6970) 9744 this.buttonElement 9745 .bind( "mousedown" + this.eventNamespace, function( event ) { 9746 if ( options.disabled ) { 9747 return; 9748 } 9749 clickDragged = false; 9750 startXPos = event.pageX; 9751 startYPos = event.pageY; 9752 }) 9753 .bind( "mouseup" + this.eventNamespace, function( event ) { 9754 if ( options.disabled ) { 9755 return; 9756 } 9757 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { 9758 clickDragged = true; 9759 } 9760 }); 9761 } 9762 9763 if ( this.type === "checkbox" ) { 9764 this.buttonElement.bind( "click" + this.eventNamespace, function() { 9765 if ( options.disabled || clickDragged ) { 9766 return false; 9767 } 9768 $( this ).toggleClass( "ui-state-active" ); 9769 that.buttonElement.attr( "aria-pressed", that.element[0].checked ); 9770 }); 9771 } else if ( this.type === "radio" ) { 9772 this.buttonElement.bind( "click" + this.eventNamespace, function() { 9773 if ( options.disabled || clickDragged ) { 9774 return false; 9775 } 9776 $( this ).addClass( "ui-state-active" ); 9777 that.buttonElement.attr( "aria-pressed", "true" ); 9778 9779 var radio = that.element[ 0 ]; 9780 radioGroup( radio ) 9781 .not( radio ) 9782 .map(function() { 9783 return $( this ).button( "widget" )[ 0 ]; 9784 }) 9785 .removeClass( "ui-state-active" ) 9786 .attr( "aria-pressed", "false" ); 9787 }); 9788 } else { 9789 this.buttonElement 9790 .bind( "mousedown" + this.eventNamespace, function() { 9791 if ( options.disabled ) { 9792 return false; 9793 } 9794 $( this ).addClass( "ui-state-active" ); 9795 lastActive = this; 9796 that.document.one( "mouseup", function() { 9797 lastActive = null; 9798 }); 9799 }) 9800 .bind( "mouseup" + this.eventNamespace, function() { 9801 if ( options.disabled ) { 9802 return false; 9803 } 9804 $( this ).removeClass( "ui-state-active" ); 9805 }) 9806 .bind( "keydown" + this.eventNamespace, function(event) { 9807 if ( options.disabled ) { 9808 return false; 9809 } 9810 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { 9811 $( this ).addClass( "ui-state-active" ); 9812 } 9813 }) 9814 .bind( "keyup" + this.eventNamespace, function() { 9815 $( this ).removeClass( "ui-state-active" ); 9816 }); 9817 9818 if ( this.buttonElement.is("a") ) { 9819 this.buttonElement.keyup(function(event) { 9820 if ( event.keyCode === $.ui.keyCode.SPACE ) { 9821 // TODO pass through original event correctly (just as 2nd argument doesn't work) 9822 $( this ).click(); 9823 } 9824 }); 9825 } 9826 } 9827 9828 // TODO: pull out $.Widget's handling for the disabled option into 9829 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can 9830 // be overridden by individual plugins 9831 this._setOption( "disabled", options.disabled ); 9832 this._resetButton(); 9833 }, 9834 9835 _determineButtonType: function() { 9836 var ancestor, labelSelector, checked; 9837 9838 if ( this.element.is("[type=checkbox]") ) { 9839 this.type = "checkbox"; 9840 } else if ( this.element.is("[type=radio]") ) { 9841 this.type = "radio"; 9842 } else if ( this.element.is("input") ) { 9843 this.type = "input"; 9844 } else { 9845 this.type = "button"; 9846 } 9847 9848 if ( this.type === "checkbox" || this.type === "radio" ) { 9849 // we don't search against the document in case the element 9850 // is disconnected from the DOM 9851 ancestor = this.element.parents().last(); 9852 labelSelector = "label[for='" + this.element.attr("id") + "']"; 9853 this.buttonElement = ancestor.find( labelSelector ); 9854 if ( !this.buttonElement.length ) { 9855 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); 9856 this.buttonElement = ancestor.filter( labelSelector ); 9857 if ( !this.buttonElement.length ) { 9858 this.buttonElement = ancestor.find( labelSelector ); 9859 } 9860 } 9861 this.element.addClass( "ui-helper-hidden-accessible" ); 9862 9863 checked = this.element.is( ":checked" ); 9864 if ( checked ) { 9865 this.buttonElement.addClass( "ui-state-active" ); 9866 } 9867 this.buttonElement.prop( "aria-pressed", checked ); 9868 } else { 9869 this.buttonElement = this.element; 9870 } 9871 }, 9872 9873 widget: function() { 9874 return this.buttonElement; 9875 }, 9876 9877 _destroy: function() { 9878 this.element 9879 .removeClass( "ui-helper-hidden-accessible" ); 9880 this.buttonElement 9881 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) 9882 .removeAttr( "role" ) 9883 .removeAttr( "aria-pressed" ) 9884 .html( this.buttonElement.find(".ui-button-text").html() ); 9885 9886 if ( !this.hasTitle ) {
vendor: 6,439 bytes, lines 9887-10076
9887 this.buttonElement.removeAttr( "title" ); 9888 } 9889 }, 9890 9891 _setOption: function( key, value ) { 9892 this._super( key, value ); 9893 if ( key === "disabled" ) { 9894 if ( value ) { 9895 this.element.prop( "disabled", true ); 9896 } else { 9897 this.element.prop( "disabled", false ); 9898 } 9899 return; 9900 } 9901 this._resetButton(); 9902 }, 9903 9904 refresh: function() { 9905 var isDisabled = this.element.is( ":disabled" ) || this.element.hasClass( "ui-button-disabled" ); 9906 if ( isDisabled !== this.options.disabled ) { 9907 this._setOption( "disabled", isDisabled ); 9908 } 9909 if ( this.type === "radio" ) { 9910 radioGroup( this.element[0] ).each(function() { 9911 if ( $( this ).is( ":checked" ) ) { 9912 $( this ).button( "widget" ) 9913 .addClass( "ui-state-active" ) 9914 .attr( "aria-pressed", "true" ); 9915 } else { 9916 $( this ).button( "widget" ) 9917 .removeClass( "ui-state-active" ) 9918 .attr( "aria-pressed", "false" ); 9919 } 9920 }); 9921 } else if ( this.type === "checkbox" ) { 9922 if ( this.element.is( ":checked" ) ) { 9923 this.buttonElement 9924 .addClass( "ui-state-active" ) 9925 .attr( "aria-pressed", "true" ); 9926 } else { 9927 this.buttonElement 9928 .removeClass( "ui-state-active" ) 9929 .attr( "aria-pressed", "false" ); 9930 } 9931 } 9932 }, 9933 9934 _resetButton: function() { 9935 if ( this.type === "input" ) { 9936 if ( this.options.label ) { 9937 this.element.val( this.options.label ); 9938 } 9939 return; 9940 } 9941 var buttonElement = this.buttonElement.removeClass( typeClasses ), 9942 buttonText = $( "<span></span>", this.document[0] ) 9943 .addClass( "ui-button-text" ) 9944 .html( this.options.label ) 9945 .appendTo( buttonElement.empty() ) 9946 .text(), 9947 icons = this.options.icons, 9948 multipleIcons = icons.primary && icons.secondary, 9949 buttonClasses = []; 9950 9951 if ( icons.primary || icons.secondary ) { 9952 if ( this.options.text ) { 9953 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); 9954 } 9955 9956 if ( icons.primary ) { 9957 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); 9958 } 9959 9960 if ( icons.secondary ) { 9961 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); 9962 } 9963 9964 if ( !this.options.text ) { 9965 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); 9966 9967 if ( !this.hasTitle ) { 9968 buttonElement.attr( "title", $.trim( buttonText ) ); 9969 } 9970 } 9971 } else { 9972 buttonClasses.push( "ui-button-text-only" ); 9973 } 9974 buttonElement.addClass( buttonClasses.join( " " ) ); 9975 } 9976}); 9977 9978$.widget( "ui.buttonset", { 9979 version: "1.9.1", 9980 options: { 9981 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)" 9982 }, 9983 9984 _create: function() { 9985 this.element.addClass( "ui-buttonset" ); 9986 }, 9987 9988 _init: function() { 9989 this.refresh(); 9990 }, 9991 9992 _setOption: function( key, value ) { 9993 if ( key === "disabled" ) { 9994 this.buttons.button( "option", key, value ); 9995 } 9996 9997 this._super( key, value ); 9998 }, 9999 10000 refresh: function() { 10001 var rtl = this.element.css( "direction" ) === "rtl"; 10002 10003 this.buttons = this.element.find( this.options.items ) 10004 .filter( ":ui-button" ) 10005 .button( "refresh" ) 10006 .end() 10007 .not( ":ui-button" ) 10008 .button() 10009 .end() 10010 .map(function() { 10011 return $( this ).button( "widget" )[ 0 ]; 10012 }) 10013 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) 10014 .filter( ":first" ) 10015 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) 10016 .end() 10017 .filter( ":last" ) 10018 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) 10019 .end() 10020 .end(); 10021 }, 10022 10023 _destroy: function() { 10024 this.element.removeClass( "ui-buttonset" ); 10025 this.buttons 10026 .map(function() { 10027 return $( this ).button( "widget" )[ 0 ]; 10028 }) 10029 .removeClass( "ui-corner-left ui-corner-right" ) 10030 .end() 10031 .button( "destroy" ); 10032 } 10033}); 10034 10035}( jQuery ) ); 10036 10037(function( $, undefined ) { 10038 10039$.extend($.ui, { datepicker: { version: "1.9.1" } }); 10040 10041var PROP_NAME = 'datepicker'; 10042var dpuuid = new Date().getTime(); 10043var instActive; 10044 10045/* Date picker manager. 10046 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 10047 Settings for (groups of) date pickers are maintained in an instance object, 10048 allowing multiple different settings on the same page. */ 10049 10050function Datepicker() { 10051 this.debug = false; // Change this to true to start debugging 10052 this._curInst = null; // The current instance in use 10053 this._keyEvent = false; // If the last event was a key event 10054 this._disabledInputs = []; // List of date picker inputs that have been disabled 10055 this._datepickerShowing = false; // True if the popup picker is showing , false if not 10056 this._inDialog = false; // True if showing within a "dialog", false if not 10057 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division 10058 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class 10059 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class 10060 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class 10061 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class 10062 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class 10063 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class 10064 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class 10065 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class 10066 this.regional = []; // Available regional settings, indexed by language code 10067 this.regional[''] = { // Default regional settings 10068 closeText: 'Done', // Display text for close link 10069 prevText: 'Prev', // Display text for previous month link 10070 nextText: 'Next', // Display text for next month link 10071 currentText: 'Today', // Display text for current month link 10072 monthNames: ['January','February','March','April','May','June', 10073 'July','August','September','October','November','December'], // Names of months for drop-down and formatting 10074 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting 10075 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting 10076 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
10077 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday 10078 weekHeader: 'Wk', // Column header for week of the year 10079 dateFormat: 'mm/dd/yy', // See format options on parseDate 10080 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 10081 isRTL: false, // True if right-to-left language, false if left-to-right 10082 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 10083 yearSuffix: '' // Additional text to append to the year in the month headers 10084 }; 10085 this._defaults = { // Global defaults for all the date picker instances 10086 showOn: 'focus', // 'focus' for popup on focus, 10087 // 'button' for trigger button, or 'both' for either 10088 showAnim: 'fadeIn', // Name of jQuery animation for popup 10089 showOptions: {}, // Options for enhanced animations 10090 defaultDate: null, // Used when field is blank: actual date, 10091 // +/-number for offset from today, null for today 10092 appendText: '', // Display text following the input box, e.g. showing the format 10093 buttonText: '...', // Text for trigger button 10094 buttonImage: '', // URL for trigger button image 10095 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 10096 hideIfNoPrevNext: false, // True to hide next/previous month links 10097 // if not applicable, false to just disable them 10098 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 10099 gotoCurrent: false, // True if today link goes back to current selection instead 10100 changeMonth: false, // True if month can be selected directly, false if only prev/next 10101 changeYear: false, // True if year can be selected directly, false if only prev/next 10102 yearRange: 'c-10:c+10', // Range of years to display in drop-down, 10103 // either relative to today's year (-nn:+nn), relative to currently displayed year 10104 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 10105 showOtherMonths: false, // True to show dates in other months, false to leave blank 10106 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 10107 showWeek: false, // True to show week of the year, false to not show it 10108 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 10109 // takes a Date and returns the number of the week for it 10110 shortYearCutoff: '+10', // Short year values < this are in the current century, 10111 // > this are in the previous century, 10112 // string value starting with '+' for current year + value 10113 minDate: null, // The earliest selectable date, or null for no limit 10114 maxDate: null, // The latest selectable date, or null for no limit 10115 duration: 'fast', // Duration of display/closure 10116 beforeShowDay: null, // Function that takes a date and returns an array with 10117 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', 10118 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 10119 beforeShow: null, // Function that takes an input field and 10120 // returns a set of custom settings for the date picker 10121 onSelect: null, // Define a callback function when a date is selected 10122 onChangeMonthYear: null, // Define a callback function when the month or year is changed 10123 onClose: null, // Define a callback function when the datepicker is closed 10124 numberOfMonths: 1, // Number of months to show at a time 10125 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 10126 stepMonths: 1, // Number of months to step back/forward 10127 stepBigMonths: 12, // Number of months to step back/forward for the big links 10128 altField: '', // Selector for an alternate field to store selected dates into 10129 altFormat: '', // The date format to use for the alternate field 10130 constrainInput: true, // The input is constrained by the current date format 10131 showButtonPanel: false, // True to show button panel, false to not show it 10132 autoSize: false, // True to size the input for the date format, false to leave as is 10133 disabled: false // The initial disabled state 10134 }; 10135 $.extend(this._defaults, this.regional['']); 10136 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')); 10137} 10138 10139$.extend(Datepicker.prototype, { 10140 /* Class name added to elements to indicate already configured with a date picker. */ 10141 markerClassName: 'hasDatepicker', 10142 10143 //Keep track of the maximum number of rows displayed (see #7043) 10144 maxRows: 4, 10145 10146 /* Debug logging (if enabled). */ 10147 log: function () { 10148 if (this.debug) 10149 console.log.apply('', arguments); 10150 }, 10151 10152 // TODO rename to "widget" when switching to widget factory 10153 _widgetDatepicker: function() { 10154 return this.dpDiv; 10155 }, 10156 10157 /* Override the default settings for all instances of the date picker. 10158 @param settings object - the new settings to use as defaults (anonymous object) 10159 @return the manager object */ 10160 setDefaults: function(settings) { 10161 extendRemove(this._defaults, settings || {}); 10162 return this; 10163 }, 10164 10165 /* Attach the date picker to a jQuery selection. 10166 @param target element - the target input field or division or span 10167 @param settings object - the new settings to use for this date picker instance (anonymous) */ 10168 _attachDatepicker: function(target, settings) { 10169 // check for settings on the control itself - in namespace 'date:' 10170 var inlineSettings = null; 10171 for (var attrName in this._defaults) { 10172 var attrValue = target.getAttribute('date:' + attrName); 10173 if (attrValue) { 10174 inlineSettings = inlineSettings || {};
10175 try { 10176 inlineSettings[attrName] = eval(attrValue); 10177 } catch (err) { 10178 inlineSettings[attrName] = attrValue; 10179 } 10180 } 10181 } 10182 var nodeName = target.nodeName.toLowerCase(); 10183 var inline = (nodeName == 'div' || nodeName == 'span'); 10184 if (!target.id) { 10185 this.uuid += 1; 10186 target.id = 'dp' + this.uuid; 10187 } 10188 var inst = this._newInst($(target), inline); 10189 inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 10190 if (nodeName == 'input') { 10191 this._connectDatepicker(target, inst); 10192 } else if (inline) { 10193 this._inlineDatepicker(target, inst); 10194 } 10195 }, 10196 10197 /* Create a new instance object. */ 10198 _newInst: function(target, inline) { 10199 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars 10200 return {id: id, input: target, // associated target 10201 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 10202 drawMonth: 0, drawYear: 0, // month being drawn 10203 inline: inline, // is datepicker inline or not 10204 dpDiv: (!inline ? this.dpDiv : // presentation div 10205 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))}; 10206 }, 10207 10208 /* Attach the date picker to an input field. */ 10209 _connectDatepicker: function(target, inst) { 10210 var input = $(target); 10211 inst.append = $([]); 10212 inst.trigger = $([]); 10213 if (input.hasClass(this.markerClassName)) 10214 return; 10215 this._attachments(input, inst); 10216 input.addClass(this.markerClassName).keydown(this._doKeyDown). 10217 keypress(this._doKeyPress).keyup(this._doKeyUp). 10218 bind("setData.datepicker", function(event, key, value) { 10219 inst.settings[key] = value; 10220 }).bind("getData.datepicker", function(event, key) { 10221 return this._get(inst, key); 10222 }); 10223 this._autoSize(inst); 10224 $.data(target, PROP_NAME, inst); 10225 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 10226 if( inst.settings.disabled ) { 10227 this._disableDatepicker( target ); 10228 } 10229 }, 10230 10231 /* Make attachments based on settings. */ 10232 _attachments: function(input, inst) { 10233 var appendText = this._get(inst, 'appendText'); 10234 var isRTL = this._get(inst, 'isRTL'); 10235 if (inst.append) 10236 inst.append.remove(); 10237 if (appendText) { 10238 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); 10239 input[isRTL ? 'before' : 'after'](inst.append); 10240 } 10241 input.unbind('focus', this._showDatepicker); 10242 if (inst.trigger) 10243 inst.trigger.remove(); 10244 var showOn = this._get(inst, 'showOn'); 10245 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field 10246 input.focus(this._showDatepicker); 10247 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked 10248 var buttonText = this._get(inst, 'buttonText'); 10249 var buttonImage = this._get(inst, 'buttonImage'); 10250 inst.trigger = $(this._get(inst, 'buttonImageOnly') ? 10251 $('<img/>').addClass(this._triggerClass). 10252 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : 10253 $('<button type="button"></button>').addClass(this._triggerClass). 10254 html(buttonImage == '' ? buttonText : $('<img/>').attr( 10255 { src:buttonImage, alt:buttonText, title:buttonText }))); 10256 input[isRTL ? 'before' : 'after'](inst.trigger); 10257 inst.trigger.click(function() { 10258 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) 10259 $.datepicker._hideDatepicker(); 10260 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { 10261 $.datepicker._hideDatepicker(); 10262 $.datepicker._showDatepicker(input[0]); 10263 } else 10264 $.datepicker._showDatepicker(input[0]); 10265 return false; 10266 }); 10267 } 10268 }, 10269 10270 /* Apply the maximum length for the date format. */ 10271 _autoSize: function(inst) { 10272 if (this._get(inst, 'autoSize') && !inst.inline) { 10273 var date = new Date(2009, 12 - 1, 20); // Ensure double digits 10274 var dateFormat = this._get(inst, 'dateFormat'); 10275 if (dateFormat.match(/[DM]/)) { 10276 var findMax = function(names) { 10277 var max = 0; 10278 var maxI = 0; 10279 for (var i = 0; i < names.length; i++) { 10280 if (names[i].length > max) { 10281 max = names[i].length; 10282 maxI = i; 10283 } 10284 }
10285 return maxI; 10286 }; 10287 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? 10288 'monthNames' : 'monthNamesShort')))); 10289 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? 10290 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); 10291 } 10292 inst.input.attr('size', this._formatDate(inst, date).length); 10293 } 10294 }, 10295 10296 /* Attach an inline date picker to a div. */ 10297 _inlineDatepicker: function(target, inst) { 10298 var divSpan = $(target); 10299 if (divSpan.hasClass(this.markerClassName)) 10300 return; 10301 divSpan.addClass(this.markerClassName).append(inst.dpDiv). 10302 bind("setData.datepicker", function(event, key, value){ 10303 inst.settings[key] = value; 10304 }).bind("getData.datepicker", function(event, key){ 10305 return this._get(inst, key); 10306 }); 10307 $.data(target, PROP_NAME, inst); 10308 this._setDate(inst, this._getDefaultDate(inst), true); 10309 this._updateDatepicker(inst); 10310 this._updateAlternate(inst); 10311 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 10312 if( inst.settings.disabled ) { 10313 this._disableDatepicker( target ); 10314 } 10315 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 10316 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 10317 inst.dpDiv.css( "display", "block" ); 10318 }, 10319 10320 /* Pop-up the date picker in a "dialog" box. 10321 @param input element - ignored 10322 @param date string or Date - the initial date to display 10323 @param onSelect function - the function to call when a date is selected 10324 @param settings object - update the dialog date picker instance's settings (anonymous object) 10325 @param pos int[2] - coordinates for the dialog's position within the screen or 10326 event - with x/y coordinates or 10327 leave empty for default (screen centre) 10328 @return the manager object */ 10329 _dialogDatepicker: function(input, date, onSelect, settings, pos) { 10330 var inst = this._dialogInst; // internal instance 10331 if (!inst) { 10332 this.uuid += 1; 10333 var id = 'dp' + this.uuid; 10334 this._dialogInput = $('<input type="text" id="' + id + 10335 '" style="position: absolute; top: -100px; width: 0px;"/>'); 10336 this._dialogInput.keydown(this._doKeyDown); 10337 $('body').append(this._dialogInput); 10338 inst = this._dialogInst = this._newInst(this._dialogInput, false); 10339 inst.settings = {}; 10340 $.data(this._dialogInput[0], PROP_NAME, inst); 10341 } 10342 extendRemove(inst.settings, settings || {}); 10343 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); 10344 this._dialogInput.val(date); 10345 10346 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); 10347 if (!this._pos) { 10348 var browserWidth = document.documentElement.clientWidth; 10349 var browserHeight = document.documentElement.clientHeight; 10350 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 10351 var scrollY = document.documentElement.scrollTop || document.body.scrollTop; 10352 this._pos = // should use actual width/height below 10353 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; 10354 } 10355 10356 // move input on screen for focus, but hidden behind dialog 10357 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); 10358 inst.settings.onSelect = onSelect; 10359 this._inDialog = true; 10360 this.dpDiv.addClass(this._dialogClass); 10361 this._showDatepicker(this._dialogInput[0]); 10362 if ($.blockUI) 10363 $.blockUI(this.dpDiv); 10364 $.data(this._dialogInput[0], PROP_NAME, inst); 10365 return this; 10366 }, 10367 10368 /* Detach a datepicker from its control. 10369 @param target element - the target input field or division or span */ 10370 _destroyDatepicker: function(target) { 10371 var $target = $(target); 10372 var inst = $.data(target, PROP_NAME); 10373 if (!$target.hasClass(this.markerClassName)) { 10374 return; 10375 } 10376 var nodeName = target.nodeName.toLowerCase(); 10377 $.removeData(target, PROP_NAME); 10378 if (nodeName == 'input') { 10379 inst.append.remove(); 10380 inst.trigger.remove(); 10381 $target.removeClass(this.markerClassName). 10382 unbind('focus', this._showDatepicker). 10383 unbind('keydown', this._doKeyDown). 10384 unbind('keypress', this._doKeyPress). 10385 unbind('keyup', this._doKeyUp); 10386 } else if (nodeName == 'div' || nodeName == 'span') 10387 $target.removeClass(this.markerClassName).empty(); 10388 }, 10389 10390 /* Enable the date picker to a jQuery selection. 10391 @param target element - the target input field or division or span */ 10392 _enableDatepicker: function(target) { 10393 var $target = $(target); 10394 var inst = $.data(target, PROP_NAME); 10395 if (!$target.hasClass(this.markerClassName)) { 10396 return; 10397 } 10398 var nodeName = target.nodeName.toLowerCase(); 10399 if (nodeName == 'input') { 10400 target.disabled = false;
10401 inst.trigger.filter('button'). 10402 each(function() { this.disabled = false; }).end(). 10403 filter('img').css({opacity: '1.0', cursor: ''}); 10404 } 10405 else if (nodeName == 'div' || nodeName == 'span') { 10406 var inline = $target.children('.' + this._inlineClass); 10407 inline.children().removeClass('ui-state-disabled'); 10408 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 10409 prop("disabled", false); 10410 } 10411 this._disabledInputs = $.map(this._disabledInputs, 10412 function(value) { return (value == target ? null : value); }); // delete entry 10413 }, 10414 10415 /* Disable the date picker to a jQuery selection. 10416 @param target element - the target input field or division or span */ 10417 _disableDatepicker: function(target) { 10418 var $target = $(target); 10419 var inst = $.data(target, PROP_NAME); 10420 if (!$target.hasClass(this.markerClassName)) { 10421 return; 10422 } 10423 var nodeName = target.nodeName.toLowerCase(); 10424 if (nodeName == 'input') { 10425 target.disabled = true; 10426 inst.trigger.filter('button'). 10427 each(function() { this.disabled = true; }).end(). 10428 filter('img').css({opacity: '0.5', cursor: 'default'}); 10429 } 10430 else if (nodeName == 'div' || nodeName == 'span') { 10431 var inline = $target.children('.' + this._inlineClass); 10432 inline.children().addClass('ui-state-disabled'); 10433 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 10434 prop("disabled", true); 10435 } 10436 this._disabledInputs = $.map(this._disabledInputs, 10437 function(value) { return (value == target ? null : value); }); // delete entry 10438 this._disabledInputs[this._disabledInputs.length] = target; 10439 }, 10440 10441 /* Is the first field in a jQuery collection disabled as a datepicker? 10442 @param target element - the target input field or division or span 10443 @return boolean - true if disabled, false if enabled */ 10444 _isDisabledDatepicker: function(target) { 10445 if (!target) { 10446 return false; 10447 } 10448 for (var i = 0; i < this._disabledInputs.length; i++) { 10449 if (this._disabledInputs[i] == target) 10450 return true; 10451 } 10452 return false; 10453 }, 10454 10455 /* Retrieve the instance data for the target control. 10456 @param target element - the target input field or division or span 10457 @return object - the associated instance data 10458 @throws error if a jQuery problem getting data */ 10459 _getInst: function(target) { 10460 try { 10461 return $.data(target, PROP_NAME); 10462 } 10463 catch (err) { 10464 throw 'Missing instance data for this datepicker'; 10465 } 10466 }, 10467 10468 /* Update or retrieve the settings for a date picker attached to an input field or division. 10469 @param target element - the target input field or division or span 10470 @param name object - the new settings to update or 10471 string - the name of the setting to change or retrieve, 10472 when retrieving also 'all' for all instance settings or 10473 'defaults' for all global defaults 10474 @param value any - the new value for the setting 10475 (omit if above is an object or to retrieve a value) */ 10476 _optionDatepicker: function(target, name, value) { 10477 var inst = this._getInst(target); 10478 if (arguments.length == 2 && typeof name == 'string') { 10479 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : 10480 (inst ? (name == 'all' ? $.extend({}, inst.settings) : 10481 this._get(inst, name)) : null)); 10482 } 10483 var settings = name || {}; 10484 if (typeof name == 'string') { 10485 settings = {}; 10486 settings[name] = value; 10487 } 10488 if (inst) { 10489 if (this._curInst == inst) { 10490 this._hideDatepicker(); 10491 } 10492 var date = this._getDateDatepicker(target, true); 10493 var minDate = this._getMinMaxDate(inst, 'min'); 10494 var maxDate = this._getMinMaxDate(inst, 'max'); 10495 extendRemove(inst.settings, settings); 10496 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 10497 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) 10498 inst.settings.minDate = this._formatDate(inst, minDate); 10499 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) 10500 inst.settings.maxDate = this._formatDate(inst, maxDate); 10501 this._attachments($(target), inst); 10502 this._autoSize(inst); 10503 this._setDate(inst, date); 10504 this._updateAlternate(inst); 10505 this._updateDatepicker(inst); 10506 } 10507 }, 10508 10509 // change method deprecated 10510 _changeDatepicker: function(target, name, value) { 10511 this._optionDatepicker(target, name, value); 10512 }, 10513 10514 /* Redraw the date picker attached to an input field or division. 10515 @param target element - the target input field or division or span */ 10516 _refreshDatepicker: function(target) { 10517 var inst = this._getInst(target); 10518 if (inst) { 10519 this._updateDatepicker(inst); 10520 } 10521 }, 10522 10523 /* Set the dates for a jQuery selection. 10524 @param target element - the target input field or division or span 10525 @param date Date - the new date */ 10526 _setDateDatepicker: function(target, date) { 10527 var inst = this._getInst(target); 10528 if (inst) { 10529 this._setDate(inst, date); 10530 this._updateDatepicker(inst); 10531 this._updateAlternate(inst); 10532 } 10533 }, 10534 10535 /* Get the date(s) for the first entry in a jQuery selection. 10536 @param target element - the target input field or division or span 10537 @param noDefault boolean - true if no default date is to be used 10538 @return Date - the current date */ 10539 _getDateDatepicker: function(target, noDefault) { 10540 var inst = this._getInst(target); 10541 if (inst && !inst.inline) 10542 this._setDateFromField(inst, noDefault); 10543 return (inst ? this._getDate(inst) : null); 10544 }, 10545 10546 /* Handle keystrokes. */ 10547 _doKeyDown: function(event) { 10548 var inst = $.datepicker._getInst(event.target); 10549 var handled = true; 10550 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); 10551 inst._keyEvent = true; 10552 if ($.datepicker._datepickerShowing) 10553 switch (event.keyCode) { 10554 case 9: $.datepicker._hideDatepicker(); 10555 handled = false;
10556 break; // hide on tab out 10557 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 10558 $.datepicker._currentClass + ')', inst.dpDiv); 10559 if (sel[0]) 10560 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 10561 var onSelect = $.datepicker._get(inst, 'onSelect'); 10562 if (onSelect) { 10563 var dateStr = $.datepicker._formatDate(inst); 10564 10565 // trigger custom callback 10566 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 10567 } 10568 else 10569 $.datepicker._hideDatepicker(); 10570 return false; // don't submit the form 10571 break; // select the value on enter 10572 case 27: $.datepicker._hideDatepicker(); 10573 break; // hide on escape 10574 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10575 -$.datepicker._get(inst, 'stepBigMonths') : 10576 -$.datepicker._get(inst, 'stepMonths')), 'M'); 10577 break; // previous month/year on page up/+ ctrl 10578 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10579 +$.datepicker._get(inst, 'stepBigMonths') : 10580 +$.datepicker._get(inst, 'stepMonths')), 'M'); 10581 break; // next month/year on page down/+ ctrl 10582 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); 10583 handled = event.ctrlKey || event.metaKey; 10584 break; // clear on ctrl or command +end 10585 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); 10586 handled = event.ctrlKey || event.metaKey; 10587 break; // current on ctrl or command +home 10588 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); 10589 handled = event.ctrlKey || event.metaKey; 10590 // -1 day on ctrl or command +left 10591 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10592 -$.datepicker._get(inst, 'stepBigMonths') : 10593 -$.datepicker._get(inst, 'stepMonths')), 'M'); 10594 // next month/year on alt +left on Mac 10595 break; 10596 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); 10597 handled = event.ctrlKey || event.metaKey; 10598 break; // -1 week on ctrl or command +up 10599 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); 10600 handled = event.ctrlKey || event.metaKey; 10601 // +1 day on ctrl or command +right 10602 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? 10603 +$.datepicker._get(inst, 'stepBigMonths') : 10604 +$.datepicker._get(inst, 'stepMonths')), 'M'); 10605 // next month/year on alt +right 10606 break; 10607 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); 10608 handled = event.ctrlKey || event.metaKey; 10609 break; // +1 week on ctrl or command +down 10610 default: handled = false; 10611 } 10612 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home 10613 $.datepicker._showDatepicker(this); 10614 else { 10615 handled = false; 10616 } 10617 if (handled) { 10618 event.preventDefault(); 10619 event.stopPropagation(); 10620 } 10621 }, 10622 10623 /* Filter entered characters - based on date format. */ 10624 _doKeyPress: function(event) { 10625 var inst = $.datepicker._getInst(event.target); 10626 if ($.datepicker._get(inst, 'constrainInput')) { 10627 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); 10628 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); 10629 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); 10630 } 10631 }, 10632 10633 /* Synchronise manual entry and field/alternate field. */ 10634 _doKeyUp: function(event) { 10635 var inst = $.datepicker._getInst(event.target);
10636 if (inst.input.val() != inst.lastVal) { 10637 try { 10638 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 10639 (inst.input ? inst.input.val() : null), 10640 $.datepicker._getFormatConfig(inst)); 10641 if (date) { // only if valid 10642 $.datepicker._setDateFromField(inst); 10643 $.datepicker._updateAlternate(inst); 10644 $.datepicker._updateDatepicker(inst); 10645 } 10646 } 10647 catch (err) { 10648 $.datepicker.log(err); 10649 } 10650 } 10651 return true; 10652 }, 10653 10654 /* Pop-up the date picker for a given input field. 10655 If false returned from beforeShow event handler do not show. 10656 @param input element - the input field attached to the date picker or 10657 event - if triggered by focus */ 10658 _showDatepicker: function(input) { 10659 input = input.target || input; 10660 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger 10661 input = $('input', input.parentNode)[0]; 10662 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here 10663 return; 10664 var inst = $.datepicker._getInst(input); 10665 if ($.datepicker._curInst && $.datepicker._curInst != inst) { 10666 $.datepicker._curInst.dpDiv.stop(true, true); 10667 if ( inst && $.datepicker._datepickerShowing ) { 10668 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); 10669 } 10670 } 10671 var beforeShow = $.datepicker._get(inst, 'beforeShow'); 10672 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 10673 if(beforeShowSettings === false){ 10674 //false 10675 return; 10676 } 10677 extendRemove(inst.settings, beforeShowSettings); 10678 inst.lastVal = null; 10679 $.datepicker._lastInput = input; 10680 $.datepicker._setDateFromField(inst); 10681 if ($.datepicker._inDialog) // hide cursor 10682 input.value = ''; 10683 if (!$.datepicker._pos) { // position below input 10684 $.datepicker._pos = $.datepicker._findPos(input); 10685 $.datepicker._pos[1] += input.offsetHeight; // add the height 10686 } 10687 var isFixed = false; 10688 $(input).parents().each(function() { 10689 isFixed |= $(this).css('position') == 'fixed'; 10690 return !isFixed; 10691 }); 10692 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; 10693 $.datepicker._pos = null; 10694 //to avoid flashes on Firefox 10695 inst.dpDiv.empty(); 10696 // determine sizing offscreen 10697 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); 10698 $.datepicker._updateDatepicker(inst); 10699 // fix width for dynamic number of date pickers 10700 // and adjust position before showing 10701 offset = $.datepicker._checkOffset(inst, offset, isFixed); 10702 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? 10703 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', 10704 left: offset.left + 'px', top: offset.top + 'px'}); 10705 if (!inst.inline) { 10706 var showAnim = $.datepicker._get(inst, 'showAnim'); 10707 var duration = $.datepicker._get(inst, 'duration'); 10708 var postProcess = function() { 10709 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 10710 if( !! cover.length ){ 10711 var borders = $.datepicker._getBorders(inst.dpDiv); 10712 cover.css({left: -borders[0], top: -borders[1], 10713 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); 10714 } 10715 }; 10716 inst.dpDiv.zIndex($(input).zIndex()+1); 10717 $.datepicker._datepickerShowing = true; 10718 10719 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 10720 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 10721 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 10722 else 10723 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); 10724 if (!showAnim || !duration) 10725 postProcess(); 10726 if (inst.input.is(':visible') && !inst.input.is(':disabled')) 10727 inst.input.focus(); 10728 $.datepicker._curInst = inst; 10729 } 10730 }, 10731 10732 /* Generate the date picker content. */ 10733 _updateDatepicker: function(inst) { 10734 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 10735 var borders = $.datepicker._getBorders(inst.dpDiv); 10736 instActive = inst; // for delegate hover events 10737 inst.dpDiv.empty().append(this._generateHTML(inst)); 10738 this._attachHandlers(inst);
10739 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 10740 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 10741 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) 10742 } 10743 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); 10744 var numMonths = this._getNumberOfMonths(inst); 10745 var cols = numMonths[1]; 10746 var width = 17; 10747 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); 10748 if (cols > 1) 10749 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); 10750 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 10751 'Class']('ui-datepicker-multi'); 10752 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 10753 'Class']('ui-datepicker-rtl'); 10754 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && 10755 // #6694 - don't focus the input if it's already focused 10756 // this breaks the change event in IE 10757 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) 10758 inst.input.focus(); 10759 // deffered render of the years select (to avoid flashes on Firefox) 10760 if( inst.yearshtml ){ 10761 var origyearshtml = inst.yearshtml; 10762 setTimeout(function(){ 10763 //assure that inst.yearshtml didn't change. 10764 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 10765 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); 10766 } 10767 origyearshtml = inst.yearshtml = null; 10768 }, 0); 10769 } 10770 }, 10771 10772 /* Retrieve the size of left and top borders for an element. 10773 @param elem (jQuery object) the element of interest 10774 @return (number[2]) the left and top borders */ 10775 _getBorders: function(elem) { 10776 var convert = function(value) { 10777 return {thin: 1, medium: 2, thick: 3}[value] || value; 10778 }; 10779 return [parseFloat(convert(elem.css('border-left-width'))), 10780 parseFloat(convert(elem.css('border-top-width')))]; 10781 }, 10782 10783 /* Check positioning to remain on screen. */ 10784 _checkOffset: function(inst, offset, isFixed) { 10785 var dpWidth = inst.dpDiv.outerWidth(); 10786 var dpHeight = inst.dpDiv.outerHeight(); 10787 var inputWidth = inst.input ? inst.input.outerWidth() : 0; 10788 var inputHeight = inst.input ? inst.input.outerHeight() : 0; 10789 var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()); 10790 var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); 10791 10792 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); 10793 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; 10794 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; 10795 10796 // now check if datepicker is showing outside window viewport - move to a better place if so. 10797 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? 10798 Math.abs(offset.left + dpWidth - viewWidth) : 0); 10799 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? 10800 Math.abs(dpHeight + inputHeight) : 0); 10801 10802 return offset; 10803 }, 10804 10805 /* Find an object's position on the screen. */ 10806 _findPos: function(obj) { 10807 var inst = this._getInst(obj); 10808 var isRTL = this._get(inst, 'isRTL'); 10809 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { 10810 obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; 10811 } 10812 var position = $(obj).offset(); 10813 return [position.left, position.top]; 10814 }, 10815 10816 /* Hide the date picker from view. 10817 @param input element - the input field attached to the date picker */ 10818 _hideDatepicker: function(input) { 10819 var inst = this._curInst; 10820 if (!inst || (input && inst != $.data(input, PROP_NAME))) 10821 return; 10822 if (this._datepickerShowing) { 10823 var showAnim = this._get(inst, 'showAnim'); 10824 var duration = this._get(inst, 'duration'); 10825 var postProcess = function() { 10826 $.datepicker._tidyDialog(inst); 10827 }; 10828 10829 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 10830 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) 10831 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); 10832 else 10833 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : 10834 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); 10835 if (!showAnim) 10836 postProcess(); 10837 this._datepickerShowing = false;
10838 var onClose = this._get(inst, 'onClose'); 10839 if (onClose) 10840 onClose.apply((inst.input ? inst.input[0] : null), 10841 [(inst.input ? inst.input.val() : ''), inst]); 10842 this._lastInput = null; 10843 if (this._inDialog) { 10844 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); 10845 if ($.blockUI) { 10846 $.unblockUI(); 10847 $('body').append(this.dpDiv); 10848 } 10849 } 10850 this._inDialog = false; 10851 } 10852 }, 10853 10854 /* Tidy up after a dialog display. */ 10855 _tidyDialog: function(inst) { 10856 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); 10857 }, 10858 10859 /* Close date picker if clicked elsewhere. */ 10860 _checkExternalClick: function(event) { 10861 if (!$.datepicker._curInst) 10862 return; 10863 10864 var $target = $(event.target), 10865 inst = $.datepicker._getInst($target[0]); 10866 10867 if ( ( ( $target[0].id != $.datepicker._mainDivId && 10868 $target.parents('#' + $.datepicker._mainDivId).length == 0 && 10869 !$target.hasClass($.datepicker.markerClassName) && 10870 !$target.closest("." + $.datepicker._triggerClass).length && 10871 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || 10872 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) 10873 $.datepicker._hideDatepicker(); 10874 }, 10875 10876 /* Adjust one of the date sub-fields. */ 10877 _adjustDate: function(id, offset, period) { 10878 var target = $(id); 10879 var inst = this._getInst(target[0]); 10880 if (this._isDisabledDatepicker(target[0])) { 10881 return; 10882 } 10883 this._adjustInstDate(inst, offset + 10884 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning 10885 period); 10886 this._updateDatepicker(inst); 10887 }, 10888 10889 /* Action for current link. */ 10890 _gotoToday: function(id) { 10891 var target = $(id); 10892 var inst = this._getInst(target[0]); 10893 if (this._get(inst, 'gotoCurrent') && inst.currentDay) { 10894 inst.selectedDay = inst.currentDay; 10895 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 10896 inst.drawYear = inst.selectedYear = inst.currentYear; 10897 } 10898 else { 10899 var date = new Date(); 10900 inst.selectedDay = date.getDate(); 10901 inst.drawMonth = inst.selectedMonth = date.getMonth(); 10902 inst.drawYear = inst.selectedYear = date.getFullYear(); 10903 } 10904 this._notifyChange(inst); 10905 this._adjustDate(target); 10906 }, 10907 10908 /* Action for selecting a new month/year. */ 10909 _selectMonthYear: function(id, select, period) { 10910 var target = $(id); 10911 var inst = this._getInst(target[0]); 10912 inst['selected' + (period == 'M' ? 'Month' : 'Year')] = 10913 inst['draw' + (period == 'M' ? 'Month' : 'Year')] = 10914 parseInt(select.options[select.selectedIndex].value,10); 10915 this._notifyChange(inst); 10916 this._adjustDate(target); 10917 }, 10918 10919 /* Action for selecting a day. */ 10920 _selectDay: function(id, month, year, td) { 10921 var target = $(id); 10922 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { 10923 return; 10924 } 10925 var inst = this._getInst(target[0]); 10926 inst.selectedDay = inst.currentDay = $('a', td).html(); 10927 inst.selectedMonth = inst.currentMonth = month; 10928 inst.selectedYear = inst.currentYear = year; 10929 this._selectDate(id, this._formatDate(inst, 10930 inst.currentDay, inst.currentMonth, inst.currentYear)); 10931 }, 10932 10933 /* Erase the input field and hide the date picker. */ 10934 _clearDate: function(id) { 10935 var target = $(id); 10936 var inst = this._getInst(target[0]); 10937 this._selectDate(target, ''); 10938 }, 10939 10940 /* Update the input field with the selected date. */ 10941 _selectDate: function(id, dateStr) { 10942 var target = $(id); 10943 var inst = this._getInst(target[0]); 10944 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 10945 if (inst.input) 10946 inst.input.val(dateStr); 10947 this._updateAlternate(inst); 10948 var onSelect = this._get(inst, 'onSelect'); 10949 if (onSelect) 10950 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 10951 else if (inst.input) 10952 inst.input.trigger('change'); // fire the change event 10953 if (inst.inline) 10954 this._updateDatepicker(inst); 10955 else { 10956 this._hideDatepicker(); 10957 this._lastInput = inst.input[0]; 10958 if (typeof(inst.input[0]) != 'object') 10959 inst.input.focus(); // restore focus 10960 this._lastInput = null; 10961 } 10962 }, 10963 10964 /* Update any alternate field to synchronise with the main field. */ 10965 _updateAlternate: function(inst) { 10966 var altField = this._get(inst, 'altField'); 10967 if (altField) { // update alternate field too 10968 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); 10969 var date = this._getDate(inst); 10970 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); 10971 $(altField).each(function() { $(this).val(dateStr); }); 10972 } 10973 }, 10974 10975 /* Set as beforeShowDay function to prevent selection of weekends. 10976 @param date Date - the date to customise 10977 @return [boolean, string] - is this date selectable?, what is its CSS class? */ 10978 noWeekends: function(date) { 10979 var day = date.getDay(); 10980 return [(day > 0 && day < 6), '']; 10981 }, 10982 10983 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 10984 @param date Date - the date to get the week for 10985 @return number - the number of the week within the year that contains this date */ 10986 iso8601Week: function(date) { 10987 var checkDate = new Date(date.getTime()); 10988 // Find Thursday of this week starting on Monday 10989 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); 10990 var time = checkDate.getTime(); 10991 checkDate.setMonth(0); // Compare with Jan 1 10992 checkDate.setDate(1); 10993 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; 10994 }, 10995 10996 /* Parse a string value into a date object. 10997 See formatDate below for the possible formats. 10998
10999 @param format string - the expected format of the date 11000 @param value string - the date in the above format 11001 @param settings Object - attributes include: 11002 shortYearCutoff number - the cutoff year for determining the century (optional) 11003 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 11004 dayNames string[7] - names of the days from Sunday (optional) 11005 monthNamesShort string[12] - abbreviated names of the months (optional) 11006 monthNames string[12] - names of the months (optional) 11007 @return Date - the extracted date value or null if value is blank */ 11008 parseDate: function (format, value, settings) { 11009 if (format == null || value == null) 11010 throw 'Invalid arguments'; 11011 value = (typeof value == 'object' ? value.toString() : value + ''); 11012 if (value == '') 11013 return null; 11014 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; 11015 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 11016 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 11017 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 11018 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 11019 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 11020 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 11021 var year = -1; 11022 var month = -1; 11023 var day = -1; 11024 var doy = -1; 11025 var literal = false; 11026 // Check whether a format character is doubled 11027 var lookAhead = function(match) { 11028 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 11029 if (matches) 11030 iFormat++; 11031 return matches; 11032 }; 11033 // Extract a number from the string value 11034 var getNumber = function(match) { 11035 var isDoubled = lookAhead(match); 11036 var size = (match == '@' ? 14 : (match == '!' ? 20 : 11037 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); 11038 var digits = new RegExp('^\\d{1,' + size + '}'); 11039 var num = value.substring(iValue).match(digits); 11040 if (!num) 11041 throw 'Missing number at position ' + iValue; 11042 iValue += num[0].length; 11043 return parseInt(num[0], 10); 11044 }; 11045 // Extract a name from the string value and convert to an index 11046 var getName = function(match, shortNames, longNames) { 11047 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 11048 return [ [k, v] ]; 11049 }).sort(function (a, b) { 11050 return -(a[1].length - b[1].length); 11051 }); 11052 var index = -1; 11053 $.each(names, function (i, pair) { 11054 var name = pair[1]; 11055 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { 11056 index = pair[0]; 11057 iValue += name.length; 11058 return false; 11059 } 11060 }); 11061 if (index != -1) 11062 return index + 1; 11063 else 11064 throw 'Unknown name at position ' + iValue; 11065 }; 11066 // Confirm that a literal character matches the string value 11067 var checkLiteral = function() { 11068 if (value.charAt(iValue) != format.charAt(iFormat)) 11069 throw 'Unexpected literal at position ' + iValue; 11070 iValue++; 11071 }; 11072 var iValue = 0; 11073 for (var iFormat = 0; iFormat < format.length; iFormat++) { 11074 if (literal) 11075 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 11076 literal = false; 11077 else 11078 checkLiteral(); 11079 else 11080 switch (format.charAt(iFormat)) { 11081 case 'd': 11082 day = getNumber('d'); 11083 break; 11084 case 'D': 11085 getName('D', dayNamesShort, dayNames); 11086 break; 11087 case 'o': 11088 doy = getNumber('o'); 11089 break; 11090 case 'm': 11091 month = getNumber('m'); 11092 break; 11093 case 'M': 11094 month = getName('M', monthNamesShort, monthNames); 11095 break; 11096 case 'y': 11097 year = getNumber('y'); 11098 break; 11099 case '@': 11100 var date = new Date(getNumber('@')); 11101 year = date.getFullYear(); 11102 month = date.getMonth() + 1; 11103 day = date.getDate(); 11104 break; 11105 case '!': 11106 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); 11107 year = date.getFullYear();
11108 month = date.getMonth() + 1; 11109 day = date.getDate(); 11110 break; 11111 case "'": 11112 if (lookAhead("'")) 11113 checkLiteral(); 11114 else 11115 literal = true; 11116 break; 11117 default: 11118 checkLiteral(); 11119 } 11120 } 11121 if (iValue < value.length){ 11122 var extra = value.substr(iValue); 11123 if (!/^\s+/.test(extra)) { 11124 throw "Extra/unparsed characters found in date: " + extra; 11125 } 11126 } 11127 if (year == -1) 11128 year = new Date().getFullYear(); 11129 else if (year < 100) 11130 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 11131 (year <= shortYearCutoff ? 0 : -100); 11132 if (doy > -1) { 11133 month = 1; 11134 day = doy; 11135 do { 11136 var dim = this._getDaysInMonth(year, month - 1); 11137 if (day <= dim) 11138 break; 11139 month++; 11140 day -= dim; 11141 } while (true); 11142 } 11143 var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 11144 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 11145 throw 'Invalid date'; // E.g. 31/02/00 11146 return date; 11147 }, 11148 11149 /* Standard date formats. */ 11150 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) 11151 COOKIE: 'D, dd M yy', 11152 ISO_8601: 'yy-mm-dd', 11153 RFC_822: 'D, d M y', 11154 RFC_850: 'DD, dd-M-y', 11155 RFC_1036: 'D, d M y', 11156 RFC_1123: 'D, d M yy', 11157 RFC_2822: 'D, d M yy', 11158 RSS: 'D, d M y', // RFC 822 11159 TICKS: '!', 11160 TIMESTAMP: '@', 11161 W3C: 'yy-mm-dd', // ISO 8601 11162 11163 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + 11164 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), 11165 11166 /* Format a date object into a string value. 11167 The format can be combinations of the following: 11168 d - day of month (no leading zero) 11169 dd - day of month (two digit) 11170 o - day of year (no leading zeros) 11171 oo - day of year (three digit) 11172 D - day name short 11173 DD - day name long 11174 m - month of year (no leading zero) 11175 mm - month of year (two digit) 11176 M - month name short 11177 MM - month name long 11178 y - year (two digit) 11179 yy - year (four digit) 11180 @ - Unix timestamp (ms since 01/01/1970) 11181 ! - Windows ticks (100ns since 01/01/0001) 11182 '...' - literal text 11183 '' - single quote 11184 11185 @param format string - the desired format of the date 11186 @param date Date - the date value to format 11187 @param settings Object - attributes include: 11188 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 11189 dayNames string[7] - names of the days from Sunday (optional) 11190 monthNamesShort string[12] - abbreviated names of the months (optional) 11191 monthNames string[12] - names of the months (optional) 11192 @return string - the date in the above format */ 11193 formatDate: function (format, date, settings) { 11194 if (!date) 11195 return ''; 11196 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; 11197 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; 11198 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; 11199 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; 11200 // Check whether a format character is doubled 11201 var lookAhead = function(match) { 11202 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 11203 if (matches) 11204 iFormat++; 11205 return matches; 11206 }; 11207 // Format a number, with leading zero if necessary 11208 var formatNumber = function(match, value, len) { 11209 var num = '' + value; 11210 if (lookAhead(match)) 11211 while (num.length < len) 11212 num = '0' + num; 11213 return num; 11214 }; 11215 // Format a name, short or long as requested 11216 var formatName = function(match, value, shortNames, longNames) { 11217 return (lookAhead(match) ? longNames[value] : shortNames[value]); 11218 }; 11219 var output = ''; 11220 var literal = false; 11221 if (date) 11222 for (var iFormat = 0; iFormat < format.length; iFormat++) { 11223 if (literal) 11224 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 11225 literal = false; 11226 else 11227 output += format.charAt(iFormat); 11228 else 11229 switch (format.charAt(iFormat)) { 11230 case 'd': 11231 output += formatNumber('d', date.getDate(), 2); 11232 break; 11233 case 'D': 11234 output += formatName('D', date.getDay(), dayNamesShort, dayNames); 11235 break; 11236 case 'o': 11237 output += formatNumber('o', 11238 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 11239 break; 11240 case 'm': 11241 output += formatNumber('m', date.getMonth() + 1, 2); 11242 break; 11243 case 'M': 11244 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 11245 break; 11246 case 'y': 11247 output += (lookAhead('y') ? date.getFullYear() : 11248 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); 11249 break; 11250 case '@': 11251 output += date.getTime(); 11252 break; 11253 case '!': 11254 output += date.getTime() * 10000 + this._ticksTo1970; 11255 break;
11256 case "'": 11257 if (lookAhead("'")) 11258 output += "'"; 11259 else 11260 literal = true; 11261 break; 11262 default: 11263 output += format.charAt(iFormat); 11264 } 11265 } 11266 return output; 11267 }, 11268 11269 /* Extract all possible characters from the date format. */ 11270 _possibleChars: function (format) { 11271 var chars = ''; 11272 var literal = false; 11273 // Check whether a format character is doubled 11274 var lookAhead = function(match) { 11275 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); 11276 if (matches) 11277 iFormat++; 11278 return matches; 11279 }; 11280 for (var iFormat = 0; iFormat < format.length; iFormat++) 11281 if (literal) 11282 if (format.charAt(iFormat) == "'" && !lookAhead("'")) 11283 literal = false; 11284 else 11285 chars += format.charAt(iFormat); 11286 else 11287 switch (format.charAt(iFormat)) { 11288 case 'd': case 'm': case 'y': case '@': 11289 chars += '0123456789'; 11290 break; 11291 case 'D': case 'M': 11292 return null; // Accept anything 11293 case "'": 11294 if (lookAhead("'")) 11295 chars += "'"; 11296 else 11297 literal = true; 11298 break; 11299 default: 11300 chars += format.charAt(iFormat); 11301 } 11302 return chars; 11303 }, 11304 11305 /* Get a setting value, defaulting if necessary. */ 11306 _get: function(inst, name) { 11307 return inst.settings[name] !== undefined ? 11308 inst.settings[name] : this._defaults[name]; 11309 }, 11310 11311 /* Parse existing date and initialise date picker. */ 11312 _setDateFromField: function(inst, noDefault) { 11313 if (inst.input.val() == inst.lastVal) { 11314 return; 11315 } 11316 var dateFormat = this._get(inst, 'dateFormat'); 11317 var dates = inst.lastVal = inst.input ? inst.input.val() : null; 11318 var date, defaultDate; 11319 date = defaultDate = this._getDefaultDate(inst); 11320 var settings = this._getFormatConfig(inst); 11321 try { 11322 date = this.parseDate(dateFormat, dates, settings) || defaultDate; 11323 } catch (event) { 11324 this.log(event); 11325 dates = (noDefault ? '' : dates); 11326 } 11327 inst.selectedDay = date.getDate(); 11328 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11329 inst.drawYear = inst.selectedYear = date.getFullYear(); 11330 inst.currentDay = (dates ? date.getDate() : 0); 11331 inst.currentMonth = (dates ? date.getMonth() : 0); 11332 inst.currentYear = (dates ? date.getFullYear() : 0); 11333 this._adjustInstDate(inst); 11334 }, 11335 11336 /* Retrieve the default date shown on opening. */ 11337 _getDefaultDate: function(inst) { 11338 return this._restrictMinMax(inst, 11339 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); 11340 }, 11341 11342 /* A date may be specified as an exact value or a relative one. */ 11343 _determineDate: function(inst, date, defaultDate) { 11344 var offsetNumeric = function(offset) { 11345 var date = new Date(); 11346 date.setDate(date.getDate() + offset); 11347 return date; 11348 }; 11349 var offsetString = function(offset) { 11350 try { 11351 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), 11352 offset, $.datepicker._getFormatConfig(inst)); 11353 } 11354 catch (e) { 11355 // Ignore 11356 } 11357 var date = (offset.toLowerCase().match(/^c/) ? 11358 $.datepicker._getDate(inst) : null) || new Date(); 11359 var year = date.getFullYear(); 11360 var month = date.getMonth(); 11361 var day = date.getDate(); 11362 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; 11363 var matches = pattern.exec(offset); 11364 while (matches) { 11365 switch (matches[2] || 'd') { 11366 case 'd' : case 'D' : 11367 day += parseInt(matches[1],10); break; 11368 case 'w' : case 'W' : 11369 day += parseInt(matches[1],10) * 7; break; 11370 case 'm' : case 'M' : 11371 month += parseInt(matches[1],10); 11372 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 11373 break; 11374 case 'y': case 'Y' : 11375 year += parseInt(matches[1],10); 11376 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); 11377 break; 11378 } 11379 matches = pattern.exec(offset); 11380 } 11381 return new Date(year, month, day); 11382 }; 11383 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : 11384 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); 11385 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); 11386 if (newDate) { 11387 newDate.setHours(0); 11388 newDate.setMinutes(0); 11389 newDate.setSeconds(0); 11390 newDate.setMilliseconds(0); 11391 } 11392 return this._daylightSavingAdjust(newDate); 11393 }, 11394 11395 /* Handle switch to/from daylight saving. 11396 Hours may be non-zero on daylight saving cut-over: 11397 > 12 when midnight changeover, but then cannot generate 11398 midnight datetime, so jump to 1AM, otherwise reset. 11399 @param date (Date) the date to check 11400 @return (Date) the corrected date */ 11401 _daylightSavingAdjust: function(date) { 11402 if (!date) return null; 11403 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); 11404 return date; 11405 }, 11406 11407 /* Set the date(s) directly. */ 11408 _setDate: function(inst, date, noChange) { 11409 var clear = !date; 11410 var origMonth = inst.selectedMonth; 11411 var origYear = inst.selectedYear; 11412 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); 11413 inst.selectedDay = inst.currentDay = newDate.getDate(); 11414 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 11415 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 11416 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) 11417 this._notifyChange(inst); 11418 this._adjustInstDate(inst); 11419 if (inst.input) { 11420 inst.input.val(clear ? '' : this._formatDate(inst)); 11421 } 11422 }, 11423 11424 /* Retrieve the date(s) directly. */ 11425 _getDate: function(inst) { 11426 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : 11427 this._daylightSavingAdjust(new Date( 11428 inst.currentYear, inst.currentMonth, inst.currentDay))); 11429 return startDate; 11430 }, 11431 11432 /* Attach the onxxx handlers. These are declared statically so 11433 * they work with static code transformers like Caja. 11434 */ 11435 _attachHandlers: function(inst) { 11436 var stepMonths = this._get(inst, 'stepMonths'); 11437 var id = '#' + inst.id.replace( /\\\\/g, "\\" );
11438 inst.dpDiv.find('[data-handler]').map(function () { 11439 var handler = { 11440 prev: function () { 11441 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); 11442 }, 11443 next: function () { 11444 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); 11445 }, 11446 hide: function () { 11447 window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); 11448 }, 11449 today: function () { 11450 window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); 11451 }, 11452 selectDay: function () { 11453 window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); 11454 return false; 11455 }, 11456 selectMonth: function () { 11457 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); 11458 return false; 11459 }, 11460 selectYear: function () { 11461 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); 11462 return false; 11463 } 11464 }; 11465 $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]); 11466 }); 11467 }, 11468 11469 /* Generate the HTML for the current state of the date picker. */ 11470 _generateHTML: function(inst) { 11471 var today = new Date(); 11472 today = this._daylightSavingAdjust( 11473 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time 11474 var isRTL = this._get(inst, 'isRTL'); 11475 var showButtonPanel = this._get(inst, 'showButtonPanel'); 11476 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); 11477 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); 11478 var numMonths = this._getNumberOfMonths(inst); 11479 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); 11480 var stepMonths = this._get(inst, 'stepMonths'); 11481 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); 11482 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : 11483 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 11484 var minDate = this._getMinMaxDate(inst, 'min'); 11485 var maxDate = this._getMinMaxDate(inst, 'max'); 11486 var drawMonth = inst.drawMonth - showCurrentAtPos; 11487 var drawYear = inst.drawYear; 11488 if (drawMonth < 0) { 11489 drawMonth += 12; 11490 drawYear--; 11491 } 11492 if (maxDate) { 11493 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), 11494 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); 11495 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); 11496 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { 11497 drawMonth--; 11498 if (drawMonth < 0) { 11499 drawMonth = 11; 11500 drawYear--; 11501 } 11502 } 11503 } 11504 inst.drawMonth = drawMonth; 11505 inst.drawYear = drawYear; 11506 var prevText = this._get(inst, 'prevText'); 11507 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, 11508 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), 11509 this._getFormatConfig(inst))); 11510 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 11511 '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' + 11512 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : 11513 (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>')); 11514 var nextText = this._get(inst, 'nextText'); 11515 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, 11516 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), 11517 this._getFormatConfig(inst))); 11518 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? 11519 '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' + 11520 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : 11521 (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>')); 11522 var currentText = this._get(inst, 'currentText'); 11523 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); 11524 currentText = (!navigationAsDateFormat ? currentText : 11525 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); 11526 var 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">' + 11527 this._get(inst, 'closeText') + '</button>' : ''); 11528 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + 11529 (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"' + 11530 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; 11531 var firstDay = parseInt(this._get(inst, 'firstDay'),10); 11532 firstDay = (isNaN(firstDay) ? 0 : firstDay); 11533 var showWeek = this._get(inst, 'showWeek'); 11534 var dayNames = this._get(inst, 'dayNames'); 11535 var dayNamesShort = this._get(inst, 'dayNamesShort'); 11536 var dayNamesMin = this._get(inst, 'dayNamesMin'); 11537 var monthNames = this._get(inst, 'monthNames'); 11538 var monthNamesShort = this._get(inst, 'monthNamesShort'); 11539 var beforeShowDay = this._get(inst, 'beforeShowDay'); 11540 var showOtherMonths = this._get(inst, 'showOtherMonths'); 11541 var selectOtherMonths = this._get(inst, 'selectOtherMonths'); 11542 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; 11543 var defaultDate = this._getDefaultDate(inst); 11544 var html = ''; 11545 for (var row = 0; row < numMonths[0]; row++) { 11546 var group = ''; 11547 this.maxRows = 4; 11548 for (var col = 0; col < numMonths[1]; col++) { 11549 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); 11550 var cornerClass = ' ui-corner-all'; 11551 var calender = ''; 11552 if (isMultiMonth) { 11553 calender += '<div class="ui-datepicker-group'; 11554 if (numMonths[1] > 1) 11555 switch (col) { 11556 case 0: calender += ' ui-datepicker-group-first'; 11557 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; 11558 case numMonths[1]-1: calender += ' ui-datepicker-group-last'; 11559 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; 11560 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break; 11561 } 11562 calender += '">'; 11563 } 11564 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + 11565 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + 11566 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + 11567 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, 11568 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers 11569 '</div><table class="ui-datepicker-calendar"><thead>' + 11570 '<tr>'; 11571 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''); 11572 for (var dow = 0; dow < 7; dow++) { // days of the week 11573 var day = (dow + firstDay) % 7; 11574 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
11574' + 11575 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>'; 11576 } 11577 calender += thead + '</tr></thead><tbody>'; 11578 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); 11579 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) 11580 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 11581 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 11582 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 11583 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 11584 this.maxRows = numRows; 11585 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 11586 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows 11587 calender += '<tr>'; 11588 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' + 11589 this._get(inst, 'calculateWeek')(printDate) + '</td>'); 11590 for (var dow = 0; dow < 7; dow++) { // create date picker days 11591 var daySettings = (beforeShowDay ? 11592 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); 11593 var otherMonth = (printDate.getMonth() != drawMonth); 11594 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || 11595 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); 11596 tbody += '<td class="' + 11597 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends 11598 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months 11599 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key 11600 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ? 11601 // or defaultDate is current printedDate and defaultDate is selectedDate 11602 ' ' + this._dayOverClass : '') + // highlight selected day 11603 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days 11604 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates 11605 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day 11606 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) 11607 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title 11608 (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions 11609 (otherMonth && !showOtherMonths ? ' ' : // display for other months 11610 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + 11611 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + 11612 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day 11613 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months 11614 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date 11615 printDate.setDate(printDate.getDate() + 1); 11616 printDate = this._daylightSavingAdjust(printDate); 11617 } 11618 calender += tbody + '</tr>'; 11619 } 11620 drawMonth++; 11621 if (drawMonth > 11) { 11622 drawMonth = 0; 11623 drawYear++; 11624 } 11625 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 11626 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); 11627 group += calender; 11628 } 11629 html += group; 11630 } 11631 html += buttonPanel + ($.ui.ie6 && !inst.inline ? 11632 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : ''); 11633 inst._keyEvent = false; 11634 return html; 11635 }, 11636 11637 /* Generate the month and year header. */ 11638 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, 11639 secondary, monthNames, monthNamesShort) { 11640 var changeMonth = this._get(inst, 'changeMonth'); 11641 var changeYear = this._get(inst, 'changeYear'); 11642 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); 11643 var html = '<div class="ui-datepicker-title">'; 11644 var monthHtml = ''; 11645 // month selection 11646 if (secondary || !changeMonth) 11647 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; 11648 else { 11649 var inMinYear = (minDate && minDate.getFullYear() == drawYear); 11650 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); 11651 monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
11652 for (var month = 0; month < 12; month++) { 11653 if ((!inMinYear || month >= minDate.getMonth()) && 11654 (!inMaxYear || month <= maxDate.getMonth())) 11655 monthHtml += '<option value="' + month + '"' + 11656 (month == drawMonth ? ' selected="selected"' : '') + 11657 '>' + monthNamesShort[month] + '</option>'; 11658 } 11659 monthHtml += '</select>'; 11660 } 11661 if (!showMonthAfterYear) 11662 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); 11663 // year selection 11664 if ( !inst.yearshtml ) { 11665 inst.yearshtml = ''; 11666 if (secondary || !changeYear) 11667 html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; 11668 else { 11669 // determine range of years to display 11670 var years = this._get(inst, 'yearRange').split(':'); 11671 var thisYear = new Date().getFullYear(); 11672 var determineYear = function(value) { 11673 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 11674 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 11675 parseInt(value, 10))); 11676 return (isNaN(year) ? thisYear : year); 11677 }; 11678 var year = determineYear(years[0]); 11679 var endYear = Math.max(year, determineYear(years[1] || '')); 11680 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 11681 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 11682 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">'; 11683 for (; year <= endYear; year++) { 11684 inst.yearshtml += '<option value="' + year + '"' + 11685 (year == drawYear ? ' selected="selected"' : '') + 11686 '>' + year + '</option>'; 11687 } 11688 inst.yearshtml += '</select>'; 11689 11690 html += inst.yearshtml; 11691 inst.yearshtml = null; 11692 } 11693 } 11694 html += this._get(inst, 'yearSuffix'); 11695 if (showMonthAfterYear) 11696 html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; 11697 html += '</div>'; // Close datepicker_header 11698 return html; 11699 }, 11700 11701 /* Adjust one of the date sub-fields. */ 11702 _adjustInstDate: function(inst, offset, period) { 11703 var year = inst.drawYear + (period == 'Y' ? offset : 0); 11704 var month = inst.drawMonth + (period == 'M' ? offset : 0); 11705 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + 11706 (period == 'D' ? offset : 0); 11707 var date = this._restrictMinMax(inst, 11708 this._daylightSavingAdjust(new Date(year, month, day))); 11709 inst.selectedDay = date.getDate(); 11710 inst.drawMonth = inst.selectedMonth = date.getMonth(); 11711 inst.drawYear = inst.selectedYear = date.getFullYear(); 11712 if (period == 'M' || period == 'Y') 11713 this._notifyChange(inst); 11714 }, 11715 11716 /* Ensure a date is within any min/max bounds. */ 11717 _restrictMinMax: function(inst, date) { 11718 var minDate = this._getMinMaxDate(inst, 'min'); 11719 var maxDate = this._getMinMaxDate(inst, 'max'); 11720 var newDate = (minDate && date < minDate ? minDate : date); 11721 newDate = (maxDate && newDate > maxDate ? maxDate : newDate); 11722 return newDate; 11723 }, 11724 11725 /* Notify change of month/year. */ 11726 _notifyChange: function(inst) { 11727 var onChange = this._get(inst, 'onChangeMonthYear'); 11728 if (onChange) 11729 onChange.apply((inst.input ? inst.input[0] : null), 11730 [inst.selectedYear, inst.selectedMonth + 1, inst]); 11731 }, 11732 11733 /* Determine the number of months to show. */ 11734 _getNumberOfMonths: function(inst) { 11735 var numMonths = this._get(inst, 'numberOfMonths'); 11736 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); 11737 }, 11738 11739 /* Determine the current maximum date - ensure no time components are set. */ 11740 _getMinMaxDate: function(inst, minMax) { 11741 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); 11742 }, 11743 11744 /* Find the number of days in a given month. */ 11745 _getDaysInMonth: function(year, month) { 11746 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); 11747 }, 11748 11749 /* Find the day of the week of the first of a month. */ 11750 _getFirstDayOfMonth: function(year, month) { 11751 return new Date(year, month, 1).getDay(); 11752 }, 11753 11754 /* Determines if we should allow a "next/prev" month display change. */ 11755 _canAdjustMonth: function(inst, offset, curYear, curMonth) { 11756 var numMonths = this._getNumberOfMonths(inst); 11757 var date = this._daylightSavingAdjust(new Date(curYear, 11758 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); 11759 if (offset < 0) 11760 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); 11761 return this._isInRange(inst, date); 11762 }, 11763 11764 /* Is the given date in the accepted range? */ 11765 _isInRange: function(inst, date) { 11766 var minDate = this._getMinMaxDate(inst, 'min'); 11767 var maxDate = this._getMinMaxDate(inst, 'max'); 11768 return ((!minDate || date.getTime() >= minDate.getTime()) && 11769 (!maxDate || date.getTime() <= maxDate.getTime())); 11770 }, 11771 11772 /* Provide the configuration settings for formatting/parsing. */ 11773 _getFormatConfig: function(inst) { 11774 var shortYearCutoff = this._get(inst, 'shortYearCutoff'); 11775 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : 11776 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); 11777 return {shortYearCutoff: shortYearCutoff, 11778 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), 11779 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; 11780 }, 11781 11782 /* Format the given date for display. */ 11783 _formatDate: function(inst, day, month, year) { 11784 if (!day) { 11785 inst.currentDay = inst.selectedDay; 11786 inst.currentMonth = inst.selectedMonth; 11787 inst.currentYear = inst.selectedYear; 11788 } 11789 var date = (day ? (typeof day == 'object' ? day : 11790 this._daylightSavingAdjust(new Date(year, month, day))) : 11791 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); 11792 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); 11793 } 11794}); 11795 11796/* 11797 * Bind hover events for datepicker elements. 11798 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 11799 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 11800 */ 11801function bindHover(dpDiv) { 11802 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; 11803 return dpDiv.delegate(selector, 'mouseout', function() { 11804 $(this).removeClass('ui-state-hover'); 11805 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); 11806 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); 11807 }) 11808 .delegate(selector, 'mouseover', function(){ 11809 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { 11810 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 11811 $(this).addClass('ui-state-hover'); 11812 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); 11813 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); 11814 } 11815 }); 11816} 11817 11818/* jQuery extend now ignores nulls! */ 11819function extendRemove(target, props) { 11820 $.extend(target, props); 11821 for (var name in props) 11822 if (props[name] == null || props[name] == undefined) 11823 target[name] = props[name]; 11824 return target; 11825}; 11826 11827/* Invoke the datepicker functionality. 11828 @param options string - a command, optionally followed by additional parameters or 11829 Object - settings for attaching new datepicker functionality 11830 @return jQuery object */ 11831$.fn.datepicker = function(options){ 11832 11833 /* Verify an empty collection wasn't passed - Fixes #6976 */ 11834 if ( !this.length ) { 11835 return this; 11836 } 11837 11838 /* Initialise the date picker. */ 11839 if (!$.datepicker.initialized) { 11840 $(document).mousedown($.datepicker._checkExternalClick). 11841 find(document.body).append($.datepicker.dpDiv); 11842 $.datepicker.initialized = true; 11843 } 11844 11845 var otherArgs = Array.prototype.slice.call(arguments, 1); 11846 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) 11847 return $.datepicker['_' + options + 'Datepicker']. 11848 apply($.datepicker, [this[0]].concat(otherArgs)); 11849 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') 11850 return $.datepicker['_' + options + 'Datepicker']. 11851 apply($.datepicker, [this[0]].concat(otherArgs)); 11852 return this.each(function() { 11853 typeof options == 'string' ? 11854 $.datepicker['_' + options + 'Datepicker']. 11855 apply($.datepicker, [this].concat(otherArgs)) : 11856 $.datepicker._attachDatepicker(this, options); 11857 }); 11858}; 11859 11860$.datepicker = new Datepicker(); // singleton instance 11861$.datepicker.initialized = false;
11862$.datepicker.uuid = new Date().getTime(); 11863$.datepicker.version = "1.9.1"; 11864 11865// Workaround for #4055 11866// Add another global to avoid noConflict issues with inline event handlers 11867window['DP_jQuery_' + dpuuid] = $; 11868 11869})(jQuery); 11870 11871(function( $, undefined ) { 11872 11873var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", 11874 sizeRelatedOptions = { 11875 buttons: true, 11876 height: true, 11877 maxHeight: true, 11878 maxWidth: true, 11879 minHeight: true, 11880 minWidth: true, 11881 width: true 11882 }, 11883 resizableRelatedOptions = { 11884 maxHeight: true, 11885 maxWidth: true, 11886 minHeight: true, 11887 minWidth: true 11888 }; 11889 11890$.widget("ui.dialog", { 11891 version: "1.9.1", 11892 options: { 11893 autoOpen: true, 11894 buttons: {}, 11895 closeOnEscape: true, 11896 closeText: "close", 11897 dialogClass: "", 11898 draggable: true, 11899 hide: null, 11900 height: "auto", 11901 maxHeight: false, 11902 maxWidth: false, 11903 minHeight: 150, 11904 minWidth: 150, 11905 modal: false, 11906 position: { 11907 my: "center", 11908 at: "center", 11909 of: window, 11910 collision: "fit", 11911 // ensure that the titlebar is never outside the document 11912 using: function( pos ) { 11913 var topOffset = $( this ).css( pos ).offset().top; 11914 if ( topOffset < 0 ) { 11915 $( this ).css( "top", pos.top - topOffset ); 11916 } 11917 } 11918 }, 11919 resizable: true, 11920 show: null, 11921 stack: true, 11922 title: "", 11923 width: 300, 11924 zIndex: 1000 11925 }, 11926 11927 _create: function() { 11928 this.originalTitle = this.element.attr( "title" ); 11929 // #5742 - .attr() might return a DOMElement 11930 if ( typeof this.originalTitle !== "string" ) { 11931 this.originalTitle = ""; 11932 } 11933 this.oldPosition = { 11934 parent: this.element.parent(), 11935 index: this.element.parent().children().index( this.element ) 11936 }; 11937 this.options.title = this.options.title || this.originalTitle; 11938 var that = this, 11939 options = this.options, 11940 11941 title = options.title || " ", 11942 uiDialog, 11943 uiDialogTitlebar, 11944 uiDialogTitlebarClose, 11945 uiDialogTitle, 11946 uiDialogButtonPane; 11947 11948 uiDialog = ( this.uiDialog = $( "<div>" ) ) 11949 .addClass( uiDialogClasses + options.dialogClass ) 11950 .css({ 11951 display: "none", 11952 outline: 0, // TODO: move to stylesheet 11953 zIndex: options.zIndex 11954 }) 11955 // setting tabIndex makes the div focusable 11956 .attr( "tabIndex", -1) 11957 .keydown(function( event ) { 11958 if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 11959 event.keyCode === $.ui.keyCode.ESCAPE ) { 11960 that.close( event ); 11961 event.preventDefault(); 11962 } 11963 }) 11964 .mousedown(function( event ) { 11965 that.moveToTop( false, event ); 11966 }) 11967 .appendTo( "body" ); 11968 11969 this.element 11970 .show() 11971 .removeAttr( "title" ) 11972 .addClass( "ui-dialog-content ui-widget-content" ) 11973 .appendTo( uiDialog ); 11974 11975 uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) ) 11976 .addClass( "ui-dialog-titlebar ui-widget-header " + 11977 "ui-corner-all ui-helper-clearfix" ) 11978 .bind( "mousedown", function() { 11979 // Dialog isn't getting focus when dragging (#8063) 11980 uiDialog.focus(); 11981 }) 11982 .prependTo( uiDialog ); 11983 11984 uiDialogTitlebarClose = $( "<a href='#'></a>" ) 11985 .addClass( "ui-dialog-titlebar-close ui-corner-all" ) 11986 .attr( "role", "button" ) 11987 .click(function( event ) { 11988 event.preventDefault(); 11989 that.close( event ); 11990 }) 11991 .appendTo( uiDialogTitlebar ); 11992 11993 ( this.uiDialogTitlebarCloseText = $( "<span>" ) ) 11994 .addClass( "ui-icon ui-icon-closethick" ) 11995 .text( options.closeText ) 11996 .appendTo( uiDialogTitlebarClose ); 11997 11998 uiDialogTitle = $( "<span>" ) 11999 .uniqueId() 12000 .addClass( "ui-dialog-title" ) 12001 .html( title ) 12002 .prependTo( uiDialogTitlebar ); 12003 12004 uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) ) 12005 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); 12006 12007 ( this.uiButtonSet = $( "<div>" ) ) 12008 .addClass( "ui-dialog-buttonset" ) 12009 .appendTo( uiDialogButtonPane ); 12010 12011 uiDialog.attr({ 12012 role: "dialog", 12013 "aria-labelledby": uiDialogTitle.attr( "id" ) 12014 }); 12015 12016 uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); 12017 this._hoverable( uiDialogTitlebarClose ); 12018 this._focusable( uiDialogTitlebarClose ); 12019 12020 if ( options.draggable && $.fn.draggable ) { 12021 this._makeDraggable(); 12022 } 12023 if ( options.resizable && $.fn.resizable ) { 12024 this._makeResizable(); 12025 } 12026
12027 this._createButtons( options.buttons ); 12028 this._isOpen = false; 12029 12030 if ( $.fn.bgiframe ) { 12031 uiDialog.bgiframe(); 12032 } 12033 12034 // prevent tabbing out of modal dialogs 12035 this._on( uiDialog, { keydown: function( event ) { 12036 if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { 12037 return; 12038 } 12039 12040 var tabbables = $( ":tabbable", uiDialog ), 12041 first = tabbables.filter( ":first" ), 12042 last = tabbables.filter( ":last" ); 12043 12044 if ( event.target === last[0] && !event.shiftKey ) { 12045 first.focus( 1 ); 12046 return false; 12047 } else if ( event.target === first[0] && event.shiftKey ) { 12048 last.focus( 1 ); 12049 return false; 12050 } 12051 }}); 12052 }, 12053 12054 _init: function() { 12055 if ( this.options.autoOpen ) { 12056 this.open(); 12057 } 12058 }, 12059 12060 _destroy: function() { 12061 var next, 12062 oldPosition = this.oldPosition; 12063 12064 if ( this.overlay ) { 12065 this.overlay.destroy(); 12066 } 12067 this.uiDialog.hide(); 12068 this.element 12069 .removeClass( "ui-dialog-content ui-widget-content" ) 12070 .hide() 12071 .appendTo( "body" ); 12072 this.uiDialog.remove(); 12073 12074 if ( this.originalTitle ) { 12075 this.element.attr( "title", this.originalTitle ); 12076 } 12077 12078 next = oldPosition.parent.children().eq( oldPosition.index ); 12079 // Don't try to place the dialog next to itself (#8613) 12080 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 12081 next.before( this.element ); 12082 } else { 12083 oldPosition.parent.append( this.element ); 12084 } 12085 }, 12086 12087 widget: function() { 12088 return this.uiDialog; 12089 }, 12090 12091 close: function( event ) { 12092 var that = this, 12093 maxZ, thisZ; 12094 12095 if ( !this._isOpen ) { 12096 return; 12097 } 12098 12099 if ( false === this._trigger( "beforeClose", event ) ) { 12100 return; 12101 } 12102 12103 this._isOpen = false; 12104 12105 if ( this.overlay ) { 12106 this.overlay.destroy(); 12107 } 12108 12109 if ( this.options.hide ) { 12110 this._hide( this.uiDialog, this.options.hide, function() { 12111 that._trigger( "close", event ); 12112 }); 12113 } else { 12114 this.uiDialog.hide(); 12115 this._trigger( "close", event ); 12116 } 12117 12118 $.ui.dialog.overlay.resize(); 12119 12120 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 12121 if ( this.options.modal ) { 12122 maxZ = 0; 12123 $( ".ui-dialog" ).each(function() { 12124 if ( this !== that.uiDialog[0] ) { 12125 thisZ = $( this ).css( "z-index" ); 12126 if ( !isNaN( thisZ ) ) { 12127 maxZ = Math.max( maxZ, thisZ ); 12128 } 12129 } 12130 }); 12131 $.ui.dialog.maxZ = maxZ; 12132 } 12133 12134 return this; 12135 }, 12136 12137 isOpen: function() { 12138 return this._isOpen; 12139 }, 12140 12141 // the force parameter allows us to move modal dialogs to their correct 12142 // position on open 12143 moveToTop: function( force, event ) { 12144 var options = this.options, 12145 saveScroll; 12146 12147 if ( ( options.modal && !force ) || 12148 ( !options.stack && !options.modal ) ) { 12149 return this._trigger( "focus", event ); 12150 } 12151 12152 if ( options.zIndex > $.ui.dialog.maxZ ) { 12153 $.ui.dialog.maxZ = options.zIndex; 12154 } 12155 if ( this.overlay ) { 12156 $.ui.dialog.maxZ += 1; 12157 $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; 12158 this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); 12159 } 12160 12161 // Save and then restore scroll 12162 // Opera 9.5+ resets when parent z-index is changed. 12163 // http://bugs.jqueryui.com/ticket/3193 12164 saveScroll = { 12165 scrollTop: this.element.scrollTop(), 12166 scrollLeft: this.element.scrollLeft() 12167 }; 12168 $.ui.dialog.maxZ += 1; 12169 this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); 12170 this.element.attr( saveScroll ); 12171 this._trigger( "focus", event ); 12172 12173 return this; 12174 }, 12175 12176 open: function() { 12177 if ( this._isOpen ) { 12178 return; 12179 } 12180 12181 var hasFocus, 12182 options = this.options, 12183 uiDialog = this.uiDialog; 12184 12185 this._size(); 12186 this._position( options.position ); 12187 uiDialog.show( options.show ); 12188 this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; 12189 this.moveToTop( true ); 12190 12191 // set focus to the first tabbable element in the content area or the first button 12192 // if there are no tabbable elements, set focus on the dialog itself 12193 hasFocus = this.element.find( ":tabbable" ); 12194 if ( !hasFocus.length ) { 12195 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 12196 if ( !hasFocus.length ) { 12197 hasFocus = uiDialog; 12198 } 12199 } 12200 hasFocus.eq( 0 ).focus(); 12201 12202 this._isOpen = true; 12203 this._trigger( "open" ); 12204 12205 return this; 12206 }, 12207 12208 _createButtons: function( buttons ) { 12209 var that = this, 12210 hasButtons = false;
12211 12212 // if we already have a button pane, remove it 12213 this.uiDialogButtonPane.remove(); 12214 this.uiButtonSet.empty(); 12215 12216 if ( typeof buttons === "object" && buttons !== null ) { 12217 $.each( buttons, function() { 12218 return !(hasButtons = true); 12219 }); 12220 } 12221 if ( hasButtons ) { 12222 $.each( buttons, function( name, props ) { 12223 props = $.isFunction( props ) ? 12224 { click: props, text: name } : 12225 props; 12226 var button = $( "<button type='button'></button>" ) 12227 .attr( props, true ) 12228 .unbind( "click" ) 12229 .click(function() { 12230 props.click.apply( that.element[0], arguments ); 12231 }) 12232 .appendTo( that.uiButtonSet ); 12233 if ( $.fn.button ) { 12234 button.button(); 12235 } 12236 }); 12237 this.uiDialog.addClass( "ui-dialog-buttons" ); 12238 this.uiDialogButtonPane.appendTo( this.uiDialog ); 12239 } else { 12240 this.uiDialog.removeClass( "ui-dialog-buttons" ); 12241 } 12242 }, 12243 12244 _makeDraggable: function() { 12245 var that = this, 12246 options = this.options; 12247 12248 function filteredUi( ui ) { 12249 return { 12250 position: ui.position, 12251 offset: ui.offset 12252 }; 12253 } 12254 12255 this.uiDialog.draggable({ 12256 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 12257 handle: ".ui-dialog-titlebar", 12258 containment: "document", 12259 start: function( event, ui ) { 12260 $( this ) 12261 .addClass( "ui-dialog-dragging" ); 12262 that._trigger( "dragStart", event, filteredUi( ui ) ); 12263 }, 12264 drag: function( event, ui ) { 12265 that._trigger( "drag", event, filteredUi( ui ) ); 12266 }, 12267 stop: function( event, ui ) { 12268 options.position = [ 12269 ui.position.left - that.document.scrollLeft(), 12270 ui.position.top - that.document.scrollTop() 12271 ]; 12272 $( this ) 12273 .removeClass( "ui-dialog-dragging" ); 12274 that._trigger( "dragStop", event, filteredUi( ui ) ); 12275 $.ui.dialog.overlay.resize(); 12276 } 12277 }); 12278 }, 12279 12280 _makeResizable: function( handles ) { 12281 handles = (handles === undefined ? this.options.resizable : handles); 12282 var that = this, 12283 options = this.options, 12284 // .ui-resizable has position: relative defined in the stylesheet 12285 // but dialogs have to use absolute or fixed positioning 12286 position = this.uiDialog.css( "position" ), 12287 resizeHandles = typeof handles === 'string' ? 12288 handles : 12289 "n,e,s,w,se,sw,ne,nw"; 12290 12291 function filteredUi( ui ) { 12292 return { 12293 originalPosition: ui.originalPosition, 12294 originalSize: ui.originalSize, 12295 position: ui.position, 12296 size: ui.size 12297 }; 12298 } 12299 12300 this.uiDialog.resizable({ 12301 cancel: ".ui-dialog-content", 12302 containment: "document", 12303 alsoResize: this.element, 12304 maxWidth: options.maxWidth, 12305 maxHeight: options.maxHeight, 12306 minWidth: options.minWidth, 12307 minHeight: this._minHeight(), 12308 handles: resizeHandles, 12309 start: function( event, ui ) { 12310 $( this ).addClass( "ui-dialog-resizing" ); 12311 that._trigger( "resizeStart", event, filteredUi( ui ) ); 12312 }, 12313 resize: function( event, ui ) { 12314 that._trigger( "resize", event, filteredUi( ui ) ); 12315 }, 12316 stop: function( event, ui ) { 12317 $( this ).removeClass( "ui-dialog-resizing" ); 12318 options.height = $( this ).height(); 12319 options.width = $( this ).width(); 12320 that._trigger( "resizeStop", event, filteredUi( ui ) ); 12321 $.ui.dialog.overlay.resize(); 12322 } 12323 }) 12324 .css( "position", position ) 12325 .find( ".ui-resizable-se" ) 12326 .addClass( "ui-icon ui-icon-grip-diagonal-se" ); 12327 }, 12328 12329 _minHeight: function() { 12330 var options = this.options; 12331 12332 if ( options.height === "auto" ) { 12333 return options.minHeight; 12334 } else { 12335 return Math.min( options.minHeight, options.height ); 12336 } 12337 }, 12338 12339 _position: function( position ) { 12340 var myAt = [], 12341 offset = [ 0, 0 ], 12342 isVisible; 12343 12344 if ( position ) { 12345 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( 12346 // if (typeof position == 'string' || $.isArray(position)) { 12347 // myAt = $.isArray(position) ? position : position.split(' '); 12348 12349 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { 12350 myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; 12351 if ( myAt.length === 1 ) { 12352 myAt[ 1 ] = myAt[ 0 ]; 12353 } 12354 12355 $.each( [ "left", "top" ], function( i, offsetPosition ) { 12356 if ( +myAt[ i ] === myAt[ i ] ) { 12357 offset[ i ] = myAt[ i ]; 12358 myAt[ i ] = offsetPosition; 12359 } 12360 }); 12361 12362 position = { 12363 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + 12364 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), 12365 at: myAt.join( " " ) 12366 }; 12367 } 12368 12369 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); 12370 } else { 12371 position = $.ui.dialog.prototype.options.position; 12372 } 12373 12374 // need to show the dialog to get the actual offset in the position plugin 12375 isVisible = this.uiDialog.is( ":visible" ); 12376 if ( !isVisible ) { 12377 this.uiDialog.show(); 12378 } 12379 this.uiDialog.position( position ); 12380 if ( !isVisible ) { 12381 this.uiDialog.hide(); 12382 } 12383 }, 12384 12385 _setOptions: function( options ) { 12386 var that = this, 12387 resizableOptions = {}, 12388 resize = false;
12389 12390 $.each( options, function( key, value ) { 12391 that._setOption( key, value ); 12392 12393 if ( key in sizeRelatedOptions ) { 12394 resize = true; 12395 } 12396 if ( key in resizableRelatedOptions ) { 12397 resizableOptions[ key ] = value; 12398 } 12399 }); 12400 12401 if ( resize ) { 12402 this._size(); 12403 } 12404 if ( this.uiDialog.is( ":data(resizable)" ) ) { 12405 this.uiDialog.resizable( "option", resizableOptions ); 12406 } 12407 }, 12408 12409 _setOption: function( key, value ) { 12410 var isDraggable, isResizable, 12411 uiDialog = this.uiDialog; 12412 12413 switch ( key ) { 12414 case "buttons": 12415 this._createButtons( value ); 12416 break; 12417 case "closeText": 12418 // ensure that we always pass a string 12419 this.uiDialogTitlebarCloseText.text( "" + value ); 12420 break; 12421 case "dialogClass": 12422 uiDialog 12423 .removeClass( this.options.dialogClass ) 12424 .addClass( uiDialogClasses + value ); 12425 break; 12426 case "disabled": 12427 if ( value ) { 12428 uiDialog.addClass( "ui-dialog-disabled" ); 12429 } else { 12430 uiDialog.removeClass( "ui-dialog-disabled" ); 12431 } 12432 break; 12433 case "draggable": 12434 isDraggable = uiDialog.is( ":data(draggable)" ); 12435 if ( isDraggable && !value ) { 12436 uiDialog.draggable( "destroy" ); 12437 } 12438 12439 if ( !isDraggable && value ) { 12440 this._makeDraggable(); 12441 } 12442 break; 12443 case "position": 12444 this._position( value ); 12445 break; 12446 case "resizable": 12447 // currently resizable, becoming non-resizable 12448 isResizable = uiDialog.is( ":data(resizable)" ); 12449 if ( isResizable && !value ) { 12450 uiDialog.resizable( "destroy" ); 12451 } 12452 12453 // currently resizable, changing handles 12454 if ( isResizable && typeof value === "string" ) { 12455 uiDialog.resizable( "option", "handles", value ); 12456 } 12457 12458 // currently non-resizable, becoming resizable 12459 if ( !isResizable && value !== false ) { 12460 this._makeResizable( value ); 12461 } 12462 break; 12463 case "title": 12464 // convert whatever was passed in o a string, for html() to not throw up 12465 $( ".ui-dialog-title", this.uiDialogTitlebar ) 12466 .html( "" + ( value || " " ) ); 12467 break; 12468 } 12469 12470 this._super( key, value ); 12471 }, 12472 12473 _size: function() { 12474 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 12475 * divs will both have width and height set, so we need to reset them 12476 */ 12477 var nonContentHeight, minContentHeight, autoHeight, 12478 options = this.options, 12479 isVisible = this.uiDialog.is( ":visible" ); 12480 12481 // reset content sizing 12482 this.element.show().css({ 12483 width: "auto", 12484 minHeight: 0, 12485 height: 0 12486 }); 12487 12488 if ( options.minWidth > options.width ) { 12489 options.width = options.minWidth; 12490 } 12491 12492 // reset wrapper sizing 12493 // determine the height of all the non-content elements 12494 nonContentHeight = this.uiDialog.css({ 12495 height: "auto", 12496 width: options.width 12497 }) 12498 .outerHeight(); 12499 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 12500 12501 if ( options.height === "auto" ) { 12502 // only needed for IE6 support 12503 if ( $.support.minHeight ) { 12504 this.element.css({ 12505 minHeight: minContentHeight, 12506 height: "auto" 12507 }); 12508 } else { 12509 this.uiDialog.show(); 12510 autoHeight = this.element.css( "height", "auto" ).height(); 12511 if ( !isVisible ) { 12512 this.uiDialog.hide(); 12513 } 12514 this.element.height( Math.max( autoHeight, minContentHeight ) ); 12515 } 12516 } else { 12517 this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); 12518 } 12519 12520 if (this.uiDialog.is( ":data(resizable)" ) ) { 12521 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 12522 } 12523 } 12524}); 12525 12526$.extend($.ui.dialog, { 12527 uuid: 0, 12528 maxZ: 0, 12529 12530 getTitleId: function($el) { 12531 var id = $el.attr( "id" ); 12532 if ( !id ) { 12533 this.uuid += 1; 12534 id = this.uuid; 12535 } 12536 return "ui-dialog-title-" + id; 12537 }, 12538 12539 overlay: function( dialog ) { 12540 this.$el = $.ui.dialog.overlay.create( dialog ); 12541 } 12542}); 12543 12544$.extend( $.ui.dialog.overlay, { 12545 instances: [], 12546 // reuse old instances due to IE memory leak with alpha transparency (see #5185) 12547 oldInstances: [], 12548 maxZ: 0, 12549 events: $.map( 12550 "focus,mousedown,mouseup,keydown,keypress,click".split( "," ), 12551 function( event ) { 12552 return event + ".dialog-overlay"; 12553 } 12554 ).join( " " ), 12555 create: function( dialog ) { 12556 if ( this.instances.length === 0 ) { 12557 // prevent use of anchors and inputs 12558 // we use a setTimeout in case the overlay is created from an 12559 // event that we're going to be cancelling (see #2804) 12560 setTimeout(function() { 12561 // handle $(el).dialog().dialog('close') (see #4065) 12562 if ( $.ui.dialog.overlay.instances.length ) { 12563 $( document ).bind( $.ui.dialog.overlay.events, function( event ) { 12564 // stop events if the z-index of the target is < the z-index of the overlay 12565 // we cannot return true when we don't want to cancel the event (#3523) 12566 if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) { 12567 return false;
12568 } 12569 }); 12570 } 12571 }, 1 ); 12572 12573 // handle window resize 12574 $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); 12575 } 12576 12577 var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ); 12578 12579 // allow closing by pressing the escape key 12580 $( document ).bind( "keydown.dialog-overlay", function( event ) { 12581 var instances = $.ui.dialog.overlay.instances; 12582 // only react to the event if we're the top overlay 12583 if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el && 12584 dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 12585 event.keyCode === $.ui.keyCode.ESCAPE ) { 12586 12587 dialog.close( event ); 12588 event.preventDefault(); 12589 } 12590 }); 12591 12592 $el.appendTo( document.body ).css({ 12593 width: this.width(), 12594 height: this.height() 12595 }); 12596 12597 if ( $.fn.bgiframe ) { 12598 $el.bgiframe(); 12599 } 12600 12601 this.instances.push( $el ); 12602 return $el; 12603 }, 12604 12605 destroy: function( $el ) { 12606 var indexOf = $.inArray( $el, this.instances ), 12607 maxZ = 0; 12608 12609 if ( indexOf !== -1 ) { 12610 this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] ); 12611 } 12612 12613 if ( this.instances.length === 0 ) { 12614 $( [ document, window ] ).unbind( ".dialog-overlay" ); 12615 } 12616 12617 $el.height( 0 ).width( 0 ).remove(); 12618 12619 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) 12620 $.each( this.instances, function() { 12621 maxZ = Math.max( maxZ, this.css( "z-index" ) ); 12622 }); 12623 this.maxZ = maxZ; 12624 }, 12625 12626 height: function() { 12627 var scrollHeight, 12628 offsetHeight; 12629 // handle IE 12630 if ( $.ui.ie ) { 12631 scrollHeight = Math.max( 12632 document.documentElement.scrollHeight, 12633 document.body.scrollHeight 12634 ); 12635 offsetHeight = Math.max( 12636 document.documentElement.offsetHeight, 12637 document.body.offsetHeight 12638 ); 12639 12640 if ( scrollHeight < offsetHeight ) { 12641 return $( window ).height() + "px"; 12642 } else { 12643 return scrollHeight + "px"; 12644 } 12645 // handle "good" browsers 12646 } else { 12647 return $( document ).height() + "px"; 12648 } 12649 }, 12650 12651 width: function() { 12652 var scrollWidth, 12653 offsetWidth; 12654 // handle IE 12655 if ( $.ui.ie ) { 12656 scrollWidth = Math.max( 12657 document.documentElement.scrollWidth, 12658 document.body.scrollWidth 12659 ); 12660 offsetWidth = Math.max( 12661 document.documentElement.offsetWidth, 12662 document.body.offsetWidth 12663 ); 12664 12665 if ( scrollWidth < offsetWidth ) { 12666 return $( window ).width() + "px"; 12667 } else { 12668 return scrollWidth + "px"; 12669 } 12670 // handle "good" browsers 12671 } else { 12672 return $( document ).width() + "px"; 12673 } 12674 }, 12675 12676 resize: function() { 12677 /* If the dialog is draggable and the user drags it past the 12678 * right edge of the window, the document becomes wider so we 12679 * need to stretch the overlay. If the user then drags the 12680 * dialog back to the left, the document will become narrower, 12681 * so we need to shrink the overlay to the appropriate size. 12682 * This is handled by shrinking the overlay before setting it 12683 * to the full document size. 12684 */ 12685 var $overlays = $( [] ); 12686 $.each( $.ui.dialog.overlay.instances, function() { 12687 $overlays = $overlays.add( this ); 12688 }); 12689 12690 $overlays.css({ 12691 width: 0, 12692 height: 0 12693 }).css({ 12694 width: $.ui.dialog.overlay.width(), 12695 height: $.ui.dialog.overlay.height() 12696 }); 12697 } 12698}); 12699 12700$.extend( $.ui.dialog.overlay.prototype, { 12701 destroy: function() { 12702 $.ui.dialog.overlay.destroy( this.$el ); 12703 } 12704}); 12705 12706}( jQuery ) ); 12707 12708(function( $, undefined ) { 12709 12710var rvertical = /up|down|vertical/, 12711 rpositivemotion = /up|left|vertical|horizontal/; 12712 12713$.effects.effect.blind = function( o, done ) { 12714 // Create element 12715 var el = $( this ), 12716 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 12717 mode = $.effects.setMode( el, o.mode || "hide" ), 12718 direction = o.direction || "up", 12719 vertical = rvertical.test( direction ), 12720 ref = vertical ? "height" : "width", 12721 ref2 = vertical ? "top" : "left", 12722 motion = rpositivemotion.test( direction ), 12723 animation = {}, 12724 show = mode === "show", 12725 wrapper, distance, margin; 12726 12727 // if already wrapped, the wrapper's properties are my property. #6245 12728 if ( el.parent().is( ".ui-effects-wrapper" ) ) { 12729 $.effects.save( el.parent(), props ); 12730 } else { 12731 $.effects.save( el, props ); 12732 } 12733 el.show(); 12734 wrapper = $.effects.createWrapper( el ).css({ 12735 overflow: "hidden" 12736 }); 12737 12738 distance = wrapper[ ref ](); 12739 margin = parseFloat( wrapper.css( ref2 ) ) || 0; 12740 12741 animation[ ref ] = show ? distance : 0; 12742 if ( !motion ) { 12743 el 12744 .css( vertical ? "bottom" : "right", 0 ) 12745 .css( vertical ? "top" : "left", "auto" ) 12746 .css({ position: "absolute" }); 12747 12748 animation[ ref2 ] = show ? margin : distance + margin; 12749 } 12750 12751 // start at 0 if we are showing 12752 if ( show ) { 12753 wrapper.css( ref, 0 ); 12754 if ( ! motion ) { 12755 wrapper.css( ref2, margin + distance ); 12756 } 12757 } 12758 12759 // Animate 12760 wrapper.animate( animation, { 12761 duration: o.duration, 12762 easing: o.easing, 12763 queue: false, 12764 complete: function() { 12765 if ( mode === "hide" ) { 12766 el.hide(); 12767 } 12768 $.effects.restore( el, props ); 12769 $.effects.removeWrapper( el ); 12770 done(); 12771 } 12772 }); 12773 12774}; 12775 12776})(jQuery); 12777 12778(function( $, undefined ) { 12779 12780$.effects.effect.bounce = function( o, done ) { 12781 var el = $( this ), 12782 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 12783 12784 // defaults: 12785 mode = $.effects.setMode( el, o.mode || "effect" ), 12786 hide = mode === "hide", 12787 show = mode === "show", 12788 direction = o.direction || "up", 12789 distance = o.distance, 12790 times = o.times || 5, 12791 12792 // number of internal animations 12793 anims = times * 2 + ( show || hide ? 1 : 0 ), 12794 speed = o.duration / anims, 12795 easing = o.easing, 12796 12797 // utility: 12798 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 12799 motion = ( direction === "up" || direction === "left" ), 12800 i, 12801 upAnim, 12802 downAnim, 12803 12804 // we will need to re-assemble the queue to stack our animations in place 12805 queue = el.queue(), 12806 queuelen = queue.length; 12807 12808 // Avoid touching opacity to prevent clearType and PNG issues in IE 12809 if ( show || hide ) { 12810 props.push( "opacity" ); 12811 } 12812 12813 $.effects.save( el, props ); 12814 el.show(); 12815 $.effects.createWrapper( el ); // Create Wrapper 12816 12817 // default distance for the BIGGEST bounce is the outer Distance / 3 12818 if ( !distance ) { 12819 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 12820 } 12821 12822 if ( show ) { 12823 downAnim = { opacity: 1 }; 12824 downAnim[ ref ] = 0; 12825 12826 // if we are showing, force opacity 0 and set the initial position 12827 // then do the "first" animation 12828 el.css( "opacity", 0 ) 12829 .css( ref, motion ? -distance * 2 : distance * 2 ) 12830 .animate( downAnim, speed, easing ); 12831 } 12832 12833 // start at the smallest distance if we are hiding 12834 if ( hide ) { 12835 distance = distance / Math.pow( 2, times - 1 ); 12836 } 12837 12838 downAnim = {}; 12839 downAnim[ ref ] = 0; 12840 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 12841 for ( i = 0; i < times; i++ ) { 12842 upAnim = {}; 12843 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 12844 12845 el.animate( upAnim, speed, easing ) 12846 .animate( downAnim, speed, easing ); 12847 12848 distance = hide ? distance * 2 : distance / 2; 12849 } 12850 12851 // Last Bounce when Hiding 12852 if ( hide ) { 12853 upAnim = { opacity: 0 }; 12854 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 12855 12856 el.animate( upAnim, speed, easing ); 12857 } 12858 12859 el.queue(function() { 12860 if ( hide ) { 12861 el.hide(); 12862 } 12863 $.effects.restore( el, props ); 12864 $.effects.removeWrapper( el ); 12865 done(); 12866 }); 12867 12868 // inject all the animations we just queued to be first in line (after "inprogress") 12869 if ( queuelen > 1) { 12870 queue.splice.apply( queue, 12871 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 12872 } 12873 el.dequeue(); 12874 12875}; 12876 12877})(jQuery); 12878 12879(function( $, undefined ) { 12880 12881$.effects.effect.clip = function( o, done ) { 12882 // Create element 12883 var el = $( this ), 12884 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 12885 mode = $.effects.setMode( el, o.mode || "hide" ), 12886 show = mode === "show", 12887 direction = o.direction || "vertical", 12888 vert = direction === "vertical", 12889 size = vert ? "height" : "width", 12890 position = vert ? "top" : "left", 12891 animation = {}, 12892 wrapper, animate, distance; 12893 12894 // Save & Show 12895 $.effects.save( el, props ); 12896 el.show(); 12897 12898 // Create Wrapper 12899 wrapper = $.effects.createWrapper( el ).css({ 12900 overflow: "hidden" 12901 }); 12902 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; 12903 distance = animate[ size ](); 12904 12905 // Shift 12906 if ( show ) { 12907 animate.css( size, 0 ); 12908 animate.css( position, distance / 2 ); 12909 } 12910 12911 // Create Animation Object: 12912 animation[ size ] = show ? distance : 0; 12913 animation[ position ] = show ? 0 : distance / 2; 12914 12915 // Animate 12916 animate.animate( animation, { 12917 queue: false, 12918 duration: o.duration, 12919 easing: o.easing,
vendor: 17,802 bytes, lines 12920-13658
12920 complete: function() { 12921 if ( !show ) { 12922 el.hide(); 12923 } 12924 $.effects.restore( el, props ); 12925 $.effects.removeWrapper( el ); 12926 done(); 12927 } 12928 }); 12929 12930}; 12931 12932})(jQuery); 12933 12934(function( $, undefined ) { 12935 12936$.effects.effect.drop = function( o, done ) { 12937 12938 var el = $( this ), 12939 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], 12940 mode = $.effects.setMode( el, o.mode || "hide" ), 12941 show = mode === "show", 12942 direction = o.direction || "left", 12943 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 12944 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", 12945 animation = { 12946 opacity: show ? 1 : 0 12947 }, 12948 distance; 12949 12950 // Adjust 12951 $.effects.save( el, props ); 12952 el.show(); 12953 $.effects.createWrapper( el ); 12954 12955 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; 12956 12957 if ( show ) { 12958 el 12959 .css( "opacity", 0 ) 12960 .css( ref, motion === "pos" ? -distance : distance ); 12961 } 12962 12963 // Animation 12964 animation[ ref ] = ( show ? 12965 ( motion === "pos" ? "+=" : "-=" ) : 12966 ( motion === "pos" ? "-=" : "+=" ) ) + 12967 distance; 12968 12969 // Animate 12970 el.animate( animation, { 12971 queue: false, 12972 duration: o.duration, 12973 easing: o.easing, 12974 complete: function() { 12975 if ( mode === "hide" ) { 12976 el.hide(); 12977 } 12978 $.effects.restore( el, props ); 12979 $.effects.removeWrapper( el ); 12980 done(); 12981 } 12982 }); 12983}; 12984 12985})(jQuery); 12986 12987(function( $, undefined ) { 12988 12989$.effects.effect.explode = function( o, done ) { 12990 12991 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, 12992 cells = rows, 12993 el = $( this ), 12994 mode = $.effects.setMode( el, o.mode || "hide" ), 12995 show = mode === "show", 12996 12997 // show and then visibility:hidden the element before calculating offset 12998 offset = el.show().css( "visibility", "hidden" ).offset(), 12999 13000 // width and height of a piece 13001 width = Math.ceil( el.outerWidth() / cells ), 13002 height = Math.ceil( el.outerHeight() / rows ), 13003 pieces = [], 13004 13005 // loop 13006 i, j, left, top, mx, my; 13007 13008 // children animate complete: 13009 function childComplete() { 13010 pieces.push( this ); 13011 if ( pieces.length === rows * cells ) { 13012 animComplete(); 13013 } 13014 } 13015 13016 // clone the element for each row and cell. 13017 for( i = 0; i < rows ; i++ ) { // ===> 13018 top = offset.top + i * height; 13019 my = i - ( rows - 1 ) / 2 ; 13020 13021 for( j = 0; j < cells ; j++ ) { // ||| 13022 left = offset.left + j * width; 13023 mx = j - ( cells - 1 ) / 2 ; 13024 13025 // Create a clone of the now hidden main element that will be absolute positioned 13026 // within a wrapper div off the -left and -top equal to size of our pieces 13027 el 13028 .clone() 13029 .appendTo( "body" ) 13030 .wrap( "<div></div>" ) 13031 .css({ 13032 position: "absolute", 13033 visibility: "visible", 13034 left: -j * width, 13035 top: -i * height 13036 }) 13037 13038 // select the wrapper - make it overflow: hidden and absolute positioned based on 13039 // where the original was located +left and +top equal to the size of pieces 13040 .parent() 13041 .addClass( "ui-effects-explode" ) 13042 .css({ 13043 position: "absolute", 13044 overflow: "hidden", 13045 width: width, 13046 height: height, 13047 left: left + ( show ? mx * width : 0 ), 13048 top: top + ( show ? my * height : 0 ), 13049 opacity: show ? 0 : 1 13050 }).animate({ 13051 left: left + ( show ? 0 : mx * width ), 13052 top: top + ( show ? 0 : my * height ), 13053 opacity: show ? 1 : 0 13054 }, o.duration || 500, o.easing, childComplete ); 13055 } 13056 } 13057 13058 function animComplete() { 13059 el.css({ 13060 visibility: "visible" 13061 }); 13062 $( pieces ).remove(); 13063 if ( !show ) { 13064 el.hide(); 13065 } 13066 done(); 13067 } 13068}; 13069 13070})(jQuery); 13071 13072(function( $, undefined ) { 13073 13074$.effects.effect.fade = function( o, done ) { 13075 var el = $( this ), 13076 mode = $.effects.setMode( el, o.mode || "toggle" ); 13077 13078 el.animate({ 13079 opacity: mode 13080 }, { 13081 queue: false, 13082 duration: o.duration, 13083 easing: o.easing, 13084 complete: done 13085 }); 13086}; 13087 13088})( jQuery ); 13089 13090(function( $, undefined ) { 13091 13092$.effects.effect.fold = function( o, done ) { 13093 13094 // Create element 13095 var el = $( this ), 13096 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 13097 mode = $.effects.setMode( el, o.mode || "hide" ), 13098 show = mode === "show", 13099 hide = mode === "hide", 13100 size = o.size || 15, 13101 percent = /([0-9]+)%/.exec( size ), 13102 horizFirst = !!o.horizFirst, 13103 widthFirst = show !== horizFirst, 13104 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], 13105 duration = o.duration / 2, 13106 wrapper, distance, 13107 animation1 = {}, 13108 animation2 = {}; 13109 13110 $.effects.save( el, props ); 13111 el.show(); 13112 13113 // Create Wrapper 13114 wrapper = $.effects.createWrapper( el ).css({ 13115 overflow: "hidden" 13116 }); 13117 distance = widthFirst ? 13118 [ wrapper.width(), wrapper.height() ] : 13119 [ wrapper.height(), wrapper.width() ]; 13120 13121 if ( percent ) { 13122 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 13123 } 13124 if ( show ) { 13125 wrapper.css( horizFirst ? { 13126 height: 0, 13127 width: size 13128 } : { 13129 height: size, 13130 width: 0 13131 }); 13132 } 13133 13134 // Animation 13135 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; 13136 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; 13137 13138 // Animate 13139 wrapper 13140 .animate( animation1, duration, o.easing ) 13141 .animate( animation2, duration, o.easing, function() { 13142 if ( hide ) { 13143 el.hide(); 13144 } 13145 $.effects.restore( el, props ); 13146 $.effects.removeWrapper( el ); 13147 done(); 13148 }); 13149 13150}; 13151 13152})(jQuery); 13153 13154(function( $, undefined ) { 13155 13156$.effects.effect.highlight = function( o, done ) { 13157 var elem = $( this ), 13158 props = [ "backgroundImage", "backgroundColor", "opacity" ], 13159 mode = $.effects.setMode( elem, o.mode || "show" ), 13160 animation = { 13161 backgroundColor: elem.css( "backgroundColor" ) 13162 }; 13163 13164 if (mode === "hide") { 13165 animation.opacity = 0; 13166 } 13167 13168 $.effects.save( elem, props ); 13169 13170 elem 13171 .show() 13172 .css({ 13173 backgroundImage: "none", 13174 backgroundColor: o.color || "#ffff99" 13175 }) 13176 .animate( animation, { 13177 queue: false, 13178 duration: o.duration, 13179 easing: o.easing, 13180 complete: function() { 13181 if ( mode === "hide" ) { 13182 elem.hide(); 13183 } 13184 $.effects.restore( elem, props ); 13185 done(); 13186 } 13187 }); 13188}; 13189 13190})(jQuery); 13191 13192(function( $, undefined ) { 13193 13194$.effects.effect.pulsate = function( o, done ) { 13195 var elem = $( this ), 13196 mode = $.effects.setMode( elem, o.mode || "show" ), 13197 show = mode === "show", 13198 hide = mode === "hide", 13199 showhide = ( show || mode === "hide" ), 13200 13201 // showing or hiding leaves of the "last" animation 13202 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 13203 duration = o.duration / anims, 13204 animateTo = 0, 13205 queue = elem.queue(), 13206 queuelen = queue.length, 13207 i; 13208 13209 if ( show || !elem.is(":visible")) { 13210 elem.css( "opacity", 0 ).show(); 13211 animateTo = 1; 13212 } 13213 13214 // anims - 1 opacity "toggles" 13215 for ( i = 1; i < anims; i++ ) { 13216 elem.animate({ 13217 opacity: animateTo 13218 }, duration, o.easing ); 13219 animateTo = 1 - animateTo; 13220 } 13221 13222 elem.animate({ 13223 opacity: animateTo 13224 }, duration, o.easing); 13225 13226 elem.queue(function() { 13227 if ( hide ) { 13228 elem.hide(); 13229 } 13230 done(); 13231 }); 13232 13233 // We just queued up "anims" animations, we need to put them next in the queue 13234 if ( queuelen > 1 ) { 13235 queue.splice.apply( queue, 13236 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 13237 } 13238 elem.dequeue(); 13239}; 13240 13241})(jQuery); 13242 13243(function( $, undefined ) { 13244 13245$.effects.effect.puff = function( o, done ) { 13246 var elem = $( this ), 13247 mode = $.effects.setMode( elem, o.mode || "hide" ), 13248 hide = mode === "hide", 13249 percent = parseInt( o.percent, 10 ) || 150, 13250 factor = percent / 100, 13251 original = { 13252 height: elem.height(), 13253 width: elem.width() 13254 }; 13255 13256 $.extend( o, { 13257 effect: "scale", 13258 queue: false, 13259 fade: true, 13260 mode: mode, 13261 complete: done, 13262 percent: hide ? percent : 100, 13263 from: hide ? 13264 original : 13265 { 13266 height: original.height * factor, 13267 width: original.width * factor 13268 } 13269 }); 13270 13271 elem.effect( o ); 13272}; 13273 13274$.effects.effect.scale = function( o, done ) { 13275 13276 // Create element 13277 var el = $( this ), 13278 options = $.extend( true, {}, o ), 13279 mode = $.effects.setMode( el, o.mode || "effect" ), 13280 percent = parseInt( o.percent, 10 ) || 13281 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), 13282 direction = o.direction || "both", 13283 origin = o.origin, 13284 original = { 13285 height: el.height(), 13286 width: el.width(), 13287 outerHeight: el.outerHeight(), 13288 outerWidth: el.outerWidth() 13289 }, 13290 factor = { 13291 y: direction !== "horizontal" ? (percent / 100) : 1, 13292 x: direction !== "vertical" ? (percent / 100) : 1 13293 }; 13294 13295 // We are going to pass this effect to the size effect: 13296 options.effect = "size"; 13297 options.queue = false; 13298 options.complete = done; 13299 13300 // Set default origin and restore for show/hide 13301 if ( mode !== "effect" ) { 13302 options.origin = origin || ["middle","center"]; 13303 options.restore = true; 13304 } 13305 13306 options.from = o.from || ( mode === "show" ? { height: 0, width: 0 } : original ); 13307 options.to = { 13308 height: original.height * factor.y, 13309 width: original.width * factor.x, 13310 outerHeight: original.outerHeight * factor.y, 13311 outerWidth: original.outerWidth * factor.x 13312 }; 13313 13314 // Fade option to support puff 13315 if ( options.fade ) { 13316 if ( mode === "show" ) { 13317 options.from.opacity = 0; 13318 options.to.opacity = 1; 13319 } 13320 if ( mode === "hide" ) { 13321 options.from.opacity = 1; 13322 options.to.opacity = 0; 13323 } 13324 } 13325 13326 // Animate 13327 el.effect( options ); 13328 13329}; 13330 13331$.effects.effect.size = function( o, done ) { 13332 13333 // Create element 13334 var original, baseline, factor, 13335 el = $( this ), 13336 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], 13337 13338 // Always restore 13339 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], 13340 13341 // Copy for children 13342 props2 = [ "width", "height", "overflow" ], 13343 cProps = [ "fontSize" ], 13344 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 13345 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 13346 13347 // Set options 13348 mode = $.effects.setMode( el, o.mode || "effect" ), 13349 restore = o.restore || mode !== "effect", 13350 scale = o.scale || "both", 13351 origin = o.origin || [ "middle", "center" ], 13352 position = el.css( "position" ), 13353 props = restore ? props0 : props1, 13354 zero = { 13355 height: 0, 13356 width: 0 13357 }; 13358 13359 if ( mode === "show" ) { 13360 el.show(); 13361 } 13362 original = { 13363 height: el.height(), 13364 width: el.width(), 13365 outerHeight: el.outerHeight(), 13366 outerWidth: el.outerWidth() 13367 }; 13368 13369 if ( o.mode === "toggle" && mode === "show" ) { 13370 el.from = o.to || zero; 13371 el.to = o.from || original; 13372 } else { 13373 el.from = o.from || ( mode === "show" ? zero : original ); 13374 el.to = o.to || ( mode === "hide" ? zero : original ); 13375 } 13376 13377 // Set scaling factor 13378 factor = { 13379 from: { 13380 y: el.from.height / original.height, 13381 x: el.from.width / original.width 13382 }, 13383 to: { 13384 y: el.to.height / original.height, 13385 x: el.to.width / original.width 13386 } 13387 }; 13388 13389 // Scale the css box 13390 if ( scale === "box" || scale === "both" ) { 13391 13392 // Vertical props scaling 13393 if ( factor.from.y !== factor.to.y ) { 13394 props = props.concat( vProps ); 13395 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); 13396 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); 13397 } 13398 13399 // Horizontal props scaling 13400 if ( factor.from.x !== factor.to.x ) { 13401 props = props.concat( hProps ); 13402 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); 13403 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); 13404 } 13405 } 13406 13407 // Scale the content 13408 if ( scale === "content" || scale === "both" ) { 13409 13410 // Vertical props scaling 13411 if ( factor.from.y !== factor.to.y ) { 13412 props = props.concat( cProps ).concat( props2 ); 13413 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); 13414 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); 13415 } 13416 } 13417 13418 $.effects.save( el, props ); 13419 el.show(); 13420 $.effects.createWrapper( el ); 13421 el.css( "overflow", "hidden" ).css( el.from ); 13422 13423 // Adjust 13424 if (origin) { // Calculate baseline shifts 13425 baseline = $.effects.getBaseline( origin, original ); 13426 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; 13427 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; 13428 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; 13429 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; 13430 } 13431 el.css( el.from ); // set top & left 13432 13433 // Animate 13434 if ( scale === "content" || scale === "both" ) { // Scale the children 13435 13436 // Add margins/font-size 13437 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); 13438 hProps = hProps.concat([ "marginLeft", "marginRight" ]); 13439 props2 = props0.concat(vProps).concat(hProps); 13440 13441 el.find( "*[width]" ).each( function(){ 13442 var child = $( this ), 13443 c_original = { 13444 height: child.height(), 13445 width: child.width() 13446 }; 13447 if (restore) { 13448 $.effects.save(child, props2); 13449 } 13450 13451 child.from = { 13452 height: c_original.height * factor.from.y, 13453 width: c_original.width * factor.from.x 13454 }; 13455 child.to = { 13456 height: c_original.height * factor.to.y, 13457 width: c_original.width * factor.to.x 13458 }; 13459 13460 // Vertical props scaling 13461 if ( factor.from.y !== factor.to.y ) { 13462 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); 13463 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); 13464 } 13465 13466 // Horizontal props scaling 13467 if ( factor.from.x !== factor.to.x ) { 13468 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); 13469 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); 13470 } 13471 13472 // Animate children 13473 child.css( child.from ); 13474 child.animate( child.to, o.duration, o.easing, function() { 13475 13476 // Restore children 13477 if ( restore ) { 13478 $.effects.restore( child, props2 ); 13479 } 13480 }); 13481 }); 13482 } 13483 13484 // Animate 13485 el.animate( el.to, { 13486 queue: false, 13487 duration: o.duration, 13488 easing: o.easing, 13489 complete: function() { 13490 if ( el.to.opacity === 0 ) { 13491 el.css( "opacity", el.from.opacity ); 13492 } 13493 if( mode === "hide" ) { 13494 el.hide(); 13495 } 13496 $.effects.restore( el, props ); 13497 if ( !restore ) { 13498 13499 // we need to calculate our new positioning based on the scaling 13500 if ( position === "static" ) { 13501 el.css({ 13502 position: "relative", 13503 top: el.to.top, 13504 left: el.to.left 13505 }); 13506 } else { 13507 $.each([ "top", "left" ], function( idx, pos ) { 13508 el.css( pos, function( _, str ) { 13509 var val = parseInt( str, 10 ), 13510 toRef = idx ? el.to.left : el.to.top; 13511 13512 // if original was "auto", recalculate the new value from wrapper 13513 if ( str === "auto" ) { 13514 return toRef + "px"; 13515 } 13516 13517 return val + toRef + "px"; 13518 }); 13519 }); 13520 } 13521 } 13522 13523 $.effects.removeWrapper( el ); 13524 done(); 13525 } 13526 }); 13527 13528}; 13529 13530})(jQuery); 13531 13532(function( $, undefined ) { 13533 13534$.effects.effect.shake = function( o, done ) { 13535 13536 var el = $( this ), 13537 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], 13538 mode = $.effects.setMode( el, o.mode || "effect" ), 13539 direction = o.direction || "left", 13540 distance = o.distance || 20, 13541 times = o.times || 3, 13542 anims = times * 2 + 1, 13543 speed = Math.round(o.duration/anims), 13544 ref = (direction === "up" || direction === "down") ? "top" : "left", 13545 positiveMotion = (direction === "up" || direction === "left"), 13546 animation = {}, 13547 animation1 = {}, 13548 animation2 = {}, 13549 i, 13550 13551 // we will need to re-assemble the queue to stack our animations in place 13552 queue = el.queue(), 13553 queuelen = queue.length; 13554 13555 $.effects.save( el, props ); 13556 el.show(); 13557 $.effects.createWrapper( el ); 13558 13559 // Animation 13560 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 13561 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 13562 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 13563 13564 // Animate 13565 el.animate( animation, speed, o.easing ); 13566 13567 // Shakes 13568 for ( i = 1; i < times; i++ ) { 13569 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); 13570 } 13571 el 13572 .animate( animation1, speed, o.easing ) 13573 .animate( animation, speed / 2, o.easing ) 13574 .queue(function() { 13575 if ( mode === "hide" ) { 13576 el.hide(); 13577 } 13578 $.effects.restore( el, props ); 13579 $.effects.removeWrapper( el ); 13580 done(); 13581 }); 13582 13583 // inject all the animations we just queued to be first in line (after "inprogress") 13584 if ( queuelen > 1) { 13585 queue.splice.apply( queue, 13586 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); 13587 } 13588 el.dequeue(); 13589 13590}; 13591 13592})(jQuery); 13593 13594(function( $, undefined ) { 13595 13596$.effects.effect.slide = function( o, done ) { 13597 13598 // Create element 13599 var el = $( this ), 13600 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], 13601 mode = $.effects.setMode( el, o.mode || "show" ), 13602 show = mode === "show", 13603 direction = o.direction || "left", 13604 ref = (direction === "up" || direction === "down") ? "top" : "left", 13605 positiveMotion = (direction === "up" || direction === "left"), 13606 distance, 13607 animation = {}; 13608 13609 // Adjust 13610 $.effects.save( el, props ); 13611 el.show(); 13612 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); 13613 13614 $.effects.createWrapper( el ).css({ 13615 overflow: "hidden" 13616 }); 13617 13618 if ( show ) { 13619 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); 13620 } 13621 13622 // Animation 13623 animation[ ref ] = ( show ? 13624 ( positiveMotion ? "+=" : "-=") : 13625 ( positiveMotion ? "-=" : "+=")) + 13626 distance; 13627 13628 // Animate 13629 el.animate( animation, { 13630 queue: false, 13631 duration: o.duration, 13632 easing: o.easing, 13633 complete: function() { 13634 if ( mode === "hide" ) { 13635 el.hide(); 13636 } 13637 $.effects.restore( el, props ); 13638 $.effects.removeWrapper( el ); 13639 done(); 13640 } 13641 }); 13642}; 13643 13644})(jQuery); 13645 13646(function( $, undefined ) { 13647 13648$.effects.effect.transfer = function( o, done ) { 13649 var elem = $( this ), 13650 target = $( o.to ), 13651 targetFixed = target.css( "position" ) === "fixed", 13652 body = $("body"), 13653 fixTop = targetFixed ? body.scrollTop() : 0, 13654 fixLeft = targetFixed ? body.scrollLeft() : 0, 13655 endPosition = target.offset(), 13656 animation = { 13657 top: endPosition.top - fixTop , 13658 left: endPosition.left - fixLeft ,
13659 height: target.innerHeight(), 13660 width: target.innerWidth() 13661 }, 13662 startPosition = elem.offset(), 13663 transfer = $( '<div class="ui-effects-transfer"></div>' ) 13664 .appendTo( document.body ) 13665 .addClass( o.className ) 13666 .css({ 13667 top: startPosition.top - fixTop , 13668 left: startPosition.left - fixLeft , 13669 height: elem.innerHeight(), 13670 width: elem.innerWidth(), 13671 position: targetFixed ? "fixed" : "absolute" 13672 }) 13673 .animate( animation, o.duration, o.easing, function() { 13674 transfer.remove(); 13675 done(); 13676 }); 13677}; 13678 13679})(jQuery); 13680 13681(function( $, undefined ) { 13682 13683var mouseHandled = false; 13684 13685$.widget( "ui.menu", { 13686 version: "1.9.1", 13687 defaultElement: "<ul>", 13688 delay: 300, 13689 options: { 13690 icons: { 13691 submenu: "ui-icon-carat-1-e" 13692 }, 13693 menus: "ul", 13694 position: { 13695 my: "left top", 13696 at: "right top" 13697 }, 13698 role: "menu", 13699 13700 // callbacks 13701 blur: null, 13702 focus: null, 13703 select: null 13704 }, 13705 13706 _create: function() { 13707 this.activeMenu = this.element; 13708 this.element 13709 .uniqueId() 13710 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 13711 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) 13712 .attr({ 13713 role: this.options.role, 13714 tabIndex: 0 13715 }) 13716 // need to catch all clicks on disabled menu 13717 // not possible through _on 13718 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { 13719 if ( this.options.disabled ) { 13720 event.preventDefault(); 13721 } 13722 }, this )); 13723 13724 if ( this.options.disabled ) { 13725 this.element 13726 .addClass( "ui-state-disabled" ) 13727 .attr( "aria-disabled", "true" ); 13728 } 13729 13730 this._on({ 13731 // Prevent focus from sticking to links inside menu after clicking 13732 // them (focus should always stay on UL during navigation). 13733 "mousedown .ui-menu-item > a": function( event ) { 13734 event.preventDefault(); 13735 }, 13736 "click .ui-state-disabled > a": function( event ) { 13737 event.preventDefault(); 13738 }, 13739 "click .ui-menu-item:has(a)": function( event ) { 13740 var target = $( event.target ).closest( ".ui-menu-item" ); 13741 if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) { 13742 mouseHandled = true; 13743 13744 this.select( event ); 13745 // Open submenu on click 13746 if ( target.has( ".ui-menu" ).length ) { 13747 this.expand( event ); 13748 } else if ( !this.element.is( ":focus" ) ) { 13749 // Redirect focus to the menu 13750 this.element.trigger( "focus", [ true ] ); 13751 13752 // If the active item is on the top level, let it stay active. 13753 // Otherwise, blur the active item since it is no longer visible. 13754 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 13755 clearTimeout( this.timer ); 13756 } 13757 } 13758 } 13759 }, 13760 "mouseenter .ui-menu-item": function( event ) { 13761 var target = $( event.currentTarget ); 13762 // Remove ui-state-active class from siblings of the newly focused menu item 13763 // to avoid a jump caused by adjacent elements both having a class with a border 13764 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); 13765 this.focus( event, target ); 13766 }, 13767 mouseleave: "collapseAll", 13768 "mouseleave .ui-menu": "collapseAll", 13769 focus: function( event, keepActiveItem ) { 13770 // If there's already an active item, keep it active 13771 // If not, activate the first item 13772 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); 13773 13774 if ( !keepActiveItem ) { 13775 this.focus( event, item ); 13776 } 13777 }, 13778 blur: function( event ) { 13779 this._delay(function() { 13780 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { 13781 this.collapseAll( event ); 13782 } 13783 }); 13784 }, 13785 keydown: "_keydown" 13786 }); 13787 13788 this.refresh(); 13789
vendor: 29,387 bytes, lines 13790-14801
13790 // Clicks outside of a menu collapse any open menus 13791 this._on( this.document, { 13792 click: function( event ) { 13793 if ( !$( event.target ).closest( ".ui-menu" ).length ) { 13794 this.collapseAll( event ); 13795 } 13796 13797 // Reset the mouseHandled flag 13798 mouseHandled = false; 13799 } 13800 }); 13801 }, 13802 13803 _destroy: function() { 13804 // Destroy (sub)menus 13805 this.element 13806 .removeAttr( "aria-activedescendant" ) 13807 .find( ".ui-menu" ).andSelf() 13808 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) 13809 .removeAttr( "role" ) 13810 .removeAttr( "tabIndex" ) 13811 .removeAttr( "aria-labelledby" ) 13812 .removeAttr( "aria-expanded" ) 13813 .removeAttr( "aria-hidden" ) 13814 .removeAttr( "aria-disabled" ) 13815 .removeUniqueId() 13816 .show(); 13817 13818 // Destroy menu items 13819 this.element.find( ".ui-menu-item" ) 13820 .removeClass( "ui-menu-item" ) 13821 .removeAttr( "role" ) 13822 .removeAttr( "aria-disabled" ) 13823 .children( "a" ) 13824 .removeUniqueId() 13825 .removeClass( "ui-corner-all ui-state-hover" ) 13826 .removeAttr( "tabIndex" ) 13827 .removeAttr( "role" ) 13828 .removeAttr( "aria-haspopup" ) 13829 .children().each( function() { 13830 var elem = $( this ); 13831 if ( elem.data( "ui-menu-submenu-carat" ) ) { 13832 elem.remove(); 13833 } 13834 }); 13835 13836 // Destroy menu dividers 13837 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); 13838 }, 13839 13840 _keydown: function( event ) { 13841 var match, prev, character, skip, regex, 13842 preventDefault = true; 13843 13844 function escape( value ) { 13845 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 13846 } 13847 13848 switch ( event.keyCode ) { 13849 case $.ui.keyCode.PAGE_UP: 13850 this.previousPage( event ); 13851 break; 13852 case $.ui.keyCode.PAGE_DOWN: 13853 this.nextPage( event ); 13854 break; 13855 case $.ui.keyCode.HOME: 13856 this._move( "first", "first", event ); 13857 break; 13858 case $.ui.keyCode.END: 13859 this._move( "last", "last", event ); 13860 break; 13861 case $.ui.keyCode.UP: 13862 this.previous( event ); 13863 break; 13864 case $.ui.keyCode.DOWN: 13865 this.next( event ); 13866 break; 13867 case $.ui.keyCode.LEFT: 13868 this.collapse( event ); 13869 break; 13870 case $.ui.keyCode.RIGHT: 13871 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 13872 this.expand( event ); 13873 } 13874 break; 13875 case $.ui.keyCode.ENTER: 13876 case $.ui.keyCode.SPACE: 13877 this._activate( event ); 13878 break; 13879 case $.ui.keyCode.ESCAPE: 13880 this.collapse( event ); 13881 break; 13882 default: 13883 preventDefault = false; 13884 prev = this.previousFilter || ""; 13885 character = String.fromCharCode( event.keyCode ); 13886 skip = false; 13887 13888 clearTimeout( this.filterTimer ); 13889 13890 if ( character === prev ) { 13891 skip = true; 13892 } else { 13893 character = prev + character; 13894 } 13895 13896 regex = new RegExp( "^" + escape( character ), "i" ); 13897 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 13898 return regex.test( $( this ).children( "a" ).text() ); 13899 }); 13900 match = skip && match.index( this.active.next() ) !== -1 ? 13901 this.active.nextAll( ".ui-menu-item" ) : 13902 match; 13903 13904 // If no matches on the current filter, reset to the last character pressed 13905 // to move down the menu to the first item that starts with that character 13906 if ( !match.length ) { 13907 character = String.fromCharCode( event.keyCode ); 13908 regex = new RegExp( "^" + escape( character ), "i" ); 13909 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { 13910 return regex.test( $( this ).children( "a" ).text() ); 13911 }); 13912 } 13913 13914 if ( match.length ) { 13915 this.focus( event, match ); 13916 if ( match.length > 1 ) { 13917 this.previousFilter = character; 13918 this.filterTimer = this._delay(function() { 13919 delete this.previousFilter; 13920 }, 1000 ); 13921 } else { 13922 delete this.previousFilter; 13923 } 13924 } else { 13925 delete this.previousFilter; 13926 } 13927 } 13928 13929 if ( preventDefault ) { 13930 event.preventDefault(); 13931 } 13932 }, 13933 13934 _activate: function( event ) { 13935 if ( !this.active.is( ".ui-state-disabled" ) ) { 13936 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { 13937 this.expand( event ); 13938 } else { 13939 this.select( event ); 13940 } 13941 } 13942 }, 13943 13944 refresh: function() { 13945 // Initialize nested menus 13946 var menus, 13947 icon = this.options.icons.submenu, 13948 submenus = this.element.find( this.options.menus + ":not(.ui-menu)" ) 13949 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) 13950 .hide() 13951 .attr({ 13952 role: this.options.role, 13953 "aria-hidden": "true", 13954 "aria-expanded": "false" 13955 }); 13956 13957 // Don't refresh list items that are already adapted 13958 menus = submenus.add( this.element ); 13959 13960 menus.children( ":not(.ui-menu-item):has(a)" ) 13961 .addClass( "ui-menu-item" ) 13962 .attr( "role", "presentation" ) 13963 .children( "a" ) 13964 .uniqueId() 13965 .addClass( "ui-corner-all" ) 13966 .attr({ 13967 tabIndex: -1, 13968 role: this._itemRole() 13969 }); 13970 13971 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers 13972 menus.children( ":not(.ui-menu-item)" ).each(function() { 13973 var item = $( this ); 13974 // hyphen, em dash, en dash 13975 if ( !/[^\-ââ\s]/.test( item.text() ) ) { 13976 item.addClass( "ui-widget-content ui-menu-divider" ); 13977 } 13978 }); 13979 13980 // Add aria-disabled attribute to any disabled menu item 13981 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 13982 13983 submenus.each(function() { 13984 var menu = $( this ), 13985 item = menu.prev( "a" ), 13986 submenuCarat = $( "<span>" ) 13987 .addClass( "ui-menu-icon ui-icon " + icon ) 13988 .data( "ui-menu-submenu-carat", true ); 13989 13990 item 13991 .attr( "aria-haspopup", "true" ) 13992 .prepend( submenuCarat ); 13993 menu.attr( "aria-labelledby", item.attr( "id" ) ); 13994 }); 13995 13996 // If the active item has been removed, blur the menu 13997 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 13998 this.blur(); 13999 } 14000 }, 14001 14002 _itemRole: function() { 14003 return { 14004 menu: "menuitem", 14005 listbox: "option" 14006 }[ this.options.role ]; 14007 }, 14008 14009 focus: function( event, item ) { 14010 var nested, focused; 14011 this.blur( event, event && event.type === "focus" ); 14012 14013 this._scrollIntoView( item ); 14014 14015 this.active = item.first(); 14016 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); 14017 // Only update aria-activedescendant if there's a role 14018 // otherwise we assume focus is managed elsewhere 14019 if ( this.options.role ) { 14020 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 14021 } 14022 14023 // Highlight active parent menu item, if any 14024 this.active 14025 .parent() 14026 .closest( ".ui-menu-item" ) 14027 .children( "a:first" ) 14028 .addClass( "ui-state-active" ); 14029 14030 if ( event && event.type === "keydown" ) { 14031 this._close(); 14032 } else { 14033 this.timer = this._delay(function() { 14034 this._close(); 14035 }, this.delay ); 14036 } 14037 14038 nested = item.children( ".ui-menu" ); 14039 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { 14040 this._startOpening(nested); 14041 } 14042 this.activeMenu = item.parent(); 14043 14044 this._trigger( "focus", event, { item: item } ); 14045 }, 14046 14047 _scrollIntoView: function( item ) { 14048 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 14049 if ( this._hasScroll() ) { 14050 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; 14051 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; 14052 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 14053 scroll = this.activeMenu.scrollTop(); 14054 elementHeight = this.activeMenu.height(); 14055 itemHeight = item.height(); 14056 14057 if ( offset < 0 ) { 14058 this.activeMenu.scrollTop( scroll + offset ); 14059 } else if ( offset + itemHeight > elementHeight ) { 14060 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 14061 } 14062 } 14063 }, 14064 14065 blur: function( event, fromFocus ) { 14066 if ( !fromFocus ) { 14067 clearTimeout( this.timer ); 14068 } 14069 14070 if ( !this.active ) { 14071 return; 14072 } 14073 14074 this.active.children( "a" ).removeClass( "ui-state-focus" ); 14075 this.active = null; 14076 14077 this._trigger( "blur", event, { item: this.active } ); 14078 }, 14079 14080 _startOpening: function( submenu ) { 14081 clearTimeout( this.timer ); 14082 14083 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 14084 // shift in the submenu position when mousing over the carat icon 14085 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 14086 return; 14087 } 14088 14089 this.timer = this._delay(function() { 14090 this._close(); 14091 this._open( submenu ); 14092 }, this.delay ); 14093 }, 14094 14095 _open: function( submenu ) { 14096 var position = $.extend({ 14097 of: this.active 14098 }, this.options.position ); 14099 14100 clearTimeout( this.timer ); 14101 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 14102 .hide() 14103 .attr( "aria-hidden", "true" ); 14104 14105 submenu 14106 .show() 14107 .removeAttr( "aria-hidden" ) 14108 .attr( "aria-expanded", "true" ) 14109 .position( position ); 14110 }, 14111 14112 collapseAll: function( event, all ) { 14113 clearTimeout( this.timer ); 14114 this.timer = this._delay(function() { 14115 // If we were passed an event, look for the submenu that contains the event 14116 var currentMenu = all ? this.element : 14117 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 14118 14119 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway 14120 if ( !currentMenu.length ) { 14121 currentMenu = this.element; 14122 } 14123 14124 this._close( currentMenu ); 14125 14126 this.blur( event ); 14127 this.activeMenu = currentMenu; 14128 }, this.delay ); 14129 }, 14130 14131 // With no arguments, closes the currently active menu - if nothing is active 14132 // it closes all menus. If passed an argument, it will search for menus BELOW 14133 _close: function( startMenu ) { 14134 if ( !startMenu ) { 14135 startMenu = this.active ? this.active.parent() : this.element; 14136 } 14137 14138 startMenu 14139 .find( ".ui-menu" ) 14140 .hide() 14141 .attr( "aria-hidden", "true" ) 14142 .attr( "aria-expanded", "false" ) 14143 .end() 14144 .find( "a.ui-state-active" ) 14145 .removeClass( "ui-state-active" ); 14146 }, 14147 14148 collapse: function( event ) { 14149 var newItem = this.active && 14150 this.active.parent().closest( ".ui-menu-item", this.element ); 14151 if ( newItem && newItem.length ) { 14152 this._close(); 14153 this.focus( event, newItem ); 14154 } 14155 }, 14156 14157 expand: function( event ) { 14158 var newItem = this.active && 14159 this.active 14160 .children( ".ui-menu " ) 14161 .children( ".ui-menu-item" ) 14162 .first(); 14163 14164 if ( newItem && newItem.length ) { 14165 this._open( newItem.parent() ); 14166 14167 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 14168 this._delay(function() { 14169 this.focus( event, newItem ); 14170 }); 14171 } 14172 }, 14173 14174 next: function( event ) { 14175 this._move( "next", "first", event ); 14176 }, 14177 14178 previous: function( event ) { 14179 this._move( "prev", "last", event ); 14180 }, 14181 14182 isFirstItem: function() { 14183 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 14184 }, 14185 14186 isLastItem: function() { 14187 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 14188 }, 14189 14190 _move: function( direction, filter, event ) { 14191 var next; 14192 if ( this.active ) { 14193 if ( direction === "first" || direction === "last" ) { 14194 next = this.active 14195 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 14196 .eq( -1 ); 14197 } else { 14198 next = this.active 14199 [ direction + "All" ]( ".ui-menu-item" ) 14200 .eq( 0 ); 14201 } 14202 } 14203 if ( !next || !next.length || !this.active ) { 14204 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); 14205 } 14206 14207 this.focus( event, next ); 14208 }, 14209 14210 nextPage: function( event ) { 14211 var item, base, height; 14212 14213 if ( !this.active ) { 14214 this.next( event ); 14215 return; 14216 } 14217 if ( this.isLastItem() ) { 14218 return; 14219 } 14220 if ( this._hasScroll() ) { 14221 base = this.active.offset().top; 14222 height = this.element.height(); 14223 this.active.nextAll( ".ui-menu-item" ).each(function() { 14224 item = $( this ); 14225 return item.offset().top - base - height < 0; 14226 }); 14227 14228 this.focus( event, item ); 14229 } else { 14230 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) 14231 [ !this.active ? "first" : "last" ]() ); 14232 } 14233 }, 14234 14235 previousPage: function( event ) { 14236 var item, base, height; 14237 if ( !this.active ) { 14238 this.next( event ); 14239 return; 14240 } 14241 if ( this.isFirstItem() ) { 14242 return; 14243 } 14244 if ( this._hasScroll() ) { 14245 base = this.active.offset().top; 14246 height = this.element.height(); 14247 this.active.prevAll( ".ui-menu-item" ).each(function() { 14248 item = $( this ); 14249 return item.offset().top - base + height > 0; 14250 }); 14251 14252 this.focus( event, item ); 14253 } else { 14254 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); 14255 } 14256 }, 14257 14258 _hasScroll: function() { 14259 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 14260 }, 14261 14262 select: function( event ) { 14263 // TODO: It should never be possible to not have an active item at this 14264 // point, but the tests don't trigger mouseenter before click. 14265 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 14266 var ui = { item: this.active }; 14267 if ( !this.active.has( ".ui-menu" ).length ) { 14268 this.collapseAll( event, true ); 14269 } 14270 this._trigger( "select", event, ui ); 14271 } 14272}); 14273 14274}( jQuery )); 14275 14276(function( $, undefined ) { 14277 14278$.ui = $.ui || {}; 14279 14280var cachedScrollbarWidth, 14281 max = Math.max, 14282 abs = Math.abs, 14283 round = Math.round, 14284 rhorizontal = /left|center|right/, 14285 rvertical = /top|center|bottom/, 14286 roffset = /[\+\-]\d+%?/, 14287 rposition = /^\w+/, 14288 rpercent = /%$/, 14289 _position = $.fn.position; 14290 14291function getOffsets( offsets, width, height ) { 14292 return [ 14293 parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 14294 parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 14295 ]; 14296} 14297function parseCss( element, property ) { 14298 return parseInt( $.css( element, property ), 10 ) || 0; 14299} 14300 14301$.position = { 14302 scrollbarWidth: function() { 14303 if ( cachedScrollbarWidth !== undefined ) { 14304 return cachedScrollbarWidth; 14305 } 14306 var w1, w2, 14307 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), 14308 innerDiv = div.children()[0]; 14309 14310 $( "body" ).append( div ); 14311 w1 = innerDiv.offsetWidth; 14312 div.css( "overflow", "scroll" ); 14313 14314 w2 = innerDiv.offsetWidth; 14315 14316 if ( w1 === w2 ) { 14317 w2 = div[0].clientWidth; 14318 } 14319 14320 div.remove(); 14321 14322 return (cachedScrollbarWidth = w1 - w2); 14323 }, 14324 getScrollInfo: function( within ) { 14325 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), 14326 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), 14327 hasOverflowX = overflowX === "scroll" || 14328 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), 14329 hasOverflowY = overflowY === "scroll" || 14330 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); 14331 return { 14332 width: hasOverflowX ? $.position.scrollbarWidth() : 0, 14333 height: hasOverflowY ? $.position.scrollbarWidth() : 0 14334 }; 14335 }, 14336 getWithinInfo: function( element ) { 14337 var withinElement = $( element || window ), 14338 isWindow = $.isWindow( withinElement[0] ); 14339 return { 14340 element: withinElement, 14341 isWindow: isWindow, 14342 offset: withinElement.offset() || { left: 0, top: 0 }, 14343 scrollLeft: withinElement.scrollLeft(), 14344 scrollTop: withinElement.scrollTop(), 14345 width: isWindow ? withinElement.width() : withinElement.outerWidth(), 14346 height: isWindow ? withinElement.height() : withinElement.outerHeight() 14347 }; 14348 } 14349}; 14350 14351$.fn.position = function( options ) { 14352 if ( !options || !options.of ) { 14353 return _position.apply( this, arguments ); 14354 } 14355 14356 // make a copy, we don't want to modify arguments 14357 options = $.extend( {}, options ); 14358 14359 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, 14360 target = $( options.of ), 14361 within = $.position.getWithinInfo( options.within ), 14362 scrollInfo = $.position.getScrollInfo( within ), 14363 targetElem = target[0], 14364 collision = ( options.collision || "flip" ).split( " " ), 14365 offsets = {}; 14366 14367 if ( targetElem.nodeType === 9 ) { 14368 targetWidth = target.width(); 14369 targetHeight = target.height(); 14370 targetOffset = { top: 0, left: 0 }; 14371 } else if ( $.isWindow( targetElem ) ) { 14372 targetWidth = target.width(); 14373 targetHeight = target.height(); 14374 targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; 14375 } else if ( targetElem.preventDefault ) { 14376 // force left top to allow flipping 14377 options.at = "left top"; 14378 targetWidth = targetHeight = 0; 14379 targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; 14380 } else { 14381 targetWidth = target.outerWidth(); 14382 targetHeight = target.outerHeight(); 14383 targetOffset = target.offset(); 14384 } 14385 // clone to reuse original targetOffset later 14386 basePosition = $.extend( {}, targetOffset ); 14387 14388 // force my and at to have valid horizontal and vertical positions 14389 // if a value is missing or invalid, it will be converted to center 14390 $.each( [ "my", "at" ], function() { 14391 var pos = ( options[ this ] || "" ).split( " " ), 14392 horizontalOffset, 14393 verticalOffset; 14394 14395 if ( pos.length === 1) { 14396 pos = rhorizontal.test( pos[ 0 ] ) ? 14397 pos.concat( [ "center" ] ) : 14398 rvertical.test( pos[ 0 ] ) ? 14399 [ "center" ].concat( pos ) : 14400 [ "center", "center" ]; 14401 } 14402 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 14403 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 14404 14405 // calculate offsets 14406 horizontalOffset = roffset.exec( pos[ 0 ] ); 14407 verticalOffset = roffset.exec( pos[ 1 ] ); 14408 offsets[ this ] = [ 14409 horizontalOffset ? horizontalOffset[ 0 ] : 0, 14410 verticalOffset ? verticalOffset[ 0 ] : 0 14411 ]; 14412 14413 // reduce to just the positions without the offsets 14414 options[ this ] = [ 14415 rposition.exec( pos[ 0 ] )[ 0 ], 14416 rposition.exec( pos[ 1 ] )[ 0 ] 14417 ]; 14418 }); 14419 14420 // normalize collision option 14421 if ( collision.length === 1 ) { 14422 collision[ 1 ] = collision[ 0 ]; 14423 } 14424 14425 if ( options.at[ 0 ] === "right" ) { 14426 basePosition.left += targetWidth; 14427 } else if ( options.at[ 0 ] === "center" ) { 14428 basePosition.left += targetWidth / 2; 14429 } 14430 14431 if ( options.at[ 1 ] === "bottom" ) { 14432 basePosition.top += targetHeight; 14433 } else if ( options.at[ 1 ] === "center" ) { 14434 basePosition.top += targetHeight / 2; 14435 } 14436 14437 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 14438 basePosition.left += atOffset[ 0 ]; 14439 basePosition.top += atOffset[ 1 ]; 14440 14441 return this.each(function() { 14442 var collisionPosition, using, 14443 elem = $( this ), 14444 elemWidth = elem.outerWidth(), 14445 elemHeight = elem.outerHeight(), 14446 marginLeft = parseCss( this, "marginLeft" ), 14447 marginTop = parseCss( this, "marginTop" ), 14448 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, 14449 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, 14450 position = $.extend( {}, basePosition ), 14451 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 14452 14453 if ( options.my[ 0 ] === "right" ) { 14454 position.left -= elemWidth; 14455 } else if ( options.my[ 0 ] === "center" ) { 14456 position.left -= elemWidth / 2; 14457 } 14458 14459 if ( options.my[ 1 ] === "bottom" ) { 14460 position.top -= elemHeight; 14461 } else if ( options.my[ 1 ] === "center" ) { 14462 position.top -= elemHeight / 2; 14463 } 14464 14465 position.left += myOffset[ 0 ]; 14466 position.top += myOffset[ 1 ]; 14467 14468 // if the browser doesn't support fractions, then round for consistent results 14469 if ( !$.support.offsetFractions ) { 14470 position.left = round( position.left ); 14471 position.top = round( position.top ); 14472 } 14473 14474 collisionPosition = { 14475 marginLeft: marginLeft, 14476 marginTop: marginTop 14477 }; 14478 14479 $.each( [ "left", "top" ], function( i, dir ) { 14480 if ( $.ui.position[ collision[ i ] ] ) { 14481 $.ui.position[ collision[ i ] ][ dir ]( position, { 14482 targetWidth: targetWidth, 14483 targetHeight: targetHeight, 14484 elemWidth: elemWidth, 14485 elemHeight: elemHeight, 14486 collisionPosition: collisionPosition, 14487 collisionWidth: collisionWidth, 14488 collisionHeight: collisionHeight, 14489 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 14490 my: options.my, 14491 at: options.at, 14492 within: within, 14493 elem : elem 14494 }); 14495 } 14496 }); 14497 14498 if ( $.fn.bgiframe ) { 14499 elem.bgiframe(); 14500 } 14501 14502 if ( options.using ) { 14503 // adds feedback as second argument to using callback, if present 14504 using = function( props ) { 14505 var left = targetOffset.left - position.left, 14506 right = left + targetWidth - elemWidth, 14507 top = targetOffset.top - position.top, 14508 bottom = top + targetHeight - elemHeight, 14509 feedback = { 14510 target: { 14511 element: target, 14512 left: targetOffset.left, 14513 top: targetOffset.top, 14514 width: targetWidth, 14515 height: targetHeight 14516 }, 14517 element: { 14518 element: elem, 14519 left: position.left, 14520 top: position.top, 14521 width: elemWidth, 14522 height: elemHeight 14523 }, 14524 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 14525 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 14526 }; 14527 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 14528 feedback.horizontal = "center"; 14529 } 14530 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 14531 feedback.vertical = "middle"; 14532 } 14533 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 14534 feedback.important = "horizontal"; 14535 } else { 14536 feedback.important = "vertical"; 14537 } 14538 options.using.call( this, props, feedback ); 14539 }; 14540 } 14541 14542 elem.offset( $.extend( position, { using: using } ) ); 14543 }); 14544}; 14545 14546$.ui.position = { 14547 fit: { 14548 left: function( position, data ) { 14549 var within = data.within, 14550 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 14551 outerWidth = within.width, 14552 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 14553 overLeft = withinOffset - collisionPosLeft, 14554 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 14555 newOverRight; 14556 14557 // element is wider than within 14558 if ( data.collisionWidth > outerWidth ) { 14559 // element is initially over the left side of within 14560 if ( overLeft > 0 && overRight <= 0 ) { 14561 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; 14562 position.left += overLeft - newOverRight; 14563 // element is initially over right side of within 14564 } else if ( overRight > 0 && overLeft <= 0 ) { 14565 position.left = withinOffset; 14566 // element is initially over both left and right sides of within 14567 } else { 14568 if ( overLeft > overRight ) { 14569 position.left = withinOffset + outerWidth - data.collisionWidth; 14570 } else { 14571 position.left = withinOffset; 14572 } 14573 } 14574 // too far left -> align with left edge 14575 } else if ( overLeft > 0 ) { 14576 position.left += overLeft; 14577 // too far right -> align with right edge 14578 } else if ( overRight > 0 ) { 14579 position.left -= overRight; 14580 // adjust based on position and margin 14581 } else { 14582 position.left = max( position.left - collisionPosLeft, position.left ); 14583 } 14584 }, 14585 top: function( position, data ) { 14586 var within = data.within, 14587 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 14588 outerHeight = data.within.height, 14589 collisionPosTop = position.top - data.collisionPosition.marginTop, 14590 overTop = withinOffset - collisionPosTop, 14591 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 14592 newOverBottom; 14593 14594 // element is taller than within 14595 if ( data.collisionHeight > outerHeight ) { 14596 // element is initially over the top of within 14597 if ( overTop > 0 && overBottom <= 0 ) { 14598 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; 14599 position.top += overTop - newOverBottom; 14600 // element is initially over bottom of within 14601 } else if ( overBottom > 0 && overTop <= 0 ) { 14602 position.top = withinOffset; 14603 // element is initially over both top and bottom of within 14604 } else { 14605 if ( overTop > overBottom ) { 14606 position.top = withinOffset + outerHeight - data.collisionHeight; 14607 } else { 14608 position.top = withinOffset; 14609 } 14610 } 14611 // too far up -> align with top 14612 } else if ( overTop > 0 ) { 14613 position.top += overTop; 14614 // too far down -> align with bottom edge 14615 } else if ( overBottom > 0 ) { 14616 position.top -= overBottom; 14617 // adjust based on position and margin 14618 } else { 14619 position.top = max( position.top - collisionPosTop, position.top ); 14620 } 14621 } 14622 }, 14623 flip: { 14624 left: function( position, data ) { 14625 var within = data.within, 14626 withinOffset = within.offset.left + within.scrollLeft, 14627 outerWidth = within.width, 14628 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 14629 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 14630 overLeft = collisionPosLeft - offsetLeft, 14631 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 14632 myOffset = data.my[ 0 ] === "left" ? 14633 -data.elemWidth : 14634 data.my[ 0 ] === "right" ? 14635 data.elemWidth : 14636 0, 14637 atOffset = data.at[ 0 ] === "left" ? 14638 data.targetWidth : 14639 data.at[ 0 ] === "right" ? 14640 -data.targetWidth : 14641 0, 14642 offset = -2 * data.offset[ 0 ], 14643 newOverRight, 14644 newOverLeft; 14645 14646 if ( overLeft < 0 ) { 14647 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; 14648 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 14649 position.left += myOffset + atOffset + offset; 14650 } 14651 } 14652 else if ( overRight > 0 ) { 14653 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; 14654 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 14655 position.left += myOffset + atOffset + offset; 14656 } 14657 } 14658 }, 14659 top: function( position, data ) { 14660 var within = data.within, 14661 withinOffset = within.offset.top + within.scrollTop, 14662 outerHeight = within.height, 14663 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 14664 collisionPosTop = position.top - data.collisionPosition.marginTop, 14665 overTop = collisionPosTop - offsetTop, 14666 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 14667 top = data.my[ 1 ] === "top", 14668 myOffset = top ? 14669 -data.elemHeight : 14670 data.my[ 1 ] === "bottom" ? 14671 data.elemHeight : 14672 0, 14673 atOffset = data.at[ 1 ] === "top" ? 14674 data.targetHeight : 14675 data.at[ 1 ] === "bottom" ? 14676 -data.targetHeight : 14677 0, 14678 offset = -2 * data.offset[ 1 ], 14679 newOverTop, 14680 newOverBottom; 14681 if ( overTop < 0 ) { 14682 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; 14683 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { 14684 position.top += myOffset + atOffset + offset; 14685 } 14686 } 14687 else if ( overBottom > 0 ) { 14688 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; 14689 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { 14690 position.top += myOffset + atOffset + offset; 14691 } 14692 } 14693 } 14694 }, 14695 flipfit: { 14696 left: function() { 14697 $.ui.position.flip.left.apply( this, arguments ); 14698 $.ui.position.fit.left.apply( this, arguments ); 14699 }, 14700 top: function() { 14701 $.ui.position.flip.top.apply( this, arguments ); 14702 $.ui.position.fit.top.apply( this, arguments ); 14703 } 14704 } 14705}; 14706 14707// fraction support test 14708(function () { 14709 var testElement, testElementParent, testElementStyle, offsetLeft, i, 14710 body = document.getElementsByTagName( "body" )[ 0 ], 14711 div = document.createElement( "div" ); 14712 14713 //Create a "fake body" for testing based on method used in jQuery.support 14714 testElement = document.createElement( body ? "div" : "body" ); 14715 testElementStyle = { 14716 visibility: "hidden", 14717 width: 0, 14718 height: 0, 14719 border: 0, 14720 margin: 0, 14721 background: "none" 14722 }; 14723 if ( body ) { 14724 $.extend( testElementStyle, { 14725 position: "absolute", 14726 left: "-1000px", 14727 top: "-1000px" 14728 }); 14729 } 14730 for ( i in testElementStyle ) { 14731 testElement.style[ i ] = testElementStyle[ i ]; 14732 } 14733 testElement.appendChild( div ); 14734 testElementParent = body || document.documentElement; 14735 testElementParent.insertBefore( testElement, testElementParent.firstChild ); 14736 14737 div.style.cssText = "position: absolute; left: 10.7432222px;"; 14738 14739 offsetLeft = $( div ).offset().left; 14740 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; 14741 14742 testElement.innerHTML = ""; 14743 testElementParent.removeChild( testElement ); 14744})(); 14745 14746// DEPRECATED 14747if ( $.uiBackCompat !== false ) { 14748 // offset option 14749 (function( $ ) { 14750 var _position = $.fn.position; 14751 $.fn.position = function( options ) { 14752 if ( !options || !options.offset ) { 14753 return _position.call( this, options ); 14754 } 14755 var offset = options.offset.split( " " ), 14756 at = options.at.split( " " ); 14757 if ( offset.length === 1 ) { 14758 offset[ 1 ] = offset[ 0 ]; 14759 } 14760 if ( /^\d/.test( offset[ 0 ] ) ) { 14761 offset[ 0 ] = "+" + offset[ 0 ]; 14762 } 14763 if ( /^\d/.test( offset[ 1 ] ) ) { 14764 offset[ 1 ] = "+" + offset[ 1 ]; 14765 } 14766 if ( at.length === 1 ) { 14767 if ( /left|center|right/.test( at[ 0 ] ) ) { 14768 at[ 1 ] = "center"; 14769 } else { 14770 at[ 1 ] = at[ 0 ]; 14771 at[ 0 ] = "center"; 14772 } 14773 } 14774 return _position.call( this, $.extend( options, { 14775 at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], 14776 offset: undefined 14777 } ) ); 14778 }; 14779 }( jQuery ) ); 14780} 14781 14782}( jQuery ) ); 14783 14784(function( $, undefined ) { 14785 14786$.widget( "ui.progressbar", { 14787 version: "1.9.1", 14788 options: { 14789 value: 0, 14790 max: 100 14791 }, 14792 14793 min: 0, 14794 14795 _create: function() { 14796 this.element 14797 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 14798 .attr({ 14799 role: "progressbar", 14800 "aria-valuemin": this.min, 14801 "aria-valuemax": this.options.max,
14802 "aria-valuenow": this._value() 14803 }); 14804 14805 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) 14806 .appendTo( this.element ); 14807 14808 this.oldValue = this._value(); 14809 this._refreshValue(); 14810 }, 14811 14812 _destroy: function() { 14813 this.element 14814 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) 14815 .removeAttr( "role" ) 14816 .removeAttr( "aria-valuemin" ) 14817 .removeAttr( "aria-valuemax" ) 14818 .removeAttr( "aria-valuenow" ); 14819 14820 this.valueDiv.remove(); 14821 }, 14822 14823 value: function( newValue ) { 14824 if ( newValue === undefined ) { 14825 return this._value(); 14826 } 14827 14828 this._setOption( "value", newValue ); 14829 return this; 14830 }, 14831 14832 _setOption: function( key, value ) { 14833 if ( key === "value" ) { 14834 this.options.value = value; 14835 this._refreshValue(); 14836 if ( this._value() === this.options.max ) { 14837 this._trigger( "complete" ); 14838 } 14839 } 14840 14841 this._super( key, value ); 14842 }, 14843 14844 _value: function() { 14845 var val = this.options.value; 14846 // normalize invalid value 14847 if ( typeof val !== "number" ) { 14848 val = 0; 14849 } 14850 return Math.min( this.options.max, Math.max( this.min, val ) ); 14851 }, 14852 14853 _percentage: function() { 14854 return 100 * this._value() / this.options.max; 14855 }, 14856 14857 _refreshValue: function() { 14858 var value = this.value(), 14859 percentage = this._percentage(); 14860 14861 if ( this.oldValue !== value ) { 14862 this.oldValue = value; 14863 this._trigger( "change" ); 14864 } 14865 14866 this.valueDiv 14867 .toggle( value > this.min ) 14868 .toggleClass( "ui-corner-right", value === this.options.max ) 14869 .width( percentage.toFixed(0) + "%" ); 14870 this.element.attr( "aria-valuenow", value ); 14871 } 14872}); 14873 14874})( jQuery ); 14875 14876(function( $, undefined ) { 14877 14878// number of pages in a slider 14879// (how many times can you page up/down to go through the whole range) 14880var numPages = 5; 14881 14882$.widget( "ui.slider", $.ui.mouse, { 14883 version: "1.9.1", 14884 widgetEventPrefix: "slide", 14885 14886 options: { 14887 animate: false, 14888 distance: 0, 14889 max: 100, 14890 min: 0, 14891 orientation: "horizontal", 14892 range: false, 14893 step: 1, 14894 value: 0, 14895 values: null 14896 }, 14897 14898 _create: function() { 14899 var i, handleCount, 14900 o = this.options, 14901 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), 14902 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", 14903 handles = []; 14904 14905 this._keySliding = false; 14906 this._mouseSliding = false; 14907 this._animateOff = true; 14908 this._handleIndex = null; 14909 this._detectOrientation(); 14910 this._mouseInit(); 14911 14912 this.element 14913 .addClass( "ui-slider" + 14914 " ui-slider-" + this.orientation + 14915 " ui-widget" + 14916 " ui-widget-content" + 14917 " ui-corner-all" + 14918 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); 14919 14920 this.range = $([]); 14921 14922 if ( o.range ) { 14923 if ( o.range === true ) { 14924 if ( !o.values ) { 14925 o.values = [ this._valueMin(), this._valueMin() ]; 14926 } 14927 if ( o.values.length && o.values.length !== 2 ) { 14928 o.values = [ o.values[0], o.values[0] ]; 14929 } 14930 } 14931 14932 this.range = $( "<div></div>" ) 14933 .appendTo( this.element ) 14934 .addClass( "ui-slider-range" + 14935 // note: this isn't the most fittingly semantic framework class for this element, 14936 // but worked best visually with a variety of themes 14937 " ui-widget-header" + 14938 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); 14939 } 14940 14941 handleCount = ( o.values && o.values.length ) || 1; 14942 14943 for ( i = existingHandles.length; i < handleCount; i++ ) { 14944 handles.push( handle ); 14945 } 14946 14947 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 14948 14949 this.handle = this.handles.eq( 0 ); 14950 14951 this.handles.add( this.range ).filter( "a" ) 14952 .click(function( event ) { 14953 event.preventDefault(); 14954 }) 14955 .mouseenter(function() { 14956 if ( !o.disabled ) { 14957 $( this ).addClass( "ui-state-hover" ); 14958 } 14959 }) 14960 .mouseleave(function() { 14961 $( this ).removeClass( "ui-state-hover" ); 14962 }) 14963 .focus(function() { 14964 if ( !o.disabled ) { 14965 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); 14966 $( this ).addClass( "ui-state-focus" ); 14967 } else { 14968 $( this ).blur(); 14969 } 14970 }) 14971 .blur(function() { 14972 $( this ).removeClass( "ui-state-focus" ); 14973 }); 14974 14975 this.handles.each(function( i ) { 14976 $( this ).data( "ui-slider-handle-index", i ); 14977 }); 14978 14979 this._on( this.handles, { 14980 keydown: function( event ) { 14981 var allowed, curVal, newVal, step, 14982 index = $( event.target ).data( "ui-slider-handle-index" ); 14983 14984 switch ( event.keyCode ) { 14985 case $.ui.keyCode.HOME: 14986 case $.ui.keyCode.END: 14987 case $.ui.keyCode.PAGE_UP: 14988 case $.ui.keyCode.PAGE_DOWN: 14989 case $.ui.keyCode.UP: 14990 case $.ui.keyCode.RIGHT: 14991 case $.ui.keyCode.DOWN: 14992 case $.ui.keyCode.LEFT: 14993 event.preventDefault(); 14994 if ( !this._keySliding ) { 14995 this._keySliding = true; 14996 $( event.target ).addClass( "ui-state-active" ); 14997 allowed = this._start( event, index ); 14998 if ( allowed === false ) { 14999 return; 15000 } 15001 } 15002 break; 15003 } 15004 15005 step = this.options.step; 15006 if ( this.options.values && this.options.values.length ) { 15007 curVal = newVal = this.values( index ); 15008 } else { 15009 curVal = newVal = this.value(); 15010 } 15011 15012 switch ( event.keyCode ) { 15013 case $.ui.keyCode.HOME: 15014 newVal = this._valueMin(); 15015 break; 15016 case $.ui.keyCode.END: 15017 newVal = this._valueMax(); 15018 break; 15019 case $.ui.keyCode.PAGE_UP: 15020 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); 15021 break; 15022 case $.ui.keyCode.PAGE_DOWN: 15023 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); 15024 break; 15025 case $.ui.keyCode.UP: 15026 case $.ui.keyCode.RIGHT: 15027 if ( curVal === this._valueMax() ) { 15028 return; 15029 } 15030 newVal = this._trimAlignValue( curVal + step ); 15031 break; 15032 case $.ui.keyCode.DOWN: 15033 case $.ui.keyCode.LEFT: 15034 if ( curVal === this._valueMin() ) { 15035 return; 15036 } 15037 newVal = this._trimAlignValue( curVal - step ); 15038 break; 15039 } 15040 15041 this._slide( event, index, newVal ); 15042 }, 15043 keyup: function( event ) { 15044 var index = $( event.target ).data( "ui-slider-handle-index" ); 15045 15046 if ( this._keySliding ) { 15047 this._keySliding = false;
vendor: 21,330 bytes, lines 15048-15844
15048 this._stop( event, index ); 15049 this._change( event, index ); 15050 $( event.target ).removeClass( "ui-state-active" ); 15051 } 15052 } 15053 }); 15054 15055 this._refreshValue(); 15056 15057 this._animateOff = false; 15058 }, 15059 15060 _destroy: function() { 15061 this.handles.remove(); 15062 this.range.remove(); 15063 15064 this.element 15065 .removeClass( "ui-slider" + 15066 " ui-slider-horizontal" + 15067 " ui-slider-vertical" + 15068 " ui-slider-disabled" + 15069 " ui-widget" + 15070 " ui-widget-content" + 15071 " ui-corner-all" ); 15072 15073 this._mouseDestroy(); 15074 }, 15075 15076 _mouseCapture: function( event ) { 15077 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 15078 that = this, 15079 o = this.options; 15080 15081 if ( o.disabled ) { 15082 return false; 15083 } 15084 15085 this.elementSize = { 15086 width: this.element.outerWidth(), 15087 height: this.element.outerHeight() 15088 }; 15089 this.elementOffset = this.element.offset(); 15090 15091 position = { x: event.pageX, y: event.pageY }; 15092 normValue = this._normValueFromMouse( position ); 15093 distance = this._valueMax() - this._valueMin() + 1; 15094 this.handles.each(function( i ) { 15095 var thisDistance = Math.abs( normValue - that.values(i) ); 15096 if ( distance > thisDistance ) { 15097 distance = thisDistance; 15098 closestHandle = $( this ); 15099 index = i; 15100 } 15101 }); 15102 15103 // workaround for bug #3736 (if both handles of a range are at 0, 15104 // the first is always used as the one with least distance, 15105 // and moving it is obviously prevented by preventing negative ranges) 15106 if( o.range === true && this.values(1) === o.min ) { 15107 index += 1; 15108 closestHandle = $( this.handles[index] ); 15109 } 15110 15111 allowed = this._start( event, index ); 15112 if ( allowed === false ) { 15113 return false; 15114 } 15115 this._mouseSliding = true; 15116 15117 this._handleIndex = index; 15118 15119 closestHandle 15120 .addClass( "ui-state-active" ) 15121 .focus(); 15122 15123 offset = closestHandle.offset(); 15124 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); 15125 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 15126 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 15127 top: event.pageY - offset.top - 15128 ( closestHandle.height() / 2 ) - 15129 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - 15130 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + 15131 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) 15132 }; 15133 15134 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 15135 this._slide( event, index, normValue ); 15136 } 15137 this._animateOff = true; 15138 return true; 15139 }, 15140 15141 _mouseStart: function() { 15142 return true; 15143 }, 15144 15145 _mouseDrag: function( event ) { 15146 var position = { x: event.pageX, y: event.pageY }, 15147 normValue = this._normValueFromMouse( position ); 15148 15149 this._slide( event, this._handleIndex, normValue ); 15150 15151 return false; 15152 }, 15153 15154 _mouseStop: function( event ) { 15155 this.handles.removeClass( "ui-state-active" ); 15156 this._mouseSliding = false; 15157 15158 this._stop( event, this._handleIndex ); 15159 this._change( event, this._handleIndex ); 15160 15161 this._handleIndex = null; 15162 this._clickOffset = null; 15163 this._animateOff = false; 15164 15165 return false; 15166 }, 15167 15168 _detectOrientation: function() { 15169 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 15170 }, 15171 15172 _normValueFromMouse: function( position ) { 15173 var pixelTotal, 15174 pixelMouse, 15175 percentMouse, 15176 valueTotal, 15177 valueMouse; 15178 15179 if ( this.orientation === "horizontal" ) { 15180 pixelTotal = this.elementSize.width; 15181 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); 15182 } else { 15183 pixelTotal = this.elementSize.height; 15184 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); 15185 } 15186 15187 percentMouse = ( pixelMouse / pixelTotal ); 15188 if ( percentMouse > 1 ) { 15189 percentMouse = 1; 15190 } 15191 if ( percentMouse < 0 ) { 15192 percentMouse = 0; 15193 } 15194 if ( this.orientation === "vertical" ) { 15195 percentMouse = 1 - percentMouse; 15196 } 15197 15198 valueTotal = this._valueMax() - this._valueMin(); 15199 valueMouse = this._valueMin() + percentMouse * valueTotal; 15200 15201 return this._trimAlignValue( valueMouse ); 15202 }, 15203 15204 _start: function( event, index ) { 15205 var uiHash = { 15206 handle: this.handles[ index ], 15207 value: this.value() 15208 }; 15209 if ( this.options.values && this.options.values.length ) { 15210 uiHash.value = this.values( index ); 15211 uiHash.values = this.values(); 15212 } 15213 return this._trigger( "start", event, uiHash ); 15214 }, 15215 15216 _slide: function( event, index, newVal ) { 15217 var otherVal, 15218 newValues, 15219 allowed; 15220 15221 if ( this.options.values && this.options.values.length ) { 15222 otherVal = this.values( index ? 0 : 1 ); 15223 15224 if ( ( this.options.values.length === 2 && this.options.range === true ) && 15225 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) 15226 ) { 15227 newVal = otherVal; 15228 } 15229 15230 if ( newVal !== this.values( index ) ) { 15231 newValues = this.values(); 15232 newValues[ index ] = newVal; 15233 // A slide can be canceled by returning false from the slide callback 15234 allowed = this._trigger( "slide", event, { 15235 handle: this.handles[ index ], 15236 value: newVal, 15237 values: newValues 15238 } ); 15239 otherVal = this.values( index ? 0 : 1 ); 15240 if ( allowed !== false ) { 15241 this.values( index, newVal, true ); 15242 } 15243 } 15244 } else { 15245 if ( newVal !== this.value() ) { 15246 // A slide can be canceled by returning false from the slide callback 15247 allowed = this._trigger( "slide", event, { 15248 handle: this.handles[ index ], 15249 value: newVal 15250 } ); 15251 if ( allowed !== false ) { 15252 this.value( newVal ); 15253 } 15254 } 15255 } 15256 }, 15257 15258 _stop: function( event, index ) { 15259 var uiHash = { 15260 handle: this.handles[ index ], 15261 value: this.value() 15262 }; 15263 if ( this.options.values && this.options.values.length ) { 15264 uiHash.value = this.values( index ); 15265 uiHash.values = this.values(); 15266 } 15267 15268 this._trigger( "stop", event, uiHash ); 15269 }, 15270 15271 _change: function( event, index ) { 15272 if ( !this._keySliding && !this._mouseSliding ) { 15273 var uiHash = { 15274 handle: this.handles[ index ], 15275 value: this.value() 15276 }; 15277 if ( this.options.values && this.options.values.length ) { 15278 uiHash.value = this.values( index ); 15279 uiHash.values = this.values(); 15280 } 15281 15282 this._trigger( "change", event, uiHash ); 15283 } 15284 }, 15285 15286 value: function( newValue ) { 15287 if ( arguments.length ) { 15288 this.options.value = this._trimAlignValue( newValue ); 15289 this._refreshValue(); 15290 this._change( null, 0 ); 15291 return; 15292 } 15293 15294 return this._value(); 15295 }, 15296 15297 values: function( index, newValue ) { 15298 var vals, 15299 newValues, 15300 i; 15301 15302 if ( arguments.length > 1 ) { 15303 this.options.values[ index ] = this._trimAlignValue( newValue ); 15304 this._refreshValue(); 15305 this._change( null, index ); 15306 return; 15307 } 15308 15309 if ( arguments.length ) { 15310 if ( $.isArray( arguments[ 0 ] ) ) { 15311 vals = this.options.values; 15312 newValues = arguments[ 0 ]; 15313 for ( i = 0; i < vals.length; i += 1 ) { 15314 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 15315 this._change( null, i ); 15316 } 15317 this._refreshValue(); 15318 } else { 15319 if ( this.options.values && this.options.values.length ) { 15320 return this._values( index ); 15321 } else { 15322 return this.value(); 15323 } 15324 } 15325 } else { 15326 return this._values(); 15327 } 15328 }, 15329 15330 _setOption: function( key, value ) { 15331 var i, 15332 valsLength = 0; 15333 15334 if ( $.isArray( this.options.values ) ) { 15335 valsLength = this.options.values.length; 15336 } 15337 15338 $.Widget.prototype._setOption.apply( this, arguments ); 15339 15340 switch ( key ) { 15341 case "disabled": 15342 if ( value ) { 15343 this.handles.filter( ".ui-state-focus" ).blur(); 15344 this.handles.removeClass( "ui-state-hover" ); 15345 this.handles.prop( "disabled", true ); 15346 this.element.addClass( "ui-disabled" ); 15347 } else { 15348 this.handles.prop( "disabled", false ); 15349 this.element.removeClass( "ui-disabled" ); 15350 } 15351 break; 15352 case "orientation": 15353 this._detectOrientation(); 15354 this.element 15355 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) 15356 .addClass( "ui-slider-" + this.orientation ); 15357 this._refreshValue(); 15358 break; 15359 case "value": 15360 this._animateOff = true; 15361 this._refreshValue(); 15362 this._change( null, 0 ); 15363 this._animateOff = false; 15364 break; 15365 case "values": 15366 this._animateOff = true; 15367 this._refreshValue(); 15368 for ( i = 0; i < valsLength; i += 1 ) { 15369 this._change( null, i ); 15370 } 15371 this._animateOff = false; 15372 break; 15373 case "min": 15374 case "max": 15375 this._animateOff = true; 15376 this._refreshValue(); 15377 this._animateOff = false; 15378 break; 15379 } 15380 }, 15381 15382 //internal value getter 15383 // _value() returns value trimmed by min and max, aligned by step 15384 _value: function() { 15385 var val = this.options.value; 15386 val = this._trimAlignValue( val ); 15387 15388 return val; 15389 }, 15390 15391 //internal values getter 15392 // _values() returns array of values trimmed by min and max, aligned by step 15393 // _values( index ) returns single value trimmed by min and max, aligned by step 15394 _values: function( index ) { 15395 var val, 15396 vals, 15397 i; 15398 15399 if ( arguments.length ) { 15400 val = this.options.values[ index ]; 15401 val = this._trimAlignValue( val ); 15402 15403 return val; 15404 } else { 15405 // .slice() creates a copy of the array 15406 // this copy gets trimmed by min and max and then returned 15407 vals = this.options.values.slice(); 15408 for ( i = 0; i < vals.length; i+= 1) { 15409 vals[ i ] = this._trimAlignValue( vals[ i ] ); 15410 } 15411 15412 return vals; 15413 } 15414 }, 15415 15416 // returns the step-aligned value that val is closest to, between (inclusive) min and max 15417 _trimAlignValue: function( val ) { 15418 if ( val <= this._valueMin() ) { 15419 return this._valueMin(); 15420 } 15421 if ( val >= this._valueMax() ) { 15422 return this._valueMax(); 15423 } 15424 var step = ( this.options.step > 0 ) ? this.options.step : 1, 15425 valModStep = (val - this._valueMin()) % step, 15426 alignValue = val - valModStep; 15427 15428 if ( Math.abs(valModStep) * 2 >= step ) { 15429 alignValue += ( valModStep > 0 ) ? step : ( -step ); 15430 } 15431 15432 // Since JavaScript has problems with large floats, round 15433 // the final value to 5 digits after the decimal point (see #4124) 15434 return parseFloat( alignValue.toFixed(5) ); 15435 }, 15436 15437 _valueMin: function() { 15438 return this.options.min; 15439 }, 15440 15441 _valueMax: function() { 15442 return this.options.max; 15443 }, 15444 15445 _refreshValue: function() { 15446 var lastValPercent, valPercent, value, valueMin, valueMax, 15447 oRange = this.options.range, 15448 o = this.options, 15449 that = this, 15450 animate = ( !this._animateOff ) ? o.animate : false, 15451 _set = {}; 15452 15453 if ( this.options.values && this.options.values.length ) { 15454 this.handles.each(function( i ) { 15455 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; 15456 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 15457 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 15458 if ( that.options.range === true ) { 15459 if ( that.orientation === "horizontal" ) { 15460 if ( i === 0 ) { 15461 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); 15462 } 15463 if ( i === 1 ) { 15464 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 15465 } 15466 } else { 15467 if ( i === 0 ) { 15468 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); 15469 } 15470 if ( i === 1 ) { 15471 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); 15472 } 15473 } 15474 } 15475 lastValPercent = valPercent; 15476 }); 15477 } else { 15478 value = this.value(); 15479 valueMin = this._valueMin(); 15480 valueMax = this._valueMax(); 15481 valPercent = ( valueMax !== valueMin ) ? 15482 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 15483 0; 15484 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 15485 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 15486 15487 if ( oRange === "min" && this.orientation === "horizontal" ) { 15488 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); 15489 } 15490 if ( oRange === "max" && this.orientation === "horizontal" ) { 15491 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 15492 } 15493 if ( oRange === "min" && this.orientation === "vertical" ) { 15494 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); 15495 } 15496 if ( oRange === "max" && this.orientation === "vertical" ) { 15497 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); 15498 } 15499 } 15500 } 15501 15502}); 15503 15504}(jQuery)); 15505 15506(function( $ ) { 15507 15508function modifier( fn ) { 15509 return function() { 15510 var previous = this.element.val(); 15511 fn.apply( this, arguments ); 15512 this._refresh(); 15513 if ( previous !== this.element.val() ) { 15514 this._trigger( "change" ); 15515 } 15516 }; 15517} 15518 15519$.widget( "ui.spinner", { 15520 version: "1.9.1", 15521 defaultElement: "<input>", 15522 widgetEventPrefix: "spin", 15523 options: { 15524 culture: null, 15525 icons: { 15526 down: "ui-icon-triangle-1-s", 15527 up: "ui-icon-triangle-1-n" 15528 }, 15529 incremental: true, 15530 max: null, 15531 min: null, 15532 numberFormat: null, 15533 page: 10, 15534 step: 1, 15535 15536 change: null, 15537 spin: null, 15538 start: null, 15539 stop: null 15540 }, 15541 15542 _create: function() { 15543 // handle string values that need to be parsed 15544 this._setOption( "max", this.options.max ); 15545 this._setOption( "min", this.options.min ); 15546 this._setOption( "step", this.options.step ); 15547 15548 // format the value, but don't constrain 15549 this._value( this.element.val(), true ); 15550 15551 this._draw(); 15552 this._on( this._events ); 15553 this._refresh(); 15554 15555 // turning off autocomplete prevents the browser from remembering the 15556 // value when navigating through history, so we re-enable autocomplete 15557 // if the page is unloaded before the widget is destroyed. #7790 15558 this._on( this.window, { 15559 beforeunload: function() { 15560 this.element.removeAttr( "autocomplete" ); 15561 } 15562 }); 15563 }, 15564 15565 _getCreateOptions: function() { 15566 var options = {}, 15567 element = this.element; 15568 15569 $.each( [ "min", "max", "step" ], function( i, option ) { 15570 var value = element.attr( option ); 15571 if ( value !== undefined && value.length ) { 15572 options[ option ] = value; 15573 } 15574 }); 15575 15576 return options; 15577 }, 15578 15579 _events: { 15580 keydown: function( event ) { 15581 if ( this._start( event ) && this._keydown( event ) ) { 15582 event.preventDefault(); 15583 } 15584 }, 15585 keyup: "_stop", 15586 focus: function() { 15587 this.previous = this.element.val(); 15588 }, 15589 blur: function( event ) { 15590 if ( this.cancelBlur ) { 15591 delete this.cancelBlur; 15592 return; 15593 } 15594 15595 this._refresh(); 15596 if ( this.previous !== this.element.val() ) { 15597 this._trigger( "change", event ); 15598 } 15599 }, 15600 mousewheel: function( event, delta ) { 15601 if ( !delta ) { 15602 return; 15603 } 15604 if ( !this.spinning && !this._start( event ) ) { 15605 return false; 15606 } 15607 15608 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); 15609 clearTimeout( this.mousewheelTimer ); 15610 this.mousewheelTimer = this._delay(function() { 15611 if ( this.spinning ) { 15612 this._stop( event ); 15613 } 15614 }, 100 ); 15615 event.preventDefault(); 15616 }, 15617 "mousedown .ui-spinner-button": function( event ) { 15618 var previous; 15619 15620 // We never want the buttons to have focus; whenever the user is 15621 // interacting with the spinner, the focus should be on the input. 15622 // If the input is focused then this.previous is properly set from 15623 // when the input first received focus. If the input is not focused 15624 // then we need to set this.previous based on the value before spinning. 15625 previous = this.element[0] === this.document[0].activeElement ? 15626 this.previous : this.element.val(); 15627 function checkFocus() { 15628 var isActive = this.element[0] === this.document[0].activeElement; 15629 if ( !isActive ) { 15630 this.element.focus(); 15631 this.previous = previous; 15632 // support: IE 15633 // IE sets focus asynchronously, so we need to check if focus 15634 // moved off of the input because the user clicked on the button. 15635 this._delay(function() { 15636 this.previous = previous; 15637 }); 15638 } 15639 } 15640 15641 // ensure focus is on (or stays on) the text field 15642 event.preventDefault(); 15643 checkFocus.call( this ); 15644 15645 // support: IE 15646 // IE doesn't prevent moving focus even with event.preventDefault() 15647 // so we set a flag to know when we should ignore the blur event 15648 // and check (again) if focus moved off of the input. 15649 this.cancelBlur = true; 15650 this._delay(function() { 15651 delete this.cancelBlur; 15652 checkFocus.call( this ); 15653 }); 15654 15655 if ( this._start( event ) === false ) { 15656 return; 15657 } 15658 15659 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 15660 }, 15661 "mouseup .ui-spinner-button": "_stop", 15662 "mouseenter .ui-spinner-button": function( event ) { 15663 // button will add ui-state-active if mouse was down while mouseleave and kept down 15664 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 15665 return; 15666 } 15667 15668 if ( this._start( event ) === false ) { 15669 return false; 15670 } 15671 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 15672 }, 15673 // TODO: do we really want to consider this a stop? 15674 // shouldn't we just stop the repeater and wait until mouseup before 15675 // we trigger the stop event? 15676 "mouseleave .ui-spinner-button": "_stop" 15677 }, 15678 15679 _draw: function() { 15680 var uiSpinner = this.uiSpinner = this.element 15681 .addClass( "ui-spinner-input" ) 15682 .attr( "autocomplete", "off" ) 15683 .wrap( this._uiSpinnerHtml() ) 15684 .parent() 15685 // add buttons 15686 .append( this._buttonHtml() ); 15687 15688 this.element.attr( "role", "spinbutton" ); 15689 15690 // button bindings 15691 this.buttons = uiSpinner.find( ".ui-spinner-button" ) 15692 .attr( "tabIndex", -1 ) 15693 .button() 15694 .removeClass( "ui-corner-all" ); 15695 15696 // IE 6 doesn't understand height: 50% for the buttons 15697 // unless the wrapper has an explicit height 15698 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && 15699 uiSpinner.height() > 0 ) { 15700 uiSpinner.height( uiSpinner.height() ); 15701 } 15702 15703 // disable spinner if element was already disabled 15704 if ( this.options.disabled ) { 15705 this.disable(); 15706 } 15707 }, 15708 15709 _keydown: function( event ) { 15710 var options = this.options, 15711 keyCode = $.ui.keyCode; 15712 15713 switch ( event.keyCode ) { 15714 case keyCode.UP: 15715 this._repeat( null, 1, event ); 15716 return true; 15717 case keyCode.DOWN: 15718 this._repeat( null, -1, event ); 15719 return true; 15720 case keyCode.PAGE_UP: 15721 this._repeat( null, options.page, event ); 15722 return true; 15723 case keyCode.PAGE_DOWN: 15724 this._repeat( null, -options.page, event ); 15725 return true; 15726 } 15727 15728 return false; 15729 }, 15730 15731 _uiSpinnerHtml: function() { 15732 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; 15733 }, 15734 15735 _buttonHtml: function() { 15736 return "" + 15737 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + 15738 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + 15739 "</a>" + 15740 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + 15741 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + 15742 "</a>"; 15743 }, 15744 15745 _start: function( event ) { 15746 if ( !this.spinning && this._trigger( "start", event ) === false ) { 15747 return false; 15748 } 15749 15750 if ( !this.counter ) { 15751 this.counter = 1; 15752 } 15753 this.spinning = true; 15754 return true; 15755 }, 15756 15757 _repeat: function( i, steps, event ) { 15758 i = i || 500; 15759 15760 clearTimeout( this.timer ); 15761 this.timer = this._delay(function() { 15762 this._repeat( 40, steps, event ); 15763 }, i ); 15764 15765 this._spin( steps * this.options.step, event ); 15766 }, 15767 15768 _spin: function( step, event ) { 15769 var value = this.value() || 0; 15770 15771 if ( !this.counter ) { 15772 this.counter = 1; 15773 } 15774 15775 value = this._adjustValue( value + step * this._increment( this.counter ) ); 15776 15777 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { 15778 this._value( value ); 15779 this.counter++; 15780 } 15781 }, 15782 15783 _increment: function( i ) { 15784 var incremental = this.options.incremental; 15785 15786 if ( incremental ) { 15787 return $.isFunction( incremental ) ? 15788 incremental( i ) : 15789 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); 15790 } 15791 15792 return 1; 15793 }, 15794 15795 _precision: function() { 15796 var precision = this._precisionOf( this.options.step ); 15797 if ( this.options.min !== null ) { 15798 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 15799 } 15800 return precision; 15801 }, 15802 15803 _precisionOf: function( num ) { 15804 var str = num.toString(), 15805 decimal = str.indexOf( "." ); 15806 return decimal === -1 ? 0 : str.length - decimal - 1; 15807 }, 15808 15809 _adjustValue: function( value ) { 15810 var base, aboveMin, 15811 options = this.options; 15812 15813 // make sure we're at a valid step 15814 // - find out where we are relative to the base (min or 0) 15815 base = options.min !== null ? options.min : 0; 15816 aboveMin = value - base; 15817 // - round to the nearest step 15818 aboveMin = Math.round(aboveMin / options.step) * options.step; 15819 // - rounding is based on 0, so adjust back to our base 15820 value = base + aboveMin; 15821 15822 // fix precision from bad JS floating point math 15823 value = parseFloat( value.toFixed( this._precision() ) ); 15824 15825 // clamp the value 15826 if ( options.max !== null && value > options.max) { 15827 return options.max; 15828 } 15829 if ( options.min !== null && value < options.min ) { 15830 return options.min; 15831 } 15832 15833 return value; 15834 }, 15835 15836 _stop: function( event ) { 15837 if ( !this.spinning ) { 15838 return; 15839 } 15840 15841 clearTimeout( this.timer ); 15842 clearTimeout( this.mousewheelTimer ); 15843 this.counter = 0; 15844 this.spinning = false;
15845 this._trigger( "stop", event ); 15846 }, 15847 15848 _setOption: function( key, value ) { 15849 if ( key === "culture" || key === "numberFormat" ) { 15850 var prevValue = this._parse( this.element.val() ); 15851 this.options[ key ] = value; 15852 this.element.val( this._format( prevValue ) ); 15853 return; 15854 } 15855 15856 if ( key === "max" || key === "min" || key === "step" ) { 15857 if ( typeof value === "string" ) { 15858 value = this._parse( value ); 15859 } 15860 } 15861 15862 this._super( key, value ); 15863 15864 if ( key === "disabled" ) { 15865 if ( value ) { 15866 this.element.prop( "disabled", true ); 15867 this.buttons.button( "disable" ); 15868 } else { 15869 this.element.prop( "disabled", false ); 15870 this.buttons.button( "enable" ); 15871 } 15872 } 15873 }, 15874 15875 _setOptions: modifier(function( options ) { 15876 this._super( options ); 15877 this._value( this.element.val() ); 15878 }), 15879 15880 _parse: function( val ) { 15881 if ( typeof val === "string" && val !== "" ) { 15882 val = window.Globalize && this.options.numberFormat ? 15883 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 15884 } 15885 return val === "" || isNaN( val ) ? null : val; 15886 }, 15887 15888 _format: function( value ) { 15889 if ( value === "" ) { 15890 return ""; 15891 } 15892 return window.Globalize && this.options.numberFormat ? 15893 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 15894 value; 15895 }, 15896 15897 _refresh: function() { 15898 this.element.attr({ 15899 "aria-valuemin": this.options.min, 15900 "aria-valuemax": this.options.max, 15901 // TODO: what should we do with values that can't be parsed? 15902 "aria-valuenow": this._parse( this.element.val() ) 15903 }); 15904 }, 15905 15906 // update the value without triggering change 15907 _value: function( value, allowAny ) { 15908 var parsed; 15909 if ( value !== "" ) { 15910 parsed = this._parse( value ); 15911 if ( parsed !== null ) { 15912 if ( !allowAny ) { 15913 parsed = this._adjustValue( parsed ); 15914 } 15915 value = this._format( parsed ); 15916 } 15917 } 15918 this.element.val( value ); 15919 this._refresh(); 15920 }, 15921 15922 _destroy: function() { 15923 this.element 15924 .removeClass( "ui-spinner-input" ) 15925 .prop( "disabled", false ) 15926 .removeAttr( "autocomplete" ) 15927 .removeAttr( "role" ) 15928 .removeAttr( "aria-valuemin" ) 15929 .removeAttr( "aria-valuemax" ) 15930 .removeAttr( "aria-valuenow" ); 15931 this.uiSpinner.replaceWith( this.element ); 15932 }, 15933 15934 stepUp: modifier(function( steps ) { 15935 this._stepUp( steps ); 15936 }), 15937 _stepUp: function( steps ) { 15938 this._spin( (steps || 1) * this.options.step ); 15939 }, 15940 15941 stepDown: modifier(function( steps ) { 15942 this._stepDown( steps ); 15943 }), 15944 _stepDown: function( steps ) { 15945 this._spin( (steps || 1) * -this.options.step ); 15946 }, 15947 15948 pageUp: modifier(function( pages ) { 15949 this._stepUp( (pages || 1) * this.options.page ); 15950 }), 15951 15952 pageDown: modifier(function( pages ) { 15953 this._stepDown( (pages || 1) * this.options.page ); 15954 }), 15955 15956 value: function( newVal ) { 15957 if ( !arguments.length ) { 15958 return this._parse( this.element.val() ); 15959 } 15960 modifier( this._value ).call( this, newVal ); 15961 }, 15962 15963 widget: function() { 15964 return this.uiSpinner; 15965 } 15966}); 15967 15968}( jQuery ) ); 15969 15970(function( $, undefined ) { 15971 15972var tabId = 0, 15973 rhash = /#.*$/; 15974 15975function getNextTabId() { 15976 return ++tabId; 15977} 15978 15979function isLocal( anchor ) { 15980 return anchor.hash.length > 1 && 15981 anchor.href.replace( rhash, "" ) === location.href.replace( rhash, "" ); 15982} 15983 15984$.widget( "ui.tabs", { 15985 version: "1.9.1", 15986 delay: 300, 15987 options: { 15988 active: null, 15989 collapsible: false, 15990 event: "click", 15991 heightStyle: "content", 15992 hide: null, 15993 show: null, 15994 15995 // callbacks 15996 activate: null, 15997 beforeActivate: null, 15998 beforeLoad: null, 15999 load: null 16000 }, 16001 16002 _create: function() { 16003 var that = this, 16004 options = this.options, 16005 active = options.active, 16006 locationHash = location.hash.substring( 1 ); 16007 16008 this.running = false; 16009 16010 this.element 16011 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) 16012 .toggleClass( "ui-tabs-collapsible", options.collapsible ) 16013 // Prevent users from focusing disabled tabs via click 16014 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { 16015 if ( $( this ).is( ".ui-state-disabled" ) ) { 16016 event.preventDefault(); 16017 } 16018 }) 16019 // support: IE <9 16020 // Preventing the default action in mousedown doesn't prevent IE
vendor: 18,126 bytes, lines 16021-16692
16021 // from focusing the element, so if the anchor gets focused, blur. 16022 // We don't have to worry about focusing the previously focused 16023 // element since clicking on a non-focusable element should focus 16024 // the body anyway. 16025 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { 16026 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 16027 this.blur(); 16028 } 16029 }); 16030 16031 this._processTabs(); 16032 16033 if ( active === null ) { 16034 // check the fragment identifier in the URL 16035 if ( locationHash ) { 16036 this.tabs.each(function( i, tab ) { 16037 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 16038 active = i; 16039 return false; 16040 } 16041 }); 16042 } 16043 16044 // check for a tab marked active via a class 16045 if ( active === null ) { 16046 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 16047 } 16048 16049 // no active tab, set to false 16050 if ( active === null || active === -1 ) { 16051 active = this.tabs.length ? 0 : false; 16052 } 16053 } 16054 16055 // handle numbers: negative, out of range 16056 if ( active !== false ) { 16057 active = this.tabs.index( this.tabs.eq( active ) ); 16058 if ( active === -1 ) { 16059 active = options.collapsible ? false : 0; 16060 } 16061 } 16062 options.active = active; 16063 16064 // don't allow collapsible: false and active: false 16065 if ( !options.collapsible && options.active === false && this.anchors.length ) { 16066 options.active = 0; 16067 } 16068 16069 // Take disabling tabs via class attribute from HTML 16070 // into account and update option properly. 16071 if ( $.isArray( options.disabled ) ) { 16072 options.disabled = $.unique( options.disabled.concat( 16073 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 16074 return that.tabs.index( li ); 16075 }) 16076 ) ).sort(); 16077 } 16078 16079 // check for length avoids error when initializing empty list 16080 if ( this.options.active !== false && this.anchors.length ) { 16081 this.active = this._findActive( this.options.active ); 16082 } else { 16083 this.active = $(); 16084 } 16085 16086 this._refresh(); 16087 16088 if ( this.active.length ) { 16089 this.load( options.active ); 16090 } 16091 }, 16092 16093 _getCreateEventData: function() { 16094 return { 16095 tab: this.active, 16096 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 16097 }; 16098 }, 16099 16100 _tabKeydown: function( event ) { 16101 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), 16102 selectedIndex = this.tabs.index( focusedTab ), 16103 goingForward = true; 16104 16105 if ( this._handlePageNav( event ) ) { 16106 return; 16107 } 16108 16109 switch ( event.keyCode ) { 16110 case $.ui.keyCode.RIGHT: 16111 case $.ui.keyCode.DOWN: 16112 selectedIndex++; 16113 break; 16114 case $.ui.keyCode.UP: 16115 case $.ui.keyCode.LEFT: 16116 goingForward = false; 16117 selectedIndex--; 16118 break; 16119 case $.ui.keyCode.END: 16120 selectedIndex = this.anchors.length - 1; 16121 break; 16122 case $.ui.keyCode.HOME: 16123 selectedIndex = 0; 16124 break; 16125 case $.ui.keyCode.SPACE: 16126 // Activate only, no collapsing 16127 event.preventDefault(); 16128 clearTimeout( this.activating ); 16129 this._activate( selectedIndex ); 16130 return; 16131 case $.ui.keyCode.ENTER: 16132 // Toggle (cancel delayed activation, allow collapsing) 16133 event.preventDefault(); 16134 clearTimeout( this.activating ); 16135 // Determine if we should collapse or activate 16136 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 16137 return; 16138 default: 16139 return; 16140 } 16141 16142 // Focus the appropriate tab, based on which key was pressed 16143 event.preventDefault(); 16144 clearTimeout( this.activating ); 16145 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 16146 16147 // Navigating with control key will prevent automatic activation 16148 if ( !event.ctrlKey ) { 16149 // Update aria-selected immediately so that AT think the tab is already selected. 16150 // Otherwise AT may confuse the user by stating that they need to activate the tab, 16151 // but the tab will already be activated by the time the announcement finishes. 16152 focusedTab.attr( "aria-selected", "false" ); 16153 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 16154 16155 this.activating = this._delay(function() { 16156 this.option( "active", selectedIndex ); 16157 }, this.delay ); 16158 } 16159 }, 16160 16161 _panelKeydown: function( event ) { 16162 if ( this._handlePageNav( event ) ) { 16163 return; 16164 } 16165 16166 // Ctrl+up moves focus to the current tab 16167 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 16168 event.preventDefault(); 16169 this.active.focus(); 16170 } 16171 }, 16172 16173 // Alt+page up/down moves focus to the previous/next tab (and activates) 16174 _handlePageNav: function( event ) { 16175 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 16176 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 16177 return true; 16178 } 16179 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 16180 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 16181 return true; 16182 } 16183 }, 16184 16185 _findNextTab: function( index, goingForward ) { 16186 var lastTabIndex = this.tabs.length - 1; 16187 16188 function constrain() { 16189 if ( index > lastTabIndex ) { 16190 index = 0; 16191 } 16192 if ( index < 0 ) { 16193 index = lastTabIndex; 16194 } 16195 return index; 16196 } 16197 16198 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 16199 index = goingForward ? index + 1 : index - 1; 16200 } 16201 16202 return index; 16203 }, 16204 16205 _focusNextTab: function( index, goingForward ) { 16206 index = this._findNextTab( index, goingForward ); 16207 this.tabs.eq( index ).focus(); 16208 return index; 16209 }, 16210 16211 _setOption: function( key, value ) { 16212 if ( key === "active" ) { 16213 // _activate() will handle invalid values and update this.options 16214 this._activate( value ); 16215 return; 16216 } 16217 16218 if ( key === "disabled" ) { 16219 // don't use the widget factory's disabled handling 16220 this._setupDisabled( value ); 16221 return; 16222 } 16223 16224 this._super( key, value); 16225 16226 if ( key === "collapsible" ) { 16227 this.element.toggleClass( "ui-tabs-collapsible", value ); 16228 // Setting collapsible: false while collapsed; open first panel 16229 if ( !value && this.options.active === false ) { 16230 this._activate( 0 ); 16231 } 16232 } 16233 16234 if ( key === "event" ) { 16235 this._setupEvents( value ); 16236 } 16237 16238 if ( key === "heightStyle" ) { 16239 this._setupHeightStyle( value ); 16240 } 16241 }, 16242 16243 _tabId: function( tab ) { 16244 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); 16245 }, 16246 16247 _sanitizeSelector: function( hash ) { 16248 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 16249 }, 16250 16251 refresh: function() { 16252 var options = this.options, 16253 lis = this.tablist.children( ":has(a[href])" ); 16254 16255 // get disabled tabs from class attribute from HTML 16256 // this will get converted to a boolean if needed in _refresh() 16257 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 16258 return lis.index( tab ); 16259 }); 16260 16261 this._processTabs(); 16262 16263 // was collapsed or no tabs 16264 if ( options.active === false || !this.anchors.length ) { 16265 options.active = false; 16266 this.active = $(); 16267 // was active, but active tab is gone 16268 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 16269 // all remaining tabs are disabled 16270 if ( this.tabs.length === options.disabled.length ) { 16271 options.active = false; 16272 this.active = $(); 16273 // activate previous tab 16274 } else { 16275 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 16276 } 16277 // was active, active tab still exists 16278 } else { 16279 // make sure active index is correct 16280 options.active = this.tabs.index( this.active ); 16281 } 16282 16283 this._refresh(); 16284 }, 16285 16286 _refresh: function() { 16287 this._setupDisabled( this.options.disabled ); 16288 this._setupEvents( this.options.event ); 16289 this._setupHeightStyle( this.options.heightStyle ); 16290 16291 this.tabs.not( this.active ).attr({ 16292 "aria-selected": "false", 16293 tabIndex: -1 16294 }); 16295 this.panels.not( this._getPanelForTab( this.active ) ) 16296 .hide() 16297 .attr({ 16298 "aria-expanded": "false", 16299 "aria-hidden": "true" 16300 }); 16301 16302 // Make sure one tab is in the tab order 16303 if ( !this.active.length ) { 16304 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 16305 } else { 16306 this.active 16307 .addClass( "ui-tabs-active ui-state-active" ) 16308 .attr({ 16309 "aria-selected": "true", 16310 tabIndex: 0 16311 }); 16312 this._getPanelForTab( this.active ) 16313 .show() 16314 .attr({ 16315 "aria-expanded": "true", 16316 "aria-hidden": "false" 16317 }); 16318 } 16319 }, 16320 16321 _processTabs: function() { 16322 var that = this; 16323 16324 this.tablist = this._getList() 16325 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 16326 .attr( "role", "tablist" ); 16327 16328 this.tabs = this.tablist.find( "> li:has(a[href])" ) 16329 .addClass( "ui-state-default ui-corner-top" ) 16330 .attr({ 16331 role: "tab", 16332 tabIndex: -1 16333 }); 16334 16335 this.anchors = this.tabs.map(function() { 16336 return $( "a", this )[ 0 ]; 16337 }) 16338 .addClass( "ui-tabs-anchor" ) 16339 .attr({ 16340 role: "presentation", 16341 tabIndex: -1 16342 }); 16343 16344 this.panels = $(); 16345 16346 this.anchors.each(function( i, anchor ) { 16347 var selector, panel, panelId, 16348 anchorId = $( anchor ).uniqueId().attr( "id" ), 16349 tab = $( anchor ).closest( "li" ), 16350 originalAriaControls = tab.attr( "aria-controls" ); 16351 16352 // inline tab 16353 if ( isLocal( anchor ) ) { 16354 selector = anchor.hash; 16355 panel = that.element.find( that._sanitizeSelector( selector ) ); 16356 // remote tab 16357 } else { 16358 panelId = that._tabId( tab ); 16359 selector = "#" + panelId; 16360 panel = that.element.find( selector ); 16361 if ( !panel.length ) { 16362 panel = that._createPanel( panelId ); 16363 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 16364 } 16365 panel.attr( "aria-live", "polite" ); 16366 } 16367 16368 if ( panel.length) { 16369 that.panels = that.panels.add( panel ); 16370 } 16371 if ( originalAriaControls ) { 16372 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 16373 } 16374 tab.attr({ 16375 "aria-controls": selector.substring( 1 ), 16376 "aria-labelledby": anchorId 16377 }); 16378 panel.attr( "aria-labelledby", anchorId ); 16379 }); 16380 16381 this.panels 16382 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 16383 .attr( "role", "tabpanel" ); 16384 }, 16385 16386 // allow overriding how to find the list for rare usage scenarios (#7715) 16387 _getList: function() { 16388 return this.element.find( "ol,ul" ).eq( 0 ); 16389 }, 16390 16391 _createPanel: function( id ) { 16392 return $( "<div>" ) 16393 .attr( "id", id ) 16394 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 16395 .data( "ui-tabs-destroy", true ); 16396 }, 16397 16398 _setupDisabled: function( disabled ) { 16399 if ( $.isArray( disabled ) ) { 16400 if ( !disabled.length ) { 16401 disabled = false; 16402 } else if ( disabled.length === this.anchors.length ) { 16403 disabled = true; 16404 } 16405 } 16406 16407 // disable tabs 16408 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { 16409 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 16410 $( li ) 16411 .addClass( "ui-state-disabled" ) 16412 .attr( "aria-disabled", "true" ); 16413 } else { 16414 $( li ) 16415 .removeClass( "ui-state-disabled" ) 16416 .removeAttr( "aria-disabled" ); 16417 } 16418 } 16419 16420 this.options.disabled = disabled; 16421 }, 16422 16423 _setupEvents: function( event ) { 16424 var events = { 16425 click: function( event ) { 16426 event.preventDefault(); 16427 } 16428 }; 16429 if ( event ) { 16430 $.each( event.split(" "), function( index, eventName ) { 16431 events[ eventName ] = "_eventHandler"; 16432 }); 16433 } 16434 16435 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 16436 this._on( this.anchors, events ); 16437 this._on( this.tabs, { keydown: "_tabKeydown" } ); 16438 this._on( this.panels, { keydown: "_panelKeydown" } ); 16439 16440 this._focusable( this.tabs ); 16441 this._hoverable( this.tabs ); 16442 }, 16443 16444 _setupHeightStyle: function( heightStyle ) { 16445 var maxHeight, overflow, 16446 parent = this.element.parent(); 16447 16448 if ( heightStyle === "fill" ) { 16449 // IE 6 treats height like minHeight, so we need to turn off overflow 16450 // in order to get a reliable height 16451 // we use the minHeight support test because we assume that only 16452 // browsers that don't support minHeight will treat height as minHeight 16453 if ( !$.support.minHeight ) { 16454 overflow = parent.css( "overflow" ); 16455 parent.css( "overflow", "hidden"); 16456 } 16457 maxHeight = parent.height(); 16458 this.element.siblings( ":visible" ).each(function() { 16459 var elem = $( this ), 16460 position = elem.css( "position" ); 16461 16462 if ( position === "absolute" || position === "fixed" ) { 16463 return; 16464 } 16465 maxHeight -= elem.outerHeight( true ); 16466 }); 16467 if ( overflow ) { 16468 parent.css( "overflow", overflow ); 16469 } 16470 16471 this.element.children().not( this.panels ).each(function() { 16472 maxHeight -= $( this ).outerHeight( true ); 16473 }); 16474 16475 this.panels.each(function() { 16476 $( this ).height( Math.max( 0, maxHeight - 16477 $( this ).innerHeight() + $( this ).height() ) ); 16478 }) 16479 .css( "overflow", "auto" ); 16480 } else if ( heightStyle === "auto" ) { 16481 maxHeight = 0; 16482 this.panels.each(function() { 16483 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 16484 }).height( maxHeight ); 16485 } 16486 }, 16487 16488 _eventHandler: function( event ) { 16489 var options = this.options, 16490 active = this.active, 16491 anchor = $( event.currentTarget ), 16492 tab = anchor.closest( "li" ), 16493 clickedIsActive = tab[ 0 ] === active[ 0 ], 16494 collapsing = clickedIsActive && options.collapsible, 16495 toShow = collapsing ? $() : this._getPanelForTab( tab ), 16496 toHide = !active.length ? $() : this._getPanelForTab( active ), 16497 eventData = { 16498 oldTab: active, 16499 oldPanel: toHide, 16500 newTab: collapsing ? $() : tab, 16501 newPanel: toShow 16502 }; 16503 16504 event.preventDefault(); 16505 16506 if ( tab.hasClass( "ui-state-disabled" ) || 16507 // tab is already loading 16508 tab.hasClass( "ui-tabs-loading" ) || 16509 // can't switch durning an animation 16510 this.running || 16511 // click on active header, but not collapsible 16512 ( clickedIsActive && !options.collapsible ) || 16513 // allow canceling activation 16514 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 16515 return; 16516 } 16517 16518 options.active = collapsing ? false : this.tabs.index( tab ); 16519 16520 this.active = clickedIsActive ? $() : tab; 16521 if ( this.xhr ) { 16522 this.xhr.abort(); 16523 } 16524 16525 if ( !toHide.length && !toShow.length ) { 16526 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 16527 } 16528 16529 if ( toShow.length ) { 16530 this.load( this.tabs.index( tab ), event ); 16531 } 16532 this._toggle( event, eventData ); 16533 }, 16534 16535 // handles show/hide for selecting tabs 16536 _toggle: function( event, eventData ) { 16537 var that = this, 16538 toShow = eventData.newPanel, 16539 toHide = eventData.oldPanel; 16540 16541 this.running = true; 16542 16543 function complete() { 16544 that.running = false; 16545 that._trigger( "activate", event, eventData ); 16546 } 16547 16548 function show() { 16549 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 16550 16551 if ( toShow.length && that.options.show ) { 16552 that._show( toShow, that.options.show, complete ); 16553 } else { 16554 toShow.show(); 16555 complete(); 16556 } 16557 } 16558 16559 // start out by hiding, then showing, then completing 16560 if ( toHide.length && this.options.hide ) { 16561 this._hide( toHide, this.options.hide, function() { 16562 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 16563 show(); 16564 }); 16565 } else { 16566 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 16567 toHide.hide(); 16568 show(); 16569 } 16570 16571 toHide.attr({ 16572 "aria-expanded": "false", 16573 "aria-hidden": "true" 16574 }); 16575 eventData.oldTab.attr( "aria-selected", "false" ); 16576 // If we're switching tabs, remove the old tab from the tab order. 16577 // If we're opening from collapsed state, remove the previous tab from the tab order. 16578 // If we're collapsing, then keep the collapsing tab in the tab order. 16579 if ( toShow.length && toHide.length ) { 16580 eventData.oldTab.attr( "tabIndex", -1 ); 16581 } else if ( toShow.length ) { 16582 this.tabs.filter(function() { 16583 return $( this ).attr( "tabIndex" ) === 0; 16584 }) 16585 .attr( "tabIndex", -1 ); 16586 } 16587 16588 toShow.attr({ 16589 "aria-expanded": "true", 16590 "aria-hidden": "false" 16591 }); 16592 eventData.newTab.attr({ 16593 "aria-selected": "true", 16594 tabIndex: 0 16595 }); 16596 }, 16597 16598 _activate: function( index ) { 16599 var anchor, 16600 active = this._findActive( index ); 16601 16602 // trying to activate the already active panel 16603 if ( active[ 0 ] === this.active[ 0 ] ) { 16604 return; 16605 } 16606 16607 // trying to collapse, simulate a click on the current active header 16608 if ( !active.length ) { 16609 active = this.active; 16610 } 16611 16612 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 16613 this._eventHandler({ 16614 target: anchor, 16615 currentTarget: anchor, 16616 preventDefault: $.noop 16617 }); 16618 }, 16619 16620 _findActive: function( index ) { 16621 return index === false ? $() : this.tabs.eq( index ); 16622 }, 16623 16624 _getIndex: function( index ) { 16625 // meta-function to give users option to provide a href string instead of a numerical index. 16626 if ( typeof index === "string" ) { 16627 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); 16628 } 16629 16630 return index; 16631 }, 16632 16633 _destroy: function() { 16634 if ( this.xhr ) { 16635 this.xhr.abort(); 16636 } 16637 16638 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); 16639 16640 this.tablist 16641 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) 16642 .removeAttr( "role" ); 16643 16644 this.anchors 16645 .removeClass( "ui-tabs-anchor" ) 16646 .removeAttr( "role" ) 16647 .removeAttr( "tabIndex" ) 16648 .removeData( "href.tabs" ) 16649 .removeData( "load.tabs" ) 16650 .removeUniqueId(); 16651 16652 this.tabs.add( this.panels ).each(function() { 16653 if ( $.data( this, "ui-tabs-destroy" ) ) { 16654 $( this ).remove(); 16655 } else { 16656 $( this ) 16657 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + 16658 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) 16659 .removeAttr( "tabIndex" ) 16660 .removeAttr( "aria-live" ) 16661 .removeAttr( "aria-busy" ) 16662 .removeAttr( "aria-selected" ) 16663 .removeAttr( "aria-labelledby" ) 16664 .removeAttr( "aria-hidden" ) 16665 .removeAttr( "aria-expanded" ) 16666 .removeAttr( "role" ); 16667 } 16668 }); 16669 16670 this.tabs.each(function() { 16671 var li = $( this ), 16672 prev = li.data( "ui-tabs-aria-controls" ); 16673 if ( prev ) { 16674 li.attr( "aria-controls", prev ); 16675 } else { 16676 li.removeAttr( "aria-controls" ); 16677 } 16678 }); 16679 16680 if ( this.options.heightStyle !== "content" ) { 16681 this.panels.css( "height", "" ); 16682 } 16683 }, 16684 16685 enable: function( index ) { 16686 var disabled = this.options.disabled; 16687 if ( disabled === false ) { 16688 return; 16689 } 16690 16691 if ( index === undefined ) { 16692 disabled = false;
16693 } else { 16694 index = this._getIndex( index ); 16695 if ( $.isArray( disabled ) ) { 16696 disabled = $.map( disabled, function( num ) { 16697 return num !== index ? num : null; 16698 }); 16699 } else { 16700 disabled = $.map( this.tabs, function( li, num ) { 16701 return num !== index ? num : null; 16702 }); 16703 } 16704 } 16705 this._setupDisabled( disabled ); 16706 }, 16707 16708 disable: function( index ) { 16709 var disabled = this.options.disabled; 16710 if ( disabled === true ) { 16711 return; 16712 } 16713 16714 if ( index === undefined ) { 16715 disabled = true; 16716 } else { 16717 index = this._getIndex( index ); 16718 if ( $.inArray( index, disabled ) !== -1 ) { 16719 return; 16720 } 16721 if ( $.isArray( disabled ) ) { 16722 disabled = $.merge( [ index ], disabled ).sort(); 16723 } else { 16724 disabled = [ index ]; 16725 } 16726 } 16727 this._setupDisabled( disabled ); 16728 }, 16729 16730 load: function( index, event ) { 16731 index = this._getIndex( index ); 16732 var that = this, 16733 tab = this.tabs.eq( index ), 16734 anchor = tab.find( ".ui-tabs-anchor" ), 16735 panel = this._getPanelForTab( tab ), 16736 eventData = { 16737 tab: tab, 16738 panel: panel 16739 }; 16740 16741 // not remote 16742 if ( isLocal( anchor[ 0 ] ) ) { 16743 return; 16744 } 16745 16746 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 16747 16748 // support: jQuery <1.8 16749 // jQuery <1.8 returns false if the request is canceled in beforeSend, 16750 // but as of 1.8, $.ajax() always returns a jqXHR object. 16751 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 16752 tab.addClass( "ui-tabs-loading" ); 16753 panel.attr( "aria-busy", "true" ); 16754 16755 this.xhr 16756 .success(function( response ) { 16757 // support: jQuery <1.8 16758 // http://bugs.jquery.com/ticket/11778 16759 setTimeout(function() { 16760 panel.html( response ); 16761 that._trigger( "load", event, eventData ); 16762 }, 1 ); 16763 }) 16764 .complete(function( jqXHR, status ) { 16765 // support: jQuery <1.8 16766 // http://bugs.jquery.com/ticket/11778 16767 setTimeout(function() { 16768 if ( status === "abort" ) { 16769 that.panels.stop( false, true ); 16770 } 16771 16772 tab.removeClass( "ui-tabs-loading" ); 16773 panel.removeAttr( "aria-busy" ); 16774 16775 if ( jqXHR === that.xhr ) { 16776 delete that.xhr; 16777 } 16778 }, 1 ); 16779 }); 16780 } 16781 }, 16782 16783 // TODO: Remove this function in 1.10 when ajaxOptions is removed 16784 _ajaxSettings: function( anchor, event, eventData ) { 16785 var that = this; 16786 return { 16787 url: anchor.attr( "href" ), 16788 beforeSend: function( jqXHR, settings ) { 16789 return that._trigger( "beforeLoad", event, 16790 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); 16791 } 16792 }; 16793 }, 16794 16795 _getPanelForTab: function( tab ) { 16796 var id = $( tab ).attr( "aria-controls" ); 16797 return this.element.find( this._sanitizeSelector( "#" + id ) ); 16798 } 16799}); 16800 16801// DEPRECATED 16802if ( $.uiBackCompat !== false ) { 16803 16804 // helper method for a lot of the back compat extensions 16805 $.ui.tabs.prototype._ui = function( tab, panel ) { 16806 return { 16807 tab: tab, 16808 panel: panel, 16809 index: this.anchors.index( tab ) 16810 }; 16811 }; 16812 16813 // url method 16814 $.widget( "ui.tabs", $.ui.tabs, { 16815 url: function( index, url ) { 16816 this.anchors.eq( index ).attr( "href", url ); 16817 } 16818 }); 16819 16820 // TODO: Remove _ajaxSettings() method when removing this extension 16821 // ajaxOptions and cache options 16822 $.widget( "ui.tabs", $.ui.tabs, { 16823 options: { 16824 ajaxOptions: null, 16825 cache: false 16826 }, 16827 16828 _create: function() { 16829 this._super(); 16830 16831 var that = this; 16832 16833 this._on({ tabsbeforeload: function( event, ui ) { 16834 // tab is already cached 16835 if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) { 16836 event.preventDefault(); 16837 return; 16838 } 16839 16840 ui.jqXHR.success(function() { 16841 if ( that.options.cache ) { 16842 $.data( ui.tab[ 0 ], "cache.tabs", true ); 16843 } 16844 }); 16845 }}); 16846 }, 16847 16848 _ajaxSettings: function( anchor, event, ui ) { 16849 var ajaxOptions = this.options.ajaxOptions; 16850 return $.extend( {}, ajaxOptions, { 16851 error: function( xhr, status ) { 16852 try { 16853 // Passing index avoid a race condition when this method is 16854 // called after the user has selected another tab. 16855 // Pass the anchor that initiated this request allows 16856 // loadError to manipulate the tab content panel via $(a.hash) 16857 ajaxOptions.error( 16858 xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] ); 16859 } 16860 catch ( error ) {} 16861 } 16862 }, this._superApply( arguments ) ); 16863 }, 16864 16865 _setOption: function( key, value ) { 16866 // reset cache if switching from cached to not cached 16867 if ( key === "cache" && value === false ) { 16868 this.anchors.removeData( "cache.tabs" ); 16869 } 16870 this._super( key, value ); 16871 }, 16872 16873 _destroy: function() { 16874 this.anchors.removeData( "cache.tabs" ); 16875 this._super(); 16876 }, 16877 16878 url: function( index ){ 16879 this.anchors.eq( index ).removeData( "cache.tabs" ); 16880 this._superApply( arguments ); 16881 } 16882 }); 16883 16884 // abort method 16885 $.widget( "ui.tabs", $.ui.tabs, { 16886 abort: function() { 16887 if ( this.xhr ) { 16888 this.xhr.abort(); 16889 } 16890 } 16891 }); 16892 16893 // spinner 16894 $.widget( "ui.tabs", $.ui.tabs, { 16895 options: { 16896 spinner: "<em>Loading…</em>" 16897 }, 16898 _create: function() { 16899 this._super(); 16900 this._on({ 16901 tabsbeforeload: function( event, ui ) { 16902 // Don't react to nested tabs or tabs that don't use a spinner 16903 if ( event.target !== this.element[ 0 ] || 16904 !this.options.spinner ) { 16905 return; 16906 } 16907 16908 var span = ui.tab.find( "span" ), 16909 html = span.html(); 16910 span.html( this.options.spinner ); 16911 ui.jqXHR.complete(function() { 16912 span.html( html ); 16913 }); 16914 } 16915 }); 16916 } 16917 }); 16918 16919 // enable/disable events 16920 $.widget( "ui.tabs", $.ui.tabs, { 16921 options: { 16922 enable: null, 16923 disable: null 16924 }, 16925 16926 enable: function( index ) { 16927 var options = this.options, 16928 trigger; 16929 16930 if ( index && options.disabled === true || 16931 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) { 16932 trigger = true; 16933 } 16934 16935 this._superApply( arguments ); 16936 16937 if ( trigger ) { 16938 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 16939 } 16940 }, 16941 16942 disable: function( index ) { 16943 var options = this.options, 16944 trigger; 16945 16946 if ( index && options.disabled === false || 16947 ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) { 16948 trigger = true; 16949 } 16950 16951 this._superApply( arguments ); 16952 16953 if ( trigger ) { 16954 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 16955 } 16956 } 16957 }); 16958 16959 // add/remove methods and events 16960 $.widget( "ui.tabs", $.ui.tabs, { 16961 options: { 16962 add: null, 16963 remove: null, 16964 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" 16965 }, 16966 16967 add: function( url, label, index ) { 16968 if ( index === undefined ) { 16969 index = this.anchors.length; 16970 } 16971 16972 var doInsertAfter, panel, 16973 options = this.options, 16974 li = $( options.tabTemplate 16975 .replace( /#\{href\}/g, url ) 16976 .replace( /#\{label\}/g, label ) ), 16977 id = !url.indexOf( "#" ) ? 16978 url.replace( "#", "" ) : 16979 this._tabId( li ); 16980 16981 li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true ); 16982 li.attr( "aria-controls", id ); 16983 16984 doInsertAfter = index >= this.tabs.length; 16985 16986 // try to find an existing element before creating a new one 16987 panel = this.element.find( "#" + id ); 16988 if ( !panel.length ) { 16989 panel = this._createPanel( id ); 16990 if ( doInsertAfter ) { 16991 if ( index > 0 ) { 16992 panel.insertAfter( this.panels.eq( -1 ) ); 16993 } else { 16994 panel.appendTo( this.element ); 16995 } 16996 } else { 16997 panel.insertBefore( this.panels[ index ] ); 16998 } 16999 } 17000 panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); 17001 17002 if ( doInsertAfter ) { 17003 li.appendTo( this.tablist ); 17004 } else { 17005 li.insertBefore( this.tabs[ index ] ); 17006 } 17007 17008 options.disabled = $.map( options.disabled, function( n ) { 17009 return n >= index ? ++n : n; 17010 }); 17011 17012 this.refresh(); 17013 if ( this.tabs.length === 1 && options.active === false ) { 17014 this.option( "active", 0 ); 17015 } 17016 17017 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); 17018 return this; 17019 }, 17020 17021 remove: function( index ) { 17022 index = this._getIndex( index ); 17023 var options = this.options, 17024 tab = this.tabs.eq( index ).remove(), 17025 panel = this._getPanelForTab( tab ).remove(); 17026 17027 // If selected tab was removed focus tab to the right or 17028 // in case the last tab was removed the tab to the left. 17029 // We check for more than 2 tabs, because if there are only 2, 17030 // then when we remove this tab, there will only be one tab left 17031 // so we don't need to detect which tab to activate. 17032 if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) { 17033 this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); 17034 } 17035 17036 options.disabled = $.map( 17037 $.grep( options.disabled, function( n ) { 17038 return n !== index; 17039 }), 17040 function( n ) { 17041 return n >= index ? --n : n; 17042 }); 17043 17044 this.refresh(); 17045 17046 this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) ); 17047 return this; 17048 } 17049 }); 17050 17051 // length method 17052 $.widget( "ui.tabs", $.ui.tabs, { 17053 length: function() { 17054 return this.anchors.length; 17055 } 17056 }); 17057 17058 // panel ids (idPrefix option + title attribute) 17059 $.widget( "ui.tabs", $.ui.tabs, { 17060 options: { 17061 idPrefix: "ui-tabs-" 17062 }, 17063 17064 _tabId: function( tab ) { 17065 var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab; 17066 a = a[0]; 17067 return $( a ).closest( "li" ).attr( "aria-controls" ) || 17068 a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) || 17069 this.options.idPrefix + getNextTabId(); 17070 } 17071 }); 17072 17073 // _createPanel method 17074 $.widget( "ui.tabs", $.ui.tabs, { 17075 options: { 17076 panelTemplate: "<div></div>" 17077 }, 17078 17079 _createPanel: function( id ) { 17080 return $( this.options.panelTemplate ) 17081 .attr( "id", id ) 17082 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) 17083 .data( "ui-tabs-destroy", true ); 17084 } 17085 }); 17086 17087 // selected option 17088 $.widget( "ui.tabs", $.ui.tabs, { 17089 _create: function() { 17090 var options = this.options; 17091 if ( options.active === null && options.selected !== undefined ) { 17092 options.active = options.selected === -1 ? false : options.selected; 17093 } 17094 this._super(); 17095 options.selected = options.active; 17096 if ( options.selected === false ) { 17097 options.selected = -1; 17098 } 17099 }, 17100 17101 _setOption: function( key, value ) { 17102 if ( key !== "selected" ) { 17103 return this._super( key, value ); 17104 } 17105 17106 var options = this.options; 17107 this._super( "active", value === -1 ? false : value ); 17108 options.selected = options.active; 17109 if ( options.selected === false ) { 17110 options.selected = -1; 17111 } 17112 }, 17113 17114 _eventHandler: function() { 17115 this._superApply( arguments ); 17116 this.options.selected = this.options.active; 17117 if ( this.options.selected === false ) { 17118 this.options.selected = -1; 17119 } 17120 } 17121 }); 17122 17123 // show and select event 17124 $.widget( "ui.tabs", $.ui.tabs, { 17125 options: { 17126 show: null, 17127 select: null 17128 }, 17129 _create: function() { 17130 this._super(); 17131 if ( this.options.active !== false ) { 17132 this._trigger( "show", null, this._ui( 17133 this.active.find( ".ui-tabs-anchor" )[ 0 ], 17134 this._getPanelForTab( this.active )[ 0 ] ) ); 17135 } 17136 }, 17137 _trigger: function( type, event, data ) { 17138 var ret = this._superApply( arguments ); 17139 if ( !ret ) { 17140 return false;
17141 } 17142 if ( type === "beforeActivate" && data.newTab.length ) { 17143 ret = this._super( "select", event, { 17144 tab: data.newTab.find( ".ui-tabs-anchor" )[ 0], 17145 panel: data.newPanel[ 0 ], 17146 index: data.newTab.closest( "li" ).index() 17147 }); 17148 } else if ( type === "activate" && data.newTab.length ) { 17149 ret = this._super( "show", event, { 17150 tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ], 17151 panel: data.newPanel[ 0 ], 17152 index: data.newTab.closest( "li" ).index() 17153 }); 17154 } 17155 return ret; 17156 } 17157 }); 17158 17159 // select method 17160 $.widget( "ui.tabs", $.ui.tabs, { 17161 select: function( index ) { 17162 index = this._getIndex( index ); 17163 if ( index === -1 ) { 17164 if ( this.options.collapsible && this.options.selected !== -1 ) { 17165 index = this.options.selected; 17166 } else { 17167 return; 17168 } 17169 } 17170 this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace ); 17171 } 17172 }); 17173 17174 // cookie option 17175 (function() { 17176 17177 var listId = 0; 17178 17179 $.widget( "ui.tabs", $.ui.tabs, { 17180 options: { 17181 cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } 17182 }, 17183 _create: function() { 17184 var options = this.options, 17185 active; 17186 if ( options.active == null && options.cookie ) { 17187 active = parseInt( this._cookie(), 10 ); 17188 if ( active === -1 ) { 17189 active = false; 17190 } 17191 options.active = active; 17192 } 17193 this._super(); 17194 }, 17195 _cookie: function( active ) { 17196 var cookie = [ this.cookie || 17197 ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ]; 17198 if ( arguments.length ) { 17199 cookie.push( active === false ? -1 : active ); 17200 cookie.push( this.options.cookie ); 17201 } 17202 return $.cookie.apply( null, cookie ); 17203 }, 17204 _refresh: function() { 17205 this._super(); 17206 if ( this.options.cookie ) { 17207 this._cookie( this.options.active, this.options.cookie ); 17208 } 17209 }, 17210 _eventHandler: function() { 17211 this._superApply( arguments ); 17212 if ( this.options.cookie ) { 17213 this._cookie( this.options.active, this.options.cookie ); 17214 } 17215 }, 17216 _destroy: function() { 17217 this._super(); 17218 if ( this.options.cookie ) { 17219 this._cookie( null, this.options.cookie ); 17220 } 17221 } 17222 }); 17223 17224 })(); 17225 17226 // load event 17227 $.widget( "ui.tabs", $.ui.tabs, { 17228 _trigger: function( type, event, data ) { 17229 var _data = $.extend( {}, data ); 17230 if ( type === "load" ) { 17231 _data.panel = _data.panel[ 0 ]; 17232 _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ]; 17233 } 17234 return this._super( type, event, _data ); 17235 } 17236 }); 17237 17238 // fx option 17239 // The new animation options (show, hide) conflict with the old show callback. 17240 // The old fx option wins over show/hide anyway (always favor back-compat). 17241 // If a user wants to use the new animation API, they must give up the old API. 17242 $.widget( "ui.tabs", $.ui.tabs, { 17243 options: { 17244 fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 } 17245 }, 17246 17247 _getFx: function() { 17248 var hide, show, 17249 fx = this.options.fx; 17250 17251 if ( fx ) { 17252 if ( $.isArray( fx ) ) { 17253 hide = fx[ 0 ]; 17254 show = fx[ 1 ]; 17255 } else { 17256 hide = show = fx; 17257 } 17258 } 17259 17260 return fx ? { show: show, hide: hide } : null; 17261 }, 17262 17263 _toggle: function( event, eventData ) { 17264 var that = this, 17265 toShow = eventData.newPanel, 17266 toHide = eventData.oldPanel, 17267 fx = this._getFx(); 17268 17269 if ( !fx ) { 17270 return this._super( event, eventData ); 17271 } 17272 17273 that.running = true; 17274 17275 function complete() { 17276 that.running = false; 17277 that._trigger( "activate", event, eventData ); 17278 } 17279 17280 function show() { 17281 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); 17282 17283 if ( toShow.length && fx.show ) { 17284 toShow 17285 .animate( fx.show, fx.show.duration, function() { 17286 complete(); 17287 }); 17288 } else { 17289 toShow.show(); 17290 complete(); 17291 } 17292 } 17293 17294 // start out by hiding, then showing, then completing 17295 if ( toHide.length && fx.hide ) { 17296 toHide.animate( fx.hide, fx.hide.duration, function() { 17297 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 17298 show(); 17299 }); 17300 } else { 17301 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); 17302 toHide.hide(); 17303 show(); 17304 } 17305 } 17306 }); 17307} 17308 17309})( jQuery ); 17310 17311(function( $ ) { 17312 17313var increments = 0; 17314 17315function addDescribedBy( elem, id ) { 17316 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); 17317 describedby.push( id ); 17318 elem 17319 .data( "ui-tooltip-id", id ) 17320 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); 17321} 17322 17323function removeDescribedBy( elem ) { 17324 var id = elem.data( "ui-tooltip-id" ),
17325 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), 17326 index = $.inArray( id, describedby ); 17327 if ( index !== -1 ) { 17328 describedby.splice( index, 1 ); 17329 } 17330 17331 elem.removeData( "ui-tooltip-id" ); 17332 describedby = $.trim( describedby.join( " " ) ); 17333 if ( describedby ) { 17334 elem.attr( "aria-describedby", describedby ); 17335 } else { 17336 elem.removeAttr( "aria-describedby" ); 17337 } 17338} 17339 17340$.widget( "ui.tooltip", { 17341 version: "1.9.1", 17342 options: { 17343 content: function() { 17344 return $( this ).attr( "title" ); 17345 }, 17346 hide: true, 17347 // Disabled elements have inconsistent behavior across browsers (#8661) 17348 items: "[title]:not([disabled])", 17349 position: { 17350 my: "left top+15", 17351 at: "left bottom", 17352 collision: "flipfit flipfit" 17353 }, 17354 show: true, 17355 tooltipClass: null, 17356 track: false, 17357 17358 // callbacks 17359 close: null, 17360 open: null 17361 }, 17362 17363 _create: function() { 17364 this._on({ 17365 mouseover: "open", 17366 focusin: "open" 17367 }); 17368 17369 // IDs of generated tooltips, needed for destroy 17370 this.tooltips = {}; 17371 // IDs of parent tooltips where we removed the title attribute 17372 this.parents = {}; 17373 17374 if ( this.options.disabled ) { 17375 this._disable(); 17376 } 17377 }, 17378 17379 _setOption: function( key, value ) { 17380 var that = this; 17381 17382 if ( key === "disabled" ) { 17383 this[ value ? "_disable" : "_enable" ](); 17384 this.options[ key ] = value; 17385 // disable element style changes 17386 return; 17387 } 17388 17389 this._super( key, value ); 17390 17391 if ( key === "content" ) { 17392 $.each( this.tooltips, function( id, element ) { 17393 that._updateContent( element ); 17394 }); 17395 } 17396 }, 17397 17398 _disable: function() { 17399 var that = this; 17400 17401 // close open tooltips 17402 $.each( this.tooltips, function( id, element ) { 17403 var event = $.Event( "blur" ); 17404 event.target = event.currentTarget = element[0]; 17405 that.close( event, true ); 17406 }); 17407 17408 // remove title attributes to prevent native tooltips 17409 this.element.find( this.options.items ).andSelf().each(function() { 17410 var element = $( this ); 17411 if ( element.is( "[title]" ) ) { 17412 element 17413 .data( "ui-tooltip-title", element.attr( "title" ) ) 17414 .attr( "title", "" ); 17415 } 17416 }); 17417 }, 17418 17419 _enable: function() { 17420 // restore title attributes 17421 this.element.find( this.options.items ).andSelf().each(function() { 17422 var element = $( this ); 17423 if ( element.data( "ui-tooltip-title" ) ) { 17424 element.attr( "title", element.data( "ui-tooltip-title" ) ); 17425 } 17426 }); 17427 }, 17428 17429 open: function( event ) { 17430 var that = this, 17431 target = $( event ? event.target : this.element ) 17432 // we need closest here due to mouseover bubbling, 17433 // but always pointing at the same event target 17434 .closest( this.options.items ); 17435 17436 // No element to show a tooltip for 17437 if ( !target.length ) { 17438 return; 17439 } 17440 17441 // If the tooltip is open and we're tracking then reposition the tooltip. 17442 // This makes sure that a tracking tooltip doesn't obscure a focused element 17443 // if the user was hovering when the element gained focused. 17444 if ( this.options.track && target.data( "ui-tooltip-id" ) ) { 17445 this._find( target ).position( $.extend({ 17446 of: target 17447 }, this.options.position ) ); 17448 // Stop tracking (#8622) 17449 this._off( this.document, "mousemove" ); 17450 return; 17451 } 17452 17453 if ( target.attr( "title" ) ) { 17454 target.data( "ui-tooltip-title", target.attr( "title" ) ); 17455 } 17456 17457 target.data( "tooltip-open", true ); 17458 17459 // kill parent tooltips, custom or native, for hover 17460 if ( event && event.type === "mouseover" ) { 17461 target.parents().each(function() { 17462 var blurEvent; 17463 if ( $( this ).data( "tooltip-open" ) ) { 17464 blurEvent = $.Event( "blur" ); 17465 blurEvent.target = blurEvent.currentTarget = this; 17466 that.close( blurEvent, true ); 17467 } 17468 if ( this.title ) { 17469 $( this ).uniqueId(); 17470 that.parents[ this.id ] = { 17471 element: this, 17472 title: this.title 17473 }; 17474 this.title = ""; 17475 } 17476 }); 17477 } 17478 17479 this._updateContent( target, event ); 17480 }, 17481 17482 _updateContent: function( target, event ) { 17483 var content, 17484 contentOption = this.options.content, 17485 that = this; 17486 17487 if ( typeof contentOption === "string" ) { 17488 return this._open( event, target, contentOption ); 17489 } 17490 17491 content = contentOption.call( target[0], function( response ) { 17492 // ignore async response if tooltip was closed already 17493 if ( !target.data( "tooltip-open" ) ) { 17494 return; 17495 } 17496 // IE may instantly serve a cached response for ajax requests 17497 // delay this call to _open so the other call to _open runs first 17498 that._delay(function() { 17499 this._open( event, target, response ); 17500 }); 17501 }); 17502 if ( content ) { 17503 this._open( event, target, content ); 17504 } 17505 }, 17506 17507 _open: function( event, target, content ) { 17508 var tooltip, events, delayedShow, 17509 positionOption = $.extend( {}, this.options.position ); 17510 17511 if ( !content ) { 17512 return; 17513 } 17514 17515 // Content can be updated multiple times. If the tooltip already 17516 // exists, then just update the content and bail. 17517 tooltip = this._find( target ); 17518 if ( tooltip.length ) { 17519 tooltip.find( ".ui-tooltip-content" ).html( content ); 17520 return; 17521 } 17522 17523 // if we have a title, clear it to prevent the native tooltip 17524 // we have to check first to avoid defining a title if none exists 17525 // (we don't want to cause an element to start matching [title]) 17526 // 17527 // We use removeAttr only for key events, to allow IE to export the correct 17528 // accessible attributes. For mouse events, set to empty string to avoid 17529 // native tooltip showing up (happens only when removing inside mouseover). 17530 if ( target.is( "[title]" ) ) { 17531 if ( event && event.type === "mouseover" ) { 17532 target.attr( "title", "" ); 17533 } else {
17534 target.removeAttr( "title" ); 17535 } 17536 } 17537 17538 tooltip = this._tooltip( target ); 17539 addDescribedBy( target, tooltip.attr( "id" ) ); 17540 tooltip.find( ".ui-tooltip-content" ).html( content ); 17541 17542 function position( event ) { 17543 positionOption.of = event; 17544 if ( tooltip.is( ":hidden" ) ) { 17545 return; 17546 } 17547 tooltip.position( positionOption ); 17548 } 17549 if ( this.options.track && event && /^mouse/.test( event.originalEvent.type ) ) { 17550 this._on( this.document, { 17551 mousemove: position 17552 }); 17553 // trigger once to override element-relative positioning 17554 position( event ); 17555 } else { 17556 tooltip.position( $.extend({ 17557 of: target 17558 }, this.options.position ) ); 17559 } 17560 17561 tooltip.hide(); 17562 17563 this._show( tooltip, this.options.show ); 17564 // Handle tracking tooltips that are shown with a delay (#8644). As soon 17565 // as the tooltip is visible, position the tooltip using the most recent 17566 // event. 17567 if ( this.options.show && this.options.show.delay ) { 17568 delayedShow = setInterval(function() { 17569 if ( tooltip.is( ":visible" ) ) { 17570 position( positionOption.of ); 17571 clearInterval( delayedShow ); 17572 } 17573 }, $.fx.interval ); 17574 } 17575 17576 this._trigger( "open", event, { tooltip: tooltip } ); 17577 17578 events = { 17579 keyup: function( event ) { 17580 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 17581 var fakeEvent = $.Event(event); 17582 fakeEvent.currentTarget = target[0]; 17583 this.close( fakeEvent, true ); 17584 } 17585 }, 17586 remove: function() { 17587 this._removeTooltip( tooltip ); 17588 } 17589 }; 17590 if ( !event || event.type === "mouseover" ) { 17591 events.mouseleave = "close"; 17592 } 17593 if ( !event || event.type === "focusin" ) { 17594 events.focusout = "close"; 17595 } 17596 this._on( target, events ); 17597 }, 17598 17599 close: function( event ) { 17600 var that = this, 17601 target = $( event ? event.currentTarget : this.element ), 17602 tooltip = this._find( target ); 17603 17604 // disabling closes the tooltip, so we need to track when we're closing 17605 // to avoid an infinite loop in case the tooltip becomes disabled on close 17606 if ( this.closing ) { 17607 return; 17608 } 17609 17610 // only set title if we had one before (see comment in _open()) 17611 if ( target.data( "ui-tooltip-title" ) ) { 17612 target.attr( "title", target.data( "ui-tooltip-title" ) ); 17613 } 17614 17615 removeDescribedBy( target ); 17616 17617 tooltip.stop( true ); 17618 this._hide( tooltip, this.options.hide, function() { 17619 that._removeTooltip( $( this ) ); 17620 }); 17621 17622 target.removeData( "tooltip-open" ); 17623 this._off( target, "mouseleave focusout keyup" ); 17624 // Remove 'remove' binding only on delegated targets 17625 if ( target[0] !== this.element[0] ) { 17626 this._off( target, "remove" ); 17627 } 17628 this._off( this.document, "mousemove" ); 17629 17630 if ( event && event.type === "mouseleave" ) { 17631 $.each( this.parents, function( id, parent ) { 17632 parent.element.title = parent.title; 17633 delete that.parents[ id ]; 17634 }); 17635 } 17636 17637 this.closing = true; 17638 this._trigger( "close", event, { tooltip: tooltip } ); 17639 this.closing = false; 17640 }, 17641 17642 _tooltip: function( element ) { 17643 var id = "ui-tooltip-" + increments++, 17644 tooltip = $( "<div>" ) 17645 .attr({ 17646 id: id, 17647 role: "tooltip" 17648 }) 17649 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + 17650 ( this.options.tooltipClass || "" ) ); 17651 $( "<div>" ) 17652 .addClass( "ui-tooltip-content" ) 17653 .appendTo( tooltip ); 17654 tooltip.appendTo( this.document[0].body ); 17655 if ( $.fn.bgiframe ) { 17656 tooltip.bgiframe(); 17657 } 17658 this.tooltips[ id ] = element; 17659 return tooltip; 17660 }, 17661 17662 _find: function( target ) { 17663 var id = target.data( "ui-tooltip-id" ); 17664 return id ? $( "#" + id ) : $(); 17665 }, 17666 17667 _removeTooltip: function( tooltip ) { 17668 tooltip.remove(); 17669 delete this.tooltips[ tooltip.attr( "id" ) ]; 17670 }, 17671 17672 _destroy: function() { 17673 var that = this; 17674 17675 // close open tooltips 17676 $.each( this.tooltips, function( id, element ) { 17677 // Delegate to close method to handle common cleanup 17678 var event = $.Event( "blur" ); 17679 event.target = event.currentTarget = element[0]; 17680 that.close( event, true ); 17681 17682 // Remove immediately; destroying an open tooltip doesn't use the 17683 // hide animation 17684 $( "#" + id ).remove(); 17685 17686 // Restore the title 17687 if ( element.data( "ui-tooltip-title" ) ) { 17688 element.attr( "title", element.data( "ui-tooltip-title" ) ); 17689 element.removeData( "ui-tooltip-title" ); 17690 } 17691 }); 17692 } 17693}); 17694 17695}( jQuery ) ); 17696 17697//fgnass.github.com/spin.js#v1.2.5 17698(function(a,b,c){function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}function h(a){for(var b=1,c=arguments.length;b<c;b++)a.appendChild(arguments[b]);return a}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";return e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1),g}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function m(a){for(var b=1;b<arguments.length;b++){var d=arguments[b];for(var e in d)a[e]===c&&(a[e]=d[e])}return a}function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}var d=["webkit","Moz","ms","O"],e={},f,i=function(){var a=g("style");return h(b.getElementsByTagName("head")[0],a),a.sheet||a.styleSheet}(),o={lines:12,length:7,width:5,radius:10,rotate:0,color:"#000",speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"auto",left:"auto"},p=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},q.defaults,o)};p.defaults={},m(p.prototype,{spin:function(a){this.stop();var b=this,c=b.opts,d=b.el=l(g(0,{className:c.className}),{position:"relative",zIndex:c.zIndex}),e=c.radius+c.length+c.width,h,i;a&&(a.insertBefore(d,a.firstChild||null),i=n(a),h=n(d),l(d,{left:(c.left=="auto"?i.x-h.x+(a.offsetWidth>>1):c.left+e)+"px",top:(c.top=="auto"?i.y-h.y+(a.offsetHeight>>1):c.top+e)+"px"})),d.setAttribute("aria-role","progressbar"),b.lines(d,b.opts);if(!f){var j=0,k=c.fps,m=k/c.speed,o=(1-c.opacity)/(m*c.trail/100),p=m/c.lines;!function q(){j++;for(var a=c.lines;a;a--){var e=Math.max(1-(j+a*p)%m*o,c.opacity);b.opacity(d,c.lines-a,e,c)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))}()}return b},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c),this},lines:function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c+b.rotate)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:b.hwaccel?"translate3d(0,
176980,0)":"",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}}),!function(){function a(a,b){return g("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',b)}var b=l(g("group"),{behavior:"url(#default#VML)"});!k(b,"transform")&&b.adj?(i.addRule(".spin-vml","behavior:url(#default#VML)"),p.prototype.lines=function(b,c){function f(){return l(a("group",{coordsize:e+" "+e,coordorigin:-d+" "+ -d}),{width:e,height:e})}function k(b,e,g){h(i,h(l(f(),{rotation:360/c.lines*b+"deg",left:~~e}),h(l(a("roundrect",{arcsize:1}),{width:d,height:c.width,left:c.radius,top:-c.width>>1,filter:g}),a("fill",{color:c.color,opacity:c.opacity}),a("stroke",{opacity:0}))))}var d=c.length+c.width,e=2*d,g=-(c.width+c.length)*2+"px",i=l(f(),{position:"absolute",top:g,left:g}),j;if(c.shadow)for(j=1;j<=c.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=c.lines;j++)k(j);return h(b,i)},p.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}):f=k(b,"animation")}(),a.Spinner=p})(window,document); 17699 17700var opts = { 17701 lines: 9, // The number of lines to draw 17702 length: 13, // The length of each line 17703 width: 5, // The line thickness 17704 radius: 10, // The radius of the inner circle 17705 rotate: 31, // The rotation offset 17706 color: '#000', // #rgb or #rrggbb 17707 speed: 1.1, // Rounds per second 17708 trail: 70, // Afterglow percentage 17709 shadow: true, // Whether to render a shadow 17710 hwaccel: false, // Whether to use hardware acceleration 17711 className: 'spinner', // The CSS class to assign to the spinner 17712 zIndex: 2e9, // The z-index (defaults to 2000000000) 17713 top: 'auto', // Top position relative to parent in px 17714 left: 'auto' // Left position relative to parent in px 17715}; 17716var target = document.getElementById('foo'); 17717var spinner = new Spinner(opts).spin(target); 17718/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 17719 * Licensed under the MIT License (LICENSE.txt). 17720 * 17721 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 17722 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 17723 * Thanks to: Seamus Leahy for adding deltaX and deltaY 17724 * 17725 * Version: 3.0.6 17726 * 17727 * Requires: 1.2.2+ 17728 */ 17729 17730(function($) { 17731 17732var types = ['DOMMouseScroll', 'mousewheel']; 17733 17734if ($.event.fixHooks) { 17735 for ( var i=types.length; i; ) { 17736 $.event.fixHooks[ types[--i] ] = $.event.mouseHooks; 17737 } 17738} 17739 17740$.event.special.mousewheel = { 17741 setup: function() { 17742 if ( this.addEventListener ) { 17743 for ( var i=types.length; i; ) { 17744 this.addEventListener( types[--i], handler, false ); 17745 } 17746 } else { 17747 this.onmousewheel = handler; 17748 } 17749 }, 17750 17751 teardown: function() { 17752 if ( this.removeEventListener ) { 17753 for ( var i=types.length; i; ) { 17754 this.removeEventListener( types[--i], handler, false ); 17755 } 17756 } else { 17757 this.onmousewheel = null; 17758 } 17759 } 17760}; 17761 17762$.fn.extend({ 17763 mousewheel: function(fn) { 17764 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 17765 }, 17766 17767 unmousewheel: function(fn) { 17768 return this.unbind("mousewheel", fn); 17769 } 17770}); 17771 17772 17773function handler(event) { 17774 var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; 17775 event = $.event.fix(orgEvent); 17776 event.type = "mousewheel"; 17777 17778 // Old school scrollwheel delta 17779 if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; } 17780 if ( orgEvent.detail ) { delta = -orgEvent.detail/3; } 17781 17782 // New school multidimensional scroll (touchpads) deltas 17783 deltaY = delta; 17784 17785 // Gecko 17786 if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { 17787 deltaY = 0; 17788 deltaX = -1*delta; 17789 } 17790 17791 // Webkit 17792 if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } 17793 if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } 17794 17795 // Add event and delta to the front of the arguments 17796 args.unshift(event, delta, deltaX, deltaY); 17797 17798 return ($.event.dispatch || $.event.handle).apply(this, args); 17799} 17800 17801})(jQuery); 17802 17803/* 17804 Smooth Zoom Pan - jQuery Image Viewer 17805 Copyright (c) 2011-12 Ramesh Kumar 17806 http://codecanyon.net/user/VF 17807 17808 Version: 1.6.3 17809 RELEASE: 09 SEP 2011 17810 UPDATE: 18 JUL 2012 17811 17812 Built using: 17813 jQuery version:1.7.1 http://jquery.com/ 17814 Modernizr version:2.5.3 http://www.modernizr.com/ 17815 MouseWheel version:3.0.6 http://brandonaaron.net/code/mousewheel/docs 17816 17817 */ 17818 17819(function($, window, document) { 17820 17821 /***************************************************************************** 17822 Default settings: 17823 For detailed description of individual parameters, see the help document 17824 ******************************************************************************/ 17825 var defaults = { 17826 width: '', //Width of the view area [480, '480px', '100%'] 17827 height: '', //Height of the view area [480, '480px', '100%'] 17828 17829 initial_ZOOM: '', //Initial zoom level to start with (in percentage) [100] 17830 initial_POSITION: '', //Initial location to be focused in pixel value [150,150 or 150 150] 17831 17832 animation_SMOOTHNESS: 5.5, //Ease or smoothness of all movements [Any number from 0] 17833 animation_SPEED_ZOOM: 5.5, //Speed of zoom movements [Any number from 0] 17834 animation_SPEED_PAN: 5.5, //Speed of pan movements [Any number from 0] 17835 17836 zoom_MAX: 800, //Maximum limit for zooming (in percentage) 17837 zoom_MIN: '', //Minimum limit for zooming (in percentage) 17838 zoom_SINGLE_STEP: false, //To reach maximum and minimum zoom levels in single click 17839 zoom_OUT_TO_FIT: true, //To allow image to be zoomed out with whitespace on sides 17840 zoom_BUTTONS_SHOW: true, //To enable/disable the + and - buttons 17841 17842 pan_BUTTONS_SHOW: true, //To enable/disable the arrow and reset buttons
17843 pan_LIMIT_BOUNDARY: true, //To allow/restrict moving the image beyond boundaries 17844 pan_REVERSE: false, 17845 reset_ALIGN_TO: 'center center', //Image can be aligned to desired position on reset. Example: 'Top Left' 17846 17847 button_SIZE: 18, //Button width and height (in pixels) 17848 button_SIZE_TOUCH_DEVICE: 30, //Button width and height (in pixels) on touch devices 17849 button_COLOR: '#FFFFFF', //Button color in hexadecimal 17850 button_BG_COLOR: '#000000', //Button set's background color in hexadecimal 17851 button_BG_TRANSPARENCY: 55, //Background transparency (in percentage) 17852 button_AUTO_HIDE: false, //To hide the button set when mouse moved outside the view area 17853 button_AUTO_HIDE_DELAY: 1, //Auto hide delay time in seconds 17854 button_ALIGN: 'bottom right', //Button set can be aligned to any side or center 17855 button_MARGIN: 10, //Space between button set and view port's edge 17856 button_ROUND_CORNERS: true, //To enable disable roundness of button corner 17857 17858 touch_DRAG: true, //Enable/disable the dragability of image (touch) 17859 mouse_DRAG: true, //Enable/disable the dragability of image (mouse) 17860 mouse_WHEEL: true, //Enable/disable mousewheel zoom 17861 mouse_WHEEL_CURSOR_POS: true, //Enable/disable position sensitive mousewheel zoom 17862 mouse_DOUBLE_CLICK: true, //Enable/disable zoom action with double click 17863 17864 background_COLOR: '#FFFFFF', //Background colour of image container 17865 border_SIZE: 1, //Border size of view area 17866 border_COLOR: '#000000', //Border color of view area 17867 border_TRANSPARENCY: 10, //Border transparency of view area 17868 17869 image_url: '', //Set url or image to be zoomed 17870 image_original_width: '', //Original width of main image 17871 image_original_height: '', //Original height of main image 17872 container: '', //Set container element of image (id of container) 17873 17874 on_IMAGE_LOAD: '', //To Call external function immediatly after image loaded 17875 on_ZOOM_PAN_UPDATE: '', //To Call external function for each zoom, pan animation frame 17876 on_ZOOM_PAN_COMPLETE: '', //To Call external function whenever zoom, pan animation completes 17877 on_LANDMARK_STATE_CHANGE: '', //To Call external function whenever the zoom leval crosses global "data-show-at-zoom" value 17878 17879 use_3D_Transform: true, //To enable / disable Hardware acceleration on webkit browsers 17880 17881 responsive: false, //To enable / disable Responsive / fluid layout 17882 responsive_maintain_ratio: true, //To maintain view area width/height ratio or not 17883 max_WIDTH: '', //Maximum allowed width of view area (helpful when 'width' parameter set with % and need limit) 17884 max_HEIGHT: '' //Maximum allowed height of view area (helpful when 'height' parameter set with % and need limit) 17885 }; 17886 17887 function Zoomer($elem, params) { 17888 17889 var self = this; 17890 this.$elem = $elem; 17891 var op = $.extend({}, defaults, params); 17892 17893 /********************************************************** 17894 Option values verified and formated if needed 17895 **********************************************************/ 17896 this.sW = op.width; 17897 this.sH = op.height; 17898 17899 this.init_zoom = op.initial_ZOOM / 100; 17900 this.init_pos = op.initial_POSITION.replace(/,/g, ' ').replace(/\s{2,}/g, ' ').split(' '); 17901 17902 this.zoom_max = op.zoom_MAX / 100; 17903 this.zoom_min = op.zoom_MIN / 100; 17904 17905 this.zoom_single = checkBoolean(op.zoom_SINGLE_STEP); 17906 this.zoom_fit = checkBoolean(op.zoom_OUT_TO_FIT); 17907 this.zoom_speed = 1 + (((op.animation_SPEED === 0 || op.animation_SPEED ? op.animation_SPEED : op.animation_SPEED_ZOOM) + 1) / 20); 17908 this.zoom_show = checkBoolean(op.zoom_BUTTONS_SHOW); 17909 17910 this.pan_speed_o = (op.animation_SPEED === 0 || op.animation_SPEED ? op.animation_SPEED : op.animation_SPEED_PAN); 17911 this.pan_show = checkBoolean(op.pan_BUTTONS_SHOW); 17912 this.pan_limit = checkBoolean(op.pan_LIMIT_BOUNDARY); 17913 this.pan_rev = checkBoolean(op.pan_REVERSE); 17914 17915 this.reset_align = op.reset_ALIGN_TO.toLowerCase().split(' '); 17916 17917 if (supportsTouch) { 17918 this.bu_size = parseInt(op.button_SIZE_TOUCH_DEVICE / 2) * 2; 17919 } else { 17920 this.bu_size = parseInt(op.button_SIZE / 2) * 2; 17921 } 17922 this.bu_color = op.button_COLOR; 17923 this.bu_bg = op.button_BG_COLOR; 17924 this.bu_bg_alpha = op.button_BG_TRANSPARENCY / 100; 17925 this.bu_icon = op.button_ICON_IMAGE; 17926 this.bu_auto = checkBoolean(op.button_AUTO_HIDE); 17927
17928 this.bu_delay = op.button_AUTO_HIDE_DELAY * 1000; 17929 this.bu_align = op.button_ALIGN.toLowerCase().split(' '); 17930 this.bu_margin = op.button_MARGIN; 17931 this.bu_round = checkBoolean(op.button_ROUND_CORNERS); 17932 17933 this.touch_drag = checkBoolean(op.touch_DRAG); 17934 this.mouse_drag = checkBoolean(op.mouse_DRAG); 17935 this.mouse_wheel = checkBoolean(op.mouse_WHEEL); 17936 this.mouse_wheel_cur = checkBoolean(op.mouse_WHEEL_CURSOR_POS); 17937 this.mouse_dbl_click = checkBoolean(op.mouse_DOUBLE_CLICK); 17938 17939 this.ani_smooth = Math.max(1, (op.animation_SMOOTHNESS + 1) / 1.45); 17940 17941 this.bg_color = op.background_COLOR; 17942 this.bord_size = op.border_SIZE; 17943 this.bord_color = op.border_COLOR; 17944 this.bord_alpha = op.border_TRANSPARENCY / 100; 17945 17946 this.container = op.container; 17947 this.image_url = op.image_url; 17948 this.image_width = op.image_original_width; 17949 this.image_height = op.image_original_height; 17950 17951 this.responsive = checkBoolean(op.responsive); 17952 this.maintain_ratio = checkBoolean(op.responsive_maintain_ratio); 17953 this.w_max = op.max_WIDTH; 17954 this.h_max = op.max_HEIGHT; 17955 17956 this.onLOAD = op.on_IMAGE_LOAD; 17957 this.onUPDATE = op.on_ZOOM_PAN_UPDATE; 17958 this.onZOOM_PAN = op.on_ZOOM_PAN_COMPLETE; 17959 this.onLANDMARK = op.on_LANDMARK_STATE_CHANGE; 17960 17961 /*********************************************************** 17962 Variables for inner operation. 17963 x, y, width, height and scale value of image 17964 ***********************************************************/ 17965 this._x; 17966 this._y; 17967 this._w; 17968 this._h; 17969 this._sc = 0; 17970 17971 this.rF = 1; 17972 this.rA = 1; 17973 this.iW = 0; 17974 this.iH = 0; 17975 this.tX = 0; 17976 this.tY = 0; 17977 this.oX = 0; 17978 this.oY = 0; 17979 this.fX = 0; 17980 this.fY = 0; 17981 this.dX = 0; 17982 this.dY = 0; 17983 this.cX = 0; 17984 this.cY = 0; 17985 17986 this.transOffX = 0; 17987 this.transOffY = 0; 17988 this.focusOffX = 0; 17989 this.focusOffY = 0; 17990 this.offX = 0; 17991 this.offY = 0; 17992 17993 /*********************************************************** 17994 Flags that convey current states and events 17995 ***********************************************************/ 17996 this._playing = false; 17997 this._dragging = false; 17998 this._onfocus = false; 17999 this._moveCursor = false; 18000 this._wheel = false; 18001 this._recent = 'zoomOut'; 18002 this._pinching = false; 18003 this._landmark = false; 18004 this._rA; 18005 this._centx; 18006 this._centy; 18007 this._onButton = false; 18008 this._onHitArea = false; 18009 this.cFlag = { 18010 _zi: false, 18011 _zo: false, 18012 _ml: false, 18013 _mr: false, 18014 _mu: false, 18015 _md: false, 18016 _rs: false, 18017 _nd: false 18018 }; 18019 18020 /*********************************************************** 18021 Elements and arrays that references elements 18022 ***********************************************************/ 18023 this.$holder; 18024 this.$hitArea; 18025 this.$controls; 18026 this.$loc_cont; 18027 this.map_coordinates = []; 18028 this.locations = []; 18029 this.buttons = []; 18030 this.border = []; 18031 18032 /*********************************************************** 18033 miscellaneous 18034 ***********************************************************/ 18035 this.buttons_total = 7; 18036 this.cButtId = 0; 18037 this.pan_speed; 18038 this.auto_timer; 18039 this.ani_timer; 18040 this.ani_end; 18041 this.focusSpeed = this.reduction = .5; 18042 this.orig_style; 18043 this.mapAreas; 18044 this.icons; 18045 this.show_at_zoom; 18046 this.assetsLoaded = false; 18047 this.zStep = 0; 18048 this.sRed = 300; 18049 this.use3D = op.use_3D_Transform && supportsTrans3D; 18050 18051 if (supportsTouch) { 18052 this.event_down = 'touchstart.sz'; 18053 this.event_up = 'touchend.sz'; 18054 this.event_move = 'touchmove.sz'; 18055 } else { 18056 this.event_down = 'mousedown.sz'; 18057 this.event_up = 'mouseup.sz'; 18058 this.event_move = 'mousemove.sz'; 18059 } 18060 18061 //Case 1: Image specificed (possibly) through img tag: 18062 if (this.image_url == '') { 18063 this.$image = $elem; 18064 this.id = this.$image.attr('id'); 18065 18066 //Case 2: Image url specificed through parameter: 18067 } else { 18068 var img = new Image(); 18069 if (this.image_width) { 18070 img.width = this.image_width; 18071 } 18072 if (this.image_height) { 18073 img.height = this.image_height; 18074 } 18075 img.src = this.image_url; 18076 this.$image = $(img).appendTo($elem); 18077 } 18078 18079 18080 //Prepare container div (Basically the element that masks image with overflow hidden) 18081 this.setContainer(); 18082 18083 //Get button icon image's url 18084 var testOb; 18085 if (!this.bu_icon) { 18086 var regx = /url\(["']?([^'")]+)['"]?\)/;
18087 testOb = $('<div class="smooth_zoom_icons"></div>'); 18088 this.$holder.append(testOb); 18089 this.bu_icon = testOb.css("background-image").replace(regx, '$1'); 18090 if (this.bu_icon == 'none') { 18091 this.bu_icon = 'zoom_assets/icons.png'; 18092 } 18093 testOb.remove(); 18094 } 18095 18096 //Firefox feature checkup 18097 if (this.$image.css('-moz-transform') && prop_transform) { 18098 testOb = $('<div style="-moz-transform: translate(1px, 1px)"></div>'); 18099 this.$holder.append(testOb); 18100 this.fixMoz = testOb.position().left === 1 ? false : true; 18101 testOb.remove(); 18102 } else { 18103 this.fixMoz = false; 18104 } 18105 18106 //Preload icons and main image. 18107 this.$image.hide(); 18108 this.imgList = [ 18109 {loaded: false, src: this.bu_icon || 'zoom_assets/icons.png'}, //Icon image 18110 {loaded: false, src: this.image_url == '' ? this.$image.attr('src') : this.image_url} // Main image 18111 ]; 18112 18113 $.each(this.imgList, function(i) { 18114 var _img = new Image(); 18115 $(_img).bind('load', {id: i, self: self}, self.loadComplete) 18116 .bind('error', {id: i, self: self}, self.loadComplete); //Allow initiation even if image is not there :( 18117 _img.src = self.imgList[i].src; 18118 }); 18119 18120 } 18121 18122 Zoomer.prototype = { 18123 /*Preload the icon and main image 18124 *********************************************************************************************************************/ 18125 loadComplete: function(e) { 18126 var self = e.data.self, 18127 complete = true; 18128 18129 self.imgList[e.data.id].loaded = true; 18130 for (var j = 0; j < self.imgList.length; j++) { 18131 if (!self.imgList[j].loaded) { 18132 complete = false; 18133 } 18134 } 18135 if (complete) { 18136 self.assetsLoaded = true; 18137 if (self.onLOAD !== '') { 18138 self.onLOAD(); 18139 } 18140 18141 //Assets loaded, initiate plugin 18142 self.init(); 18143 } 18144 }, 18145 /*Initiate after assets loaded 18146 ***********************************************************************************************************************/ 18147 init: function() { 18148 var self = this, 18149 $image = self.$image, 18150 sW = self.sW, 18151 sH = self.sH, 18152 container = self.container, 18153 cBW, cBH, pan_show = self.pan_show, 18154 zoom_show = self.zoom_show, 18155 $controls = self.$controls, 18156 buttons = self.buttons, 18157 cFlag = self.cFlag, 18158 bu_align = self.bu_align, 18159 bu_margin = self.bu_margin, 18160 $holder = self.$holder; 18161 if ($image) { 18162 //Store the default image properties so that it can be reverted back when plugin needs to be destroyed 18163 self.orig_style = self.getStyle(); 18164 18165 //IE 6 Image tool bar disabled 18166 $image.attr('galleryimg', 'no'); 18167 18168 if (!navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad)/)) { 18169 $image.removeAttr('width'); 18170 $image.removeAttr('height'); 18171 } 18172 18173 //In case parent element's display property set to 'none', we need to first set them 'block', measure the width and height and then set them back to 'none' 18174 var temp = $image, 18175 dispArray = []; 18176 for (var i = 0; i < 5; i++) { 18177 if (temp && temp[0].tagName !== 'BODY' && temp[0].tagName !== 'HTML') { 18178 if (temp.css('display') == 'none') { 18179 temp.css('display', 'block'); 18180 dispArray.push(temp); 18181 } 18182 temp = temp.parent(); 18183 } else { 18184 break; 18185 } 18186 } 18187 18188 self.iW = $image.width(); 18189 self.iH = $image.height(); 18190 18191 for (var i = 0; i < dispArray.length; i++) { 18192 dispArray[i].css('display', 'none'); 18193 } 18194 18195 //Initially the image needs to be resized to fit container. To do so, first measure the scaledown ratio 18196 self.rF = self.checkRatio(sW, sH, self.iW, self.iH, self.zoom_fit); 18197 18198 //If NO Minimum zoom value set 18199 if (self.zoom_min == 0 || self.init_zoom != 0) { 18200 if (self.init_zoom != '') { 18201 self.rA = self._sc = self.init_zoom; 18202 } else { 18203 self.rA = self._sc = self.rF; 18204 } 18205 if (self.zoom_min == 0) { 18206 self.rF = self.rA; 18207 } else { 18208 self.rF = self.zoom_min; 18209 } 18210 18211 //If Minimum zoom value set 18212 } else { 18213 self.rA = self._sc = self.rF = self.zoom_min; 18214 } 18215 18216 //Width and Height to be applied to the image 18217 self._w = self._sc * self.iW; 18218 self._h = self._sc * self.iH; 18219 18220 //Resize the image and position it centered inside the wrapper 18221 if (self.init_pos == '') { 18222 self._x = self.tX = (sW - self._w) / 2; 18223 self._y = self.tY = (sH - self._h) / 2; 18224 } else { 18225 self._x = self.tX = (sW / 2) - parseInt(self.init_pos[0]) * self._sc; 18226 self._y = self.tY = (sH / 2) - parseInt(self.init_pos[1]) * self._sc; 18227 self.oX = (self.tX - ((sW - self._w) / 2)) / (self._w / sW); 18228 self.oY = (self.tY - ((sH - self._h) / 2)) / (self._h / sH); 18229 } 18230 18231 if ((!self.pan_limit || self._moveCursor || self.init_zoom != self.rF) && self.mouse_drag) { 18232 $image.css('cursor', 'move'); 18233 self.$hitArea.css('cursor', 'move'); 18234 } 18235 18236 if ($.browser.mozilla && supportsTrans3D) { 18237 $image.css('opacity', 0); 18238 } 18239 18240 if (prop_transform) { 18241 self.$image.css(prop_origin, '0 0'); 18242 } 18243 if (self.use3D) { 18244 $image.css({
18245 '-webkit-backface-visibility': 'hidden', 18246 '-webkit-perspective': 1000 18247 }); 18248 } 18249 18250 //Start displaying the image 18251 $image.css({ 18252 position: 'absolute', 18253 'z-index': supportsTouch ? 1 : 2, 18254 left: '0px', 18255 top: '0px', 18256 '-webkit-box-shadow': '1px 1px rgba(0,0,0,0)' 18257 }) 18258 .hide() 18259 .fadeIn(500, function() { 18260 $holder.css('background-image', 'none'); 18261 if ($.browser.mozilla && supportsTrans3D) { 18262 $image.css('opacity', 1); 18263 } 18264 }); 18265 if (supportsTouch) { 18266 $image.bind(self.event_down, function(e) { 18267 e.preventDefault(); 18268 }); 18269 } 18270 //Create Control buttons and events 18271 var self = self, 18272 bs = self.bu_size, 18273 iSize = 50, 18274 sDiff = 2,
18275 bSpace = 3, 18276 mSize = Math.ceil(self.bu_size / 4), 18277 iconOff = bs < 16 ? 50 : 0, 18278 bsDiff = bs - sDiff; 18279 18280 //Show all buttons 18281 if (pan_show) { 18282 if (zoom_show) { 18283 cBW = parseInt(bs + (bs * .85) + (bsDiff * 3) + (bSpace * 2) + (mSize * 2)); 18284 } else { 18285 cBW = parseInt((bsDiff * 3) + (bSpace * 2) + (mSize * 2)); 18286 } 18287 cBH = parseInt((bsDiff * 3) + (bSpace * 2) + (mSize * 2)); 18288 18289 //Show zoom buttons only 18290 } else { 18291 if (zoom_show) { 18292 cBW = parseInt(bs + mSize * 2); 18293 cBH = parseInt(bs * 2 + mSize * 3); 18294 cBW = parseInt(cBW / 2) * 2; 18295 cBH = parseInt(cBH / 2) * 2; 18296 } else { 18297 cBW = 0; 18298 cBH = 0; 18299 } 18300 } 18301 18302 var pOff = (iSize - bs) / 2, 18303 resetCenterX = cBW - ((bs - (pan_show ? sDiff : 0)) * 2) - mSize - bSpace, 18304 resetCenterY = (cBH / 2) - ((bs - (pan_show ? sDiff : 0)) / 2); 18305 18306 var hProp, vProp, hVal, vVal; 18307 //Align button set as per settings 18308 if (bu_align[0] == 'top') { 18309 vProp = 'top'; 18310 vVal = bu_margin; 18311 } else if (bu_align[0] == 'center') { 18312 vProp = 'top'; 18313 vVal = parseInt((sH - cBH) / 2); 18314 } else { 18315 vProp = 'bottom'; 18316 vVal = bu_margin; 18317 } 18318 if (bu_align[1] == 'right') { 18319 hProp = 'right'; 18320 hVal = bu_margin; 18321 } else if (bu_align[1] == 'center') { 18322 hProp = 'right'; 18323 hVal = parseInt((sW - cBW) / 2); 18324 } else { 18325 hProp = 'left'; 18326 hVal = bu_margin; 18327 } 18328 18329 //Buttons Container 18330 $controls = $( 18331 '<div style="position: absolute; ' + hProp + ':' + hVal + 'px; ' + vProp + ': ' + vVal + 'px; width: ' + cBW + 'px; height: ' + cBH + 'px; z-index: 20;" class="noSel;">\ 18332 <div class="noSel controlsBg" style="position: relative; width: 100%; height: 100%; z-index: 1;">\ 18333 </div>\ 18334 </div>' 18335 ); 18336 18337 $holder.append($controls); 18338 var $controlsBg = $controls.find('.controlsBg'); 18339 18340 //Make the corners rounded 18341 if (self.bu_round) { 18342 if (prop_radius) { 18343 $controlsBg 18344 .css(prop_radius, (iconOff > 0 ? 4 : 5) + 'px') 18345 .css('background-color', self.bu_bg); 18346 } else { 18347 self.roundBG( 18348 $controlsBg, 18349 'cBg', 18350 cBW, 18351 cBH, 18352 iconOff > 0 ? 4 : 5, 18353 375, 18354 self.bu_bg, 18355 self.bu_icon, 18356 1, 18357 iconOff ? 50 : 0 18358 ); 18359 } 18360 } else { 18361 $controlsBg.css('background-color', self.bu_bg); 18362 } 18363 18364 $controlsBg.css('opacity', self.bu_bg_alpha); 18365 18366 //Generating Button properties (7 buttons) 18367 buttons[0] = { 18368 _var: '_zi', 18369 l: mSize, 18370 t: pan_show ? (cBH - (bs * 2) - (bSpace * 2) + 2) / 2 : mSize, 18371 w: bs, 18372 h: bs, 18373 bx: -pOff, 18374 by: -pOff - iconOff 18375 }; 18376 18377 buttons[1] = { 18378 _var: '_zo', 18379 l: mSize, 18380 t: pan_show ? ((cBH - (bs * 2) - (bSpace * 2) + 2) / 2) + bs + (bSpace * 2) - 2 : cBH - bs - mSize, 18381 w: bs, 18382 h: bs, 18383 bx: -iSize - pOff, 18384 by: -pOff - iconOff 18385 }; 18386 18387 buttons[2] = { 18388 _var: self.pan_rev ? '_ml' : '_mr', 18389 l: resetCenterX - bsDiff - bSpace, 18390 t: resetCenterY, 18391 w: bsDiff, 18392 h: bsDiff, 18393 bx: -(sDiff / 2) - iSize * 2 - pOff, 18394 by: -(sDiff / 2) - pOff - iconOff 18395 }; 18396 18397 buttons[3] = { 18398 _var: self.pan_rev ? '_mr' : '_ml', 18399 l: resetCenterX + bsDiff + bSpace, 18400 t: resetCenterY, 18401 w: bsDiff, 18402 h: bsDiff, 18403 bx: -(sDiff / 2) - iSize * 3 - pOff, 18404 by: -(sDiff / 2) - pOff - iconOff 18405 }; 18406 18407 buttons[4] = { 18408 _var: self.pan_rev ? '_md' : '_mu', 18409 l: resetCenterX, 18410 t: resetCenterY + bsDiff + bSpace, 18411 w: bsDiff, 18412 h: bsDiff, 18413 bx: -(sDiff / 2) - iSize * 4 - pOff, 18414 by: -(sDiff / 2) - pOff - iconOff 18415 }; 18416 18417 buttons[5] = { 18418 _var: self.pan_rev ? '_mu' : '_md', 18419 l: resetCenterX, 18420 t: resetCenterY - bsDiff - bSpace, 18421 w: bsDiff, 18422 h: bsDiff, 18423 bx: -(sDiff / 2) - iSize * 5 - pOff, 18424 by: -(sDiff / 2) - pOff - iconOff 18425 }; 18426 18427 buttons[6] = { 18428 _var: '_rs', 18429 l: resetCenterX, 18430 t: resetCenterY, 18431 w: bsDiff, 18432 h: bsDiff, 18433 bx: -(sDiff / 2) - iSize * 6 - pOff, 18434 by: -(sDiff / 2) - pOff - iconOff 18435 }; 18436 18437 for (var i = 0; i < 7; i++) { 18438 buttons[i].$ob = $( 18439 '<div style="position: absolute; display: ' + (i < 2 ? zoom_show ? 'block' : 'none' : pan_show ? 'block' : 'none') + '; left: ' + (buttons[i].l - 1) + 'px; top: ' + (buttons[i].t - 1) + 'px; width: ' + (buttons[i].w + 2) + 'px; height: ' + (buttons[i].h + 2) + 'px;
18439 z-index:' + (i + 1) + ';" class="noSel">\ 18440 </div>' 18441 ) 18442 .css('opacity', .7) 18443 .bind((supportsTouch ? "" : 'mouseover.sz mouseout.sz ') + self.event_down, { 18444 id: i 18445 18446 }, function(e) { 18447 self._onfocus = false; 18448 $this = $(this); 18449 18450 //Button over 18451 if (e.type == 'mouseover') { 18452 if ($this.css('opacity') > .5) { 18453 $this.css('opacity', 1); 18454 } 18455 18456 //Button out 18457 } else if (e.type == 'mouseout') { 18458 if ($this.css('opacity') > .5) { 18459 $this.css('opacity', .7); 18460 } 18461 18462 //Button press/down 18463 } else if (e.type == 'mousedown' || e.type == 'touchstart') { 18464 self.cButtId = e.data.id; 18465 self._onButton = true; 18466 self._wheel = false; 18467 18468 //If NOT already down.. 18469 if ($this.css('opacity') > .5) { 18470 $this.css('opacity', 1); 18471 $holder.find('#' + buttons[self.cButtId]._var + 'norm').hide(); 18472 $holder.find('#' + buttons[self.cButtId]._var + 'over').show(); 18473 18474 //CASE 1: If zoomIn pressed and single step zoom enabled 18475 if (self.cButtId <= 1 && self.zoom_single) { 18476 if (!cFlag[buttons[self.cButtId]._var]) { 18477 self.sRed = 300; 18478 cFlag[buttons[self.cButtId]._var] = true; 18479 } 18480 18481 //CASE 2: If any button except RESET pressed 18482 } else if (self.cButtId < 6) { 18483 cFlag[buttons[self.cButtId]._var] = true; 18484 18485 //CASE 3: RESET pressed 18486 } else { 18487 cFlag._rs = true; 18488 self.rA = self.rF; 18489 if (self.reset_align[0] == 'top') { 18490 self.fY = (self.sH / 2) * (self.rA / 2); 18491 } else if (self.reset_align[0] == 'bottom') { 18492 self.fY = -(self.sH / 2) * (self.rA / 2); 18493 } else { 18494 self.fY = 0; 18495 } 18496 if (self.reset_align[1] == 'left') { 18497 self.fX = (self.sW / 2) * (self.rA / 2); 18498 } else if (self.reset_align[1] == 'right') { 18499 self.fX = -(self.sW / 2) * (self.rA / 2); 18500 } else { 18501 self.fX = 0; 18502 } 18503 } 18504 18505 self.focusOffX = self.focusOffY = 0; 18506 self.changeOffset(true, true); 18507 if (!self._playing) { 18508 self.Animate(); 18509 } 18510 } 18511 e.preventDefault(); 18512 e.stopPropagation(); 18513 } 18514 }); 18515 18516 //Make 2 BGs for Button Normal and Over state 18517 //Button BG normal 18518 var tpm = $( 18519 '<div id="' + buttons[i]._var + 'norm" style="position: absolute; left: 1px; top: 1px; width: ' + buttons[i].w + 'px; height: ' + buttons[i].h + 'px;
18519 ' + (prop_radius || !self.bu_round ? 'background:' + self.bu_color : '') + '">\ 18520 </div>' 18521 ); 18522 18523 //Button BG hover 18524 var tpmo = $( 18525 '<div id="' + buttons[i]._var + 'over" style="position: absolute; left: 0px; top: 0px; width: ' + (buttons[i].w + 2) + 'px; height: ' + (buttons[i].h + 2) + 'px; display: none; ' + (prop_radius || !self.bu_round ? 'background:' + self.bu_color : '') + '">\ 18526 </div>' 18527 ); 18528 18529 //Add the button icons 18530 var cont = $( 18531 '<div id="' + buttons[i]._var + '_icon" style="position: absolute; left: 1px; top: 1px; width: ' + buttons[i].w + 'px; height: ' + buttons[i].h + 'px; background: transparent url(' + self.bu_icon + ') ' + buttons[i].bx + 'px ' + buttons[i].by + 'px no-repeat;" >\ 18532 </div>' 18533 ); 18534 18535 buttons[i].$ob.append(tpm, tpmo, cont); 18536 $controls.append(buttons[i].$ob); 18537 18538 //Apply corner radius 18539 if (self.bu_round) { 18540 if (prop_radius) { 18541 tpm.css(prop_radius, '2px'); 18542 tpmo.css(prop_radius, '2px'); 18543 } else { 18544 self.roundBG( 18545 tpm, 18546 buttons[i]._var + "norm", 18547 buttons[i].w, 18548 buttons[i].h, 18549 2, 18550 425, 18551 self.bu_color, 18552 self.bu_icon, 18553 i + 1, 18554 iconOff ? 50 : 0 18555 ); 18556 self.roundBG( 18557 tpmo, 18558 buttons[i]._var + "over", 18559 buttons[i].w + 2, 18560 buttons[i].h + 2, 18561 2, 18562 425, 18563 self.bu_color, 18564 self.bu_icon, 18565 i + 1, 18566 iconOff ? 50 : 0 18567 ); 18568 } 18569 } 18570 } 18571 18572 //Add Events for mouse drag / touch swipe action 18573 $(document).bind(self.event_up + self.id, {self: self}, self.mouseUp); 18574 18575 if ((self.mouse_drag && !supportsTouch) || (self.touch_drag && supportsTouch)) { 18576 if (supportsTouch) { 18577 self.$hitArea.bind(self.event_down, {self: self}, self.mouseDown);
18578 $(document).bind(self.event_move + self.id, {self: self}, self.mouseDrag); 18579 } else { 18580 self.$holder.bind(self.event_down, {self: self}, self.mouseDown); 18581 } 18582 } 18583 18584 //Add Double click / Double tap zoom 18585 if (self.mouse_dbl_click) { 18586 var dClickedX, 18587 dClickedY, 18588 dbl_click_dir = 1; 18589 18590 (supportsTouch ? self.$hitArea : self.$holder).bind('dblclick.sz', function(e) { 18591 self.focusOffX = e.pageX - $holder.offset().left - (self.sW / 2); 18592 self.focusOffY = e.pageY - $holder.offset().top - (self.sH / 2); 18593 self.changeOffset(true, true); 18594 self._wheel = false; 18595 18596 if (self.rA < self.zoom_max && dbl_click_dir == -1 && dClickedX != self.focusOffX && dClickedY != self.focusOffY) { 18597 dbl_click_dir = 1; 18598 } 18599 18600 dClickedX = self.focusOffX; 18601 dClickedY = self.focusOffY; 18602 18603 if (self.rA >= self.zoom_max && dbl_click_dir == 1) { 18604 dbl_click_dir = -1; 18605 } 18606 if (self.rA <= self.rF && dbl_click_dir == -1) { 18607 dbl_click_dir = 1; 18608 } 18609 if (dbl_click_dir > 0) { 18610 self.rA *= 2; 18611 self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA; 18612 cFlag._zi = true; 18613 clearTimeout(self.ani_timer); 18614 self._playing = true; 18615 self.Animate(); 18616 cFlag._zi = false; 18617 18618 } else { 18619 self.rA /= 2; 18620 self.rA = self.rA < self.rF ? self.rF : self.rA; 18621 cFlag._zo = true; 18622 clearTimeout(self.ani_timer); 18623 self._playing = true; 18624 self.Animate(); 18625 cFlag._zo = false; 18626 } 18627 e.preventDefault(); 18628 e.stopPropagation(); 18629 }); 18630 } 18631 18632 //Add mouse wheel event if enabled 18633 if (self.mouse_wheel) { 18634 $holder.bind('mousewheel.sz', {self: this}, self.mouseWheel); 18635 } 18636 18637 //Auto Hide the control buttons if enabled 18638 if (self.bu_auto) { 18639 $holder.bind('mouseleave.sz', {self: this}, self.autoHide); 18640 } 18641 18642 //Prevent Controls Bg from start dragging image 18643 $controls.bind(self.event_down, function(e) { 18644 e.preventDefault(); 18645 e.stopPropagation(); 18646 }); 18647 18648 //Prevent Controls Bg from double click zoom 18649 if (self.mouse_dbl_click) { 18650 $controls.bind('dblclick.sz', function(e) { 18651 e.preventDefault(); 18652 e.stopPropagation(); 18653 }); 18654 } 18655 18656 //Prevent text selection for smoother dragging and button focus 18657 $('.noSel').each(function() { 18658 this.onselectstart = function() { 18659 return false; 18660 }; 18661 }); 18662 18663 self.$holder = $holder; 18664 self.$controls = $controls; 18665 self.sW = sW; 18666 self.sH = sH; 18667 self.cBW = cBW; 18668 self.cBH = cBH; 18669 18670 //Apply initial transformation 18671 self.Animate(); 18672 } 18673 18674 }, 18675 /*Prepare the container (holder) element and get landmarks if available 18676 ***********************************************************************************************************************/ 18677 setContainer: function() { 18678 var self = this, 18679 $image = self.$image, 18680 bord_size = self.bord_size, 18681 border = self.border, 18682 $holder = self.$holder; 18683 18684 //Wrap a container for image or get the container if specified through options: 18685 if (self.container == '' && self.image_url == '') { 18686 $holder = self.$image.wrap( 18687 '<div class="noSel smooth_zoom_preloader">\ 18688 </div>' 18689 ).parent(); 18690 18691 } else { 18692 if (self.image_url == '') { 18693 $holder = $('#' + self.container); 18694 } else { 18695 $holder = self.$elem; 18696 } 18697 $holder.addClass('noSel smooth_zoom_preloader'); 18698 self.locations = []; 18699 self.$loc_cont = $holder.find('.landmarks'); 18700 if (self.$loc_cont[0]) { 18701 var locs = self.$loc_cont.children('.item'); 18702 self.loc_clone = self.$loc_cont.clone(); 18703 self.show_at_zoom = parseInt(self.$loc_cont.data('show-at-zoom'), 10) / 100; 18704 self.allow_scale = checkBoolean(self.$loc_cont.data('allow-scale')); 18705 self.allow_drag = checkBoolean(self.$loc_cont.data('allow-drag')); 18706 locs.each(function() { 18707 self.setLocation($(this)); 18708 }); 18709 } 18710 } 18711 18712 $holder.css({ 18713 'position': 'relative', 18714 'overflow': 'hidden', 18715 'text-align': 'left',
18716 '-moz-user-select': 'none', 18717 '-khtml-user-select': 'none', 18718 '-webkit-user-select': 'none', 18719 'user-select': 'none', 18720 '-webkit-touch-callout': 'none', 18721 '-webkit-tap-highlight-color': 'rgba(255, 255, 255, 0)', 18722 'background-color': self.bg_color, 18723 'background-position': 'center center', 18724 'background-repeat': 'no-repeat' 18725 }) 18726 18727 self.$hitArea = $('<div style="position: absolute; z-index: ' + (supportsTouch ? 2 : 1) + '; top: 0px; left: 0px; width: 100%; height: 100%;" ></div>').appendTo($holder); 18728 18729 self.getContainerSize(self.sW, self.sH, $holder, self.w_max, self.h_max); 18730 18731 if (self.responsive) { 18732 $(window).bind("orientationchange.sz" + self.id + " resize.sz" + self.id, {self: self}, self.resize); 18733 } 18734 var sW = self.sW; 18735 var sH = self.sH; 18736 18737 //Add Image container properties 18738 $holder.css({ 18739 'width': sW, 18740 'height': sH 18741 }); 18742 18743 //Add border if needed 18744 if (bord_size > 0) { 18745 border[0] = $('<div style="position: absolute; width: ' + bord_size + 'px; height: ' + sH + 'px; top: 0px; left: 0px; z-index: 3; background-color: ' + self.bord_color + ';"></div>').css('opacity', self.bord_alpha); 18746 border[1] = $('<div style="position: absolute; width: ' + bord_size + 'px; height: ' + sH + 'px; top: 0px; left: ' + (sW - bord_size) + 'px; z-index: 4; background-color: ' + self.bord_color + ';"></div>').css('opacity', self.bord_alpha); 18747 border[2] = $('<div style="position: absolute; width: ' + (sW - (bord_size * 2)) + 'px; height: ' + bord_size + 'px; top: 0px; left: ' + bord_size + 'px; z-index: 5; background-color: ' + self.bord_color + '; line-height: 1px;"></div>').css('opacity', self.bord_alpha); 18748 border[3] = $('<div style="position: absolute; width: ' + (sW - (bord_size * 2)) + 'px; height: ' + bord_size + 'px; top: ' + (sH - bord_size) + 'px; left: ' + bord_size + 'px; z-index: 6; background-color: ' + self.bord_color + '; line-height: 1px;"></div>').css('opacity', self.bord_alpha); 18749 $holder.append(border[0], border[1], border[2], border[3]); 18750 } 18751 18752 //Get Image maps if exists 18753 if ($image.attr('usemap') != undefined) { 18754 self.mapAreas = $("map[name='" + ($image.attr('usemap').split('#').join('')) + "']").children('area'); 18755 self.mapAreas.each(function(i) { 18756 var area = $(this); 18757 area.css('cursor', 'pointer'); 18758 if (self.mouse_drag) { 18759 area.bind(self.event_down, {self: self}, self.mouseDown);
18760 } 18761 if (self.mouse_wheel) { 18762 area.bind('mousewheel.sz', {self: self}, self.mouseWheel); 18763 } 18764 self.map_coordinates.push(area.attr('coords').split(',')); 18765 }); 18766 } 18767 18768 self.$holder = $holder; 18769 self.sW = sW; 18770 self.sH = sH; 18771 }, 18772 getContainerSize: function(sW, sH, $holder, w_max, h_max) { 18773 if (sW === '' || sW === 0) { 18774 if (this.image_url == '') { 18775 sW = Math.max($holder.parent().width(), 100); 18776 } else { 18777 sW = Math.max($holder.width(), 100); 18778 } 18779 18780 } else if (!isNaN(sW) || String(sW).indexOf('px') > -1) { 18781 sW = this.oW = parseInt(sW); 18782 if (this.responsive) { 18783 sW = Math.min($holder.parent().width(), sW); 18784 } 18785 } else if (String(sW).indexOf('%') > -1) { 18786 sW = $holder.parent().width() * (sW.split('%')[0] / 100); 18787 } else { 18788 sW = 100; 18789 } 18790 if (w_max !== 0 && w_max !== '') { 18791 sW = Math.min(sW, w_max); 18792 } 18793 if (sH === '' || sH === 0) { 18794 if (this.image_url == '') { 18795 sH = Math.max($holder.parent().height(), 100); 18796 } else { 18797 sH = Math.max($holder.height(), 100); 18798 } 18799 } else if (!isNaN(sH) || String(sH).indexOf('px') > -1) { 18800 sH = this.oH = parseInt(sH); 18801 18802 } else if (String(sH).indexOf('%') > -1) { 18803 sH = $holder.parent().height() * (sH.split('%')[0] / 100); 18804 } else { 18805 sH = 100; 18806 } 18807 if (h_max !== 0 && h_max !== '') { 18808 sH = Math.min(sH, h_max); 18809 } 18810 18811 if (this.oW && sW !== this.oW) { 18812 if (this.oH && this.maintain_ratio) { 18813 sH = sW / (this.oW / this.oH); 18814 } 18815 } 18816 18817 this.sW = sW; 18818 this.sH = sH; 18819 }, 18820 /*Each landmark / location / lable initiated here 18821 ***********************************************************************************************************************/ 18822 setLocation: function(lc) { 18823 var self = this, 18824 ob = lc, 18825 w2, h2, pos, sc; 18826 18827 if (prop_origin) { 18828 ob.css(prop_origin, '0 0'); 18829 } 18830 18831 ob.css({ 18832 'display': 'block', 18833 'z-index': 2 18834 }) 18835 if (self.use3D) { 18836 ob.css({ 18837 '-webkit-backface-visibility': 'hidden', 18838 '-webkit-perspective': 1000 18839 }); 18840 } 18841 18842 w2 = ob.outerWidth() / 2; 18843 h2 = ob.outerHeight() / 2; 18844 pos = ob.data('position').split(','); 18845 sc = ob.data('allow-scale'); 18846 if (sc == undefined) { 18847 sc = self.allow_scale; 18848 } else { 18849 sc = checkBoolean(sc); 18850 } 18851 18852 if (ob.hasClass('mark')) { 18853 var imgw = ob.find('img').css('vertical-align', 'bottom').width(); 18854 $(ob.children()[0]).css({ 18855 'position': 'absolute', 18856 'left': (-ob.width() / 2), 18857 'bottom': parseInt(ob.css('padding-bottom')) * 2 18858 }); 18859 var txt = ob.find('.text'); 18860 self.locations.push({ 18861 ob: ob, 18862 x: parseInt(pos[0]), 18863 y: parseInt(pos[1]), 18864 w2: w2, 18865 h2: h2, 18866 w2pad: w2 + (txt[0] ? parseInt(txt.css('padding-left')) : 0), 18867 vis: false, 18868 lab: false, 18869 lpx: '0', 18870 lpy: '0', 18871 showAt: isNaN(ob.data('show-at-zoom')) ? self.show_at_zoom : parseInt(ob.data('show-at-zoom'), 10) / 100, 18872 scale: sc 18873 }); 18874 18875 } else if (ob.hasClass('lable')) { 18876 var bg = ob.data('bg-color'), 18877 opacity = ob.data('bg-opacity'), 18878 cont = $(ob.eq(0).children()[0]) 18879 .css({ 18880 'position': 'absolute', 18881 'z-index': 2, 18882 left: -w2, 18883 top: -h2 18884 }); 18885 18886 self.locations.push({ 18887 ob: ob, 18888 x: parseInt(pos[0]), 18889 y: parseInt(pos[1]), 18890 w2: w2, 18891 h2: h2, 18892 w2pad: w2, 18893 vis: false, 18894 lab: true, 18895 lpx: '0', 18896 lpy: '0', 18897 showAt: isNaN(ob.data('show-at-zoom')) ? self.show_at_zoom : parseInt(ob.data('show-at-zoom'), 10) / 100, 18898 scale: sc 18899 }); 18900 18901 if (bg !== "") { 18902 if (!bg) { 18903 bg = "#000000"; 18904 opacity = .7; 18905 } 18906 var bgob = $('<div style="position: absolute; left: ' + (-w2) + 'px; top: ' + (-h2) + 'px; width: ' + ((w2 - parseInt(cont.css('padding-left'))) * 2) + 'px; height:' + ((h2 - parseInt(cont.css('padding-top'))) * 2) + 'px; background-color: ' + bg + ';"></div>').appendTo(ob); 18907 if (opacity) { 18908 bgob.css('opacity', opacity); 18909 } 18910 } 18911 } 18912 ob.hide(); 18913 if (prop_transform) { 18914 ob.css('opacity', 0); 18915 } 18916 if (!self.allow_drag) { 18917 ob.bind(self.event_down, function(e) { 18918 e.preventDefault(); 18919 e.stopPropagation(); 18920 }); 18921 } else {
18922 ob.css('pointer-events', 'none'); 18923 } 18924 }, 18925 /*Storing the original style of image (needed only when destroying) 18926 ***********************************************************************************************************************/ 18927 getStyle: function() { 18928 if (this.$image) { 18929 var el = this.$image; 18930 return { 18931 prop_origin: [prop_origin, prop_origin !== false && prop_origin !== undefined ? el.css(prop_origin) : null], 18932 prop_transform: [prop_transform, prop_transform !== false && prop_transform !== undefined ? el.css(prop_transform) : null], 18933 'position': ['position', el.css('position')], 18934 'z-index': ['z-index', el.css('z-index')], 18935 'cursor': ['cursor', el.css('cursor')], 18936 'left': ['left', el.css('left')], 18937 'top': ['top', el.css('top')], 18938 'width': ['width', el.css('width')], 18939 'height': ['height', el.css('height')] 18940 }; 18941 } 18942 }, 18943 /*Find the scale ratios 18944 ***********************************************************************************************************************/ 18945 checkRatio: function(sW, sH, iW, iH, zoom_fit) { 18946 var rF; 18947 if (iW == sW && iH == sH) { 18948 rF = 1; 18949 } else if (iW < sW && iH < sH) { 18950 rF = sW / iW; 18951 if (zoom_fit) { 18952 if (rF * iH > sH) { 18953 rF = sH / iH; 18954 } 18955 } else { 18956 if (rF * iH < sH) { 18957 rF = sH / iH; 18958 } 18959 if (sW / iW !== sH / iH && this.mouse_drag) { 18960 this._moveCursor = true; 18961 this.$image.css('cursor', 'move'); 18962 this.$hitArea.css('cursor', 'move'); 18963 } 18964 } 18965 } else { 18966 18967 rF = sW / iW; 18968 if (zoom_fit) { 18969 if (rF * iH > sH) { 18970 rF = sH / iH; 18971 } 18972 if (rF < this.init_zoom && this.mouse_drag) { 18973 this._moveCursor = true; 18974 this.$image.css('cursor', 'move'); 18975 this.$hitArea.css('cursor', 'move'); 18976 } 18977 } else { 18978 if (rF * iH < sH) { 18979 rF = sH / iH; 18980 } 18981 if (sW / iW !== sH / iH && this.mouse_drag) { 18982 this._moveCursor = true; 18983 this.$image.css('cursor', 'move'); 18984 this.$hitArea.css('cursor', 'move'); 18985 } 18986 } 18987 } 18988 return rF; 18989 }, 18990 /*Returns distance between 2 points (used for touch gesture) 18991 ***********************************************************************************************************************/ 18992 getDistance: function(x1, y1, x2, y2) { 18993 return Math.sqrt(Math.abs(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)))); 18994 }, 18995 /*Image Events for Dragging and Mouse Wheel 18996 ***********************************************************************************************************************/ 18997 mouseDown: function(e) { 18998 var self = e.data.self; 18999 self._onfocus = self._dragging = false; 19000 if (self.cFlag._nd) { 19001 if (self.fixMoz) { 19002 self.correctTransValue(); 19003 } 19004 if (e.type == 'mousedown') { 19005 self.offX = e.pageX - self.$holder.offset().left - self.$image.position().left; 19006 self.offY = e.pageY - self.$holder.offset().top - self.$image.position().top; 19007 $(document).bind(self.event_move + self.id, {self: self}, self.mouseDrag); 19008 } else { 19009 var te = e.originalEvent; 19010 if (te.targetTouches.length > 1) { 19011 self._pinching = true; 19012 self._rA = self.rA; 19013 self.dStart = self.getDistance(te.touches[0].pageX, te.touches[0].pageY, te.touches[1].pageX, te.touches[1].pageY); 19014 } else { 19015 self.offX = te.touches[0].pageX - self.$holder.offset().left - self.$image.position().left; 19016 self.offY = te.touches[0].pageY - self.$holder.offset().top - self.$image.position().top; 19017 self.setDraggedPos(te.touches[0].pageX - self.$holder.offset().left - self.offX, te.touches[0].pageY - self.$holder.offset().top - self.offY, self._sc);
19018 self._recent = 'drag'; 19019 self._dragging = true; 19020 } 19021 } 19022 self._onHitArea = true; 19023 } 19024 e.preventDefault(); 19025 if (e.type !== 'mousedown') { 19026 e.stopPropagation(); 19027 } 19028 }, 19029 /*Mouse Drag / Touch swipe operations handled here 19030 ***********************************************************************************************************************/ 19031 mouseDrag: function(e) { 19032 var self = e.data.self; 19033 19034 //Mouse 19035 if (e.type == 'mousemove') { 19036 self.setDraggedPos(e.pageX - self.$holder.offset().left - self.offX, e.pageY - self.$holder.offset().top - self.offY, self._sc); 19037 self._recent = 'drag'; 19038 self._dragging = true; 19039 if (!self._playing) { 19040 self.Animate(); 19041 } 19042 return false; 19043 19044 //Touch 19045 } else { 19046 if (self._dragging || self._pinching) { 19047 e.preventDefault(); 19048 } 19049 if (self._onHitArea) { 19050 var touches = e.originalEvent.touches; 19051 if (self._pinching || touches.length > 1) { 19052 if (!self._pinching) { 19053 self._pinching = true; 19054 self._rA = self.rA; 19055 if (touches.length > 1) { 19056 self.dStart = self.getDistance(touches[0].pageX, touches[0].pageY, touches[1].pageX, touches[1].pageY); 19057 } 19058 } 19059 if (touches.length > 1) { 19060 self._centx = (touches[0].pageX + touches[1].pageX) / 2; 19061 self._centy = (touches[0].pageY + touches[1].pageY) / 2; 19062 self.focusOffX = self._centx - self.$holder.offset().left - (self.sW / 2); 19063 self.focusOffY = self._centy - self.$holder.offset().top - (self.sH / 2); 19064 self.changeOffset(true, true); 19065 self._wheel = true; 19066 self._dragging = false; 19067 if (self.zoom_single) { 19068 self.sRed = 300; 19069 19070 } else { 19071 self.dEnd = self.getDistance(touches[0].pageX, touches[0].pageY, touches[1].pageX, touches[1].pageY); 19072 self.rA = self._rA * (self.dEnd / self.dStart); 19073 self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA; 19074 self.rA = self.rA < self.rF ? self.rF : self.rA; 19075 } 19076 if (self._sc < self.rA) { 19077 self.cFlag._zo = false; 19078 self.cFlag._zi = true; 19079 } else { 19080 self.cFlag._zi = false; 19081 self.cFlag._zo = true; 19082 } 19083 if (!self._playing) { 19084 self.Animate(); 19085 } 19086 } 19087 19088 } else if (self._dragging && touches.length < 2) { 19089 self.setDraggedPos(touches[0].pageX - self.$holder.offset().left - self.offX, touches[0].pageY - self.$holder.offset().top - self.offY, self._sc); 19090 self._recent = 'drag'; 19091 if (!self._playing) { 19092 self.Animate(); 19093 } 19094 } 19095 } 19096 } 19097 }, 19098 /*Global Mouse Up / Touch End 19099 ***********************************************************************************************************************/ 19100 mouseUp: function(e) { 19101 var self = e.data.self; 19102 19103 //If one of the buttons released 19104 if (self._onButton) { 19105 self.$holder.find('#' + self.buttons[self.cButtId]._var + 'norm').show(); 19106 self.$holder.find('#' + self.buttons[self.cButtId]._var + 'over').hide(); 19107 if (self.cButtId !== 6) { 19108 self.cFlag[self.buttons[self.cButtId]._var] = false; 19109 } 19110 if (e.type == 'touchend' && self.buttons[self.cButtId].$ob.css('opacity') > .5) { 19111 self.buttons[self.cButtId].$ob.css('opacity', .7); 19112 } 19113 self._onButton = false; 19114 e.stopPropagation(); 19115 return false; 19116 19117 //If the mouse drag or touch swipe completed 19118 } else if (self._onHitArea) { 19119 if (self.mouse_drag || self.touch_drag) { 19120 //Mouse 19121 if (e.type == 'mouseup') { 19122 $(document).unbind(self.event_move + self.id); 19123 self._recent = 'drag'; 19124 self._dragging = false; 19125 if (!self._playing) { 19126 self.Animate(); 19127 } 19128 self._onHitArea = false; 19129 19130 //Touch 19131 } else { 19132 e.preventDefault(); 19133 self._dragging = false; 19134 if (self._pinching) { 19135 self._pinching = false; 19136 self._wheel = false; 19137 self.cFlag._nd = true; 19138 self.cFlag._zi = false; 19139 self.cFlag._zo = false; 19140 } else { 19141 self._recent = 'drag'; 19142 if (!self._playing) { 19143 self.Animate(); 19144 } 19145 } 19146 self._onHitArea = false; 19147 } 19148 } 19149 } 19150 }, 19151 /*Mouse wheel zoom in-out 19152 ***********************************************************************************************************************/ 19153 mouseWheel: function(e, delta) { 19154 var self = e.data.self; 19155 self._onfocus = self._dragging = false; 19156 if (self.mouse_wheel_cur) { 19157 self.focusOffX = e.pageX - self.$holder.offset().left - (self.sW / 2); 19158 self.focusOffY = e.pageY - self.$holder.offset().top - (self.sH / 2); 19159 self.changeOffset(true, true); 19160 } 19161 19162 self._dragging = false; 19163 if (delta > 0) { 19164 if (self.rA != self.zoom_max) { 19165 if (self.zoom_single) { 19166 if (!self._wheel) { 19167 self.sRed = 300; 19168 } 19169 } else { 19170 self.rA *= delta < 1 ? 1 + (.3 * delta) : 1.3; 19171 self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA; 19172 } 19173 self._wheel = true; 19174 self.cFlag._zi = true; 19175 clearTimeout(self.ani_timer); 19176 self._playing = true; 19177 self.Animate(); 19178 self.cFlag._zi = false; 19179 } 19180 } else { 19181 if (self.rA != self.rF) { 19182 if (self.zoom_single) { 19183 if (!self._wheel) { 19184 self.sRed = 300; 19185 } 19186 } else { 19187 self.rA /= delta > -1 ? 1 + (.3 * -delta) : 1.3; 19188 self.rA = self.rA < self.rF ? self.rF : self.rA; 19189 } 19190 self._wheel = true; 19191 self.cFlag._zo = true; 19192 clearTimeout(self.ani_timer); 19193 self._playing = true; 19194 self.Animate(); 19195 self.cFlag._zo = false; 19196 } 19197 } 19198 return false; 19199 }, 19200 /*Control buttons Auto hide 19201 ***********************************************************************************************************************/ 19202 autoHide: function(e) { 19203 var self = e.data.self; 19204 19205 clearTimeout(self.auto_timer); 19206 self.auto_timer = setTimeout(function() { 19207 self.$controls.fadeOut(600); 19208 }, self.bu_delay); 19209 19210 self.$holder.bind('mouseenter.sz', function(e) { 19211 clearTimeout(self.auto_timer); 19212 self.$controls.fadeIn(300); 19213 }); 19214 }, 19215 /*Mozilla works differently than others when getting translated positions. So this correction needed 19216 ***********************************************************************************************************************/ 19217 correctTransValue: function() { 19218 var v = this.$image.css('-moz-transform').toString().replace(')', '').split(','); 19219 this.transOffX = parseInt(v[4]); 19220 this.transOffY = parseInt(v[5]); 19221 }, 19222 /*Make sure the dragged position obeying limits 19223 ***********************************************************************************************************************/ 19224 setDraggedPos: function(xp, yp, s) { 19225 var self = this; 19226 19227 if (xp !== '') { 19228 self.dX = xp + self.transOffX; 19229 if (self.pan_limit) { 19230 self.dX = self.dX + (s * self.iW) < self.sW ? self.sW - (s * self.iW) : self.dX; 19231 self.dX = self.dX > 0 ? 0 : self.dX; 19232 if ((s * self.iW) < self.sW) { 19233 self.dX = (self.sW - (s * self.iW)) / 2; 19234 } 19235 } else { 19236 self.dX = self.dX + (s * self.iW) < self.sW / 2 ? (self.sW / 2) - (s * self.iW) : self.dX; 19237 self.dX = self.dX > self.sW / 2 ? self.sW / 2 : self.dX; 19238 } 19239 } 19240 if (yp !== '') { 19241 self.dY = yp + self.transOffY; 19242 if (self.pan_limit) { 19243 self.dY = self.dY + (s * self.iH) < self.sH ? self.sH - (s * self.iH) : self.dY; 19244 self.dY = self.dY > 0 ? 0 : self.dY; 19245 if ((s * self.iH) < self.sH) { 19246 self.dY = (self.sH - (s * self.iH)) / 2; 19247 } 19248 } else { 19249 self.dY = self.dY + (s * self.iH) < self.sH / 2 ? (self.sH / 2) - (s * self.iH) : self.dY; 19250 self.dY = self.dY > self.sH / 2 ? self.sH / 2 : self.dY; 19251 } 19252 } 19253 }, 19254 /*Called to animate image transformation whenever the navigation events occur 19255 ***********************************************************************************************************************/ 19256 Animate: function() { 19257 19258 var self = this; 19259 var pixTol = .5; 19260 19261 self.cFlag._nd = true; 19262 self.ani_end = false; 19263 19264 //Zoom In 19265 if (self.cFlag._zi) { 19266 if (!self._wheel && !self.zoom_single) { 19267 self.rA *= self.zoom_speed; 19268 } 19269 if (self.rA > self.zoom_max) { 19270 self.rA = self.zoom_max; 19271 } 19272 self.cFlag._nd = false; 19273 self.cFlag._rs = false; 19274 self._recent = 'zoomIn'; 19275 self._onfocus = self._dragging = false; 19276 } 19277 19278 //Zoom Out 19279 if (self.cFlag._zo) { 19280 if (!self._wheel && !self.zoom_single) { 19281 self.rA /= self.zoom_speed; 19282 } 19283 if (self.rA < self.rF) { 19284 self.rA = self.rF; 19285 } 19286 self.cFlag._nd = false; 19287 self.cFlag._rs = false; 19288 self._recent = 'zoomOut'; 19289 self._onfocus = self._dragging = false; 19290 } 19291 19292 //Zoom In or Out - Single Step 19293 if (self.zoom_single && !self.cFlag._rs) { 19294 if (self._recent == 'zoomIn') { 19295 self.sRed += (10 - self.sRed) / 6; 19296 self.rA += (self.zoom_max - self.rA) / (((1 / (self.pan_speed_o + 1)) * self.sRed) + 1); 19297 19298 } else if (self._recent == 'zoomOut') { 19299 self.sRed += (3 - self.sRed) / 3; 19300 self.rA += (self.rF - self.rA) / (((1 / self.pan_speed_o + 1) * self.sRed) + 1); 19301 } 19302 } 19303 19304 //Pan speed needs to adjust according to application dimension and zoom level 19305 self.pan_speed = (Math.max(1, 1 + ((self.sW + self.sH) / 500)) + (self.pan_speed_o * self.pan_speed_o / 4)) / Math.max(1, self.rA / 2); 19306 19307 //Move Left 19308 if (self.cFlag._ml) { 19309 self.oX -= self.pan_speed; 19310 self.cFlag._nd = false; 19311 self.cFlag._rs = false; 19312 self._recent = 'left'; 19313 self._onfocus = self._dragging = false; 19314 } 19315 19316 //Move Right 19317 if (self.cFlag._mr) { 19318 self.oX += self.pan_speed; 19319 self.cFlag._nd = false; 19320 self.cFlag._rs = false; 19321 self._recent = 'right'; 19322 self._onfocus = self._dragging = false; 19323 } 19324 19325 //Move Up 19326 if (self.cFlag._mu) { 19327 self.oY -= self.pan_speed; 19328 self.cFlag._nd = false; 19329 self.cFlag._rs = false; 19330 self._recent = 'up'; 19331 self._onfocus = self._dragging = false; 19332 } 19333 19334 //Move Down 19335 if (self.cFlag._md) { 19336 self.oY += self.pan_speed; 19337 self.cFlag._nd = false; 19338 self.cFlag._rs = false; 19339 self._recent = 'down'; 19340 self._onfocus = self._dragging = false; 19341 } 19342 19343 //Reset 19344 if (self.cFlag._rs) { 19345 self.oX += (self.fX - self.oX) / 8; 19346 self.oY += (self.fY - self.oY) / 8; 19347 self.cFlag._nd = false; 19348 self._recent = 'reset'; 19349 self._onfocus = self._dragging = false; 19350 } 19351 19352 //Find scale value, width and height 19353 //Case 1: Single Step Zoom 19354 if (self.zoom_single && (self._recent !== 'reset')) { 19355 if (self._onfocus) { 19356 self._sc += (self.rA - self._sc) / self.reduction; 19357 } else { 19358 self._sc = self.rA; 19359 } 19360 19361 //Case 2: Normal Zoom 19362 } else { 19363 self._sc += (self.rA - self._sc) / (self.ani_smooth / (self._onfocus ? self.reduction : 1)); 19364 } 19365 19366 self._w = self._sc * self.iW; 19367 self._h = self._sc * self.iH; 19368 19369 //Dragging 19370 if (self._dragging) { 19371 self.tX = self.dX; 19372 self.tY = self.dY; 19373 self.changeOffset(true, true); 19374 } 19375 19376 //Check if Zoom In completed 19377 if (self._recent == "zoomIn") { 19378 if (self._w > (self.rA * self.iW) - pixTol && !self.zoom_single) { 19379 if (self.cFlag._nd) { 19380 self.ani_end = true; 19381 } 19382 self._sc = self.rA; 19383 } else if (self._w > (self.zoom_max * self.iW) - pixTol && self.zoom_single) { 19384 if (self.cFlag._nd) { 19385 self.ani_end = true; 19386 } 19387 self._sc = self.rA = self.zoom_max; 19388 }
19389 if (self.ani_end) { 19390 self._w = self._sc * self.iW; 19391 self._h = self._sc * self.iH; 19392 } 19393 19394 //Check if Zoom Out completed 19395 } else if (self._recent == "zoomOut") { 19396 if (self._w < (self.rA * self.iW) + pixTol && !self.zoom_single) { 19397 if (self.cFlag._nd) { 19398 self.ani_end = true; 19399 } 19400 self._sc = self.rA; 19401 } else if (self._w < (self.rF * self.iW) + pixTol && self.zoom_single) { 19402 if (self.cFlag._nd) { 19403 self.ani_end = true; 19404 } 19405 self._sc = self.rA = self.rF; 19406 } 19407 if (self.ani_end) { 19408 self._w = self._sc * self.iW; 19409 self._h = self._sc * self.iH; 19410 } 19411 } 19412 19413 //Move image according to boundary limits 19414 self.limitX = (((self._w - self.sW) / (self._w / self.sW)) / 2); 19415 self.limitY = (((self._h - self.sH) / (self._h / self.sH)) / 2); 19416 19417 if (!self._dragging) { 19418 if (self.pan_limit) { 19419 if (self.oX < -self.limitX - self.focusOffX) { 19420 self.oX = -self.limitX - self.focusOffX; 19421 } 19422 if (self.oX > self.limitX - self.focusOffX) { 19423 self.oX = self.limitX - self.focusOffX; 19424 } 19425 if (self._w < self.sW) { 19426 self.tX = (self.sW - self._w) / 2; 19427 self.changeOffset(true, false); 19428 } 19429 if (self.oY < -self.limitY - self.focusOffY) { 19430 self.oY = -self.limitY - self.focusOffY; 19431 } 19432 if (self.oY > self.limitY - self.focusOffY) { 19433 self.oY = self.limitY - self.focusOffY; 19434 } 19435 if (self._h < self.sH) { 19436 self.tY = (self.sH - self._h) / 2; 19437 self.changeOffset(false, true); 19438 } 19439 } else { 19440 if (self.oX < -self.limitX - (self.focusOffX / self._w * self.sW) - ((self.sW / 2) / (self._w / self.sW))) { 19441 self.oX = -self.limitX - (self.focusOffX / self._w * self.sW) - ((self.sW / 2) / (self._w / self.sW)); 19442 } 19443 19444 if (self.oX > self.limitX - (self.focusOffX / self._w * self.sW) + ((self.sW / 2) / (self._w / self.sW))) { 19445 self.oX = self.limitX - (self.focusOffX / self._w * self.sW) + ((self.sW / 2) / (self._w / self.sW)); 19446 } 19447 19448 if (self.oY < -self.limitY - (self.focusOffY / self._h * self.sH) - (self.sH / (self._h / self.sH * 2))) { 19449 self.oY = -self.limitY - (self.focusOffY / self._h * self.sH) - (self.sH / (self._h / self.sH * 2)); 19450 } 19451 19452 if (self.oY > self.limitY - (self.focusOffY / self._h * self.sH) + (self.sH / (self._h / self.sH * 2))) { 19453 self.oY = self.limitY - (self.focusOffY / self._h * self.sH) + (self.sH / (self._h / self.sH * 2)); 19454 } 19455 } 19456 } 19457 if (!self._dragging && self._recent != "drag") { 19458 self.tX = ((self.sW - self._w) / 2) + self.focusOffX + (self.oX * (self._w / self.sW)); 19459 self.tY = ((self.sH - self._h) / 2) + self.focusOffY + (self.oY * (self._h / self.sH)); 19460 if (self.ani_smooth === 1) { 19461 self.cFlag._nd = true; 19462 self.ani_end = true; 19463 } 19464 } 19465 if (self._recent == "zoomIn" || self._recent == "zoomOut" || self.cFlag._rs) { 19466 self._x = self.tX; 19467 self._y = self.tY; 19468 } else { 19469 self._x += (self.tX - self._x) / (self.ani_smooth / (self._onfocus ? self.reduction : 1)); 19470 self._y += (self.tY - self._y) / (self.ani_smooth / (self._onfocus ? self.reduction : 1)); 19471 } 19472 19473 //Check if Left movement completed 19474 if (self._recent == "left") { 19475 if (self._x < self.tX + pixTol || self.ani_smooth === 1) { 19476 self.cFlag._nd ? self.ani_end = true : ""; 19477 self._recent = ''; 19478 self._x = self.tX; 19479 } 19480 19481 //Check if Right movement completed 19482 } else if (self._recent == "right") { 19483 if (self._x > self.tX - pixTol || self.ani_smooth === 1) { 19484 self.cFlag._nd ? self.ani_end = true : ""; 19485 self._recent = ''; 19486 self._x = self.tX; 19487 } 19488 19489 //Check if Up movement completed 19490 } else if (self._recent == "up") { 19491 if (self._y < self.tY + pixTol || self.ani_smooth === 1) { 19492 self.cFlag._nd ? self.ani_end = true : ""; 19493 self._recent = ''; 19494 self._y = self.tY; 19495 } 19496 19497 //Check if Down movement completed 19498 } else if (self._recent == "down") { 19499 if (self._y > self.tY - pixTol || self.ani_smooth === 1) { 19500 self.cFlag._nd ? self.ani_end = true : ""; 19501 self._recent = ''; 19502 self._y = self.tY; 19503 } 19504 19505 //Check if Dragging completed 19506 } else if (self._recent == "drag") { 19507 if (self._x + pixTol >= self.tX && self._x - pixTol <= self.tX && self._y + pixTol >= self.tY && self._y - pixTol <= self.tY || self.ani_smooth === 1) { 19508 if (self._onfocus) { 19509 self._dragging = false; 19510 } 19511 self.cFlag._nd ? self.ani_end = true : ""; 19512 self._recent = ''; 19513 self._x = self.tX; 19514 self._y = self.tY; 19515 } 19516 } 19517 19518 //Check if Reset completed 19519 if (self.cFlag._rs && self._w + pixTol >= (self.rA * self.iW) && self._w - pixTol <= (self.rA * self.iW) && self.oX <= self.fX + pixTol && self.oX >
19519= self.fX - pixTol && self.oY <= self.fY + pixTol && self.oY >= self.fY - pixTol) { 19520 self.ani_end = true; 19521 self._recent = ''; 19522 self.cFlag._rs = false; 19523 self.cFlag._nd = true; 19524 self._x = self.tX; 19525 self._y = self.tY; 19526 self._sc = self.rA; 19527 self._w = self._sc * self.iW; 19528 self._h = self._sc * self.iH; 19529 } 19530 19531 //When the image fits exactly to container size, disable the pan, zoom out and reset buttons 19532 if (self.rA == self.rF && self.iW * self.rA <= self.sW && self.iH * self.rA <= self.sH) { 19533 if (self.buttons[1].$ob.css('opacity') > .5) { 19534 if (self.rA >= self.rF && (self.init_zoom == '' || self.rA < self.init_zoom) && (self.zoom_min == '' || self.rA < self.zoom_min)) { 19535 if (self.pan_limit && self._moveCursor && !self._moveCursor) { 19536 self.$image.css('cursor', 'default'); 19537 self.$hitArea.css('cursor', 'default'); 19538 } 19539 for (var bEn = 1; bEn < (self.pan_limit && !self._moveCursor ? self.buttons_total : 2); bEn++) { 19540 self.buttons[bEn].$ob.css({ 19541 'opacity': .4 19542 }); 19543 self._wheel = false; 19544 self.$holder.find('#' + self.buttons[bEn]._var + 'norm').show(); 19545 self.$holder.find('#' + self.buttons[bEn]._var + 'over').hide(); 19546 } 19547 } 19548 } 19549 19550 } else { 19551 if (self.buttons[1].$ob.css('opacity') < .5) { 19552 if (self._moveCursor && self.mouse_drag) { 19553 self.$image.css('cursor', 'move'); 19554 self.$hitArea.css('cursor', 'move'); 19555 } 19556 for (var bEn = 1; bEn < self.buttons_total; bEn++) { 19557 self.buttons[bEn].$ob.css('opacity', .7); 19558 } 19559 } 19560 } 19561 19562 //When the image reaches max zoom, disable the zoom button 19563 if (self.rA == self.zoom_max) { 19564 if (self.buttons[0].$ob.css('opacity') > .5) { 19565 self.buttons[0].$ob.css('opacity', .4); 19566 self._wheel = false; 19567 self.$holder.find('#' + self.buttons[0]._var + 'norm').show(); 19568 self.$holder.find('#' + self.buttons[0]._var + 'over').hide(); 19569 } 19570 19571 } else { 19572 if (self.buttons[0].$ob.css('opacity') < .5) { 19573 self.buttons[0].$ob.css('opacity', .7); 19574 } 19575 } 19576 19577 //Apply Scale and position to the image: 19578 if (prop_transform) { 19579 self.$image.css(prop_transform, 'translate(' + self._x.toFixed(14) + 'px,' + self._y.toFixed(14) + 'px) scale(' + self._sc + ')'); 19580 19581 } else { 19582 self.$image.css({ 19583 left: self._x, 19584 top: self._y, 19585 width: self._w, 19586 height: self._h 19587 }); 19588 } 19589 19590 if (self.$loc_cont) { 19591 self.updateLocations(self._x, self._y, self._sc, self.locations); 19592 } 19593 19594 //In case image Maps used, update them
19595 if (!prop_transform && self.map_coordinates.length > 0) { 19596 self.updateMap(); 19597 } 19598 //If the animation completed, stop running; else continue 19599 if (self.ani_end && !self._dragging && self._recent != "drag") { 19600 self._playing = false; 19601 self._recent = ''; 19602 self.cX = (-self._x + (self.sW / 2)) / self.rA; 19603 self.cY = (-self._y + (self.sH / 2)) / self.rA; 19604 if (self.onUPDATE) { 19605 self.onUPDATE(self.getZoomData(), false); 19606 } 19607 if (self.onZOOM_PAN) { 19608 self.onZOOM_PAN(self.getZoomData()); 19609 } 19610 clearTimeout(self.ani_timer); 19611 } else { 19612 self._playing = true; 19613 if (self.onUPDATE) { 19614 self.onUPDATE(self.getZoomData(), true); 19615 } 19616 self.ani_timer = setTimeout(function() { 19617 self.Animate(); 19618 }, 28); 19619 } 19620 }, 19621 /*Relocate the landmarks according to main image's position 19622 ***********************************************************************************************************************/ 19623 updateLocations: function(_x, _y, _sc, loc) { 19624 19625 if (this.onLANDMARK !== '') { 19626 if (_sc >= this.show_at_zoom) { 19627 if (!this._landmark) { 19628 this._landmark = true 19629 this.onLANDMARK(true); 19630 } 19631 } else { 19632 if (this._landmark) { 19633 this._landmark = false; 19634 this.onLANDMARK(false); 19635 } 19636 } 19637 } 19638 19639 for (var p = 0; p < loc.length; p++) { 19640 var wScaled, 19641 hScaled, 19642 lpx = (loc[p].x * _sc) + _x, 19643 lpy = (loc[p].y * _sc) + _y; 19644 19645 if (_sc >= loc[p].showAt) { 19646 if (loc[p].scale && prop_transform) { 19647 wScaled = loc[p].w2pad * this._sc; 19648 hScaled = loc[p].h2 * this._sc; 19649 } else { 19650 wScaled = loc[p].w2pad; 19651 hScaled = loc[p].h2; 19652 } 19653 if (lpx > -wScaled && lpx < this.sW + wScaled && ((lpy > -hScaled && lpy < this.sH + hScaled && loc[p].lab) || (lpy > 0 && lpy < this.sH + (hScaled * 2) && !loc[p].lab))) { 19654 if (!loc[p].vis) { 19655 loc[p].vis = true; 19656 if (prop_transform) { 19657 loc[p].ob.stop() 19658 .css('display', 'block') 19659 .animate({ 19660 opacity: 1 19661 }, 300); 19662 } else { 19663 loc[p].ob.show(); 19664 } 19665 } 19666 } else { 19667 if (loc[p].vis) { 19668 loc[p].vis = false; 19669 if (prop_transform) { 19670 loc[p].ob.stop() 19671 .animate({ 19672 opacity: 0 19673 }, 200, function() { 19674 $(this).hide(); 19675 }); 19676 } else { 19677 loc[p].ob.hide(); 19678 } 19679 } 19680 } 19681 } else { 19682 if (loc[p].vis) { 19683 loc[p].vis = false; 19684 if (prop_transform) { 19685 loc[p].ob.stop() 19686 .animate({ 19687 opacity: 0 19688 }, 200, function() { 19689 $(this).hide(); 19690 }); 19691 } else { 19692 loc[p].ob.hide(); 19693 } 19694 } 19695 } 19696 if (lpx !== loc[p].lpx || lpy !== loc[p].lpy && loc[p].vis) { 19697 if (prop_transform) { 19698 loc[p].ob.css(prop_transform, 'translate(' + lpx.toFixed(14) + 'px,' + lpy.toFixed(14) + 'px)' + (loc[p].scale ? ' scale(' + this._sc + ')' : '')); 19699 } else { 19700 loc[p].ob.css({ 19701 left: lpx, 19702 top: lpy 19703 }); 19704 } 19705 } 19706 loc[p].lpx = lpx; 19707 loc[p].lpy = lpy; 19708 } 19709 }, 19710 /*If the broswer doesn't supports css border radius, we need to go with old school png image for roun
19710ded corner 19711 ***********************************************************************************************************************/ 19712 roundBG: function(el, _name, _w, _h, _r, _p, _c, _i, _z, _yoff) { 19713 var w = 50 / 2; 19714 19715 el.append($( 19716 '<div class="bgi' + _name + '" style="background-position:' + (-(_p - _r)) + 'px ' + (-(w - _r) - _yoff) + 'px"></div>\ 19717 <div class="bgh' + _name + '"></div>\ 19718 <div class="bgi' + _name + '" style="background-position:' + (-_p) + 'px ' + (-(w - _r) - _yoff) + 'px; left:' + (_w - _r) + 'px"></div>\ 19719 <div class="bgi' + _name + '" style="background-position:' + (-(_p - _r)) + 'px ' + (-w - _yoff) + 'px; top:' + (_h - _r) + 'px"></div>\ 19720 <div class="bgh' + _name + '" style = "top:' + (_h - _r) + 'px; left:' + _r + 'px"></div>\ 19721 <div class="bgi' + _name + '" style="background-position:' + (-_p) + 'px ' + (-w - _yoff) + 'px; top:' + (_h - _r) + 'px; left:' + (_w - _r) + 'px"></div>\ 19722 <div class="bgc' + _name + '"></div>' 19723 )); 19724 $('.bgi' + _name).css({ 19725 position: 'absolute', 19726 width: _r, 19727 height: _r, 19728 'background-image': 'url(' + _i + ')', 19729 'background-repeat': 'no-repeat', 19730 '-ms-filter': 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)', 19731 'filter': 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)', 19732 'zoom': 1 19733 }); 19734 $('.bgh' + _name).css({ 19735 position: 'absolute', 19736 width: _w - _r * 2, 19737 height: _r, 19738 'background-color': _c, 19739 left: _r 19740 }); 19741 $('.bgc' + _name).css({ 19742 position: 'absolute', 19743 width: _w, 19744 height: _h - _r * 2, 19745 'background-color': _c, 19746 top: _r, 19747 left: 0 19748 }); 19749 }, 19750 /*To calibrate position offset when navigation events supposed to be overlapped 19751 ***********************************************************************************************************************/ 19752 changeOffset: function(x, y) { 19753 if (x) 19754 this.oX = (this.tX - ((this.sW - this._w) / 2) - this.focusOffX) / (this._w / this.sW); 19755 if (y) 19756 this.oY = (this.tY - ((this.sH - this._h) / 2) - this.focusOffY) / (this._h / this.sH); 19757 }, 19758 /*Transform Image Maps (hot spots) if any 19759 ***********************************************************************************************************************/ 19760 updateMap: function() { 19761 var self = this, 19762 mapId = 0; 19763 19764 self.mapAreas.each(function() { 19765 var new_vals = []; 19766 for (var i = 0; i < self.map_coordinates[mapId].length; i++) { 19767 new_vals[i] = self.map_coordinates[mapId][i] * self._sc; 19768 } 19769 new_vals = new_vals.join(","); 19770 $(this).attr('coords', new_vals); 19771 mapId++; 19772 }); 19773 }, 19774 /*To stop the timer loops immediatly 19775 ***********************************************************************************************************************/ 19776 haltAnimation: function() { 19777 clearTimeout(this.ani_timer); 19778 this._playing = false; 19779 this._recent = ''; 19780 }, 19781 /*Method to Remove the plugin instance 19782 ***********************************************************************************************************************/ 19783 destroy: function() { 19784 var self = this; 19785 19786 if (self.assetsLoaded) { 19787 self.haltAnimation(); 19788 for (prop in self.orig_style) { 19789 if (self.orig_style[prop][0] !== false && self.orig_style[prop][0] !== undefined) { 19790 if (self.orig_style[prop][0] === 'width' || self.orig_style[prop][0] === 'height') { 19791 if (parseInt(self.orig_style[prop][1]) !== 0) { 19792 self.$image.css(self.orig_style[prop][0], self.orig_style[prop][1]); 19793 } 19794 } else { 19795 self.$image.css(self.orig_style[prop][0], self.orig_style[prop][1]); 19796 } 19797 } 19798 } 19799 clearTimeout(self.auto_timer); 19800 $(document).unbind('.sz' + self.id); 19801 $(window).unbind('.sz' + self.id); 19802 self.$holder.unbind('.sz'); 19803 self.$controls = undefined; 19804 } else { 19805 self.$image.show(); 19806 } 19807 19808 if (self.container == '') { 19809 if (self.image_url == '') { 19810 self.$image.insertBefore(self.$holder); 19811 if (self.$holder !== undefined) { 19812 self.$holder.remove(); 19813 } 19814 } else { 19815 self.$elem.empty(); 19816 if (self.$loc_cont[0]) { 19817 self.$elem.append(self.loc_clone); 19818 } 19819 } 19820 } else { 19821 self.$image.insertBefore(self.$holder); 19822 self.$holder.empty(); 19823 self.$image.wrap(self.$holder); 19824 if (self.$loc_cont[0]) { 19825 self.$holder.append(self.loc_clone); 19826 } 19827 } 19828 self.$elem.removeData('smoothZoom'); 19829 self.$holder = undefined; 19830 self.Buttons = undefined; 19831 self.op = undefined; 19832 self.$image = undefined; 19833 }, 19834 /*Method to change focus point and level 19835 ***********************************************************************************************************************/ 19836 focusTo: function(params) { 19837 var self = this; 19838 19839 if (self.assetsLoaded) { 19840 if (params.zoom === undefined || params.zoom === '' || params.zoom == 0) { 19841 params.zoom = self.rA; 19842 } else { 19843 params.zoom /= 100; 19844 } 19845 self._onfocus = true; 19846 if (params.zoom > self.rA && self.rA != self.zoom_max) { 19847 self.rA = params.zoom; 19848 self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA; 19849 } else if (params.zoom < self.rA && self.rA != self.rF) { 19850 self.rA = params.zoom; 19851 self.rA = self.rA < self.rF ? self.rF : self.rA; 19852 } 19853 self.transOffX = self.transOffY = 0; 19854 self.setDraggedPos(params.x === undefined || params.x === '' ? "" : (-params.x * self.rA) + (self.sW / 2), params.y === undefined || params.y === '' ? "" : (-params.y * self.rA) + (self.sH / 2), self.rA); 19855 self.reduction = params.speed ? params.speed / 10 : self.focusSpeed; 19856 self._recent = 'drag'; 19857 self._dragging = true; 19858 if (!self._playing) { 19859 self.Animate(); 19860 } 19861 } 19862 }, 19863 zoomIn: function(params) { 19864 this.buttons[0].$ob.trigger(this.event_down, { 19865 id: 0 19866 }); 19867 }, 19868 zoomOut: function(params) { 19869 this.buttons[1].$ob.trigger(this.event_down, { 19870 id: 1 19871 }); 19872 }, 19873 moveRight: function(params) { 19874 this.buttons[2].$ob.trigger(this.event_down, { 19875 id: 2 19876 }); 19877 }, 19878 moveLeft: function(params) { 19879 this.buttons[3].$ob.trigger(this.event_down, { 19880 id: 3 19881 }); 19882 }, 19883 moveUp: function(params) { 19884 this.buttons[4].$ob.trigger(this.event_down, { 19885 id: 4 19886 }); 19887 }, 19888 moveDown: function(params) { 19889 this.buttons[5].$ob.trigger(this.event_down, { 19890 id: 5 19891 }); 19892 }, 19893 Reset: function(params) { 19894 this.buttons[6].$ob.trigger(this.event_down, { 19895 id: 6 19896 }); 19897 }, 19898 getZoomData: function(params) { 19899 return { 19900 //x offset (without scale ratio multiplied) 19901 normX: (-this._x / this.rA).toFixed(14), 19902 //y offset (without scale ratio multiplied) 19903 normY: (-this._y / this.rA).toFixed(14), 19904 //Original image Width 19905 normWidth: this.iW, 19906 //Original image height 19907 normHeight: this.iH, 19908 //x offset (with scale ratio multiplied) 19909 scaledX: -this._x.toFixed(14), 19910 //y offset (with scale ratio multiplied) 19911 scaledY: -this._y.toFixed(14), 19912 //Scaled image width 19913 scaledWidth: this._w, 19914 //Scaled image height 19915 scaledHeight: this._h, 19916 //The X location on image which is currently on center of canvas 19917 centerX: (-this._x.toFixed(14) + (this.sW / 2)) / this.rA, 19918 //The Y location on image which is currently on center of canvas 19919 centerY: (-this._y.toFixed(14) + (this.sH / 2)) / this.rA, 19920 //Scale ratio 19921 ratio: this.rA 19922 }; 19923 }, 19924 addLandmark: function(loc) { 19925 if (this.$loc_cont) { 19926 var total = loc.length; 19927 19928 for (var i = 0; i < total; i++) { 19929 var $loc = $(loc[i]); 19930 this.$loc_cont.append($loc); 19931 this.setLocation($loc); 19932 } 19933 19934 if (total > 0) { 19935 this.updateLocations(this._x, this._y, this._sc, this.locations); 19936 } 19937 } 19938 }, 19939 attachLandmark: function(loc) { 19940 if (this.$loc_cont) { 19941 var total = loc.length; 19942 for (var i = 0; i < total; i++) { 19943 this.setLocation(loc[i] instanceof jQuery ? loc[i] : $('#' + loc[i])); 19944 } 19945 if (total > 0) { 19946 this.updateLocations(this._x, this._y, this._sc, this.locations); 19947 } 19948 } 19949 }, 19950 removeLandmark: function(loc) { 19951 if (this.$loc_cont) { 19952 if (loc) { 19953 var total = loc.length; 19954 for (var i = 0; i < total; i++) { 19955 for (var j = 0; j < this.locations.length; j++) { 19956 if ((loc[i] instanceof jQuery && this.locations[j].ob[0] == loc[i][0]) || (!(loc[i] instanceof jQuery) && this.locations[j].ob.attr('id') == loc[i])) { 19957 this.locations[j].ob.remove(); 19958 this.locations.splice(j, 1); 19959 j--; 19960 } 19961 } 19962 } 19963 } else { 19964 if (this.locations.length > 0) { 19965 this.locations[this.locations.length - 1].ob.remove(); 19966 this.locations.pop(); 19967 } 19968 } 19969 if (total > 0) { 19970 this.updateLocations(this._x, this._y, this._sc, this.locations); 19971 } 19972 } 19973 }, 19974 refreshAllLandmarks: function() { 19975 var self = this; 19976 var locs = self.$loc_cont.children('.item'); 19977 self.show_at_zoom = parseInt(self.$loc_cont.data('show-at-zoom'), 10) / 100; 19978 self.allow_scale = checkBoolean(self.$loc_cont.data('allow-scale')); 19979 self.allow_drag = checkBoolean(self.$loc_cont.data('allow-drag')); 19980 19981 //Step 1: Remove records for which the elements no longer exist 19982 for (var i = 0; i < self.locations.length; i++) { 19983 var exists = false; 19984 locs.each(function() { 19985 if (self.locations[i].ob[0] == $(this)[0]) { 19986 exists = true; 19987 } 19988 }); 19989 if (!exists) { 19990 self.locations.splice(i, 1); 19991 i--; 19992 } 19993 } 19994 19995 //Step 2: Add new elements to record 19996 locs.each(function() { 19997 var exists = false; 19998 for (var i = 0; i < self.locations.length; i++) { 19999 if (self.locations[i].ob[0] == $(this)[0]) { 20000 exists = true; 20001 break; 20002 } 20003 } 20004 if (!exists) { 20005 self.setLocation($(this)); 20006 } 20007 20008 }); 20009 this.updateLocations(this._x, this._y, this._sc, this.locations); 20010 }, 20011 /*On windows resize, adjust some defaults 20012 ***********************************************************************************************************************/ 20013 resize: function(e) { 20014 var self; 20015 20016 if (e.data) { 20017 e.preventDefault(); 20018 self = e.data.self; 20019 var pw = self.$holder.parent().width(); 20020 var ph = self.$holder.parent().height(); 20021 20022 if (self.oW) { 20023 pw = Math.min(pw, self.oW); 20024 } 20025 self.sW = pw; 20026 20027 if (self.oH) { 20028 if (self.oW && self.maintain_ratio) { 20029 self.sH = pw / (self.oW / self.oH); 20030 } 20031 } else { 20032 self.sH = ph; 20033 } 20034 20035 20036 } else { 20037 self = this; 20038 if (e.width) { 20039 self.sW = e.width; 20040 } 20041 if (e.height) { 20042 self.sH = e.height; 20043 } 20044 if (e.max_WIDTH) { 20045 self.w_max = e.max_WIDTH; 20046 } 20047 if (e.max_HEIGHT) { 20048 self.h_max = e.max_HEIGHT; 20049 } 20050 } 20051 if (self.w_max !== 0 && self.w_max !== '') { 20052 self.sW = Math.min(self.sW, self.w_max); 20053 } 20054 if (self.h_max !== 0 && self.h_max !== '') { 20055 self.sH = Math.min(self.sH, self.h_max); 20056 } 20057 self.$holder.css({ 20058 'width': self.sW, 20059 'height': self.sH 20060 }); 20061 if (self.bord_size > 0) { 20062 self.border[0].height(self.sH); 20063 self.border[1].css({ 20064 height: self.sH, 20065 left: self.sW - self.bord_size 20066 }); 20067 self.border[2].width(self.sW - (self.bord_size * 2)); 20068 self.border[3].css({ 20069 width: self.sW - (self.bord_size * 2), 20070 top: self.sH - self.bord_size 20071 }); 20072 } 20073 if (self.bu_align[1] == 'center') { 20074 self.$controls.css('left', parseInt((self.sW - self.cBW) / 2)); 20075 } 20076 if (self.bu_align[0] == 'center') { 20077 self.$controls.css('top', parseInt((self.sH - self.cBH) / 2)); 20078 } 20079 20080 if (self.zoom_min == 0) { 20081 self.rF = self.checkRatio(self.sW, self.sH, self.iW, self.iH, self.zoom_fit); 20082 if (self.rA < self.rF) { 20083 self.rA = self.rF; 20084 } 20085 } 20086 20087 self.focusTo({ 20088 x: self.cX, 20089 y: self.cY, 20090 zoom: '', 20091 speed: 10 20092 }); 20093 } 20094 } 20095 20096 20097 $.fn.smoothZoom = function(params) { 20098 var self = this; 20099 var l = self.length; 20100 20101 //For single or more than one plugin instance 20102 for (var i = 0; i < l; i++) { 20103
20103 var $elem = $(self[i]); 20104 var instance = $elem.data('smoothZoom'); 20105 20106 // Case 1: Initiate the plugin if not already have an instance 20107 if (!instance) { 20108 20109 if (typeof params === 'object' || !params) { 20110 $elem.data('smoothZoom', new Zoomer($elem, params)); 20111 } 20112 20113 // Case 2: If the instance already available - Check for method call 20114 } else { 20115 20116 // getZoomData - Returns {sourceX, sourceY, sourceWidth, sourceHeight, distX, distY, distWidth, distHeight, centerX, centerY, ratio} 20117 if (params == "getZoomData") { 20118 return instance[params].apply(instance, Array.prototype.slice.call(arguments, 1)); 20119 20120 // destroy | focusTo | zoomIn | zoomOut | moveRight| moveLeft | moveUp | moveDown | Reset | addLandmark | removeLandmark | attachLandmark | refreshAllLandmarks 20121 } else if (instance[params]) { 20122 instance[params].apply(instance, Array.prototype.slice.call(arguments, 1)); 20123 } 20124 } 20125 } 20126 20127 //return for chainability for possible cases 20128 if (params !== "getZoomData") { 20129 return this; 20130 } 20131 }; 20132 20133 function checkBoolean(_var) { 20134 if (_var === true) { 20135 return true; 20136 } else if (_var) { 20137 _var = _var.toLowerCase(); 20138 if (_var == 'yes' || _var == 'true') { 20139 return true; 20140 } 20141 } 20142 return false; 20143 } 20144 20145 20146 //................................................................................................................... 20147 //Using Modernizr to check browser capabilities and property names prefixed 20148 20149 /* Modernizr 2.5.3 (Custom Build) | MIT & BSD 20150 * Build: http://www.modernizr.com/download/#-borderradius-csstransforms-csstransforms3d-touch-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes 20151 */ 20152 var Modernizr = function(a, b, c) { 20153 function y(a) { 20154 i.cssText = a 20155 } 20156 function z(a, b) { 20157 return y(l.join(a + ";") + (b || "")) 20158 } 20159 function A(a, b) { 20160 return typeof a === b 20161 } 20162 function B(a, b) { 20163 return!!~("" + a).indexOf(b) 20164 } 20165 function C(a, b) { 20166 for (var d in a) 20167 if (i[a[d]] !== c) 20168 return b == "pfx" ? a[d] : !0; 20169 return!1 20170 } 20171 function D(a, b, d) { 20172 for (var e in a) { 20173 var f = b[a[e]]; 20174 if (f !== c) 20175 return d === !1 ? a[e] : A(f, "function") ? f.bind(d || b) : f 20176 } 20177 return!1 20178 } 20179 function E(a, b, c) { 20180 var d = a.charAt(0).toUpperCase() + a.substr(1), e = (a + " " + n.join(d + " ") + d).split(" "); 20181 return A(b, "string") || A(b, "undefined") ? C(e, b) : (e = (a + " " + o.join(d + " ") + d).split(" "), D(e, b, c)) 20182 } 20183 var d = "2.5.3", e = {}, f = b.documentElement, g = "modernizr", h = b.createElement(g), i = h.style, j, k = {}.toString, l = " -webkit- -moz- -o- -ms- ".split(" "), m = "Webkit Moz O ms", n = m.split(" "), o = m.toLowerCase().split(" "), p = {}, q = {}, r = {}, s = [], t = s.slice, u, v = function(a, c, d, e) { 20184 var h, i, j, k = b.createElement("div"), l = b.body, m = l ? l : b.createElement("body"); 20185 if (parseInt(d, 10)) 20186 while (d--) 20187 j = b.createElement("div"), j.id = e ? e[d] : g + (d + 1), k.appendChild(j); 20188 return h = ["­", "<style>", a, "</style>"].join(""), k.id = g, (l ? k : m).innerHTML += h, m.appendChild(k), l || (m.style.background = "", f.appendChild(m)), i = c(k, a), l ? k.parentNode.removeChild(k) : m.parentNode.removeChild(m), !!i 20189 }, w = {}.hasOwnProperty, x; 20190 !A(w, "undefined") && !A(w.call, "undefined") ? x = function(a, b) { 20191 return w.call(a, b) 20192 } : x = function(a, b) { 20193 return b in a && A(a.constructor.prototype[b], "undefined") 20194 }, Function.prototype.bind || (Function.prototype.bind = function(b) { 20195 var c = this; 20196 if (typeof c != "function") 20197 throw new TypeError; 20198 var d = t.call(arguments, 1), e = function() { 20199 if (this instanceof e) { 20200 var a = function() { 20201 }; 20202 a.prototype = c.prototype; 20203 var f = new a, g = c.apply(f, d.concat(t.call(arguments))); 20204 return Object(g) === g ? g : f 20205 } 20206 return c.apply(b, d.concat(t.call(arguments))) 20207 }; 20208 return e 20209 }); 20210 var F = function(c, d) { 20211 var f = c.join(""), g = d.length; 20212 v(f, function(c, d) { 20213 var f = b.styleSheets[b.styleSheets.length - 1], h = f ? f.cssRules && f.cssRules[0] ? f.cssRules[0].cssText : f.cssText || "" : "", i = c.childNodes, j = {}; 20214 while (g--) 20215 j[i[g].id] = i[g]; 20216 e.touch = "ontouchstart"in a || a.DocumentTouch && b instanceof DocumentTouch || (j.touch && j.touch.offsetTop) === 9, e.csstransforms3d = (j.csstransforms3d && j.csstransforms3d.offsetLeft) === 9 && j.csstransforms3d.offsetHeight === 3 20217 }, g, d) 20218 }([, ["@media (", l.join("touch-enabled),("), g, ")", "{#touch{top:9px;position:absolute}}"].join(""), ["@media (", l.join("transform-3d),("), g, ")", "{#csstransforms3d{left:9px;position:absolute;height:3px;}}"].join("")], [, "touch", "csstransforms3d"]); 20219 p.touch = function() { 20220 return e.touch 20221 }
20221, p.borderradius = function() { 20222 return E("borderRadius") 20223 }, p.csstransforms = function() { 20224 return!!E("transform") 20225 }, p.csstransforms3d = function() { 20226 var a = !!E("perspective"); 20227 return a && "webkitPerspective"in f.style && (a = e.csstransforms3d), a 20228 }; 20229 for (var G in p) 20230 x(p, G) && (u = G.toLowerCase(), e[u] = p[G](), s.push((e[u] ? "" : "no-") + u)); 20231 return y(""), h = j = null, e._version = d, e._prefixes = l, e._domPrefixes = o, e._cssomPrefixes = n, e.testProp = function(a) { 20232 return C([a]) 20233 }, e.testAllProps = E, e.testStyles = v, e.prefixed = function(a, b, c) { 20234 return b ? E(a, b, c) : E(a, "pfx") 20235 }, e 20236 }(this, this.document); 20237 20238 var prop_transform = Modernizr.prefixed('transform'); 20239 var prop_origin = Modernizr.prefixed('transformOrigin'); 20240 var prop_radius = Modernizr.prefixed('borderRadius'); 20241 var supportsTrans3D = Modernizr.csstransforms3d; 20242 var supportsTouch = Modernizr.touch; 20243 20244})(jQuery, window, document); 20245 20246//End - smoothZoom 20247 20248//................................................................................................................... 20249//For mouse wheel support 20250 20251/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 20252 * Licensed under the MIT License (LICENSE.txt). 20253 * 20254 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 20255 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 20256 * Thanks to: Seamus Leahy for adding deltaX and deltaY 20257 * 20258 * Version: 3.0.6 20259 * 20260 * Requires: 1.2.2+ 20261 */ 20262//(function(a){function d(b){var c=b||window.event,d=[].slice.call(arguments,1),e=0,f=!0,g=0,h=0;return b=a.event.fix(c),b.type="mousewheel",c.wheelDelta&&(e=c.wheelDelta/120),c.detail&&(e=-c.detail/3),h=e,c.axis!==undefined&&c.axis===c.HORIZONTAL_AXIS&&(h=0,g=-1*e),c.wheelDeltaY!==undefined&&(h=c.wheelDeltaY/120),c.wheelDeltaX!==undefined&&(g=-1*c.wheelDeltaX/120),d.unshift(b,e,g,h),(a.event.dispatch||a.event.handle).apply(this,d)}var b=["DOMMouseScroll","mousewheel"];if(a.event.fixHooks)for(var c=b.length;c;)a.event.fixHooks[b[--c]]=a.event.mouseHooks;a.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=b.length;a;)this.addEventListener(b[--a],d,!1);else this.onmousewheel=d},teardown:function(){if(this.remove_eventListener)for(var a=b.length;a;)this.remove_eventListener(b[--a],d,!1);else this.onmousewheel=null}},a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery) 20263 20264//................................................................................................................... 20265/** 20266 * hoverIntent is similar to jQuery's built-in "hover" method except that 20267 * instead of firing the handlerIn function immediately, hoverIntent checks 20268 * to see if the user's mouse has slowed down (beneath the sensitivity 20269 * threshold) before firing the event. The handlerOut function is only 20270 * called after a matching handlerIn. 20271 * 20272 * hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+ 20273 * http://cherne.net/brian/resources/jquery.hoverIntent.html 20274 * 20275 * You may use hoverIntent under the terms of the MIT license. Basically that 20276 * means you are free to use hoverIntent as long as this header is left intact. 20277 * Copyright 2007, 2013 Brian Cherne 20278 * 20279 * // basic usage ... just like .hover() 20280 * .hoverIntent( handlerIn, handlerOut ) 20281 * .hoverIntent( handlerInOut ) 20282 * 20283 * // basic usage ... with event delegation! 20284 * .hoverIntent( handlerIn, handlerOut, selector ) 20285 * .hoverIntent( handlerInOut, selector ) 20286 * 20287 * // using a basic configuration object 20288 * .hoverIntent( config ) 20289 * 20290 * @param handlerIn function OR configuration object 20291 * @param handlerOut function OR selector for delegation OR undefined 20292 * @param selector selector OR undefined 20293 * @author Brian Cherne <brian(at)cherne(dot)net> 20294 **/ 20295(function($) { 20296 $.fn.hoverIntent = function(handlerIn,handlerOut,selector) { 20297 20298 // default configuration values 20299 var cfg = { 20300 interval: 100, 20301 sensitivity: 7, 20302 timeout: 0 20303 }; 20304
20305 if ( typeof handlerIn === "object" ) { 20306 cfg = $.extend(cfg, handlerIn ); 20307 } else if ($.isFunction(handlerOut)) { 20308 cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } ); 20309 } else { 20310 cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } ); 20311 } 20312 20313 // instantiate variables 20314 // cX, cY = current X and Y position of mouse, updated by mousemove event 20315 // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval 20316 var cX, cY, pX, pY; 20317 20318 // A private function for getting mouse position 20319 var track = function(ev) { 20320 cX = ev.pageX; 20321 cY = ev.pageY; 20322 }; 20323 20324 // A private function for comparing current and previous mouse position 20325 var compare = function(ev,ob) { 20326 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 20327 // compare mouse positions to see if they've crossed the threshold 20328 if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { 20329 $(ob).off("mousemove.hoverIntent",track); 20330 // set hoverIntent state to true (so mouseOut can be called) 20331 ob.hoverIntent_s = 1; 20332 return cfg.over.apply(ob,[ev]); 20333 } else { 20334 // set previous coordinates for next time 20335 pX = cX; pY = cY; 20336 // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) 20337 ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); 20338 } 20339 }; 20340 20341 // A private function for delaying the mouseOut function 20342 var delay = function(ev,ob) { 20343 ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); 20344 ob.hoverIntent_s = 0; 20345 return cfg.out.apply(ob,[ev]); 20346 }; 20347 20348 // A private function for handling mouse 'hovering' 20349 var handleHover = function(e) { 20350 // copy objects to be passed into t (required for event object to be passed in IE) 20351 var ev = jQuery.extend({},e); 20352 var ob = this; 20353 20354 // cancel hoverIntent timer if it exists 20355 if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } 20356 20357 // if e.type == "mouseenter" 20358 if (e.type == "mouseenter") { 20359 // set "previous" X and Y position based on initial entry point 20360 pX = ev.pageX; pY = ev.pageY; 20361 // update "current" X and Y position based on mousemove 20362 $(ob).on("mousemove.hoverIntent",track); 20363 // start polling interval (self-calling timeout) to compare mouse coordinates over time 20364 if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} 20365 20366 // else e.type == "mouseleave" 20367 } else { 20368 // unbind expensive mousemove event 20369 $(ob).off("mousemove.hoverIntent",track); 20370 // if hoverIntent state is true, then call the mouseOut function after the specified delay 20371 if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} 20372 } 20373 }; 20374 20375 // listen for mouseenter and mouseleave 20376 return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector); 20377 }; 20378})(jQuery); 20379/* 20380 * jQuery Superfish Menu Plugin 20381 * Copyright (c) 2013 Joel Birch 20382 * 20383 * Dual licensed under the MIT and GPL licenses: 20384 * http://www.opensource.org/licenses/mit-license.php 20385 * http://www.gnu.org/licenses/gpl.html 20386 */ 20387 20388(function ($) { 20389 "use strict"; 20390 20391 var methods = (function () { 20392 // private properties and methods go here 20393 var c = { 20394 bcClass: 'sf-breadcrumb', 20395 menuClass: 'sf-js-enabled', 20396 anchorClass: 'sf-with-ul', 20397 menuArrowClass: 'sf-arrows' 20398 }, 20399 ios = (function () { 20400 var ios = /iPhone|iPad|iPod/i.test(navigator.userAgent); 20401 if (ios) { 20402 // iOS clicks only bubble as far as body children 20403 $(window).load(function () { 20404 $('body').children().on('click', $.noop); 20405 }); 20406 } 20407 return ios; 20408 })(), 20409 wp7 = (function () { 20410 var style = document.documentElement.style; 20411 return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent)); 20412 })(), 20413 toggleMenuClasses = function ($menu, o) { 20414 var classes = c.menuClass; 20415 if (o.cssArrows) { 20416 classes += ' ' + c.menuArrowClass; 20417 }
vendor: 4,516 bytes, lines 20418-20575
20418 $menu.toggleClass(classes); 20419 }, 20420 setPathToCurrent = function ($menu, o) { 20421 return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels) 20422 .addClass(o.hoverClass + ' ' + c.bcClass) 20423 .filter(function () { 20424 return ($(this).children(o.popUpSelector).hide().show().length); 20425 }).removeClass(o.pathClass); 20426 }, 20427 toggleAnchorClass = function ($li) { 20428 $li.children('a').toggleClass(c.anchorClass); 20429 }, 20430 toggleTouchAction = function ($menu) { 20431 var touchAction = $menu.css('ms-touch-action'); 20432 touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y'; 20433 $menu.css('ms-touch-action', touchAction); 20434 }, 20435 applyHandlers = function ($menu, o) { 20436 var targets = 'li:has(' + o.popUpSelector + ')'; 20437 if ($.fn.hoverIntent && !o.disableHI) { 20438 $menu.hoverIntent(over, out, targets); 20439 } 20440 else { 20441 $menu 20442 .on('mouseenter.superfish', targets, over) 20443 .on('mouseleave.superfish', targets, out); 20444 } 20445 var touchevent = 'MSPointerDown.superfish'; 20446 if (!ios) { 20447 touchevent += ' touchend.superfish'; 20448 } 20449 if (wp7) { 20450 touchevent += ' mousedown.superfish'; 20451 } 20452 $menu 20453 .on('focusin.superfish', 'li', over) 20454 .on('focusout.superfish', 'li', out) 20455 .on(touchevent, 'a', o, touchHandler); 20456 }, 20457 touchHandler = function (e) { 20458 var $this = $(this), 20459 $ul = $this.siblings(e.data.popUpSelector); 20460 20461 if ($ul.length > 0 && $ul.is(':hidden')) { 20462 $this.one('click.superfish', false); 20463 if (e.type === 'MSPointerDown') { 20464 $this.trigger('focus'); 20465 } else { 20466 $.proxy(over, $this.parent('li'))(); 20467 } 20468 } 20469 }, 20470 over = function () { 20471 var $this = $(this), 20472 o = getOptions($this); 20473 clearTimeout(o.sfTimer); 20474 $this.siblings().superfish('hide').end().superfish('show'); 20475 }, 20476 out = function () { 20477 var $this = $(this), 20478 o = getOptions($this); 20479 if (ios) { 20480 $.proxy(close, $this, o)(); 20481 } 20482 else { 20483 clearTimeout(o.sfTimer); 20484 o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay); 20485 } 20486 }, 20487 close = function (o) { 20488 o.retainPath = ($.inArray(this[0], o.$path) > -1); 20489 this.superfish('hide'); 20490 20491 if (!this.parents('.' + o.hoverClass).length) { 20492 o.onIdle.call(getMenu(this)); 20493 if (o.$path.length) { 20494 $.proxy(over, o.$path)(); 20495 } 20496 } 20497 }, 20498 getMenu = function ($el) { 20499 return $el.closest('.' + c.menuClass); 20500 }, 20501 getOptions = function ($el) { 20502 return getMenu($el).data('sf-options'); 20503 }; 20504 20505 return { 20506 // public methods 20507 hide: function (instant) { 20508 if (this.length) { 20509 var $this = this, 20510 o = getOptions($this); 20511 if (!o) { 20512 return this; 20513 } 20514 var not = (o.retainPath === true) ? o.$path : '', 20515 $ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector), 20516 speed = o.speedOut; 20517 20518 if (instant) { 20519 $ul.show(); 20520 speed = 0; 20521 } 20522 o.retainPath = false; 20523 o.onBeforeHide.call($ul); 20524 $ul.stop(true, true).animate(o.animationOut, speed, function () { 20525 var $this = $(this); 20526 o.onHide.call($this); 20527 }); 20528 } 20529 return this; 20530 }, 20531 show: function () { 20532 var o = getOptions(this); 20533 if (!o) { 20534 return this; 20535 } 20536 var $this = this.addClass(o.hoverClass), 20537 $ul = $this.children(o.popUpSelector); 20538 20539 o.onBeforeShow.call($ul); 20540 $ul.stop(true, true).animate(o.animation, o.speed, function () { 20541 o.onShow.call($ul); 20542 }); 20543 return this; 20544 }, 20545 destroy: function () { 20546 return this.each(function () { 20547 var $this = $(this), 20548 o = $this.data('sf-options'), 20549 $hasPopUp; 20550 if (!o) { 20551 return false; 20552 } 20553 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 20554 clearTimeout(o.sfTimer); 20555 toggleMenuClasses($this, o); 20556 toggleAnchorClass($hasPopUp); 20557 toggleTouchAction($this); 20558 // remove event handlers 20559 $this.off('.superfish').off('.hoverIntent'); 20560 // clear animation's inline display style 20561 $hasPopUp.children(o.popUpSelector).attr('style', function (i, style) { 20562 return style.replace(/display[^;]+;?/g, ''); 20563 }); 20564 // reset 'current' path classes 20565 o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass); 20566 $this.find('.' + o.hoverClass).removeClass(o.hoverClass); 20567 o.onDestroy.call($this); 20568 $this.removeData('sf-options'); 20569 }); 20570 }, 20571 init: function (op) { 20572 return this.each(function () { 20573 var $this = $(this); 20574 if ($this.data('sf-options')) { 20575 return false;
20576 } 20577 var o = $.extend({}, $.fn.superfish.defaults, op), 20578 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 20579 o.$path = setPathToCurrent($this, o); 20580 20581 $this.data('sf-options', o); 20582 20583 toggleMenuClasses($this, o); 20584 toggleAnchorClass($hasPopUp); 20585 toggleTouchAction($this); 20586 applyHandlers($this, o); 20587 20588 $hasPopUp.not('.' + c.bcClass).superfish('hide', true); 20589 20590 o.onInit.call(this); 20591 }); 20592 } 20593 }; 20594 })(); 20595 20596 $.fn.superfish = function (method, args) { 20597 if (methods[method]) { 20598 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 20599 } 20600 else if (typeof method === 'object' || ! method) { 20601 return methods.init.apply(this, arguments); 20602 } 20603 else { 20604 return $.error('Method ' + method + ' does not exist on jQuery.fn.superfish'); 20605 } 20606 }; 20607 20608 $.fn.superfish.defaults = { 20609 popUpSelector: 'ul,.sf-mega', // within menu context 20610 hoverClass: 'sfHover', 20611 pathClass: 'overrideThisToUse', 20612 pathLevels: 1, 20613 delay: 800, 20614 animation: {opacity: 'show'}, 20615 animationOut: {opacity: 'hide'}, 20616 speed: 'normal', 20617 speedOut: 'fast', 20618 cssArrows: true, 20619 disableHI: false, 20620 onInit: $.noop, 20621 onBeforeShow: $.noop, 20622 onShow: $.noop, 20623 onBeforeHide: $.noop, 20624 onHide: $.noop, 20625 onIdle: $.noop, 20626 onDestroy: $.noop 20627 }; 20628 20629 // soon to be deprecated 20630 $.fn.extend({ 20631 hideSuperfishUl: methods.hide, 20632 showSuperfishUl: methods.show 20633 }); 20634 20635})(jQuery); 20636 20637 20638/* 20639 * Supersubs v0.3b - jQuery plugin 20640 * Copyright (c) 2013 Joel Birch 20641 * 20642 * Dual licensed under the MIT and GPL licenses: 20643 * http://www.opensource.org/licenses/mit-license.php 20644 * http://www.gnu.org/licenses/gpl.html 20645 * 20646 * 20647 * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of 20648 * their longest list item children. If you use this, please expect bugs and report them 20649 * to the jQuery Google Group with the word 'Superfish' in the subject line. 20650 * 20651 */ 20652 20653;(function($){ // $ will refer to jQuery within this closure 20654 20655 $.fn.supersubs = function(options){ 20656 var opts = $.extend({}, $.fn.supersubs.defaults, options); 20657 // return original object to support chaining 20658 return this.each(function() { 20659 // cache selections 20660 var $$ = $(this); 20661 // support metadata 20662 var o = $.meta ? $.extend({}, opts, $$.data()) : opts; 20663 // cache all ul elements and show them in preparation for measurements 20664 $ULs = $$.find('ul').show(); 20665 // get the font size of menu. 20666 // .css('fontSize') returns various results cross-browser, so measure an em dash instead 20667 var fontsize = $('<li id="menu-fontsize">—</li>').css({ 20668 'padding' : 0, 20669 'position' : 'absolute', 20670 'top' : '-999em', 20671 'width' : 'auto' 20672 }).appendTo($$)[0].clientWidth; //clientWidth is faster than .width() 20673 // remove em dash 20674 $('#menu-fontsize').remove(); 20675 // loop through each ul in menu 20676 $ULs.each(function(i) { 20677 // cache this ul 20678 var $ul = $(this); 20679 // get all (li) children of this ul 20680 var $LIs = $ul.children(); 20681 // get all anchor grand-children 20682 var $As = $LIs.children('a'); 20683 // force content to one line and save current float property 20684 var liFloat = $LIs.css('white-space','nowrap').css('float'); 20685 // remove width restrictions and floats so elements remain vertically stacked 20686 $ul.add($LIs).add($As).css({ 20687 'float' : 'none', 20688 'width' : 'auto' 20689 }); 20690 // this ul will now be shrink-wrapped to longest li due to position:absolute 20691 // so save its width as ems. 20692 var emWidth = $ul[0].clientWidth / fontsize; 20693 // add more width to ensure lines don't turn over at certain sizes in various browsers 20694 emWidth += o.extraWidth; 20695 // restrict to at least minWidth and at most maxWidth 20696 if (emWidth > o.maxWidth) { emWidth = o.maxWidth; } 20697 else if (emWidth < o.minWidth) { emWidth = o.minWidth; } 20698 emWidth += 'em'; 20699 // set ul to width in ems 20700 $ul.css('width',emWidth); 20701 // restore li floats to avoid IE bugs 20702 // set li width to full width of this ul 20703 // revert white-space to normal 20704 $LIs.css({ 20705 'float' : liFloat, 20706 'width' : '100%', 20707 'white-space' : 'normal' 20708 }) 20709 // update offset position of descendant ul to reflect new width of parent. 20710 // set it to 100% in case it isn't already set to this in the CSS 20711 .each(function(){ 20712 var $childUl = $(this).children('ul'); 20713 var offsetDirection = $childUl.css('left') !== undefined ? 'left' : 'right'; 20714 $childUl.css(offsetDirection,'100%'); 20715 }); 20716 }).hide(); 20717 20718 }); 20719 }; 20720 // expose defaults 20721 $.fn.supersubs.defaults = { 20722 minWidth : 9, // requires em unit. 20723 maxWidth : 25, // requires em unit. 20724 extraWidth : 0 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values 20725 }; 20726 20727})(jQuery); // plugin code ends 20728 20729/* 20730 * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010 20731 * http://benalman.com/projects/jquery-bbq-plugin/ 20732 * 20733 * Copyright (c) 2010 "Cowboy" Ben Alman 20734 * Dual licensed under the MIT and GPL licenses. 20735 * http://benalman.com/about/license/ 20736 */ 20737(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}
20737function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this); 20738/* 20739 * jQuery hashchange event - v1.2 - 2/11/2010 20740 * http://benalman.com/projects/jquery-hashchange-plugin/ 20741 * 20742 * Copyright (c) 2010 "Cowboy" Ben Alman 20743 * Dual licensed under the MIT and GPL licenses. 20744 * http://benalman.com/about/license/ 20745 */ 20746(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this); 20747function md5cycle(x, k) { 20748var a = x[0], b = x[1], c = x[2], d = x[3]; 20749 20750a = ff(a, b, c, d, k[0], 7, -680876936); 20751d = ff(d, a, b, c, k[1], 12, -389564586); 20752c = ff(c, d, a, b, k[2], 17, 606105819); 20753b = ff(b, c, d, a, k[3], 22, -1044525330); 20754a = ff(a, b, c, d, k[4], 7, -176418897); 20755d = ff(d, a, b, c, k[5], 12, 1200080426); 20756c = ff(c, d, a, b, k[6], 17, -1473231341); 20757b = ff(b, c, d, a, k[7], 22, -45705983); 20758a = ff(a, b, c, d, k[8], 7, 1770035416); 20759d = ff(d, a, b, c, k[9], 12, -1958414417); 20760c = ff(c, d, a, b, k[10], 17, -42063); 20761b = ff(b, c, d, a, k[11], 22, -1990404162); 20762a = ff(a, b, c, d, k[12], 7, 1804603682); 20763d = ff(d, a, b, c, k[13], 12, -40341101); 20764c = ff(c, d, a, b, k[14], 17, -1502002290); 20765b = ff(b, c, d, a, k[15], 22, 1236535329); 20766 20767a = gg(a, b, c, d, k[1], 5, -165796510); 20768d = gg(d, a, b, c, k[6], 9, -1069501632); 20769c = gg(c, d, a, b, k[11], 14, 643717713); 20770b = gg(b, c, d, a, k[0], 20, -373897302); 20771a = gg(a, b, c, d, k[5], 5, -701558691); 20772d = gg(d, a, b, c, k[10], 9, 38016083); 20773c = gg(c, d, a, b, k[15], 14, -660478335); 20774b = gg(b, c, d, a, k[4], 20, -405537848); 20775a = gg(a, b, c, d, k[9], 5, 568446438); 20776d = gg(d, a, b, c, k[14], 9, -1019803690); 20777c = gg(c, d, a, b, k[3], 14, -187363961); 20778b = gg(b, c, d, a, k[8], 20, 1163531501); 20779a = gg(a, b, c, d, k[13], 5, -1444681467); 20780d = gg(d, a, b, c, k[2], 9, -51403784); 20781c = gg(c, d, a, b, k[7], 14, 1735328473); 20782b = gg(b, c, d, a, k[12], 20, -1926607734); 20783 20784a = hh(a, b, c, d, k[5], 4, -378558); 20785d = hh(d, a, b, c, k[8], 11, -2022574463); 20786c = hh(c, d, a, b, k[11], 16, 1839030562); 20787b = hh(b, c, d, a, k[14], 23, -35309556); 20788a = hh(a, b, c, d, k[1], 4, -1530992060); 20789d = hh(d, a, b, c, k[4], 11, 1272893353); 20790c = hh(c, d, a, b, k[7], 16, -155497632); 20791b = hh(b, c, d, a, k[10], 23, -1094730640); 20792a = hh(a, b, c, d, k[13], 4, 681279174); 20793d = hh(d, a, b, c, k[0], 11, -358537222); 20794c = hh(c, d, a, b, k[3], 16, -722521979); 20795b = hh(b, c, d, a, k[6], 23, 76029189); 20796a = hh(a, b, c, d, k[9], 4, -640364487); 20797d = hh(d, a, b, c, k[12], 11, -421815835); 20798c = hh(c, d, a, b, k[15], 16, 530742520); 20799b = hh(b, c, d, a, k[2], 23, -995338651); 20800 20801a = ii(a, b, c, d, k[0], 6, -198630844); 20802d = ii(d, a, b, c, k[7], 10, 1126891415); 20803c = ii(c, d, a, b, k[14], 15, -1416354905); 20804b = ii(b, c, d, a, k[5], 21, -57434055); 20805a = ii(a, b, c, d, k[12], 6, 1700485571); 20806d = ii(d, a, b, c, k[3], 10, -1894986606); 20807c = ii(c, d, a, b, k[10], 15, -1051523); 20808b = ii(b, c, d, a, k[1], 21, -2054922799); 20809a = ii(a, b, c, d, k[8], 6, 1873313359); 20810d = ii(d, a, b, c, k[15], 10, -30611744); 20811c = ii(c, d, a, b, k[6], 15, -1560198380); 20812b = ii(b, c, d, a, k[13], 21, 1309151649); 20813a = ii(a, b, c, d, k[4], 6, -145523070); 20814d = ii(d, a, b, c, k[11], 10, -1120210379); 20815c = ii(c, d, a, b, k[2], 15, 718787259); 20816b = ii(b, c, d, a, k[9], 21, -343485551); 20817 20818x[0] = add32(a, x[0]); 20819x[1] = add32(b, x[1]); 20820x[2] = add32(c, x[2]); 20821x[3] = add32(d, x[3]); 20822 20823} 20824 20825function cmn(q, a, b, x, s, t) { 20826a = add32(add32(a, q), add32(x, t)); 20827return add32((a << s) | (a >>> (32 - s)), b); 20828} 20829 20830function ff(a, b, c, d, x, s, t) { 20831return cmn((b & c) | ((~b) & d), a, b, x, s, t); 20832} 20833 20834function gg(a, b, c, d, x, s, t) { 20835return cmn((b & d) | (c & (~d)), a, b, x, s, t); 20836} 20837 20838function hh(a, b, c, d, x, s, t) { 20839return cmn(b ^ c ^ d, a, b, x, s, t); 20840} 20841 20842function ii(a, b, c, d, x, s, t) { 20843return cmn(c ^ (b | (~d)), a, b, x, s, t); 20844} 20845 20846function md51(s) { 20847txt = ''; 20848var n = s.length, 20849state = [1732584193, -271733879, -1732584194, 271733878], i; 20850for (i=64; i<=s.length; i+=64) { 20851md5cycle(state, md5blk(s.substring(i-64, i))); 20852} 20853s = s.substring(i-64); 20854var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; 20855for (i=0; i<s.length; i++) 20856tail[i>>
208562] |= s.charCodeAt(i) << ((i%4) << 3); 20857tail[i>>2] |= 0x80 << ((i%4) << 3); 20858if (i > 55) { 20859md5cycle(state, tail); 20860for (i=0; i<16; i++) tail[i] = 0; 20861} 20862tail[14] = n*8; 20863md5cycle(state, tail); 20864return state; 20865} 20866 20867/* there needs to be support for Unicode here, 20868 * unless we pretend that we can redefine the MD-5 20869 * algorithm for multi-byte characters (perhaps 20870 * by adding every four 16-bit characters and 20871 * shortening the sum to 32 bits). Otherwise 20872 * I suggest performing MD-5 as if every character 20873 * was two bytes--e.g., 0040 0025 = @%--but then 20874 * how will an ordinary MD-5 sum be matched? 20875 * There is no way to standardize text to something 20876 * like UTF-8 before transformation; speed cost is 20877 * utterly prohibitive. The JavaScript standard 20878 * itself needs to look at this: it should start 20879 * providing access to strings as preformed UTF-8 20880 * 8-bit unsigned value arrays. 20881 */ 20882function md5blk(s) { /* I figured global was faster. */ 20883var md5blks = [], i; /* Andy King said do it this way. */ 20884for (i=0; i<64; i+=4) { 20885md5blks[i>>2] = s.charCodeAt(i) 20886+ (s.charCodeAt(i+1) << 8) 20887+ (s.charCodeAt(i+2) << 16) 20888+ (s.charCodeAt(i+3) << 24); 20889} 20890return md5blks; 20891} 20892 20893var hex_chr = '0123456789abcdef'.split(''); 20894 20895function rhex(n) 20896{ 20897var s='', j=0; 20898for(; j<4; j++) 20899s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] 20900+ hex_chr[(n >> (j * 8)) & 0x0F]; 20901return s; 20902} 20903 20904function hex(x) { 20905for (var i=0; i<x.length; i++) 20906x[i] = rhex(x[i]); 20907return x.join(''); 20908} 20909 20910function md5(s) { 20911return hex(md51(s)); 20912} 20913 20914/* this function is much faster, 20915so if possible we use it. Some IEs 20916are the only ones I know of that 20917need the idiotic second function, 20918generated by an if clause. */ 20919 20920function add32(a, b) { 20921return (a + b) & 0xFFFFFFFF; 20922} 20923 20924if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') { 20925function add32(x, y) { 20926var lsw = (x & 0xFFFF) + (y & 0xFFFF), 20927msw = (x >> 16) + (y >> 16) + (lsw >> 16); 20928return (msw << 16) | (lsw & 0xFFFF); 20929} 20930} 20931 20932/*! multilevelpushmenu 05-02-2016 */ 20933!function(a){a.fn.multilevelpushmenu=function(b){"use strict";var c=arguments,d=null;return this.each(function(){function e(a){a.stopPropagation&&a.preventDefault?(a.stopPropagation(),a.preventDefault()):(a.cancelBubble=!0,a.returnValue=!1)}function f(b,c){return void 0==b||void 0==c?!1:void b.on(c,function(d,e){b.hide();try{if(!d.pageX||!d.pageY)return!1;e=e||{pageX:d.pageX,pageY:d.pageY};var f=document.elementFromPoint(e.pageX,e.pageY);f=3==f.nodeType?f.parentNode:f,a(f).trigger(c,e)}catch(g){a.error("Error while propagating event: "+g.message)}finally{b.show()}})}function g(){var b=a("<nav />").prop({id:S.settings.menuID,className:S.settings.wrapperClass}).appendTo(S.settings.container);h(S.settings.menu,b)}function h(b,c){void 0==b.level&&(b.level=0),a.each(b,function(){var d=a("<div />").attr({"class":"levelHolderClass"+("rtl"==S.settings.direction?" rtl":" ltr"),"data-level":b.level,style:("rtl"==S.settings.direction?"margin-right: ":"margin-left: ")+(0!=b.level||S.settings.collapsed?"-200%":0)}).appendTo(c);y(S.settings.menuWidth)||x(S.settings.menuWidth)&&S.settings.menuWidth>0;d.bind(R,function(a){r(a,d)}),void 0!=this.id&&d.attr({id:this.id});var e=a("<h2 />").attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")}).text(this.title).appendTo(d),f=a("<i />").prop({"class":("rtl"==S.settings.direction?"floatLeft":"floatRight")+" cursorPointer "+this.icon}).prependTo(e);f.bind(Q,function(a){k(a,d,b)}),b.level>0&&l(d);a("<ul />").appendTo(d);a.each(this.items,function(){p(this,d,-1)})})}function i(){var a=S.settings.container.find("nav").length>0?S.settings.container.find("nav"):S.settings.menu;return 0==a.length?!1:(a.prop({id:S.settings.menuID,className:S.settings.wrapperClass}),void j(a))}function j(b){void 0==b.level&&(b.level=0),a.each(b,function(){var c=a("<div />").attr({"class":"levelHolderClass"+("rtl"==S.settings.direction?" rtl":" ltr"),"data-level":b.level,style:("rtl"==S.settings.direction?"margin-right: ":"margin-left: ")+(0!=b.level||S.settings.collapsed?"-200%":0)}).appendTo(b);y(S.settings.menuWidth)||x(S.settings.menuWidth)&&S.settings.menuWidth>0;c.bind(R,function(a){r(a,c)});var d=b.children("h2");d.attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")}),d.appendTo(c);var e=d.children("i");e.addClass(("rtl"==S.settings.direction?"floatLeft":"floatRight")+" cursorPointer"),e.bind(Q,function(a){k(a,c,b)}),b.level>0&&l(c);var f=b.children("ul");f.appendTo(c),a.each(f.children("li"),function(){var d=a(this);d.attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")});var e=d.children("a"),f=e.children("i");f.addClass("rtl"==S.settings.direction?"floatLeft":"floatRight"),d.children("ul").length>0?(e.bind(Q,function(a){n(a,c,d)}),o(e),d.level=b.level+1,j(d)):e.bind(Q,function(a){q(a,c,d)})})})}function k(b,c,d){if(a(S).find("div.levelHolderClass").is(":animated"))return!1;S.settings.onTitleItemClick.apply(this,Array.prototype.slice.call([b,c,S.settings])),e(b);var f="rtl"==S.settings.direction?parseInt(c.css("margin-right"))<0:parseInt(c.css("margin-left"))<0;if(0==d.level&&f)E();else{var g=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")>c.attr("data-level")&&parseInt(a(this).css("margin-right"))>=0:a(this).attr("data-level")>c.attr("data-level")&&parseInt(a(this).css("margin-left"))>=0;return b}),h=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")<=c.attr("data-level")&&parseInt(a(this).css("margin-right"))>=0:a(this).attr("data-level")<=c.attr("data-level")&&parseInt(a(this).css("margin-left"))>=0;return b});0==g.length&&1==h.length?C():C(parseInt(c.attr("data-level")))}c.css("visibility","visible"),c.find("."+S.settings.backItemClass).css("visibility","visible"),c.find("ul").css("visibility","visible"),c.removeClass(S.settings.menuInactiveClass)}function l(b){var c=a("<div />").attr({"class":S.settings.backItemClass}).appendTo(b),d=a("<a />").prop({href:"#"}).text(S.settings.backText).appendTo(c);a("<i />").prop({"class":("rtl"==S.settings.direction?"floatLeft ":"floatRight ")+S.settings.backItemIcon}).prependTo(d);d.bind(Q,function(a){m(a,b)})}function m(b,c){return a(S).find("div.levelHolderClass").is(":animated")?!1:(S.settings.onBackItemClick.apply(this,Array.prototype.slice.call([b,c,S.settings])),e(b),void C(parseInt(c.attr("data-level")-1)))}function n(b,c,d){return a(S).find("div.levelHolderClass").is(":animated")?!1:(S.settings.onGroupItemClick.apply(this,Array.prototype.slice.call([b,c,d,S.settings])),E(d.find("div:first")),void(S.settings.preventGroupItemClick&&e(b)))}function o(b){a("<i />").attr({"class":("rtl"==S.settings.direction?" floatRight iconSpacing_rtl ":" floatLeft iconSpacing_ltr ")+S.settings.groupIcon}).prependTo(b)}function p(){var b=arguments[0],c=arguments[1],d=arguments[2],e=c.find("ul:first"),f=a("<li />");d<e.children("li").length&&d>=0?f.insertBefore(e.children("li").eq(d)):f.appendTo(e),f.attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")}),void 0!=b.id&&f.attr({id:b.id});
20933var g=a("<a />").prop({href:b.link}).text(b.name).appendTo(f);a("<i />").prop({"class":("rtl"==S.settings.direction?"floatLeft ":"floatRight ")+b.icon}).prependTo(g);b.items?(g.bind(Q,function(a){n(a,c,f)}),o(g),b.items.level=parseInt(c.attr("data-level"),10)+1,h(b.items,f)):g.bind(Q,function(a){q(a,c,f)})}function q(a,b,c){S.settings.onItemClick.apply(this,Array.prototype.slice.call([a,b,c,S.settings])),S.settings.preventItemClick&&e(a)}function r(b,c){var d=S.settings.onMenuSwipe.apply(this,Array.prototype.slice.call([b,c,S.settings]));if(0==d)return!1;if(a(S).find("div.levelHolderClass").is(":animated"))return!1;var f=c.attr("data-level")>0?c.attr("data-level")-1:void 0;if("touchmove"==b.type&&"desktop"!=S.settings.swipe){if(e(b),b=b.touches?b:b.originalEvent,!b.touches||b.touches.length<=0)return!1;var g=b.touches[0];if(S.settings.container.unbind("touchend"),S.settings.container.bind("touchend",function(a){e(a),c.significance=0,c.swipeStart=0,S.settings.container.unbind("touchend")}),void 0==c.swipeStart||0==c.swipeStart)return c.significance=0,c.swipeStart=g.pageX,!0;c.significance=g.pageX-c.swipeStart,Math.abs(c.significance)>.3*S.settings.overlapWidth&&("rtl"==S.settings.direction&&(c.significance*=-1),c.significance>0?E(void 0==f?f:c):C(f),c.significance=0,c.swipeStart=0)}else if("touchscreen"!=S.settings.swipe){e(b);var h=0;c.unbind("mousemove"),c.bind("mousemove",function(a){return h=a.clientX-b.clientX,Math.abs(h)>.3*S.settings.overlapWidth?(c.unbind("mousemove"),"rtl"==S.settings.direction&&(h*=-1),h>0?E(void 0==f?f:c):C(f),!0):void 0}),S.settings.container.unbind("mouseup"),S.settings.container.bind("mouseup",function(a){e(a),c.unbind("mousemove"),S.settings.container.unbind("mouseup")})}}function s(){var b=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b});return b.length<1&&(b=!1),b}function t(){var b=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).position().left>S.settings.container.width()||parseInt(a(this).css("margin-right"))<0:a(this).position().left<0||parseInt(a(this).css("margin-left"))<0;return b});return b.length<1&&(b=!1),b}function u(){if(!S.redraw){S.redraw=!0;var b,c=arguments[0],d=arguments[1],e=arguments[2],f=a("#"+S.settings.menuID+" div.levelHolderClass").first().css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a("#"+S.settings.menuID+" div.levelHolderClass").first().get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0,g=void 0==c?Math.max.apply(null,a("#"+S.settings.menuID+" div.levelHolderClass").map(function(){return a(this).width()}).get())-f:c-f,h=Math.max.apply(null,a("#"+S.settings.menuID+" div.levelHolderClass").map(function(){return a(this).attr("data-level")}).get()),i=y(S.settings.menuWidth)||x(S.settings.menuWidth)&&S.settings.menuWidth>0,j=y(S.settings.menuHeight)||x(S.settings.menuHeight)&&S.settings.menuHeight>0,k=void 0==e?a("#"+S.settings.menuID+" div.levelHolderClass"):e;i||void 0==S.menuWidth||(g=S.menuWidth),i&&void 0==c?k.width(S.settings.menuWidth):k.width(g),i&&((0==k.width()||y(S.settings.menuWidth)&&-1!=S.settings.menuWidth.indexOf("%"))&&void 0==c&&(k.
20933css("min-width",""),k.width(parseInt(S.settings.container.parent().width()*parseInt(S.settings.menuWidth)/100))),g=k.width()-f,k.css("min-width",k.width()-f+"px"));var l=i&&void 0==c?k.width()-f+h*(S.settings.overlapWidth+f):g+h*(S.settings.overlapWidth+f),m=void 0==d?Math.max.apply(null,a("#"+S.settings.menuID+" div.levelHolderClass").map(function(){return a(this).height()}).get()):d;S.settings.container.css("min-height",""),S.settings.container.children("nav:first").css("min-height",""),j?(S.settings.container.height(S.settings.menuHeight),S.settings.container.css("min-height",S.settings.menuHeight),S.settings.container.children("nav:first").css("min-height",S.settings.menuHeight),a("#"+S.settings.menuID).height(S.settings.menuHeight),m=S.settings.container.height()):a("#"+S.settings.menuID).height(m),S.settings.container.css("min-height",m+"px"),S.settings.container.children("nav:first").css("min-height",m+"px"),S.settings.container.width(l),S.settings.container.height(m);var n=a("#"+S.settings.menuID+" div.levelHolderClass:first"),o=s(),p=t(),q=J(),r=1==q.length?q.attr("data-level"):0;o&&o.each(function(){"overlap"==S.settings.mode&&a(this).width(a(this).width()+(parseInt(r,10)-parseInt(a(this).attr("data-level"),10))*(S.settings.overlapWidth+f))}),p&&p.each(function(){"rtl"==S.settings.direction?a(this).css("margin-right",a(this).attr("data-level")!=n.attr("data-level")||S.settings.fullCollapse?-2*a(this).width():-1*a(this).width()+S.settings.overlapWidth):a(this).css("margin-left",a(this).attr("data-level")!=n.attr("data-level")||S.settings.fullCollapse?-2*a(this).width():-1*a(this).width()+S.settings.overlapWidth)}),b=n.width()+parseInt(n.css("rtl"==S.settings.direction?"margin-right":"margin-left"),10),v(S.settings.container,b),S.menuWidth=g,S.menuHeight=m,S.redraw=!1}}function v(a,b){return void 0==a||void 0==b?!1:(a.css("min-width",""),a.css("min-width",b+"px"),a.children("nav:first").css("min-width",""),a.children("nav:first").css("min-width",b+"px"),void a.width(b))}function w(){var b=a("#"+S.settings.menuID+" div.levelHolderClass:first"),c=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var c="rtl"==S.settings.direction?(a(this).position().left>S.settings.container.width()||parseInt(a(this).css("margin-right"))<0)&&a(this).attr("data-level")>b.attr("data-level"):(a(this).position().left<0||parseInt(a(this).css("margin-left"))<0)&&a(this).attr("data-level")>b.attr("data-level");return c});c.each(function(){"rtl"==S.settings.direction?a(this).css("margin-right",a(this).attr("data-level")!=b.attr("data-level")||S.settings.collapsed?-2*a(this).width():0):a(this).css("margin-left",a(this).attr("data-level")!=b.attr("data-level")||S.settings.collapsed?-2*a(this).width():0)}),"rtl"==S.settings.direction?b.css("margin-right",S.settings.collapsed?-2*b.width():0):b.css("margin-left",S.settings.collapsed?-2*b.width():0)}function x(a){return"number"==typeof a&&parseFloat(a)==parseInt(a,10)&&!isNaN(a)}function y(a){return"string"==typeof a&&(-1!=a.indexOf("%")||-1!=a.indexOf("px")||-1!=a.indexOf("em"))}function z(){b&&void 0!=b.menu?g():i();return f(S.settings.container,Q),u(),w(),A(S.settings.collapsed),S.settings.onMenuReady.apply(this,Array.prototype.slice.call([S.settings])),T}function A(b){if(b){var c=a("#"+S.settings.menuID+" div.levelHolderClass:first");c.find("ul").hide(),c.addClass(S.settings.menuInactiveClass),"rtl"==S.settings.direction?c.stop().animate({marginRight:-1*c.width()+(S.settings.fullCollapse?0:S.settings.overlapWidth)},S.settings.durationSlideOut):c.stop().animate({marginLeft:-1*c.width()+(S.settings.fullCollapse?0:S.settings.overlapWidth)},S.settings.durationSlideOut)}}function B(b){return null==S.settings.containersToPush?!1:void a.each(S.settings.containersToPush,function(){var c=parseInt(a(this).css("margin-left")),d=x(c)?c:0,e=parseInt(a(this).css("margin-right")),f=x(e)?e:0;a(this).stop().animate({marginLeft:d+("rtl"==S.settings.direction?-1:1)*b,marginRight:f+("rtl"==S.settings.direction?1:-1)*b},S.settings.durationSlideOut)})}function C(){if(a(S).find("div.levelHolderClass").is(":animated"))return!1;S.settings.onCollapseMenuStart.apply(this,Array.prototype.slice.call([S.settings]));var b,c,d,e,f=arguments[0],g=arguments[1],h={},i=a("#"+S.settings.menuID+" div.levelHolderClass:first"),j=void 0==f?!0:!1;if(h.collapsingEnded=!1,"object"==typeof f)f=f.attr("data-level");else if("string"==typeof f){var k=F(f);f=k&&1==k.length?k.attr("data-level"):i.attr("data-level")}else(void 0==f||!x(f)||0>f)&&(f=i.attr("data-level"));void 0==g&&"object"!=typeof g?g=[{method:S.settings.onCollapseMenuEnd,args:[S.settings]}]:a.merge(g,[{method:S.settings.onCollapseMenuEnd,args:[S.settings]}]);var l=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")>f&&parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:a(this).attr("data-level")>f&&parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b}),m=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")<=f&&parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:a(this).attr("data-level")<=f&&parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b});return m.length>0&&(h.prevAnimEnded=!1,l.each(function(d,e){b=a(e).css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a(e).get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0,c="overlap"==S.settings.mode?a(e).width()-(l.length+m.length-a(e).attr("data-level")-1)*(S.settings.overlapWidth+b)-b:a(e).width()-b,"rtl"==S.settings.direction?a(e).stop().animate({marginRight:-1*c,width:c},S.settings.durationTransition):a(e).stop().animate({marginLeft:-1*c,width:c},S.settings.durationTransition)}),h.nextAnimEnded=l.length>0?!1:!0,l.last().queue(function(){h.nextAnimEnded=!0,N(h,g)}),m.each(function(g,h){b=a(h).css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a(h).get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0;var k=m.filter(function(){return a(this).attr("data-level")==f});if(k.css("visibility","visible"),k.find("."+S.settings.backItemClass).css("visibility","visible"),k.find("ul").css("visibility","visible"),k.removeClass(S.settings.menuInactiveClass),c="overlap"==S.settings.mode?a(h).width()-l.length*(S.settings.overlapWidth+b)-b:a(h).width()-b,"rtl"==S.settings.direction?a(h).stop().animate({width:c,marginRight:a(h).attr("data-level")==i.attr("data-level")&&j?S.settings.fullCollapse?-1*a(h).width():-1*a(h).width()+("overlap"==S.settings.mode?l.length+1:1)*S.settings.overlapWidth:0},S.settings.durationSlideOut,function(){a(h).attr("data-level")==i.attr("data-level")&&j&&i.children("ul").first().hide(S.settings.durationSlideDown,function(){i.addClass(S.settings.menuInactiveClass)}),e=i.width()+parseInt(i.css("margin-right"),10),v(S.settings.container,e)}):a(h).stop().animate({width:c,marginLeft:a(h).attr("data-level")==i.attr("data-level")&&j?S.settings.fullCollapse?-1*a(h).width():-1*a(h).width()+("overlap"==S.settings.mode?l.length+1:1)*S.settings.overlapWidth:0},S.settings.durationSlideOut,function(){a(h).attr("data-level")==i.attr("data-level")&&j&&i.children("ul").first().hide(S.settings.durationSlideDown,function(){i.addClass(S.settings.menuInactiveClass)}),e=i.width()+parseInt(i.css("margin-left"),10),v(S.settings.container,e)}),d="overlap"==S.settings.mode?-1*(l.length*(S.settings.overlapWidth+b)):0,a(h).attr("data-level")==i.attr("data-level")&&j){var n=S.settings.fullCollapse?-1*(i.width()-b):-1*(i.width()-b)+S.settings.overlapWidth;B(n)}else B(d)}),m.last().queue(function(){h.prevAnimEnded=!0,N(h,g)})),h.collapsingEnded=!0,N(h,g),T}function D(){if(a(S).find("div.levelHolderClass").is(":animated"))return!1;S.settings.onExpandMenuStart.apply(this,Array.prototype.slice.call([S.settings]));var b,c,d,e,f,g=arguments[0],h=arguments[1],i={},j=a("#"+S.settings.menuID+" div.levelHolderClass:first"),k=void 0==g?!0:!1,l="rtl"==S.settings.direction?parseInt(j.css("margin-right"),10)<0||j.position().left>=S.settings.container.width()-S.settings.overlapWidth:parseInt(j.css("margin-left"),10)<0||j.position().left<0;if(i.expandingEnded=!1,void 0==h&&"object"!=typeof h?h=[{method:S.settings.onExpandMenuEnd,args:[S.settings]}]:a.merge(h,[{method:S.settings.onExpandMenuEnd,args:[S.settings]}]),k){i.baseAnimEnded=!1,j.removeClass(S.settings.menuInactiveClass),f=j.width(),v(S.settings.container,f),"rtl"==S.settings.direction?j.stop().animate({marginRight:0},S.settings.durationSlideOut,function(){j.children("ul").first().show(S.settings.durationSlideDown,function(){i.baseAnimEnded=!0,N(i,h)})}):j.stop().animate({marginLeft:0},S.settings.durationSlideOut,function(){j.children("ul").first().show(S.settings.durationSlideDown,function(){i.baseAnimEnded=!0,N(i,h)})}),e=S.settings.fullCollapse?j.width():j.width()-S.settings.overlapWidth;K(j)?null:B(e)}else{var m;if("object"==typeof g?m=g:"string"==typeof g?m=F(g):(m=null,a.error("Provided menu selector is not val
20933id")),m&&1==m.length){var n=J(),o=1==n.length?n.attr("data-level"):0,p=m.width(),q=H(m);if(i.setToOpenAnimEnded=!1,q){var r=a(q).length-1;j.find("ul").each(function(){a(this).show(0)}),a(q).find("ul").css("visibility","hidden"),a(q).find("div").css("visibility","visible"),a(q).find("."+S.settings.backItemClass).css("visibility","hidden"),a(q).each(function(d,e){b=a(e).css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a(e).get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0,c=p-b+(r-a(e).attr("data-level"))*(S.settings.overlapWidth+b),S.settings.container.width()<c&&"overlap"==S.settings.mode&&v(S.settings.container,c),"rtl"==S.settings.direction?a(e).stop().animate({marginRight:0,width:"overlap"==S.settings.mode?c:p-b},S.settings.durationTransition,function(){a(e).addClass(S.settings.menuInactiveClass)}):a(e).stop().animate({marginLeft:0,width:"overlap"==S.settings.mode?c:p-b},S.settings.durationTransition,function(){a(e).addClass(S.settings.menuInactiveClass)})}),a(q).last().queue(function(){a(this).removeClass(S.settings.menuInactiveClass),i.setToOpenAnimEnded=!0,N(i,h)}),l&&(e=S.settings.fullCollapse?j.width():j.width()-S.settings.overlapWidth,B(e)),"overlap"==S.settings.mode&&(d=l?p+(r-(S.settings.fullCollapse?0:1))*(S.settings.overlapWidth+b):(r-o)*(S.settings.overlapWidth+b),B(d)),m.css("visibility","visible"),m.find("."+S.settings.backItemClass).css("visibility","visible"),m.find("ul").css("visibility","visible"),m.removeClass(S.settings.menuInactiveClass)}else a.error("Invalid menu object provided")}else a.error("No or too many menus named "+g)}i.expandingEnded=!0,N(i,h)}function E(){var b,c,d,e,f=arguments[0],g=J();return"object"==typeof f?b=f:"string"==typeof f?(e=F(f),e?b=e.eq(0):a.error(f+" menu level does not exist!")):b=a("#"+S.settings.menuID+" div.levelHolderClass:first"),c=I(b,g,!0),d=c.length>0?Math.max.apply(null,c.map(function(){return a(this).attr("data-level")}).get()):0,d<g.attr("data-level")?C(d,[{method:D,args:arguments}]):D.apply(this,Array.prototype.slice.call(arguments)),T}function F(){var b,c=arguments[0],e=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){return a(this).children("h2").text()==c});return e.length>0?(d=e,b=d):(d=!1,b=d),b}function G(){var b,c=arguments[0],e=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass li").filter(function(){return a(this).children("a").text()==c});return e.length>0?(d=e,b=d):(d=!1,b=d),b}function H(){var b,c,e=arguments[0];return void 0==e||1!=e.length?d=!1:(b=e.parents("div.levelHolderClass"),c=a.merge(b.get().reverse(),e.get()),d=c)}function I(){var b,c,e,f,g,h,i,j=arguments[0],k=arguments[1],l=void 0!=arguments[2]?arguments[2]:!1;return void 0==j||void 0==k?d=!1:(b=1==j.length?j.parents("div.levelHolderClass"):null,c=1==k.length?k.parents("div.levelHolderClass"):null,e=null!=b?a.merge(b.get().reverse(),j.get()):[],f=null!=c?a.merge(c.get().reverse(),k.get()):[],g=e.length>=f.length?e:f,h=g===e?f:e,i=a(g).filter(function(){return l?-1!=a.inArray(this,h):-1==a.inArray(this,h)}),d=i)}function J(){var b=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b}),c=Math.max.apply(null,b.map(function(){return a(this).attr("data-level")}).get()),e=b.filter(function(){return a(this).attr("data-level")==c});return d=e}function K(){var a=arguments[0],b=!1;if(void 0==a)return b;var c="rtl"==S.settings.direction?parseInt(a.css("margin-right"))>=0&&a.position().left<S.settings.container.width()-S.settings.overlapWidth:parseInt(a.css("margin-left"))>=0&&a.position().left>=0;return c}function L(){var b=arguments[0],c=arguments[1],d=arguments[2];if(void 0==c||"object"!=typeof b||!c)return!1;void 0==b.level&&(b.level=parseInt(c.attr("data-level"),10)),void 0==d&&(d=0);c.find("ul:first");return a.each(b,function(){void 0!=this.name&&p(this,c,d)}),u(S.menuWidth),T}function M(){var b=arguments[0];if(void 0==b||"object"!=typeof b||0==b.length)return!1;b.remove();var c=J();if(1==c.length){c.css("visibility","visible"),c.find("."+S.settings.backItemClass).css("visibility","visible"),c.find("ul").css("visibility","visible"),c.removeClass(S.settings.menuInactiveClass);var d=c.width()-S.menuWidth;if(0!=d){var e=s();e&&e.each(function(){a(this).width(a(this).width()-d)})}}return u(S.menuWidth),T}function N(b,c){var d=!0;a.each(b,function(a,b){d=d&&b}),d&&window.setTimeout(function(){a.each(c,function(a,b){b.method.apply(this,Array.prototype.slice.call(b.args))})},1)}function O(){var b=!1;return void 0!=S.settings[arguments[0]]?(void 0!=arguments[1]&&(S.settings[arguments[0]]=arguments[1]),b=S.settings[arguments[0]]):a.error("No option "+arguments[0]+" found in jQuery.multilevelpushmenu"),b}function P(){var a=!1;return function(b){(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(b)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
20933sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(b.substr(0,4)))&&(a=!0)}(navigator.userAgent||navigator.vendor||window.opera),a}var Q,R,S=this,T=a(this),U=void 0!=T.context?T:a("body"),V=b&&void 0!=b.menu?b.menu:T.find("nav"),W=a.extend({container:U,containersToPush:null,menuID:(void 0!=U.prop("id")&&""!=U.prop("id")?U.prop("id"):this.nodeName.toLowerCase())+"_multilevelpushmenu",wrapperClass:"multilevelpushmenu_wrapper",menuInactiveClass:"multilevelpushmenu_inactive",menu:V,menuWidth:0,menuHeight:0,collapsed:!1,fullCollapse:!1,direction:"ltr",backText:"Back",backItemClass:"backItemClass",backItemIcon:"fa fa-angle-right",groupIcon:"fa fa-angle-left",mode:"overlap",overlapWidth:40,preventItemClick:!0,preventGroupItemClick:!0,swipe:"both",durationSlideOut:400,durationSlideDown:500,durationTransition:400,onCollapseMenuStart:function(){},onCollapseMenuEnd:function(){},onExpandMenuStart:function(){},onExpandMenuEnd:function(){},onGroupItemClick:function(){},onItemClick:function(){},onTitleItemClick:function(){},onBackItemClick:function(){},onMenuReady:function(){},onMenuSwipe:function(){}},b);a.data(S,"plugin_multilevelpushmenu")||(a.data(S,"plugin_multilevelpushmenu",W),S.settings=a.data(S,"plugin_multilevelpushmenu"));var X={init:function(){return z.apply(this,Array.prototype.slice.call(arguments))},collapse:function(){return C.apply(this,Array.prototype.slice.call(arguments))},expand:function(){return E.apply(this,Array.prototype.slice.call(arguments))},menuexpanded:function(){return K.apply(this,Array.prototype.slice.call(arguments))},activemenu:function(){return J.apply(this,Array.prototype.slice.call(arguments))},findmenusbytitle:function(){return F.apply(this,Array.prototype.slice.call(arguments))},finditemsbyname:function(){return G.apply(this,Array.prototype.slice.call(arguments))},pathtoroot:function(){return H.apply(this,Array.prototype.slice.call(arguments))},comparepaths:function(){return I.apply(this,Array.prototype.slice.call(arguments))},option:function(){return O.apply(this,Array.prototype.slice.call(arguments))},additems:function(){return L.apply(this,Array.prototype.slice.call(arguments))},removeitems:function(){return M.apply(this,Array.prototype.slice.call(arguments))},redraw:function(){return u.apply(this,Array.prototype.slice.call(arguments))},visiblemenus:function(){return s.apply(this,Array.prototype.slice.call(arguments))},hiddenmenus:function(){return t.apply(this,Array.prototype.slice.call(arguments))},propagateevent:function(){return f.apply(this,Array.prototype.slice.call(arguments))}};return P()?(Q="touchend",R="touchmove"):(Q="click",R="mousedown"),X[b]?d=X[b].apply(this,Array.prototype.slice.call(c,1)):"object"!=typeof b&&b?(a.error("No "+b+" method found in jQuery.multilevelpushmenu"),void(d||(d=this))):d=X.init.apply(this,arguments)}),d}}(jQuery); 20934!function(e){var t={};function o(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,o),i.l=!0,i.exports}o.m=e,o.c=t,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)o.d(n,i,function(t){return e[t]}.bind(null,i));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=11)}([function(e,t){e.exports='{{message}} <a aria-label="learn more about cookies" role=button tabindex=0 class=cc-link href={{href}} rel="noopener noreferrer nofollow" target={{target}}> {{link}} </a> '},function(e,t){e.exports='<div class="cc-revoke dp--revoke {{classes}}"> <i class=dp--icon-fingerprint></i> <span class=dp--hover>{{policy}}</span> </div> '},function(e,t,o){(function(e,o){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i=/^\[object .+?Constructor\]$/,s=/^(?:0|[1-9]\d*)$/,r={};
vendor: 11,313 bytes, line 20934
20934r["[object Float32Array]"]=r["[object Float64Array]"]=r["[object Int8Array]"]=r["[object Int16Array]"]=r["[object Int32Array]"]=r["[object Uint8Array]"]=r["[object Uint8ClampedArray]"]=r["[object Uint16Array]"]=r["[object Uint32Array]"]=!0,r["[object Arguments]"]=r["[object Array]"]=r["[object ArrayBuffer]"]=r["[object Boolean]"]=r["[object DataView]"]=r["[object Date]"]=r["[object Error]"]=r["[object Function]"]=r["[object Map]"]=r["[object Number]"]=r["[object Object]"]=r["[object RegExp]"]=r["[object Set]"]=r["[object String]"]=r["[object WeakMap]"]=!1;var c="object"==(void 0===e?"undefined":n(e))&&e&&e.Object===Object&&e,a="object"==("undefined"==typeof self?"undefined":n(self))&&self&&self.Object===Object&&self,l=c||a||Function("return this")(),u="object"==n(t)&&t&&!t.nodeType&&t,d=u&&"object"==n(o)&&o&&!o.nodeType&&o,p=d&&d.exports===u,h=p&&c.process,f=function(){try{var e=d&&d.require&&d.require("util").types;return e||h&&h.binding&&h.binding("util")}catch(e){}}(),v=f&&f.isTypedArray;function k(e,t,o){switch(o.length){case 0:return e.call(t);case 1:return e.call(t,o[0]);case 2:return e.call(t,o[0],o[1]);case 3:return e.call(t,o[0],o[1],o[2])}return e.apply(t,o)}var b,y,m,w=Array.prototype,g=Function.prototype,C=Object.prototype,x=l["__core-js_shared__"],_=g.toString,S=C.hasOwnProperty,O=(b=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+b:"",E=C.toString,P=_.call(Object),j=RegExp("^"+_.call(S).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=p?l.Buffer:void 0,A=l.Symbol,L=l.Uint8Array,D=T?T.allocUnsafe:void 0,N=(y=Object.getPrototypeOf,m=Object,function(e){return y(m(e))}),B=Object.create,M=C.propertyIsEnumerable,R=w.splice,I=A?A.toStringTag:void 0,F=function(){try{var e=ue(Object,"defineProperty");return e({},"",{}),e}catch(e){}}(),H=T?T.isBuffer:void 0,z=Math.max,U=Date.now,W=ue(l,"Map"),q=ue(Object,"create"),J=function(){function e(){}return function(t){if(!Ce(t))return{};if(B)return B(t);e.prototype=t;var o=new e;return e.prototype=void 0,o}}();function $(e){var t=-1,o=null==e?0:e.length;for(this.clear();++t<o;){var n=e[t];this.set(n[0],n[1])}}function K(e){var t=-1,o=null==e?0:e.length;for(this.clear();++t<o;){var n=e[t];this.set(n[0],n[1])}}function G(e){var t=-1,o=null==e?0:e.length;for(this.clear();++t<o;){var n=e[t];this.set(n[0],n[1])}}function Y(e){var t=this.__data__=new K(e);this.size=t.size}function X(e,t){var o=be(e),n=!o&&ke(e),i=!o&&!n&&me(e),s=!o&&!n&&!i&&_e(e),r=o||n||i||s,c=r?function(e,t){for(var o=-1,n=Array(e);++o<e;)n[o]=t(o);return n}(e.length,String):[],a=c.length;for(var l in e)!t&&!S.call(e,l)||r&&("length"==l||i&&("offset"==l||"parent"==l)||s&&("buffer"==l||"byteLength"==l||"byteOffset"==l)||de(l,a))||c.push(l);return c}function V(e,t,o){(void 0===o||ve(e[t],o))&&(void 0!==o||t in e)||ee(e,t,o)}function Z(e,t,o){var n=e[t];S.call(e,t)&&ve(n,o)&&(void 0!==o||t in e)||ee(e,t,o)}function Q(e,t){for(var o=e.length;o--;)if(ve(e[o][0],t))return o;return-1}function ee(e,t,o){"__proto__"==t&&F?F(e,t,{configurable:!0,enumerable:!0,value:o,writable:!0}):e[t]=o}$.prototype.clear=function(){this.__data__=q?q(null):{},this.size=0},$.prototype.delete=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t},$.prototype.get=function(e){var t=this.__data__;if(q){var o=t[e];return"__lodash_hash_undefined__"===o?void 0:o}return S.call(t,e)?t[e]:void 0},$.prototype.has=function(e){var t=this.__data__;return q?void 0!==t[e]:S.call(t,e)},$.prototype.set=function(e,t){var o=this.__data__;return this.size+=this.has(e)?0:1,o[e]=q&&void 0===t?"__lodash_hash_undefined__":t,this},K.prototype.clear=function(){this.__data__=[],this.size=0},K.prototype.delete=function(e){var t=this.__data__,o=Q(t,e);return!(o<0)&&(o==t.length-1?t.pop():R.call(t,o,1),--this.size,!0)},K.prototype.get=function(e){var t=this.__data__,o=Q(t,e);return o<0?void 0:t[o][1]},K.prototype.has=function(e){return Q(this.__data__,e)>-1},K.prototype.set=function(e,t){var o=this.__data__,n=Q(o,e);return n<0?(++this.size,o.push([e,t])):o[n][1]=t,this},G.prototype.clear=function(){this.size=0,this.__data__={hash:new $,map:new(W||K),string:new $}},G.prototype.delete=function(e){var t=le(this,e).delete(e);return this.size-=t?1:0,t},G.prototype.get=function(e){return le(this,e).get(e)},G.prototype.has=function(e){return le(this,e).has(e)},G.prototype.set=function(e,t){var o=le(this,e),n=o.size;return o.set(e,t),this.size+=o.size==n?0:1,this},Y.prototype.clear=function(){this.__data__=new K,this.size=0},Y.prototype.delete=function(e){var t=this.__data__,o=t.delete(e);return this.size=t.size,o},Y.prototype.get=function(e){return this.__data__.get(e)},Y.prototype.has=function(e){return this.__data__.has(e)},Y.prototype.set=function(e,t){var o=this.__data__;if(o instanceof K){var n=o.__data__;if(!W||n.length<199)return n.push([e,t]),this.size=++o.size,this;o=this.__data__=new G(n)}return o.set(e,t),this.size=o.size,this};var te,oe=function(e,t,o){for(var n=-1,i=Object(e),s=o(e),r=s.length;r--;){var c=s[te?r:++n];if(!1===t(i[c],c,i))break}return e};function ne(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":I&&I in Object(e)?function(e){var t=S.call(e,I),o=e[I];try{e[I]=void 0;var n=!0}catch(e){}var i=E.call(e);n&&(t?e[I]=o:delete e[I]);return i}(e):function(e){return E.call(e)}(e)}function ie(e){return xe(e)&&"[object Arguments]"==ne(e)}function se(e){return!(!Ce(e)||function(e){return!!O&&O in e}(e))&&(we(e)?j:i).test(function(e){if(null!=e){try{return _.call(e)}catch(e){}try{return e+""}catch(e){}}return""}(e))}function re(e){if(!Ce(e))return function(e){var t=[];if(null!=e)for(var o in Object(e))t.push(o);return t}(e);var t=pe(e),o=[];for(var n in e)("constructor"!=n||!t&&S.call(e,n))&&o.push(n);return o}function ce(e,t,o,n,i){e!==t&&oe(t,(function(s,r){if(i||(i=new Y),Ce(s))!function(e,t,o,n,i,s,r){var c=he(e,o),a=he(t,o),l=r.get(a);if(l)return void V(e,o,l);var u=s?s(c,a,o+"",e,t,r):void 0,d=void 0===u;if(d){var p=be(a),h=!p&&me(a),f=!p&&!h&&_e(a);u=a,p||h||f?be(c)?u=c:xe(m=c)&&ye(m)?u=function(e,t){var o=-1,n=e.length;t||(t=Array(n));for(;++o<n;)t[o]=e[o];return t}(c):h?(d=!1,u=function(e,t){if(t)return e.slice();var o=e.length,n=D?D(o):new e.constructor(o);return e.copy(n),n}(a,!0)):f?(d=!1,v=a,k=!0?(b=v.buffer,y=new b.constructor(b.byteLength),new L(y).set(new L(b)),y):v.buffer,u=new v.constructor(k,v.byteOffset,v.length)):u=[]:function(e){if(!xe(e)||"[object Object]"!=ne(e))return!1;var t=N(e);if(null===t)return!0;var o=S.call(t,"constructor")&&t.constructor;return"function"==typeof o&&o instanceof o&&_.call(o)==P}(a)||ke(a)?(u=c,ke(c)?u=function(e){return function(e,t,o,n){var i=!o;o||(o={});var s=-1,r=t.length;for(;++s<r;){var c=t[s],a=n?n(o[c],e[c],c,o,e):void 0;void 0===a&&(a=e[c]),i?ee(o,c,a):Z(o,c,a)}return o}(e,Se(e))}(c):Ce(c)&&!we(c)||(u=function(e){return"function"!=typeof e.constructor||pe(e)?{}:J(N(e))}(a))):d=!1}var v,k,b,y;var m;d&&(r.set(a,u),i(u,a,n,s,r),r.delete(a));V(e,o,u)}(e,t,r,o,ce,n,i);else{var c=n?n(he(e,r),s,r+"",e,t,i):void 0;void 0===c&&(c=s),V(e,r,c)}}),Se)}function ae(e,t){return fe(function(e,t,o){return t=z(void 0===t?e.length-1:t,0),function(){for(var n=arguments,i=-1,s=z(n.length-t,0),r=Array(s);++i<s;)r[i]=n[t+i];i=-1;for(var c=Array(t+1);++i<t;)c[i]=n[i];return c[t]=o(r),k(e,this,c)}}(e,t,Pe),e+"")}function le(e,t){var o,i,s=e.__data__;return("string"==(i=n(o=t))||"number"==i||"symbol"==i||"boolean"==i?"__proto__"!==o:null===o)?s["string"==typeof t?"string":"hash"]:s.map}function ue(e,t){var o=function(e,t){return null==e?void 0:e[t]}(e,t);return se(o)?o:void 0}function de(e,t){var o=n(e);return!!(t=null==t?9007199254740991:t)&&("number"==o||"symbol"!=o&&s.test(e))&&e>-1&&e%1==0&&e<t}function pe(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||C)}function he(e,t){if(("constructor"!==t||"function"!=typeof e[t])&&"__proto__"!=t)return e[t]}var fe=function(e){var t=0,o=0;return function(){var n=U(),i=16-(n-o);if(o=n,i>0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}(F?function(e,t){return F(e,"toString",{configurable:!0,enumerable:!1,value:(o=t,function(){return o}),writable:!0});var o}:Pe);function ve(e,t){return e===t||e!=e&&t!=t}var ke=ie(function(){return arguments}())?ie:function(e){return xe(e)&&S.call(e,"callee")&&!M.call(e,"callee")},be=Array.isArray;function ye(e){return null!=e&&ge(e.length)&&!we(e)}var me=H||function(){return!1};function we(e){if(!Ce(e))return!1;var t=ne(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}function ge(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}function Ce(e){var t=n(e);return null!=e&&("object"==t||"function"==t)}function xe(e){return null!=e&&"object"==n(e)}var _e=v?function(e){return function(t){return e(t)}}(v):function(e){return xe(e)&&ge(e.length)&&!!r[ne(e)]};function Se(e){return ye(e)?X(e,!0):re(e)}var Oe,Ee=(Oe=function(e,t,o){ce(e,t,o)},ae((function(e,t){var o=-1,i=t.length,s=i>1?t[i-1]:void 0,r=i>2?t[2]:void 0;for(s=Oe.length>3&&"function"==typeof s?(i--,s):void 0,r&&function(e,t,o){if(!Ce(o))return!1;var i=n(t);return!!("number"==i?ye(o)&&de(t,o.length):"string"==i&&t in o)&&ve(o[t],e)}(t[0],t[1],r)&&(s=i<3?void 0:s,i=1),e=Object(e);++o<i;){var c=t[o];c&&Oe(e,c,o,s)}return e})));function Pe(e){return e}o.exports=Ee}).call(this,o(13),o(14)(e))},function(e,t){e.exports='<div class="cc-compliance cc-highlight"> {{allow}} {{allow-all}} </div> '},function(e,t){e.exports='<div class=dp--cookie-check xmlns:f=http://www.w3.org/1999/html> <label for=dp--cookie-require> <input type=checkbox id=dp--cookie-require class=dp--check-box checked=checked disabled=disabled /> {{dpRequire}} </label> <label for=dp--cookie-statistics> <input type=checkbox id=dp--cookie-statistics class=dp--check-box {{checked.statistics}} value=""/> {{dpStatistik}} </label> <label for=dp--cookie-marketing> <input type=checkbox id=dp--cookie-marketing class=dp--check-box {{checked.marketing}} value=""/> {{dpMarketing}} </label> </div> '},function(e,t){e.exports="<span id=cookieconsent:desc class=cc-message> {{cookieDesc}} </span> "},function(e,t){e.exports="<span id=cookieconsent:desc class=cc-message> {{cookieDesc}} {{cookieSelect}} </span> "},function(e,t){e.exports='<a aria-label="dismiss cookies" role=button tabindex=0 class="cc-btn cc-dismiss"> {{allow-all}} </a> '},function(e,t){e.exports="{{dpmessagelink}}{{compliance}} "},function(e,t){e.exports="<div class=dp--overlay-inner> <div class=dp--overlay-header>{{notice}}</div> <div class=dp--overlay-description>{{desc}}</div> <div class=dp--overlay-button> <button class=db--overlay-submit onclick=window.DPCookieConsent.forceAccept(this) data-cookieconsent={{type}} {{style}}> {{btn}} </button> </div> </div> "},function(e,t){e.exports=function(){this.lang={message:"We use cookies and other tracking technologies to personalize and improve your experience. By continuing to use our website you consent to this.",dismiss:"allow cookies",allow:"allow cookies","allow-all":"allow all!",deny:"decline",policy:"Cookie Policy",link:"More info",dpRequire:"necessary",dpStatistik:"statistics",dpMarketing:"marketing",media:{notice:"Cookie Notice",desc:"Loading this resource will c
20934onnect to external servers which use cookies and other tracking technologies to personalize and improve experience. Further information can be found in our privacy policy.",btn:"allow cookies and load this resource"}}}},function(e,t,o){o(12),e.exports=o(16)},function(e,t,o){"use strict";o.r(t);var n=o(3),i=o.n(n),s=o(4),r=o.n(s),c=o(0),a=o.n(c),l=o(5),u=o.n(l),d=o(6),p=o.n(d),h=o(7),f=o.n(h),v=o(8),k=o.n(v),b=o(1),y=o.n(b),m=o(9),w=o.n(m),g=o(2),C=o.n(g),x=o(10),_=o.n(x);function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)} 20935/*! 20936 * Cookie Consent Adapter 20937 * Copyright 2019 Dirk Persky (https://github.com/DirkPersky/typo3-dp_cookieconsent) 20938 * Licensed under GPL v3+ (https://github.com/DirkPersky/typo3-dp_cookieconsent/blob/master/LICENSE) 20939 */window.addEventListener("load",(function(){function e(){this.cookie_name="dp_cookieconsent_status",this.cookie={path:"/",domain:"",expiryDays:365,secure:!1},this.prevCheckboxes=!1,this.checkboxes=[{name:"statistics",checked:!0},{name:"marketing",checked:!1}],this.settings={autoOpen:!0,revokable:!0,dismissOnScroll:!1,layout:"dpextend",type:"opt-in",theme:"edgeless",position:"bottom-right",reloadOnRevoke:!1,overlay:{notice:!0,box:{background:"rgba(0,0,0,.8)",text:"#fff"},btn:{background:"#F96332",text:"#fff"}},palette:{popup:{background:"rgba(0,0,0,.8)",text:"#FFFFFF"},button:{background:"#F96332",text:"#FFFFFF"}}}}"undefined"==typeof dpCookieConsentLang&&(window.DPCookieConsentL10N=_.a),window.DPCookieConsentL10N.prototype.replace=function(){window.cookieconsent_options.content=C()(this.lang,window.cookieconsent_options.content)},(new window.DPCookieConsentL10N).replace(),e.prototype.asyncLoad=function(e,t,o){var n=document,i=n.createElement(t),s=n.getElementsByTagName(t)[0];switch(t){case"script":i.src=e,i.setAttribute("defer","");break;case"link":i.rel="stylesheet",i.type="text/css",i.setAttribute("defer",""),i.href=e}o&&i.addEventListener("load",(function(e){o(null,e)}),!1),s.parentNode.insertBefore(i,s)},e.prototype.asyncJS=function(e,t){this.asyncLoad(e,"script",t)},e.prototype.getCookieElementsByTag=function(e,t){void 0===t&&(t="data-cookieconsent");var o=[];if(void 0===document.querySelectorAll)o=document.querySelectorAll(e+"["+t+"]");else{var n=document.getElementsByTagName(e);for(var i in n){var s=n[i];void 0!==s.getAttribute&&s.getAttribute(t)&&o.push(s)}}return o},e.prototype.callIframeHandler=function(e){var t=e.cloneNode(!0);t.getAttribute("data-src")&&(t.src=t.getAttribute("data-src")),e.parentNode.replaceChild(t,e),t.classList.add("dp--loaded"),t.setAttribute("data-cookieconsent-loaded",t.getAttribute("data-cookieconsent")),t.removeAttribute("data-cookieconsent"),window.DPCookieConsent.fireEvent("dp--cookie-iframe",t)},e.prototype.callScriptHandler=function(e){var t=e.innerHTML;t&&t.length&&(t=t.trim()),t&&t.length?(eval.call(this,t),window.DPCookieConsent.fireEvent("dp--cookie-fire",e)):e.getAttribute("data-src")?this.asyncJS(e.getAttribute("data-src"),(function(t){window.DPCookieConsent.fireEvent("dp--cookie-fire",e)})):e.src&&this.asyncJS(e.src,(function(t){window.DPCookieConsent.fireEvent("dp--cookie-fire",e)})),e.setAttribute("data-cookieconsent-loaded",e.getAttribute("data-cookieconsent")),e.removeAttribute("data-cookieconsent")},e.prototype.loadCookies=function(){var e,t=this.getCookieElementsByTag("script");if((t=t.concat(this.getCookieElementsByTag("iframe"))).length>0)for(e=0;e<t.length;e++){if("dpextend"===window.cookieconsent_options.layout){var o=t[e].getAttribute("data-cookieconsent");if("required"!=o&&(this.loadCookiesPreset(),!this.dpCookies.hasOwnProperty("dp--cookie-"+o)||!0!==this.dpCookies["dp--cookie-"+o]))continue}if(void 0!==t[e].tagName)switch(t[e].tagName.toUpperCase()){case"IFRAME":this.callIframeHandler(t[e]);break;default:this.callScriptHandler(t[e])}}window.DPCookieConsent.prevCheckboxes=[],window.DPCookieConsent.checkboxes.map((function(e){e&&window.DPCookieConsent.prevCheckboxes.push({name:e.name,checked:e.checked})}))},e.prototype.setClass=function(e){!0===e?document.querySelector("body").classList.remove("dp--cookie-consent"):document.querySelector("body").classList.add("dp--cookie-consent")},e.prototype.initCheckboxes=function(){if("object"===S(window.cookieconsent_options.checkboxes))for(var e in this.checkboxes=[],window.cookieconsent_options.checkboxes)this.checkboxes.push({name:e,checked:window.cookieconsent_options.checkboxes[e]});var t=DPCookieConsent.getCookieElementsByTag("script","data-dp-cookieSelect");t=t.length>0?t[0].innerHTML:r.a,this.checkboxes.map((function(e){var o="";(!0===e.checked||!1!==e.checked&&"true"===e.checked.toLowerCase())&&(o='checked="checked"'),t=t.replace("{{checked."+e.name+"}}",o)})),t=this.replaceLabels(t),window.cookieconsent_options.content.cookieSelect=t},e.prototype.replaceLabels=function(e){for(var t in window.cookieconsent_options.content)e=e.replace("{{"+t+"}}",window.cookieconsent_options.content[t]);return e},e.prototype.setCheckboxes=function(){if("dpextend"==window.cookieconsent_options.layout){var e=this,t=e.checkboxes.map((function(t){return e.loadCheckbox(t.name)}));this.saveCookie(t)}},e.prototype.loadCheckboxes=function(){if("dpextend"==window.cookieconsent_options.layout){var e=this;e.loadCookiesPreset(),e.checkboxes.map((function(t){e.loadCheckbox(t.name,!0)}))}},e.prototype.saveCookie=function(e){var t={};e.map((function(e){e&&(t[e.id]=e.checked)}
20939)),this.dpCookies=e,window.cookieconsent.utils.setCookie(this.cookie_name,JSON.stringify(t),this.cookie.expiryDays,this.cookie.domain,this.cookie.path,this.cookie.secure)},e.prototype.loadCookiesPreset=function(){if(0!=this.dpCookies&&(this.dpCookies=window.cookieconsent.utils.getCookie(this.cookie_name)),void 0!==this.dpCookies)try{this.dpCookies=JSON.parse(this.dpCookies)}catch(e){this.dpCookies=!1}else this.dpCookies=!1},e.prototype.loadCheckbox=function(e,t,o){var n=this,i="dp--cookie-"+e,s=document.getElementById(i),r=!1,c=!1;if(!0===t?this.dpCookies&&this.dpCookies.hasOwnProperty(i)&&(r=this.dpCookies[i],c=!0):void 0!==o&&(r=o,c=!0),s)return c&&(s.checked=r),n.checkboxes.map((function(t,o){t.name==e&&(n.checkboxes[o].checked=s.checked)})),s;n.checkboxes.map((function(t,o){c&&t.name==e&&(n.checkboxes[o].checked=r)}))},e.prototype.loadContentDescription=function(){var e=DPCookieConsent.getCookieElementsByTag("script","data-dp-cookieDesc");e=e.length>0?e[0].innerHTML:a.a,window.cookieconsent_options.content.cookieDesc=this.replaceLabels(e)},e.prototype.loadContentRevoke=function(){var e=DPCookieConsent.getCookieElementsByTag("script","data-dp-cookieRevoke");e.length>0?window.cookieconsent_options.revokeBtn=e[0].innerHTML:window.cookieconsent_options.revokeBtn=y.a},e.prototype.defaults=function(){window.cookieconsent_options=C()(this.settings,window.cookieconsent_options)},e.prototype.init=function(){this.defaults(),o(15),this.loadContentDescription("data-dp-cookieDesc",a.a),this.loadContentRevoke("data-dp-cookieRevoke",y.a),"dpextend"==window.cookieconsent_options.layout&&this.initCheckboxes();var e={autoOpen:window.cookieconsent_options.autoOpen,content:window.cookieconsent_options.content,theme:window.cookieconsent_options.theme,position:window.cookieconsent_options.position,palette:window.cookieconsent_options.palette,dismissOnScroll:window.cookieconsent_options.dismissOnScroll,type:window.cookieconsent_options.type,layout:window.cookieconsent_options.layout,revokable:window.cookieconsent_options.revokable,cookie:window.DPCookieConsent.cookie,layouts:{dpextend:k.a},elements:{messagelink:u.a,dpmessagelink:p.a,"allow-all":f.a},revokeBtn:window.cookieconsent_options.revokeBtn,compliance:{"opt-in":i.a},onPopupOpen:function(){window.DPCookieConsent.setClass(),window.DPCookieConsent.loadCheckboxes()},onPopupClose:function(){window.DPCookieConsent.setClass(!0)},onInitialise:function(e){!this.hasConsented()||"dismiss"!=e&&"allow"!=e||(window.DPCookieConsent.loadCheckboxes(),window.DPCookieConsent.loadCookies(),window.DPCookieConsent.fireEvent("dp--cookie-accept-init"))},onStatusChange:function(e){"opt-in"==window.cookieconsent_options.type&&"dpextend"===window.cookieconsent_options.layout&&"dismiss"==e&&window.DPCookieConsent.checkboxes.map((function(e){window.DPCookieConsent.loadCheckbox(e.name,!1,!0)}));if(window.DPCookieConsent.setCheckboxes(),!this.hasConsented()||"dismiss"!=e&&"allow"!=e)window.DPCookieConsent.fireEvent("dp--cookie-deny");else{var t=!1;window.DPCookieConsent.settings.reloadOnRevoke&&window.DPCookieConsent.prevCheckboxes&&window.DPCookieConsent.prevCheckboxes.map((function(e,o){var n=window.DPCookieConsent.checkboxes[o];!0===e.checked&&(n&&0!=n.checked||(t=!0))})),window.DPCookieConsent.loadCookies(),window.DPCookieConsent.fireEvent("dp--cookie-accept"),t&&location.reload()}},onRevokeChoice:function(){window.DPCookieConsent.fireEvent("dp--cookie-revoke")}};window.cookieconsent.initialise(e,(function(e){window.DPCookieConsent.setPopup(e),window.DPCookieConsent.overlays(),window.DPCookieConsent.fireEvent("dp--cookie-init")}))},e.prototype.setPopup=function(e){this.popup=e},e.prototype.forceAccept=function(e){var t=this;void 0!==t.popup&&setTimeout((function(){if("dpextend"===window.cookieconsent_options.layout){t.loadCheckboxes();var o=e.getAttribute("data-cookieconsent");t.checkboxes.map((function(e,n){e.name==o?t.loadCheckbox(e.name,!1,!0):t.popup.hasAnswered()||t.loadCheckbox(e.name,!1,!1)}))}t.popup.setStatus(window.cookieconsent.status.allow),t.popup.close(!0)}),250)},e.prototype.forceDeny=function(e){var t=this;void 0!==t.popup&&setTimeout((function(){if("dpextend"===window.cookieconsent_options.layout){t.loadCheckboxes();var o=e.getAttribute("data-cookieconsent");t.checkboxes.map((function(e,n){e.name==o&&t.loadCheckbox(e.name,!1,!1)}))}t.popup.setStatus(window.cookieconsent.status.deny),t.popup.close(!0)}),250)},e.prototype.fireEvent=function(e,t){var o;t?(o=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,{$el:t}):(o=document.createEvent("Event")).initEvent(e,!0,!0),document.dispatchEvent(o)},e.prototype.overlays=function(){if(window.cookieconsent_options.overlay.notice){var e,t=this.getCookieElementsByTag("iframe");
20939if(t.length>0)for(e=0;e<t.length;e++){var o=t[e],n=o.getAttribute("data-cookieconsent-notice")||window.cookieconsent_options.content.media.notice,i=o.getAttribute("data-cookieconsent-description")||window.cookieconsent_options.content.media.desc,s=o.getAttribute("data-cookieconsent-btn")||window.cookieconsent_options.content.media.btn,r=o.getAttribute("data-cookieconsent"),c=document.createElement("div");c.classList.add("dp--overlay");var a="";window.cookieconsent_options.overlay.btn.background&&(a+="background:"+window.cookieconsent_options.overlay.btn.background+";"),window.cookieconsent_options.overlay.btn.text&&(a+="color:"+window.cookieconsent_options.overlay.btn.text+";"),c.innerHTML=w.a.replace("{{notice}}",n).replace("{{desc}}",i).replace("{{type}}",r).replace("{{style}}",'style="'+a+'"').replace("{{btn}}",s),window.cookieconsent_options.overlay.box.background&&(c.style.background=window.cookieconsent_options.overlay.box.background),window.cookieconsent_options.overlay.box.text&&(c.style.color=window.cookieconsent_options.overlay.box.text),o.parentNode.appendChild(c)}}},window.DPCookieConsent=new e,window.DPCookieConsent.init()}))},function(e,t){function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"===("undefined"==typeof window?"undefined":o(window))&&(n=window)}e.exports=n},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t){function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var o=" ";return 1===e.nodeType&&(o+e.className+o).replace(/[\n\t]/g,o).indexOf(o+t+o)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var o=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(o,"")},interpolateString:function(e,t){return e.replace(/{{([a-z][a-z0-9\-_]*)}}/gi,(function(e){return t(arguments[1])||""}))},getCookie:function(e){var t=("; "+document.cookie).split("; "+e+"=");return t.length<2?void 0:t.pop().split(";").shift()}
vendor: 1,445 bytes, line 20939
20939,setCookie:function(e,t,o,n,i,s){var r=new Date;r.setHours(r.getHours()+24*(o||365));var c=[e+"="+t,"expires="+r.toUTCString(),"path="+(i||"/")];n&&c.push("domain="+n),s&&c.push("secure"),document.cookie=c.join(";")},deepExtend:function(e,t){for(var o in t)t.hasOwnProperty(o)&&(o in e&&this.isPlainObject(e[o])&&this.isPlainObject(t[o])?this.deepExtend(e[o],t[o]):e[o]=t[o]);return e},throttle:function(e,t){var o=!1;return function(){o||(e.apply(this,arguments),o=!0,setTimeout((function(){o=!1}),t))}},hash:function(e){var t,o,n=0;if(0===e.length)return n;for(t=0,o=e.length;t<o;++t)n=(n<<5)-n+e.charCodeAt(t),n|=0;return n},normaliseHex:function(e){return"#"==e[0]&&(e=e.substr(1)),3==e.length&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),e},getContrast:function(e){return e=this.normaliseHex(e),(299*parseInt(e.substr(0,2),16)+587*parseInt(e.substr(2,2),16)+114*parseInt(e.substr(4,2),16))/1e3>=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),o=38+(t>>16),n=38+(t>>8&255),i=38+(255&t);return"#"+(16777216+65536*(o<255?o<1?0:o:255)+256*(n<255?n<1?0:n:255)+(i<255?i<1?0:i:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"===o(e)&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,o){return e&&e.parentNode?t.hasClass(e,o)?e:this.traverseDOMPath(e.parentNode,o):null}};
20939e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var o in t)if(t.hasOwnProperty(o)&&void 0!==e.style[o+"ransition"])return t[o];return""}(),e.hasTransition=!!e.transitionEnd;var n=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){var o={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"❌",target:"_blank",policy:"Cookie Policy"},elements:{header:'<span class="cc-header">{{header}}</span> ',message:'<span id="cookieconsent:desc" class="cc-message">{{message}}</span>',messagelink:'<span id="cookieconsent:desc" class="cc-message">{{message}} <a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" rel="noopener noreferrer nofollow" target="{{target}}">{{link}}</a></span>',dismiss:'<a aria-label="dismiss cookie message" role=button tabindex="0" class="cc-btn cc-dismiss">{{dismiss}}</a>',allow:'<a aria-label="allow cookies" role=button tabindex="0" class="cc-btn cc-allow">{{allow}}</a>',deny:'<a aria-label="deny cookies" role=button tabindex="0" class="cc-btn cc-deny">{{deny}}</a>',link:'<a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" rel="noopener noreferrer nofollow" target="{{target}}">{{link}}</a>',close:'<span aria-label="dismiss cookie message" role=button tabindex="0" class="cc-close">{{close}}</span>'},window:'<div role="dialog" aria-live="polite" aria-label="cookieconsent" aria-describedby="cookieconsent:desc" class="cc-window {{classes}}">\x3c!--googleoff: all--\x3e{{children}}\x3c!--googleon: all--\x3e</div>',revokeBtn:'<div class="cc-revoke {{classes}}">{{policy}}</div>',compliance:{info:'<div class="cc-compliance">{{dismiss}}</div>',"opt-in":'<div class="cc-compliance cc-highlight">{{deny}}{{allow}}</div>',"opt-out":'<div class="cc-compliance cc-highlight">{{deny}}{{allow}}</div>'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};function i(){this.initialise.apply(this,arguments)}function s(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function r(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function c(){var t=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return t(e.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return t(e.status.allow),!0;var o=Object.keys(e.status),n=this.getStatus(),i=o.indexOf(n)>=0;return i&&t(n),i}function a(){var e=this.options.position.split("-"),t=[];return e.forEach((function(e){t.push("cc-"+e)})),t}function l(){var e=this.options,o="top"==e.position||"bottom"==e.position?"banner":"floating";t.isMobile()&&(o="floating");var n=["cc-"+o,"cc-type-"+e.type,"cc-theme-"+e.theme];e.static&&n.push("cc-static"),n.push.apply(n,a.call(this));h.call(this,this.options.palette);return this.customStyleSelector&&n.push(this.customStyleSelector),n}function u(){var e={},o=this.options;o.showLink||(o.elements.link="",o.elements.messagelink=o.elements.message),Object.keys(o.elements).forEac
20939h((function(n){e[n]=t.interpolateString(o.elements[n],(function(e){var t=o.content[e];return e&&"string"==typeof t&&t.length?t:""}))}));var n=o.compliance[o.type];n||(n=o.compliance.info),e.compliance=t.interpolateString(n,(function(t){return e[t]}));var i=o.layouts[o.layout];return i||(i=o.layouts.basic),t.interpolateString(i,(function(t){return e[t]}))}function d(o){var n=this.options,i=document.createElement("div"),s=n.container&&1===n.container.nodeType?n.container:document.body;i.innerHTML=o;var r=i.children[0];return r.style.display="none",t.hasClass(r,"cc-window")&&e.hasTransition&&t.addClass(r,"cc-invisible"),this.onButtonClick=p.bind(this),r.addEventListener("click",this.onButtonClick),n.autoAttach&&(s.firstChild?s.insertBefore(r,s.firstChild):s.appendChild(r)),r}function p(o){var i=t.traverseDOMPath(o.target,"cc-btn")||o.target;if(t.hasClass(i,"cc-btn")){var s=i.className.match(new RegExp("\\bcc-("+n.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(i,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0)),t.hasClass(i,"cc-revoke")&&this.revokeChoice()}function h(o){var n=t.hash(JSON.stringify(o)),i="cc-color-override-"+n,s=t.isPlainObject(o);return this.customStyleSelector=s?i:null,s&&function(o,n,i){if(e.customStyles[o])return void++e.customStyles[o].references;var s={},r=n.popup,c=n.button,a=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[i+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[i+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[i+" .cc-link,"+i+" .cc-link:active,"+i+" .cc-link:visited"]=["color: "+r.link],c&&(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[i+" .cc-btn"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background],c.padding&&s[i+" .cc-btn"].push("padding: "+c.padding),"transparent"!=c.background&&(s[i+" .cc-btn:hover, "+i+" .cc-btn:focus"]=["background-color: "+(c.hover||f(c.background))]),a?(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[i+" .cc-highlight .cc-btn:first-child"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background]):s[i+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var l=document.createElement("style");document.head.appendChild(l),e.customStyles[o]={references:1,element:l.sheet};var u=-1;for(var d in s)s.hasOwnProperty(d)&&l.sheet.insertRule(d+"{"+s[d].join(";")+"}",++u)}(n,o,"."+i),s}function f(e){return"000000"==(e=t.normaliseHex(e))?"#222":t.getLuminance(e)}function v(e,t){for(var o=0,n=e.length;o<n;++o){var i=e[o];if(i instanceof RegExp&&i.test(t)||"string"==typeof i&&i.length&&i===t)return!0}return!1}function k(){var o=this.setStatus.bind(this),n=this.close.bind(this),i=this.options.dismissOnTimeout;"number"==typeof i&&i>=0&&(this.dismissTimeout=window.setTimeout((function(){o(e.status.dismiss),n(!0)}),Math.floor(i)));var s=this.options.dismissOnScroll;if("number"==typeof s&&s>=0){var r=function t(i){window.pageYOffset>Math.floor(s)&&(o(e.status.dismiss),n(!0),window.removeEventListener("scroll",t),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=r,window.addEventListener("scroll",r))}var c=this.options.dismissOnWindowClick,a=this.options.ignoreClicksFrom;if(c){var l=function(i){for(var s=!1,r=i.path.length,c=a.length,u=0;u<r;u++)if(!s)for(var d=0;d<c;d++)s||(s=t.hasClass(i.path[u],a[d]));s||(o(e.status.dismiss),n(!0),window.removeEventListener("click",l),window.removeEventListener("touchend",l),this.onWindowClick=null)}.bind(this);this.options.enabled&&(this.onWindowClick=l,window.addEventListener("click",l),window.addEventListener("touchend",l))}}function b(){if("info"!=this.options.type&&(this.options.revokable=!0),t.isMobile()&&(this.options.animateRevokable=!1),this.options.revokable){var e=a.call(this);this.options.animateRevokable&&e.push("cc-animate"),this.customStyleSelector&&e.push(this.customStyleSelector);var o=this.options.revokeBtn.replace("{{classes}}",e.join(" ")).replace("{{policy}}",this.options.content.policy);this.revokeBtn=d.call(this,o);var n=this.revokeBtn;if(this.options.animateRevokable){var i=t.throttle((function(e){var o=!1,i=window.innerHeight-20;
vendor: 4,691 bytes, line 20939
20939t.hasClass(n,"cc-top")&&e.clientY<20&&(o=!0),t.hasClass(n,"cc-bottom")&&e.clientY>i&&(o=!0),o?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")}),200);this.onMouseMove=i,window.addEventListener("mousemove",i)}}}return i.prototype.initialise=function(e){this.options&&this.destroy(),t.deepExtend(this.options={},o),t.isPlainObject(e)&&t.deepExtend(this.options,e),c.call(this)&&(this.options.enabled=!1),v(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),v(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var n=this.options.window.replace("{{classes}}",l.call(this).join(" ")).replace("{{children}}",u.call(this)),i=this.options.overrideHTML;if("string"==typeof i&&i.length&&(n=i),this.options.static){var s=d.call(this,'<div class="cc-grower">'+n+"</div>");s.style.display="",this.element=s.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=d.call(this,n);k.call(this),b.call(this),this.options.autoOpen&&this.autoOpen()},i.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(o){if(t.isPlainObject(o)){var n=t.hash(JSON.stringify(o)),i=e.customStyles[n];if(i&&!--i.references){var s=i.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}(this.options.palette),this.options=null},i.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},i.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},i.prototype.fadeIn=function(){var o=this.element;if(e.hasTransition&&o&&(this.afterTransition&&r.call(this,o),t.hasClass(o,"cc-invisible"))){if(o.style.display="",this.options.static){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}this.openingTimeout=setTimeout(s.bind(this,o),20)}},i.prototype.fadeOut=function(){var o=this.element;e.hasTransition&&o&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),s.bind(this,o)),t.hasClass(o,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=r.bind(this,o),o.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(o,"cc-invisible")))},i.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},i.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},i.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},i.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},i.prototype.hasConsented=function(t){var o=this.getStatus();return o==e.status.allow||o==e.status.dismiss},i.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},i.prototype.setStatus=function(o){var n=this.options.cookie,i=t.getCookie(n.name),s=Object.keys(e.status).indexOf(i)>=0;Object.keys(e.status).indexOf(o)>=0?(t.setCookie(n.name,o,n.expiryDays,n.domain,n.path,n.secure),this.options.onStatusChange.call(this,o,s)):this.clearStatus()},i.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},i.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},i}(),e.Location=function(){var e={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var o=JSON.parse(t);return o.error?s(o):{code:o.country}}
20939catch(e){return s({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var o=JSON.parse(t);return"ERROR"==o.statusCode?s({error:o.statusMessage}):{code:o.countryCode}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){window.geoip2?geoip2.country((function(t){try{e({code:t.country.iso_code})}catch(t){e(s(t))}}),(function(t){e(s(t))})):e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};function o(o){t.deepExtend(this.options={},e),t.isPlainObject(o)&&t.deepExtend(this.options,o),this.currentServiceIndex=-1}function n(e,t,o){var n,i=document.createElement("script");i.type="text/"+(e.type||"javascript"),i.src=e.src||e,i.async=!1,i.onreadystatechange=i.onload=function(){var e=i.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),i.onreadystatechange=i.onload=null)},document.body.appendChild(i),n=setTimeout((function(){t.done=!0,t(),i.onreadystatechange=i.onload=null}),o)}function i(e,t,o,n,i){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(i))for(var r=0,c=i.length;r<c;++r){var a=i[r].split(":",2);s.setRequestHeader(a[0].replace(/^\s+|\s+$/g,""),a[1].replace(/^\s+|\s+$/g,""))}"function"==typeof t&&(s.onreadystatechange=function(){s.readyState>3&&t(s)}),s.send(n)}function s(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}return o.prototype.getNextService=function(){var e;do{e=this.getServiceByIdx(++this.currentServiceIndex)}while(this.currentServiceIndex<this.options.services.length&&!e);return e},o.prototype.getServiceByIdx=function(e){var o=this.options.services[e];if("function"==typeof o){var n=o();return n.name&&t.deepExtend(n,this.options.serviceDefinitions[n.name](n)),n}return"string"==typeof o?this.options.serviceDefinitions[o]():t.isPlainObject(o)?this.options.serviceDefinitions[o.name](o):null},o.prototype.locate=function(e,t){var o=this.getNextService();o?(this.callbackComplete=e,this.callbackError=t,this.runService(o,this.runNextServiceOnError.bind(this))):t(new Error("No services to run"))},o.prototype.setupUrl=function(e){var t=this.getCurrentServiceOpts();return e.url.replace(/\{(.*?)\}/g,(function(o,n){if("callback"===n){var i="callback"+Date.now();return window[i]=function(t){e.__JSONP_DATA=JSON.stringify(t)},i}if(n in t.interpolateUrl)return t.interpolateUrl[n]}))},o.prototype.runService=function(e,t){var o=this;e&&e.url&&e.callback&&(e.isScript?n:i)(this.setupUrl(e),(function(n){var i=n?n.responseText:"";e.__JSONP_DATA&&(i=e.__JSONP_DATA,delete e.__JSONP_DATA),o.runServiceCallback.call(o,t,e,i)}),this.options.timeout,e.data,e.headers)},o.prototype.runServiceCallback=function(e,t,o){var n=this,i=t.callback((function(t){i||n.onServiceResult.call(n,e,t)}),o);i&&this.onServiceResult.call(this,e,i)},o.prototype.onServiceResult=function(e,t){t instanceof Error||t&&t.error?e.call(this,t,null):e.call(this,null,t)},o.prototype.runNextServiceOnError=function(e,t){if(e){this.logError(e);var o=this.getNextService();o?this.runService(o,this.runNextServiceOnError.bind(this)):this.completeService.call(this,this.callbackError,new Error("All services failed"))}else this.completeService.call(this,this.callbackComplete,t)},o.prototype.getCurrentServiceOpts=function(){var e=this.options.services[this.currentServiceIndex];return"string"==typeof e?{name:e}:"function"==typeof e?e():t.isPlainObject(e)?e:{}},o.prototype.completeService=function(e,t){this.currentServiceIndex=-1,e&&e(t)},o.prototype.logError=function(e){var t=this.currentServiceIndex,o=this.getServiceByIdx(t);console.warn("The service["+t+"] ("+o.url+") responded with the following error",e)},o}(),e.Law=function(){var e={regionalLaw:!0,hasLaw:["AT","BE","BG","HR","CZ","CY","DK","EE","FI","FR","DE","EL","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","SK","ES","SE","GB","UK","GR","EU"],revokable:["HR","CY","DK","EE","FR","DE","LV","LT","NL","PT","ES"],explicitAction:["HR","IT","ES"]};function o(e){this.initialise.apply(this,arguments)}return o.prototype.initialise=function(o){t.deepExtend(this.options={},e),t.isPlainObject(o)&&t.deepExtend(this.options,o)},o.prototype.get=function(e){var t=this.options;return{hasLaw:t.hasLaw.indexOf(e)>=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},o.prototype.applyLaw=function(e,t){var o=this.get(t);return o.hasLaw||(e.enabled=!1,"function"==typeof e.onNoCookieLaw&&e.onNoCookieLaw(t,o)),this.options.regionalLaw&&(o.revokable&&(e.revokable=!0),o.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},o}(),e.initialise=function(o,n,i){var s=new e.Law(o.law);n||(n=function(){}),i||(i=function(){});var r=Object.keys(e.status),c=t.getCookie("cookieconsent_status");r.indexOf(c)>=0?n(new e.Popup(o)):e.getCountryCode(o,(function(t){delete o.law,delete o.location,t.code&&(o=s.applyLaw(o,t.code)),n(new e.Popup(o))}),(function(t){delete o.law,delete o.location,i(t,new e.Popup(o))}))},e.getCountryCode=function(t,o,n){t.law&&t.law.countryCode?o({code:t.law.countryCode}):t.location?new e.Location(t.location).locate((function(e){o(e||{})}),n):o({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{})},function(e,t){}]); 20940 20941jQuery(document).ready(function () { 20942 20943 $.support.cors = true; 20944 20945 /*! 20946 * jQuery Cookie Plugin v1.3.1 20947 * https://github.com/carhartl/jquery-cookie 20948 * 20949 * Copyright 2013 Klaus Hartl 20950 * Released under the MIT license 20951 */ 20952 (function (factory) { 20953 if (typeof define === 'function' && define.amd) { 20954// AMD. Register as anonymous module. 20955 define(['jquery'], factory); 20956 } else { 20957// Browser globals. 20958 factory(jQuery); 20959 } 20960 }(function ($) { 20961 20962 var pluses = /\+/g; 20963 20964 function raw(s) { 20965 return s; 20966 } 20967 20968 function decoded(s) { 20969 return decodeURIComponent(s.replace(pluses, ' ')); 20970 } 20971 20972 function converted(s) { 20973 if (s.indexOf('"') === 0) { 20974// This is a quoted cookie as according to RFC2068, unescape 20975 s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 20976 } 20977 try { 20978 return config.json ? JSON.parse(s) : s; 20979 } catch (er) { 20980 } 20981 } 20982 20983 var config = $.cookie = function (key, value, options) { 20984 20985// write 20986 if (value !== undefined) { 20987 options = $.extend({}, config.defaults, options); 20988 20989 if (typeof options.expires === 'number') { 20990 var days = options.expires, t = options.expires = new Date(); 20991 t.setDate(t.getDate() + days); 20992 } 20993 20994 value = config.json ? JSON.stringify(value) : String(value); 20995 20996 return (document.cookie = [ 20997 config.raw ? key : encodeURIComponent(key), 20998 '=', 20999 config.raw ? value : encodeURIComponent(value), 21000 options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 21001 options.path ? '; path=' + options.path : '', 21002 options.domain ? '; domain=' + options.domain : '', 21003 options.secure ? '; secure' : '' 21004 ].join(''));
21005 } 21006 21007// read 21008 var decode = config.raw ? raw : decoded; 21009 var cookies = document.cookie.split('; '); 21010 var result = key ? undefined : {}; 21011 for (var i = 0, l = cookies.length; i < l; i++) { 21012 var parts = cookies[i].split('='); 21013 var name = decode(parts.shift()); 21014 var cookie = decode(parts.join('=')); 21015 21016 if (key && key === name) { 21017 result = converted(cookie); 21018 break; 21019 } 21020 21021 if (!key) { 21022 result[name] = converted(cookie); 21023 } 21024 } 21025 21026 return result; 21027 }; 21028 21029 config.defaults = {}; 21030 21031 $.removeCookie = function (key, options) { 21032 if ($.cookie(key) !== undefined) { 21033// Must not alter options, thus extending a fresh object... 21034 $.cookie(key, '', $.extend({}, options, {expires: -1})); 21035 return true; 21036 } 21037 return false; 21038 }; 21039 21040 })); 21041 21042 /* ------------------------------------------------------------------------------------------------- 21043 * spinner 21044 * ------------------------------------------------------------------------------------------------- 21045 */ 21046 21047 (function ($) { 21048 $.fn.spin = function (opts, color) { 21049 var presets = { 21050 "tiny": { 21051 lines: 8, 21052 length: 2, 21053 width: 2, 21054 radius: 3 21055 }, 21056 "small": { 21057 lines: 8, 21058 length: 4, 21059 width: 3, 21060 radius: 5 21061 }, 21062 "large": { 21063 lines: 10, 21064 length: 8, 21065 width: 4, 21066 radius: 8 21067 } 21068 }; 21069 if (Spinner) { 21070 return this.each(function () { 21071 var $this = $(this), 21072 data = $this.data(); 21073 21074 if (data.spinner) { 21075 data.spinner.stop(); 21076 delete data.spinner; 21077 } 21078 if (opts !== false) { 21079 if (typeof opts === "string") { 21080 if (opts in presets) { 21081 opts = presets[opts]; 21082 } else { 21083 opts = {}; 21084 } 21085 if (color) { 21086 opts.color = color; 21087 } 21088 } 21089 data.spinner = new Spinner($.extend({ 21090 color: $this.css('color') 21091 }, opts)).spin(this); 21092 } 21093 }); 21094 } else { 21095 throw "Spinner class not available."; 21096 } 21097 }; 21098 })(jQuery); 21099 21100 21101 21102 function number_format(number, decimals, dec_point, thousands_sep) { 21103 // http://kevin.vanzonneveld.net 21104 // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) 21105 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 21106 // + bugfix by: Michael White (http://getsprink.com) 21107 // + bugfix by: Benjamin Lupton 21108 // + bugfix by: Allan Jensen (http://www.winternet.no) 21109 // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) 21110 // + bugfix by: Howard Yeend 21111 // + revised by: Luke Smith (http://lucassmith.name) 21112 // + bugfix by: Diogo Resende 21113 // + bugfix by: Rival 21114 // + input by: Kheang Hok Chin (http://www.distantia.ca/) 21115 // + improved by: davook 21116 // + improved by: Brett Zamir (http://brett-zamir.me) 21117 // + input by: Jay Klehr 21118 // + improved by: Brett Zamir (http://brett-zamir.me) 21119 // + input by: Amir Habibi (http://www.residence-mixte.com/) 21120 // + bugfix by: Brett Zamir (http://brett-zamir.me) 21121 // + improved by: Theriault 21122 // + input by: Amirouche 21123 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 21124 // * example 1: number_format(1234.56); 21125 // * returns 1: '1,235' 21126 // * example 2: number_format(1234.56, 2, ',', ' '); 21127 // * returns 2: '1 234,56' 21128 // * example 3: number_format(1234.5678, 2, '.', ''); 21129 // * returns 3: '1234.57' 21130 // * example 4: number_format(67, 2, ',', '.'); 21131 // * returns 4: '67,00' 21132 // * example 5: number_format(1000); 21133 // * returns 5: '1,000' 21134 // * example 6: number_format(67.311, 2); 21135 // * returns 6: '67.31' 21136 // * example 7: number_format(1000.55, 1); 21137 // * returns 7: '1,000.6' 21138 // * example 8: number_format(67000, 5, ',', '.'); 21139 // * returns 8: '67.000,00000' 21140 // * example 9: number_format(0.9, 0); 21141 // * returns 9: '1' 21142 // * example 10: number_format('1.20', 2); 21143 // * returns 10: '1.20' 21144 // * example 11: number_format('1.20', 4); 21145 // * returns 11: '1.2000' 21146 // * example 12: number_format('1.2000', 3); 21147 // * returns 12: '1.200' 21148 // * example 13: number_format('1 000,50', 2, '.', ' '); 21149 // * returns 13: '100 050.00' 21150 // Strip all characters but numerical ones. 21151 number = (number + '').replace(/[^0-9+\-Ee.]/g, ''); 21152 var n = !isFinite(+number) ? 0 : +number, 21153 prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), 21154 sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, 21155 dec = (typeof dec_point === 'undefined') ? '.' : dec_point, 21156 s = '', 21157 toFixedFix = function (n, prec) { 21158 var k = Math.pow(10, prec); 21159 return '' + Math.round(n * k) / k; 21160 }; 21161 // Fix for IE parseFloat(0.55).toFixed(0) = 0; 21162 s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.'); 21163 if (s[0].length > 3) { 21164 s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep); 21165 } 21166 if ((s[1] || '').length < prec) { 21167 s[1] = s[1] || ''; 21168 s[1] += new Array(prec - s[1].length + 1).join('0'); 21169 } 21170 return s.join(dec); 21171 } 21172 21173 21174 21175 /* ------------------------------------------------------------------------------------------------- 21176 * NeundreiviertelSmartObjects Class 21177 * ------------------------------------------------------------------------------------------------- 21178 */ 21179 21180 21181 21182 NeundreiviertelSmartObjects = function (config) { 21183 21184 // configuration 21185 this.config = { 21186 baseUrl: '', 21187 view: 'category', 21188 language: 'de', 21189 bbqEnabled: true, 21190 filters: { 21191 categories: { 21192 type: 'occurrences', 21193 field: 'categories', 21194 title: { 21195 de: 'Kategorie', 21196 en: 'Category' 21197 }, 21198 templateId: 'template-filter-selection-occurrences', 21199 build: function ($this, filter, filterName) { 21200 $this.buildFilterFunctions.occurrences($this, filter, filterName); 21201 $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links'); 21202// $('#filter-' + filterName + ' .element-' + filterName).each(function (cIndex, category) { 21203// for (pIndex in $this.data.products) { 21204// if (jQuery.inArray(String($(category).data('value')), $this.data.products[pIndex]['categories']) >= 0 && $this.data.products[pIndex]['products_image']) { 21205// $(category).css({ 21206// 'background-image': 'url(media/images/info/' + $this.data.products[pIndex]['products_image'] + ')', 21207// 'background-repeat': 'no-repeat', 21208// 'background-position': 'center center',
21209// 'background-size': 'cover' 21210// }); 21211// break; 21212// } 21213// } 21214// }); 21215 } 21216 }, 21217 size: { 21218 type: 'occurrences', 21219 field: 'ext_size', 21220 isProductOption: true, 21221 title: { 21222 de: 'GröÃe', 21223 en: 'Size' 21224 }, 21225 templateId: 'template-filter-selection-occurrences', 21226 letterSizesOrder: ['XXS', 'XS', 'S', "S\\/M", 'M', "M\\/L", 'L', 'LL', 'XL', 'XXL'], 21227 build: function ($this, filter, filterName) { 21228 $this.buildFilterFunctions.occurrences($this, filter, filterName); 21229 container = $('#filter-' + filterName + ' .element-' + filterName).first().parents('.filter-elements').first(); 21230 21231 // seperate integer-sizes 21232 integerSizes = new Array(); 21233 $('#filter-' + filterName + ' .element-' + filterName).each(function (cIndex, size) { 21234 safeValue = $(size).data('value').replace('/', '\/'); 21235 regexpResult = safeValue.match(/^([0-9]+)([A-Z]{1})$/); 21236 if (jQuery.isNumeric($(size).data('value')) || regexpResult) { 21237 integerSizes.push($(size)); 21238 } 21239 }); 21240 integerSizes.sort($this.compareSizeByIntegerValue); 21241 $(container).prepend('<div class="integerSizes btn-group"></div>'); 21242 for (sIndex in integerSizes) { 21243 $(integerSizes[sIndex]).addClass('btn'); 21244 $(container).find('.integerSizes').append(integerSizes[sIndex]); 21245 } 21246 21247 $(container).find('.inner').removeClass('font-bold'); 21248 $(container).find('.inner').addClass('btn-group'); 21249 $(container).find('.inner a').addClass('btn'); 21250 $(container).find('.inner').addClass('stringSizes'); 21251 $(container).find('.stringSizes').removeClass('inner'); 21252 21253 // seperate letter sizes 21254 letterSizes = new Array(); 21255 $('#filter-' + filterName + ' .stringSizes .element-' + filterName).each(function (cIndex, size) { 21256 letterPosition = jQuery.inArray($(size).data('value'), $this.config.filters.size.letterSizesOrder); 21257 if (letterPosition >= 0) { 21258 $(size).data('position', letterPosition); 21259 letterSizes.push($(size)); 21260 } 21261 }); 21262 21263 $(container).find('.integerSizes').after('<div class="letterSizes btn-group"></div>'); 21264 for (lIndex in $this.config.filters.size.letterSizesOrder) { 21265 for (sIndex in letterSizes) { 21266 if ($(letterSizes[sIndex]).data('position') == lIndex) { 21267 $(container).find('.letterSizes').append(letterSizes[sIndex]); 21268 } 21269 } 21270 } 21271 21272 21273 21274 $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links'); 21275 }, 21276 sortOptions: function (options, context) { 21277 if (options.length > 0) { 21278 if (jQuery.isNumeric(options[0])) { 21279 options.sort(); 21280 } 21281 else if (options[0].match(/^[0-9]+(\.[0-9]+)*/)) { 21282 options.sort(context.compareSizeByShoeSize); 21283 } 21284 else { 21285 options.sort(context.compareSizeByLetter); 21286 } 21287 } 21288 }, 21289 onOptionChange: function () { 21290 21291 } 21292 }, 21293 color: { 21294 type: 'occurrences', 21295 //field: ['ext_color_primary', 'ext_color_secondary'], 21296 field: 'ext_color_primary', 21297 isProductOption: true, 21298 imageSensitive: true, 21299 title: { 21300 de: 'Farbe', 21301 en: 'Color' 21302 }, 21303 templateId: 'template-filter-selection-occurrences', 21304 build: function ($this, filter, filterName) { 21305 $this.buildFilterFunctions.occurrences($this, filter, filterName); 21306 $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links'); 21307 }, 21308 sortOptions: function (options, context) { 21309 options.sort(); 21310 } 21311 }, 21312 material: { 21313 type: 'occurrences', 21314 //field: ['ext_material_primary', 'ext_material_secondary'], 21315 field: 'ext_material_primary', 21316 title: { 21317 de: 'Material', 21318 en: 'Material' 21319 }, 21320 templateId: 'template-filter-selection-occurrences', 21321 build: function ($this, filter, filterName) { 21322 $this.buildFilterFunctions.occurrences($this, filter, filterName); 21323 $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links'); 21324 } 21325 }, 21326 price: { 21327 type: 'range', 21328 field: 'price_plain', 21329 title: { 21330 de: 'Preis', 21331 en: 'Price' 21332 }, 21333 templateId: 'template-filter-selection-range', 21334 build: function ($this, filter, filterName) { 21335 $this.buildFilterFunctions.range($this, filter, filterName); 21336 $this.bindFilterEventFunctions.addToExecutionQueue($this, 'range'); 21337 } 21338 } 21339 }, 21340 filterCols: 5, 21341 productsCols: 4, 21342 pagination: { 21343 maxPages: 5, 21344 prevNextPages: 2 21345 }, 21346 translations: { 21347 from: { 21348 de: 'ab', 21349 en: 'from' 21350 }, 21351 to: { 21352 de: 'bis', 21353 en: 'to' 21354 }, 21355 min: { 21356 de: 'ab', 21357 en: 'from' 21358 }, 21359 max: { 21360 de: 'bis', 21361 en: 'to' 21362 }, 21363 resultAmount: { 21364 none: { 21365 de: 'keine Produkte gefunden.',
21366 en: 'no products found.' 21367 }, 21368 singular: { 21369 de: 'Produkt gefunden.', 21370 en: 'product found.' 21371 }, 21372 plural: { 21373 de: 'Produkte gefunden.', 21374 en: 'products found.' 21375 } 21376 }, 21377 moreImages: { 21378 de: 'weitere Bilder', 21379 en: 'more images' 21380 }, 21381 badges: { 21382 'new': { 21383 de: 'Neu!', 21384 en: 'New!' 21385 }, 21386 specialOffer: { 21387 de: 'Angebot!', 21388 en: 'Special Offer!' 21389 } 21390 } 21391 }, 21392 selectors: { 21393 filtersContainer: '.products-filter', 21394 templateFiltersNewRow: 'template-filter-new-row', 21395 filterRow: '.filter-row', 21396 filterTitle: '.filter-title .text', 21397 filterElements: '.filter-elements', 21398 filterRange: { 21399 mover: '#box-filter .filter-range .mover', 21400 titleMin: '.title-min', 21401 titleMax: '.title-max', 21402 valueMin: '.value-min', 21403 valueMax: '.value-max', 21404 }, 21405 selectedFiltersContainer: 'box-filter-selected', 21406 templateSelectedFilterLink: 'template-selected-filter-link', 21407 configuration: { 21408 container: '.products-configuration', 21409 sortBy: '.products-configuration .sortBy', 21410 sortOrder: '.products-configuration .sortOrder', 21411 presentation: '.products-configuration .presentation', 21412 resultsPerPage: '.products-configuration .resultsPerPage' 21413 }, 21414 pagination: { 21415 container: '.page-controls-pages', 21416 first: '.page-controls-pages .first-page', 21417 prev: '.page-controls-pages .prev-page', 21418 pages: '.page-controls-pages .pages-group', 21419 next: '.page-controls-pages .next-page', 21420 last: '.page-controls-pages .last-page', 21421 resultAmount: '.page-controls-result-amount' 21422 }, 21423 productsContainer: '#box-products', 21424 productsAppend: { 21425 grid: '#box-products .row-fluid:last', 21426 list: '#box-products' 21427 }, 21428 templateProduct: { 21429 grid: 'template-product-grid', 21430 list: 'template-product-list' 21431 }, 21432 templateProductOptions: { 21433 grid: 'template-product-options-grid', 21434 list: 'template-product-options-list', 21435 detail: 'template-product-options-detail' 21436 }, 21437 productsLinks: '.product .product-link', 21438 productOptions: '.options', 21439 productOptionLinks: '.options .values a', 21440 productsAddToCart: '.product .actions .cart a.action', 21441 productsAddToFavourites: '.product .actions .fav a.action', 21442 productDetail: '#product-detail', 21443 productDetailFull: '#product-detail-full', 21444 productDetailAddToCart: '.addToCart', 21445 templateProductDetailInfo: 'template-product-additional-info', 21446 productDetailAdditionalInfo: '#product-detail-additional-infos', 21447 templateProductsNewRow: 'template-products-new-row', 21448 cart: '#header-cart', 21449 cartContent: '#header-cart-content', 21450 favourites: '#header-favourites', 21451 favouritesContent: '#header-favourites-content', 21452 search: { 21453 form: '#globalSearch', 21454 input: '#globalSearch-query' 21455 } 21456 }, 21457 classes: { 21458 filterAddLink: 'filter-add', 21459 optionLink: 'btn option-value', 21460 resultAmount: 'amount font-bold', 21461 buttonActive: 'btn-danger', 21462 buttonActiveIcon: 'icon-white' 21463 }, 21464 detail: { 21465 additonalInfos: [ 21466 { 21467 field: 'ext_color_secondary', 21468 title: 'weitere Farbe' 21469 }, 21470 { 21471 field: 'ext_material_primary', 21472 title: 'Material' 21473 }, 21474 { 21475 field: 'ext_material_secondary', 21476 title: 'weiteres Material' 21477 } 21478 ] 21479 }, 21480 cart: { 21481 bindFixedPositionOn: '#nav' 21482 }, 21483 favourites: { 21484 cookieName: 'site-favourites', 21485 bindFixedPositionOn: '#nav' 21486 }, 21487 events: { 21488 onBeforeFilterBuild: function ($this) { 21489 if ($this.calc.filtersCount % $this.config.filterCols == 0) { 21490 $newRow = $this.getTemplate($this.config.selectors.templateFiltersNewRow, 'filter-row-' + String($this.calc.filtersCount)); 21491 $($this.config.selectors.filtersContainer).append($newRow); 21492 } 21493 }, 21494 onAfterApplyFilter: function ($this) { 21495 newFoundProducts = []; 21496 if ($this.activeFilters.hasOwnProperty('size') || $this.activeFilters.hasOwnProperty('color') || $this.activeFilters.hasOwnProperty('material')) { 21497 for (index in $this.foundProducts) { 21498 if ($this.foundProducts[index]['products_master_model'] || (!$this.foundProducts[index]['products_master_model'] && $this.foundProducts[index]['products_master_flag'] == 0)) { 21499 newFoundProducts.push($this.foundProducts[index]); 21500 } 21501 } 21502 } 21503 else { 21504 for (index in $this.foundProducts) { 21505 if (!$this.foundProducts[index]['products_master_model']) { 21506 newFoundProducts.push($this.foundProducts[index]); 21507 } 21508 } 21509 } 21510 $this.foundProducts = newFoundProducts; 21511 }, 21512 onBeforeProductBuild: function ($this) { 21513 if ($this.searchParams.presentation == 'grid') { 21514 if ($this.calc.productsCount % $this.config.productsCols == 0) { 21515 $newRow = $this.getTemplate($this.config.selectors.templateProductsNewRow, 'products-row-' + String($this.calc.productsCount)); 21516 $($this.config.selectors.productsContainer).append($newRow); 21517 } 21518 } 21519 }, 21520 onAfterProductsBuild: function ($this) { 21521 if ($this.config.onLoadProduct) {
21522 $this.openDetailView($this.config.onLoadProduct); 21523 $($this.config.selectors.productDetail).modal('show'); 21524 } 21525 } 21526 }, 21527 onLoadProduct: false 21528 21529 } 21530 21531 $.extend(true, this.config, config); 21532 21533 // properties 21534 this.data = {}; 21535 this.calc = { 21536 filtersCount: 0, 21537 productsCount: 0 21538 } 21539 this.activeFilters = {}; 21540 this.foundProducts = []; 21541 this.searchParams = { 21542 start: 0, 21543 range: 8, 21544 presentation: 'grid', 21545 sortBy: 'price', 21546 sortOrder: 'DESC' 21547 }; 21548 21549 21550 // init function 21551 this.init = function () { 21552 $this = this; 21553 this.documentTitle = document.title; 21554 21555 // BBQ 21556 if (this.config.bbqEnabled && !$('body').data('bbq-window-hashchange')) { 21557 21558 $('body').data('bbq-window-hashchange', true); 21559 $(window).bind('hashchange', {context: this}, function (event) { 21560 bbqState = event.getState(); 21561 21562 if (bbqState.hasOwnProperty('product') && bbqState.product != '0') { 21563// bbqStateProductData = event.data.context.findInObjectArray(event.data.context.data.products, 'products_id', bbqState.product); 21564// 21565// if (bbqStateProductData && !$(event.data.context.config.selectors.productDetail).hasClass('open')) { 21566// event.data.context.config.onLoadProduct = bbqStateProductData; 21567// } 21568 } 21569 else { 21570 if ($(event.data.context.config.selectors.productDetail).hasClass('open') && !bbqState.hasOwnProperty('bundle')) { 21571 $(event.data.context.config.selectors.productDetail).modal('hide'); 21572 } 21573 } 21574 21575 if (event.data.context.config.view == 'category') { 21576 hashFilter = bbqState.hasOwnProperty('filter') ? bbqState.filter : false; 21577 filterChanges = event.data.context.findFilterChanges(hashFilter); 21578 21579 21580 if (filterChanges.add) { 21581 for (aIndex in filterChanges.add) { 21582 event.data.context.selectFilter(filterChanges.add[aIndex]); 21583 } 21584 } 21585 21586 if (filterChanges.remove) { 21587 for (aIndex in filterChanges.remove) { 21588 filterLink = $(filterChanges.remove[aIndex]); 21589 event.data.context.removeFilter(filterLink.data(), filterLink); 21590 } 21591 } 21592 21593 } 21594 21595 switch (event.data.context.config.view) { 21596 case 'category': 21597 case 'search': 21598 if (bbqState.hasOwnProperty('settings')) { 21599 21600 settingsChanged = false; 21601 if (bbqState.settings.hasOwnProperty('start') && event.data.context.searchParams.start != parseInt(bbqState.settings.start)) { 21602 settingsChanged = true; 21603 } 21604 if (bbqState.settings.hasOwnProperty('range') && event.data.context.searchParams.range != parseInt(bbqState.settings.range)) { 21605 settingsChanged = true; 21606 } 21607 if (bbqState.settings.hasOwnProperty('presentation') && event.data.context.searchParams.presentation != bbqState.settings.presentation) { 21608 settingsChanged = true; 21609 } 21610 if (bbqState.settings.hasOwnProperty('sortBy') && event.data.context.searchParams.sortBy != bbqState.settings.sortBy) { 21611 settingsChanged = true; 21612 } 21613 if (bbqState.settings.hasOwnProperty('sortOrder') && event.data.context.searchParams.sortOrder != bbqState.settings.sortOrder) { 21614 settingsChanged = true; 21615 } 21616 21617 event.data.context.searchParams = { 21618 start: bbqState.settings.hasOwnProperty('start') ? parseInt(bbqState.settings.start) : 0, 21619 range: bbqState.settings.hasOwnProperty('range') ? parseInt(bbqState.settings.range) : 8, 21620 presentation: bbqState.settings.hasOwnProperty('presentation') ? bbqState.settings.presentation : 'grid', 21621 sortBy: bbqState.settings.hasOwnProperty('sortBy') ? bbqState.settings.sortBy : 'price', 21622 sortOrder: bbqState.settings.hasOwnProperty('sortOrder') ? bbqState.settings.sortOrder : 'ASC' 21623 }; 21624 21625 21626 if (settingsChanged) { 21627 21628 event.data.context.buildPagination(); 21629 21630 //event.data.context.applyFilters(); 21631 } 21632 } 21633 break; 21634 } 21635 21636 if (bbqState.hasOwnProperty('bg')) { 21637 $('.products-grid .product .image').css({ 21638 'background-size': bbqState.bg 21639 }); 21640 } 21641 21642 }); 21643 } 21644 21645 switch ($this.config.view) { 21646 case 'category': 21647 // load products 21648 this.config.rootContainer.spin(); 21649 $.ajax('/json.php', { 21650 data: { 21651 action: 'products', 21652 category: this.config.currentCategoryId, 21653 language: this.config.language 21654 }, 21655 dataType: 'json', 21656 error: function (jqXHR, textStatus, errorThrown) { 21657 if (typeof console != 'undefined') { 21658 21659 } 21660 else { 21661 alert(errorThrown); 21662 } 21663 }, 21664 success: function (data, textStatus, jqXHR) { 21665 21666 $this.config.rootContainer.spin(false); 21667 // products data 21668 $.extend(true, $this.data, data); 21669 21670 $this.assignMastersAndSlaves(); 21671 $this.buildFilters(); 21672 $this.bindConfigurationLinkEvents(); 21673 21674 $(window).trigger('hashchange'); 21675 21676// if ($this.config.currentCategoryId && data.currentCategoryType == 'sub') { 21677// startUpCategoryData = { 21678// 'filter': 'categories', 21679// 'value': String($this.config.currentCategoryId), 21680// 'title': data.currentCategory.categories_name 21681// }; 21682// for (cIndex in $this.data.categories) { 21683// if ($this.data.categories[cIndex]['id'] == $this.config.currentCategoryId) { 21684// if ($this.data.categories[cIndex].hasOwnProperty('childIds')) { 21685// for (pIndex in $this.data.products) { 21686// for (pcIndex in $this.data.products[pIndex]['categories']) { 21687// if (jQuery.inArray($this.data.products[pIndex]['categories'][pcIndex], $this.data.categories[cIndex]['childIds']) >= 0) { 21688// $this.data.products[pIndex]['categories'].push($this.config.currentCategoryId); 21689// } 21690// } 21691// } 21692// } 21693// } 21694// } 21695// 21696// $this.selectFilter(startUpCategoryData);
21697// } 21698// else { 21699 $this.applyFilters(); 21700// } 21701 21702 21703 21704 } 21705 }); 21706 break; 21707 21708 21709 21710 21711 21712 case 'cart': 21713 // cart events 21714 if ($('#welcome').length == 0) { 21715 $(window).bind('scroll', {context: $this}, function (event) { 21716 cartOffset = $(event.data.context.config.selectors.cart).offset(); 21717 bindOffset = $(event.data.context.config.cart.bindFixedPositionOn).offset(); 21718 if ($(window).scrollTop() > bindOffset.top) { 21719 if (!$(event.data.context.config.selectors.cart).hasClass('fixed')) { 21720 cartLeft = cartOffset.left; 21721 if ($(document).innerWidth() <= 767) { 21722 cartLeft = 0; 21723 } 21724 $(event.data.context.config.selectors.cart).css({ 21725 'position': 'fixed', 21726 'top': $(event.data.context.config.selectors.cart).innerHeight() * (-1), 21727 'left': cartLeft 21728 }); 21729 $(event.data.context.config.selectors.cart).addClass('fixed'); 21730 $(event.data.context.config.selectors.cartContent).addClass('fixed'); 21731 $(event.data.context.config.selectors.cart).stop().animate({ 21732 'top': -1, 21733 }, 300); 21734 21735 cartContentLeft = cartOffset.left - 100; 21736 if ($(document).innerWidth() <= 767) { 21737 cartContentLeft = 0; 21738 } 21739 $(event.data.context.config.selectors.cartContent).css({ 21740 'position': 'fixed', 21741 'top': $(event.data.context.config.selectors.cart).innerHeight() - 10, 21742 'left': cartContentLeft 21743 }); 21744 21745 } 21746 21747 } 21748 else { 21749 if ($(event.data.context.config.selectors.cart).hasClass('fixed')) { 21750 21751 cartPosition = 'absolute'; 21752 cartTop = '30px'; 21753 21754 if ($(document).innerWidth() <= 767) { 21755 cartPosition = 'relative'; 21756 cartTop = '0'; 21757 } 21758 $(event.data.context.config.selectors.cart).css({ 21759 'position': cartPosition, 21760 'top': cartTop, 21761 'left': 'auto' 21762 }); 21763 $(event.data.context.config.selectors.cart).removeClass('fixed'); 21764 $(event.data.context.config.selectors.cartContent).removeClass('fixed'); 21765 $(event.data.context.config.selectors.cartContent).css({ 21766 'position': 'absolute', 21767 'top': '65px', 21768 'left': 'auto' 21769 }); 21770 } 21771 21772 } 21773 21774 }); 21775 } 21776 21777 21778 $($this.config.selectors.cartContent).popover({ 21779 }); 21780 $($this.config.selectors.cart).bind('mouseenter', {context: $this}, function (event) { 21781 if ($(event.data.context.config.selectors.cartContent).data('totalCount') > 0) { 21782 $(event.data.context.config.selectors.cartContent).show(); 21783 } 21784 }); 21785 $($this.config.selectors.cart).bind('mouseleave', {context: $this}, function (event) { 21786 overContent = $(event.data.context.config.selectors.cartContent).data('mouseover'); 21787 if (!overContent) { 21788 //$(event.data.context.config.selectors.cartContent).hide(); 21789 } 21790 }); 21791 $($this.config.selectors.cartContent).bind('mouseenter', {context: $this}, function (event) { 21792 $(this).data('mouseover', true); 21793 }); 21794 $($this.config.selectors.cartContent).bind('mouseleave', {context: $this}, function (event) { 21795 $(this).data('mouseover', false); 21796 $(this).hide(); 21797 }); 21798 21799 $($this.config.selectors.cartContent + ' .remove-cart-product').live('click', {context: $this}, function (event) { 21800 event.preventDefault(); 21801 event.data.context.removeFromCart($(this).parents('.cart
21801-product').first()); 21802 }); 21803 21804 $('#button-sale').live('click', {context: $this}, function (event) { 21805 21806 event.preventDefault(); 21807 event.data.context.config.rootContainer.spin(); 21808 21809 $.ajax('/json.php', { 21810 data: { 21811 action: 'search', 21812 query: '::specials::', 21813 language: event.data.context.config.language 21814 }, 21815 dataType: 'json', 21816 context: event.data.context, 21817 error: function (jqXHR, textStatus, errorThrown) { 21818 if (typeof console != 'undefined') { 21819 21820 } 21821 else { 21822 alert(errorThrown); 21823 } 21824 }, 21825 success: function (data, textStatus, jqXHR) { 21826 this.config.rootContainer.spin(false); 21827 if (data.products.length > 0) { 21828 $('.original-content').hide(); 21829 $('#globalSearch-result').removeClass('hide'); 21830 21831 // products data 21832 this.data = {}; 21833 $.extend(true, this.data, data); 21834 this.assignMastersAndSlaves(); 21835 //$this.buildFilters(); 21836 this.bindConfigurationLinkEvents(); 21837 this.config.selectors.productsContainer = '#globalSearch-box-products'; 21838 21839 this.applyFilters(); 21840 } 21841 else { 21842 21843 $('#global-message .message-header').text('Ihre Suchanfrage'); 21844 $('#global-message .message').text('Für Ihre Suchanfrage konnten leider keine Produkte gefunden werden.'); 21845 $('#global-message').modal('show'); 21846 } 21847 21848 $(window).trigger('hashchange'); 21849 21850 } 21851 }); 21852 }); 21853 break; 21854 21855 case 'favourites': 21856 21857 favouritesCookie = $.cookie($this.config.favourites.cookieName); 21858 if (favouritesCookie) { 21859 21860 $container = $($this.config.selectors.favourites); 21861 $container.show(); 21862 $container.spin(); 21863 favouriteModels = favouritesCookie.split(','); 21864 $($this.config.selectors.favourites).data('favouriteModels', favouriteModels); 21865 21866 $.ajax('/json.php', { 21867 data: { 21868 action: 'staticProducts', 21869 products: favouriteModels, 21870 includeSub: 1, 21871 language: this.config.language 21872 }, 21873 dataType: 'json', 21874 context: $container, 21875 error: function (jqXHR, textStatus, errorThrown) { 21876 if (typeof console != 'undefined') { 21877 21878 } 21879 else { 21880 alert(errorThrown); 21881 } 21882 }, 21883 success: function (data, textStatus, jqXHR) { 21884 $(this).spin(false); 21885 $.extend(true, $this.data, data); 21886 $this.assignMastersAndSlaves(); 21887 $($this.config.selectors.favourites).data('content', $this.data.products); 21888 $($this.config.selectors.favourites).data('contentCount', 0); 21889 $this.refreshFavourites();
21890 } 21891 }); 21892 } 21893 else { 21894 $($this.config.selectors.favourites).data('favouriteModels', new Array()); 21895 $this.refreshFavourites(); 21896 } 21897 21898 $(window).bind('scroll', {context: $this}, function (event) { 21899 if (!$(event.data.context.config.selectors.favourites).data('show')) { 21900 $(event.data.context.config.selectors.favourites).show(); 21901 } 21902 favouritesOffset = $(event.data.context.config.selectors.favourites).offset(); 21903 if (!$(event.data.context.config.selectors.favourites).data('show')) { 21904 $(event.data.context.config.selectors.favourites).hide(); 21905 } 21906 bindOffset = $(event.data.context.config.favourites.bindFixedPositionOn).offset(); 21907 if ($(window).scrollTop() > bindOffset.top) { 21908 if (!$(event.data.context.config.selectors.favourites).hasClass('fixed')) { 21909 favouritesLeft = favouritesOffset.left; 21910 favouritesTop = $(event.data.context.config.selectors.favourites).innerHeight() * (-1); 21911 favouritesTopTarget = -1; 21912 if ($(document).innerWidth() <= 767) { 21913 favouritesLeft = 0; 21914 favouritesTopTarget = 40; 21915 } 21916 $(event.data.context.config.selectors.favourites).css({ 21917 'position': 'fixed', 21918 'top': favouritesTop, 21919 'left': favouritesLeft 21920 }); 21921 $(event.data.context.config.selectors.favourites).addClass('fixed'); 21922 $(event.data.context.config.selectors.favouritesContent).addClass('fixed'); 21923 $(event.data.context.config.selectors.favourites).stop().animate({ 21924 'top': favouritesTopTarget, 21925 }, 300); 21926 favouritesContentLeft = favouritesOffset.left - 280; 21927 if ($(document).innerWidth() <= 767) { 21928 favouritesContentLeft = 0; 21929 } 21930 $(event.data.context.config.selectors.favouritesContent).css({ 21931 'position': 'fixed', 21932 'top': $(event.data.context.config.selectors.favourites).innerHeight() - 10, 21933 'left': favouritesContentLeft 21934 }); 21935 } 21936 21937 } 21938 else { 21939 if ($(event.data.context.config.selectors.favourites).hasClass('fixed')) { 21940 favouritesPosition = 'absolute'; 21941 favouritesTop = '30px'; 21942 21943 if ($(document).innerWidth() <= 767) { 21944 favouritesPosition = 'relative'; 21945 favouritesTop = '0'; 21946 } 21947 $(event.data.context.config.selectors.favourites).css({ 21948 'position': favouritesPosition, 21949 'top': favouritesTop, 21950 'left': 'auto' 21951 }); 21952 $(event.data.context.config.selectors.favourites).removeClass('fixed'); 21953 $(event.data.context.config.selectors.favouritesContent).removeClass('fixed'); 21954 $(event.data.context.config.selectors.favouritesContent).css({ 21955 'position': 'absolute', 21956 'top': '65px', 21957 'left': 'auto' 21958 }); 21959 } 21960 21961 } 21962 21963 }); 21964 21965 $($this.config.selectors.favouritesContent).popover({ 21966 }); 21967 $($this.config.selectors.favourites).bind('mouseenter', {context: $this}, function (event) { 21968 $(event.data.context.config.selectors.favouritesContent).show(); 21969 }); 21970 $($this.config.selectors.favouritesContent).bind('mouseleave', {context: $this}, function (event) { 21971 $(this).data('mouseover', false); 21972 $(this).hide(); 21973 }); 21974 21975 $($this.config.selectors.favouritesContent + ' .remove-favourites-product').live('click', {context: $this}, function (event) { 21976 event.preventDefault(); 21977 event.data.context.removeFromFavourites($(this).parents('.favourites-product').first().data(), $($this.config.selectors.favourites)); 21978 }); 21979 21980 21981 break; 21982 21983 21984 case 'staticProducts': 21985 // load products 21986 this.config.rootContainer.spin(); 21987 21988 productModels = new Array(); 21989 $(this.config.rootContainer).find('.product').each(function (pIndex, $product) { 21990 productModels.push($($product).data('model')); 21991 }); 21992 21993 $.ajax('/json.php', { 21994 data: { 21995 action: 'staticProducts', 21996 products: productModels, 21997 includeSub: 1, 21998 language: this.config.language 21999 }, 22000 context: this, 22001 dataType: 'json', 22002 error: function (jqXHR, textStatus, errorThrown) { 22003 if (typeof console != 'undefined') { 22004 22005 } 22006 else { 22007 alert(errorThrown); 22008 } 22009 }, 22010 success: function (data, textStatus, jqXHR) { 22011 22012 this.config.rootContainer.spin(false); 22013 // products data 22014 $.extend(true, this.data, data); 22015 22016 this.assignMastersAndSlaves(); 22017 22018 $this = this; 22019 this.config.rootContainer.find('.product').each(function (pIndex, $product) { 22020 product = $this.data.products[$($product).data('id')]; 22021 $($product).data(product); 22022 $($product).find('.product-link').attr('href', '/' + product.url_text); 22023 $this.buildProductPrice($($product), product); 22024 22025 $this.buildProductOptions($($product), product); 22026 22027 if (product.ext_discount > 0) { 22028 $($product).find('.discount').show(); 22029 $($product).addClass('with-discount'); 22030 } 22031 22032 22033 }); 22034 22035 this.bindProductsEvents(this.config.rootContainer); 22036 22037 $(window).trigger('hashchange'); 22038 } 22039 }); 22040 22041 break; 22042 22043 case 'bundles': 22044 // load products 22045 this.config.rootContainer.spin(); 22046 22047 bundleIds = new Array(); 22048 $(this.config.rootContainer).find('.product').each(function (pIndex, $product) { 22049 bundleIds.push($($product).data('id')); 22050 }); 22051 22052 $.ajax('/json.php', { 22053 data: { 22054 action: 'bundles', 22055 bundles: bundleIds, 22056 includeSub: 1, 22057 language: this.config.language 22058 }, 22059 context: this, 22060 dataType: 'json', 22061 error: function (jqXHR, textStatus, errorThrown) { 22062 if (typeof console != 'undefined') { 22063 22064 } 22065 else { 22066 alert(errorThrown); 22067 } 22068 }, 22069 success: function (data, textStatus, jqXHR) { 22070 22071 this.config.rootContainer.spin(false); 22072 // products data 22073 $.extend(true, this.data, data); 22074 22075 this.assignMastersAndSlaves(); 22076 $this = this; 22077 if (this.data.bundles.length == 0) { 22078 this.config.rootContainer.hide(); 22079 this.config.rootContainer.prev('.headline-special-center').hide(); 22080 } 22081 else { 22082 this.config.rootContainer.show(); 22083 this.config.rootContainer.prev('.headline-special-center').show(); 22084 for (bIndex in this.data.bundles) { 22085 this.data.bundles[bIndex]['products'] = new Array(); 22086 for (pIdIndex in this.data.bundles[bIndex]['productIds']) { 22087 this.data.bundles[bIndex]['products'].push(this.data.products[this.data.bundles[bIndex]['productIds'][pIdIndex]]); 22088 } 22089 } 22090 22091 22092 this.config.rootContainer.find('.product').each(function (pIndex, $bundle) { 22093 if ($this.data.bundles.hasOwnProperty($($bundle).data('id'))) { 22094 bundle = $this.data.bundles[$($bundle).data('id')]; 22095 bundle.type = 'bundle'; 22096 $($bundle).data(bundle); 22097 $($bundle).addClass('bundle'); 22098 22099 bundleImageFilename = 'noimage.png'; 22100 22101 22102 22103 if (bundle.ssag_image) { 22104 bundleImageFilename = bundle.ssag_image; 22105 } 22106 else { 22107 if (bundle.products.length > 0) { 22108 for (pIndex in bundle.products) { 22109 productImageFilename = $this.findFirstProductImage(bundle.products[pIndex]); 22110 if (bundleImageFilename != productImageFilename) { 22111 bundleImageFilename = productImageFilename; 22112 break; 22113 } 22114 } 22115 } 22116 } 22117 $($bundle).find('.image').css({ 22118 'background-image': 'url(/media/images/info/' + bundleImageFilename + ')' 22119 }); 22120 $this.buildBundlePrice($($bundle), bundle); 22121// 22122// $this.buildProductOptions($($product), product); 22123// 22124// if (product.ext_discount > 0) { 22125// $($product).find('.discount').show();
22126// $($product).addClass('with-discount'); 22127// } 22128 } 22129 else { 22130 $($bundle).parents('.span3').first().detach(); 22131 } 22132 22133 22134 22135 }); 22136 22137 this.bindProductsEvents(this.config.rootContainer); 22138 22139 $(window).trigger('hashchange'); 22140 } 22141 22142 } 22143 }); 22144 22145 break; 22146 22147 22148 case 'detail': 22149 // load products 22150 this.config.rootContainer.spin(); 22151 if ($(this.config.rootContainer).data('masterModel')) { 22152 productModels = new Array($(this.config.rootContainer).data('masterModel')); 22153 } 22154 else { 22155 productModels = new Array(String($(this.config.rootContainer).data('model'))); 22156 } 22157 22158 22159 $.ajax('/json.php', { 22160 data: { 22161 action: 'staticProducts', 22162 products: productModels, 22163 includeSub: 1, 22164 language: this.config.language 22165 }, 22166 dataType: 'json', 22167 error: function (jqXHR, textStatus, errorThrown) { 22168 if (typeof console != 'undefined') { 22169 22170 } 22171 else { 22172 alert(errorThrown); 22173 } 22174 }, 22175 success: function (data, textStatus, jqXHR) { 22176 22177 $this.config.rootContainer.spin(false); 22178 22179 // products data 22180 $.extend(true, $this.data, data); 22181 22182 22183 $this.assignMastersAndSlaves(); 22184 22185 product = $this.data.products[$this.config.rootContainer.data('id')]; 22186 $this.openDetailView(product, $this.config.rootContainer); 22187 22188 22189 } 22190 }); 22191 break; 22192 22193 case 'search': 22194 22195 22196 $(this.config.selectors.search.form).bind('submit', {context: this}, function (event) { 22197 event.preventDefault(); 22198 event.data.context.config.rootContainer.spin(); 22199 22200 22201 $.ajax('/json.php', { 22202 data: { 22203 action: 'search', 22204 query: $(event.data.context.config.selectors.search.input).val(), 22205 language: event.data.context.config.language 22206 }, 22207 dataType: 'json', 22208 context: event.data.context, 22209 error: function (jqXHR, textStatus, errorThrown) { 22210 if (typeof console != 'undefined') { 22211 22212 } 22213 else { 22214 alert(errorThrown); 22215 } 22216 }, 22217 success: function (data, textStatus, jqXHR) { 22218 this.config.rootContainer.spin(false); 22219 if (data.products.length > 0) { 22220 $('.original-content').hide(); 22221 $('#globalSearch-result').removeClass('hide'); 22222 22223 // products data 22224 this.data = {}; 22225 $.extend(true, this.data, data); 22226 this.assignMastersAndSlaves(); 22227 //$this.buildFilters(); 22228 this.bindConfigurationLinkEvents(); 22229 22230 22231 this.applyFilters(); 22232 } 22233 else { 22234 22235 $('#global-message .message-header').text('Ihre Suchanfrage'); 22236 $('#global-message .message').text('Für Ihre Suchanfrage konnten leider keine Produkte gefunden werden.'); 22237 $('#global-message').modal('show'); 22238 } 22239 22240 $(window).trigger('hashchange'); 22241 22242 } 22243 }); 22244 22245 }); 22246 22247 22248 22249 22250 22251 break; 22252 22253 22254 } 22255 22256 22257 22258 }; 22259 22260 this.assignMastersAndSlaves = function () { 22261 // assign products by model 22262 this.data.productsByModel = {}; 22263 for (index in this.data.products) { 22264 this.data.productsByModel[this.data.products[index]['products_model']] = this.data.products[index]; 22265 } 22266 22267 // assign master / slaves 22268 for (index in this.data.products) { 22269 if (this.data.products[index]['products_master_model'] != '') { 22270 if (this.data.productsByModel.hasOwnProperty(this.data.products[index]['products_master_model'])) { 22271 product = this.data.productsByModel[this.data.products[index]['products_master_model']]; 22272 22273 this.data.products[index]['master'] = product; 22274 if (product.hasOwnProperty('children')) { 22275 product.children.push(this.data.products[index]); 22276 } 22277 else { 22278 product.children = new Array(this.data.products[index]); 22279 } 22280 } 22281 } 22282 } 22283 22284 // assign options for masters and product-types 22285 for (index in this.data.products) { 22286 product = this.data.products[index]; 22287 if (product['products_master_model'] == '' && product.hasOwnProperty('children') && product.children.length > 0) { 22288 product.type = 'master'; 22289 product.options = {}; 22290 for (filterKey in this.config.filters) { 22291 filter = this.config.filters[filterKey]; 22292 22293 if (filter.hasOwnProperty('isProductOption') && filter.isProductOption) { 22294 optionFields = filter.field; 22295 if (!jQuery.isArray(optionFields)) { 22296 optionFields = new Array(optionFields); 22297 } 22298 product.options[filterKey] = new Array(); 22299 for (cIndex in product.children) { 22300 child = product.children[cIndex]; 22301 for (fIndex in optionFields) { 22302 22303 22304 if (child[optionFields[fIndex]] != '' && jQuery.inArray(child[optionFields[fIndex]], product.options[filterKey]) < 0) { 22305 product.options[filterKey].push(child[optionFields[fIndex]]); 22306 22307 } 22308 } 22309 } 22310 22311 if (product.options[filterKey].length > 0) { 22312 filter.sortOptions(product.options[filterKey], this); 22313 } 22314 else { 22315 delete product.options[filterKey]; 22316 } 22317 22318 } 22319 } 22320 22321 } 22322 else if (product['products_master_model'] != '') { 22323 product.type = 'child'; 22324 } 22325 else { 22326 product.type = 'standalone'; 22327 } 22328 22329 22330 } 22331 22332 }; 22333 22334 22335 22336 // filter functions - build & bind 22337 22338 this.buildFilters = function () { 22339 22340 // html creation 22341 this.calc.filtersCount = 0; 22342 $(this.config.selectors.filtersContainer).empty(); 22343 for (filterName in this.config.filters) { 22344 filter = this.config.filters[filterName]; 22345 if (this.data.hasOwnProperty(filterName)) { 22346 this.config.events.onBeforeFilterBuild(this); 22347 filter.build(this, filter, filterName); 22348 this.calc.filtersCount++; 22349 } 22350 } 22351 // event binding 22352 this.bindFilterEventFunctions.runQueue(this); 22353 22354 $('.filter-add.element-size div').detach(); 22355 $('.filter-add.element-color div').detach(); 22356 $('.filter-add.element-material div').detach(); 22357 }; 22358 22359 this.buildFilterFunctions = { 22360 vlist: function ($this, filter, filterName) { 22361 $template = $this.getTemplate(filter.templateId, 'filter-' + filterName); 22362 $template.find($this.config.selectors.filterTitle).text(filter.title[$this.config.language]); 22363 $template.find($this.config.selectors.filterElements + ' ul').empty(); 22364 for (c = 0; c < $this.data[filterName].length; c++) { 22365 element = $this.data[filterName][c]; 22366 $template.find($this.config.selectors.filterElements + ' ul').append('<li><a href="#" class="' + $this.config.classes.filterAddLink + '">' + element.title + '</a></li>'); 22367 $template.find($this.config.selectors.filterElements + ' ul li:last a').data({ 22368 'filter': filterName,
22369 'value': element.id, 22370 'title': element.title 22371 }); 22372 $template.find($this.config.selectors.filterElements + ' ul li:last a').data('elementId', element.id); 22373 } 22374 $($this.config.selectors.filtersContainer + ' ' + $this.config.selectors.filterRow).last().append($template); 22375 22376 }, 22377 occurrences: function ($this, filter, filterName) { 22378 if ($this.data[filterName].length > 0) { 22379 $template = $this.getTemplate(filter.templateId, 'filter-' + filterName); 22380 $template.find($this.config.selectors.filterTitle).text(filter.title[$this.config.language]); 22381 $template.find($this.config.selectors.filterElements + ' .inner').empty(); 22382 for (c = 0; c < $this.data[filterName].length; c++) { 22383 element = $this.data[filterName][c]; 22384 if (typeof element === 'object') { 22385 elementValue = element.id; 22386 elementTitle = element.title; 22387 } 22388 else { 22389 elementValue = element; 22390 elementTitle = element.replace("\\/", '/'); 22391 } 22392 elementData = { 22393 'filter': filterName, 22394 'value': elementValue, 22395 'title': elementTitle 22396 }; 22397 linkId = 'filter-link-' + filterName + '-' + String(c); 22398 if (element.hasOwnProperty('childIds')) { 22399 elementData.value = [elementData.value]; 22400 elementData.value = elementData.value.concat(element.childIds); 22401// $elementWithChildren = $('<div class="row-fluid"><div class="span4 root"></div><div class="span8 children"></div></div>'); 22402// $elementWithChildren.find('.root').append('<a href="#" id="' + linkId + '" class="' + $this.config.classes.filterAddLink + ' element-' + filterName + '"><span class="bg"></span><span class="title">' + elementTitle + '</span></a>'); 22403 $elementWithChildren = $('<div class="element-with-children" style="clear:both;"><div class="root"></div><div class="children"></div></div>'); 22404 $elementWithChildren.find('.root').append('<h4 class="font-bold font-highlight">' + elementTitle + '</h4>'); 22405 22406 for (d = 0; d < element.children.length; d++) { 22407 childElement = element.children[d]; 22408 childElementData = { 22409 'filter': filterName, 22410 'value': childElement.id, 22411 'title': childElement.title, 22412 'parent': elementValue 22413 } 22414 childLinkId = 'filter-link-' + filterName + '-' + String(c) + '-' + String(d); 22415 $elementWithChildren.find('.children').append('<a href="#" id="' + childLinkId + '" class="' + $this.config.classes.filterAddLink + ' element-' + filterName + '"><span class="bg"></span><span class="title">' + childElement.title + '</span></a>'); 22416 $elementWithChildren.find('#' + childLinkId).data(childElementData); 22417 } 22418 $template.find($this.config.selectors.filterElements + ' .inner').append($elementWithChildren); 22419 } 22420 else { 22421 $template.find($this.config.selectors.filterElements + ' .inner').append('<a href="#" id="' + linkId + '" class="' + $this.config.classes.filterAddLink + ' element-' + filterName + '"><span class="bg"></span><span class="title">' + elementTitle + '</span></a>'); 22422 } 22423 22424 22425 $template.find('#' + linkId).data(elementData); 22426 22427 } 22428 22429 // mobile -> accordion 22430 if ($(document).innerWidth() <= 479) { 22431 $template.find('.dropdown-toggle').removeClass('dropdown-toggle').addClass('accordion-toggle'); 22432 $template.find('.dropdown-menu').removeClass('dropdown-menu').addClass('accordion-body collapse'); 22433 22434 $template.find('.accordion-body').attr('id', 'filter-accordion-' + filterName); 22435 $template.find('.accordion-toggle').attr('href', '#f
22435ilter-accordion-' + filterName); 22436 $template.find('.accordion-toggle').attr('data-toggle', 'collapse'); 22437 $template.find('.accordion-toggle').attr('data-parent', '#box-filter'); 22438 $('#box-filter').addClass('accordion-group'); 22439 } 22440 22441 22442 $($this.config.selectors.filtersContainer + ' ' + $this.config.selectors.filterRow).last().append($template); 22443 22444 } 22445 22446 }, 22447 range: function ($this, filter, filterName) { 22448 $template = $this.getTemplate(filter.templateId, 'filter-' + filterName); 22449 $template.find($this.config.selectors.filterTitle).text(filter.title[$this.config.language]); 22450 $template.find($this.config.selectors.filterRange.titleMin).text($this.config.translations.from[$this.config.language]); 22451 $template.find($this.config.selectors.filterRange.titleMax).text($this.config.translations.to[$this.config.language]); 22452 $template.find($this.config.selectors.filterRange.valueMin).html($this.formatPrice($this.data[filterName]['min'])); 22453 $template.find($this.config.selectors.filterRange.valueMax).html($this.formatPrice($this.data[filterName]['max'])); 22454 $template.find($this.config.selectors.filterRange.valueMin).data({ 22455 'filter': filterName, 22456 'type': 'min', 22457 'value': $this.data[filterName]['min'], 22458 'valueMin': $this.data[filterName]['min'], 22459 'valueMax': $this.data[filterName]['max'] 22460 }); 22461 $template.find($this.config.selectors.filterRange.valueMax).data({ 22462 'filter': filterName, 22463 'type': 'max', 22464 'value': $this.data[filterName]['max'], 22465 'valueMin': $this.data[filterName]['min'], 22466 'valueMax': $this.data[filterName]['max'] 22467 }); 22468 $($this.config.selectors.filtersContainer + ' ' + $this.config.selectors.filterRow).last().append($template); 22469 } 22470 22471 }; 22472 22473 22474 this.bindFilterEventFunctions = { 22475 executionQueue: [], 22476 addToExecutionQueue: function ($this, functionName) { 22477 if (jQuery.inArray(functionName, $this.bindFilterEventFunctions.executionQueue) < 0) { 22478 $this.bindFilterEventFunctions.executionQueue.push(functionName); 22479 } 22480 }, 22481 runQueue: function ($this) { 22482 for (index in $this.bindFilterEventFunctions.executionQueue) { 22483 functionName = $this.bindFilterEventFunctions.executionQueue[index]; 22484 $this.bindFilterEventFunctions[functionName]($this); 22485 } 22486 }, 22487 links: function ($this) { 22488 22489 $('.' + $this.config.classes.filterAddLink).bind('touchend click', function (event) { 22490 event.preventDefault(); 22491 $this.selectFilter($(this).data()); 22492 //$(this).addClass('disabled'); 22493 if (typeof event.originalEvent != 'undefined' && 22494 typeof event.originalEvent.touches != 'undefined') { 22495 event.stopPropagation(); 22496 } 22497 22498 22499 }); 22500 }, 22501 range: function ($this) { 22502 22503 $($this.config.selectors.filterRange.mover).each(function (mIndex, mover) { 22504 22505 positionKey = $(mover).data('type') == 'min' ? 'left' : 'right'; 22506 $(mover).data({ 22507 'startPosition': false, 22508 'positionKey': positionKey, 22509 'positionStart': parseInt($(mover).css(positionKey).replace('px', '')) 22510 }); 22511 22512 value = $(mover).nextAll($(mover).data('nextSelector')).first(); 22513 22514 $(mover).add(value).bind('touchstart mousedown', {mover: mover}, function (event) { 22515 event.preventDefault(); 22516// var debug = ''; 22517// for (var key in event.originalEvent.touches[0]) { 22518// debug += ',' + key +'=[' + event.originalEvent.touches[0][key] + ']'; 22519// } 22520// alert(debug); 22521 if (typeof event.originalEvent != 'undefined' && 22522 typeof event.originalEvent.touches != 'undefined') { 22523 pageX = event.originalEvent.touches[0].pageX; 22524 } 22525 else { 22526 pageX = event.pageX; 22527 } 22528 filterContainer = $(event.data.mover).parents('.products-listing-filter').first(); 22529 filterContainer.find('.dropdown-toggle').first().attr('data-toggle', ''); 22530 progress = $(event.data.mover).parents('.progress').first(); 22531 $(event.data.mover).data({ 22532 'totalWidth': $(progress).innerWidth(), 22533 'startPosition': pageX, 22534 'position': parseInt($(event.data.mover).css($(event.data.mover).data('positionKey')).replace('px', '')) 22535 }); 22536 $('body').data('currentMover', event.data.mover); 22537 }); 22538 22539 22540 22541 }); 22542 22543 $('body').bind('touchmove mousemove', {context: $this}, function (event) { 22544 22545 if ($(this).data('currentMover')) { 22546 // values 22547 22548 if (typeof event.originalEvent != 'undefined' && 22549 typeof event.originalEvent.touches != 'undefined') { 22550 pageX = event.originalEvent.touches[0].pageX; 22551 pageY = event.originalEvent.touches[0].pageY; 22552 } 22553 else { 22554 pageX = event.pageX; 22555 pageY = event.pageY; 22556 } 22557 22558 mover = $(this).data('currentMover'); 22559 value = $(mover).nextAll($(mover).data('nextSelector')).first(); 22560 progress = $(mover).parents('.progress').first(); 22561 movement = pageX - $(mover).data('startPosition'); 22562 positionCorrection = ($(mover).data('positionStart') < 0 ? $(mover).data('positionStart') * -1 : $(mover).data('positionStart')); 22563 if ($(mover).data('type') == 'max') { 22564 movement *= -1; 22565 } 22566 newPosition = $(mover).data('positionStart') + positionCorrection + $(mover).data('position') + movement; 22567 22568 // prevent movement above max and under min 22569 if (newPosition < $(mover).data('positionStart')) { 22570 newPosition = $(mover).data('positionStart'); 22571 } 22572 if (newPosition > $(mover).data('positionStart') + $(mover).data('totalWidth')) { 22573 newPosition = $(mover).data('positionStart') + $(mover).data('totalWidth'); 22574 } 22575 // prevent movement min over max or max under min 22576 if ($(mover).data('type') == 'min') { 22577 moverMax = $(mover).nextAll('.mover.range-max').first(); 22578 moverMaxPosition = parseInt($(moverMax).css($(moverMax).data('positionKey')).replace('px', '')); 22579 if (newPosition > $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMaxPosition - $(mover).innerWidth()) { 22580 newPosition = $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMaxPosition - $(mover).innerWidth(); 22581 } 22582 } 22583 else { 22584 moverMin = $(mover).prevAll('.mover.range-min').first(); 22585 moverMinPosition = parseInt($(moverMin).css($(moverMin).data('positionKey')).replace('px', '')); 22586 if (newPosition > $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMinPosition - $(mover).innerWidth()) { 22587 newPosition = $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMinPosition - $(mover).innerWidth(); 22588 } 22589 } 22590 // apply movement 22591 $(mover).css($(mover).data('positionKey'), String(newPosition) + 'px'); 22592 $(mover).nextAll($(mover).data('nextSelector')).css($(mover).data('positionKey'), String(newPosition + $(mover).data('valueSpace')) + 'px'); 22593 22594 // set bar 22595 moverProgressValue = newPosition + positionCorrection; 22596 moverPercentage = parseInt(100 / $(mover).data('totalWidth') * moverProgressValue); 22597 22598 if ($(mover).data('type') == 'max') { 22599 $(progress).find('.bar').css('margin-right', String(moverPercentage) + '%'); 22600 $(progress).find('.bar').data('status', moverPercentage); 22601 } 22602 else { 22603 currentWidth = parseInt($(progress).find('.bar').data('status')); 22604 $(progress).find('.bar').css({ 22605 'margin-left': String(moverPercentage) + '%' 22606 }); 22607 } 22608 22609 // set value 22610 valueDiff = ($(value).data('valueMax') - $(value).data('valueMin')) * (moverPercentage / 100); 22611 if ($(mover).data('type') == 'min') { 22612 newValue = $(value).data('valueMin') + valueDiff; 22613 } 22614 else { 22615 newValue = $(value).data('valueMax') - valueDiff; 22616 } 22617 22618 22619 newValue = parseInt(newValue); 22620 $(value).data('value', newValue); 22621 $(value).html(event.data.context.formatPrice(newValue)); 22622 22623 // select filter 22624 event.data.context.selectFilter($.extend(true, $(value).data(), { 22625 'moverElement': mover, 22626 'valueElement': value 22627 }), true); 22628 22629 } 22630 }); 22631 $('body').bind('touchend mouseup', {context: $this}, function (event) { 22632 22633 if ($(this).data('currentMover')) { 22634 mover = $(this).data('currentMover'); 22635 filterContainer = $(mover).parents('.products-listing-filter').first(); 22636 filterContainer.find('.dropdown-toggle').first().attr('data-toggle', 'dropdown'); 22637 $(mover).data('startPosition', false); 22638 $('body').data('currentMover', false); 22639 event.data.context.rerangeFilters(); 22640 } 22641 }); 22642 } 22643 }; 22644 22645 // filter functions - select & search 22646 this.selectFilter = function (filterData, disableRerange) { 22647 if (!disableRerange) { 22648 disableRerange = false; 22649 } 22650 filterConf = this.config.filters[filterData['filter']]; 22651 if (!this.activeFilters.hasOwnProperty(filterData['filter'])) { 22652 this.activeFilters[filterData['filter']] = {}; 22653 $('#' + this.config.selectors.selectedFiltersContainer).show(); 22654 } 22655 switch (filterConf.type) { 22656 case 'vlist': 22657 case 'occurrences': 22658 22659 if (!this.activeFilters[filterData['filter']].hasOwnProperty('elements')) { 22660 this.activeFilters[filterData['filter']]['elements'] = []; 22661 } 22662 if (jQuery.inArray(filterData['value'], this.activeFilters[filterData['filter']]['elements']) < 0) { 22663 if (jQuery.isArray(filterData['value'])) { 22664 for (vIndex in filterData['value']) { 22665 this.activeFilters[filterData['filter']]['elements'].push(filterData['value'][vIndex]); 22666 } 22667 } 22668 else { 22669 this.activeFilters[filterData['filter']]['elements'].push(filterData['value']); 22670 } 22671 newFilterId = 'selected-filter-' + filterData['filter']; 22672 newFilter = this.getTemplate(this.config.selectors.templateSelectedFilterLink, newFilterId); 22673 newFilter.data(filterData); 22674 newFilter.addClass('selected-filter-' + filterData['filter']); 22675 newFilter.find('.filter-title').text(filterConf.title[this.config.language]); 22676 newFilter.find('.filter-value').text(filterData['title']);
22677 newFilter.bind('click', { 22678 filterData: filterData, 22679 context: this 22680 }, function (event) { 22681 event.preventDefault(); 22682 event.data.context.removeFilter(event.data.filterData, this); 22683 }); 22684 $('#' + this.config.selectors.selectedFiltersContainer).append(newFilter); 22685 if (filterData.parent) { 22686 $('#' + this.config.selectors.selectedFiltersContainer).find('a').each(function (sfIndex, selectedFilter) { 22687 22688 if ($(selectedFilter).data('filter') == filterData['filter'] && 22689 ($(selectedFilter).data('value') == filterData.parent) || 22690 (jQuery.isArray($(selectedFilter).data('value')) && jQuery.inArray(filterData.parent, $(selectedFilter).data('value')) >= 0) 22691 ) { 22692 $(selectedFilter).click(); 22693 } 22694 }); 22695 } 22696 } 22697 break; 22698 case 'range': 22699 22700 if ((filterData['type'] == 'min' && filterData['value'] == 0) || (filterData['type'] == 'max' && filterData['value'] == parseInt(filterData['valueMax']))) { 22701 this.removeFilter(filterData, $('#selected-filter-' + filterData['filter'] + '-' + filterData['type'])); 22702 } 22703 else { 22704 if (!this.activeFilters[filterData['filter']].hasOwnProperty(filterData['type'])) { 22705 newFilter = this.getTemplate(this.config.selectors.templateSelectedFilterLink, 'selected-filter-' + filterData['filter'] + '-' + filterData['type']); 22706 newFilter.find('.filter-title').text(filterConf.title[this.config.language] + ' (' + this.config.translations[filterData['type']][this.config.language] + ')'); 22707 newFilter.find('.filter-value').html(this.formatPrice(filterData['value'])); 22708 newFilter.bind('click', { 22709 filterData: filterData, 22710 context: this 22711 }, function (event) { 22712 event.preventDefault(); 22713 event.data.context.removeFilter(event.data.filterData, this); 22714 }); 22715 $('#' + this.config.selectors.selectedFiltersContainer).append(newFilter); 22716 } 22717 else { 22718 existingFilter = $('#selected-filter-' + filterData['filter'] + '-' + filterData['type']); 22719 existingFilter.find('.filter-value').html(this.formatPrice(filterData['value'])); 22720 } 22721 this.activeFilters[filterData['filter']][filterData['type']] = filterData['value']; 22722 } 22723 22724 break; 22725 } 22726 22727 if ($(window).width() <= 767) { 22728 $(window).scrollTop($('#box-filter-selected').offset().top); 22729 } 22730 22731 22732 this.applyFilters(disableRerange); 22733 }; 22734 22735 this.removeFilter = function (filterData, link) { 22736 filterConf = this.config.filters[filterData['filter']]; 22737 if (this.activeFilters.hasOwnProperty(filterData['filter'])) { 22738 switch (filterConf.type) { 22739 case 'vlist': 22740 case 'occurrences': 22741 newElements = []; 22742 for (index in this.activeFilters[filterData['filter']]['elements']) { 22743 if (this.activeFilters[filterData['filter']]['elements'][index] != filterData['value']) { 22744 newElements.push(this.activeFilters[filterData['filter']]['elements'][index]); 22745 } 22746 } 22747 this.activeFilters[filterData['filter']]['elements'] = newElements; 22748 if (newElements.length == 0) { 22749 delete this.activeFilters[filterData['filter']]; 22750 } 22751 break; 22752 case 'range': 22753 $(filterData['moverElement']).css($(filterData['moverElement']).data('positionKey'), String($(filterData['moverElement']).data('positionStart')) + 'px'); 22754 $(filterData['moverElement']).nextAll($(filterData['moverElement']).data('nextSelector')).css($(filterData['moverElement']).data('positionKey'), String($(filterData['moverElement']).data('positionStart') + $(filterData['moverElement']).data('valueSpace')) + 'px'); 22755 newValue = 0; 22756 if (filterData['type'] == 'max') { 22757 newValue = $(filterData['valueElement']).data('valueMax'); 22758 } 22759 $(filterData['valueElement']).html(this.formatPrice(newValue)); 22760 progress = $(filterData['moverElement']).parents('.progress').first(); 22761 if (filterData['type'] == 'max') { 22762 $(progress).find('.bar').css('margin-right', '0%'); 22763 } 22764 else { 22765 $(progress).find('.bar').css('margin-left', '0%'); 22766 } 22767 delete this.activeFilters[filterData['filter']][filterData['type']]; 22768 if (!this.activeFilters[filterData['filter']].hasOwnProperty('min') && !this.activeFilters[filterData['filter']].hasOwnProperty('max')) { 22769 delete this.activeFilters[filterData['filter']]; 22770 } 22771 break; 22772 } 22773 22774 $(link).detach(); 22775 } 22776 22777 this.applyFilters(); 22778 22779 if (jQuery.isEmptyObject(this.activeFilters)) { 22780 $('#' + this.config.selectors.selectedFiltersContainer).hide(); 22781 } 22782 }; 22783 22784 this.removeAllFilters = function () { 22785 this.activeFilters = {}; 22786 $('#' + this.config.selectors.selectedFiltersContainer).empty(); 22787 }; 22788 22789 22790 this.applyFilters = function (disableRerange) { 22791 $this = this; 22792 this.searchParams.start = 0; 22793 $('#' + this.config.selectors.selectedFiltersContainer).data('activeFilters', this.activeFilters); 22794 22795 if (jQuery.isEmptyObject(this.activeFilters)) { 22796 this.foundProducts = this.data.products; 22797 } 22798 else { 22799 this.foundProducts = []; 22800 productsToSearchIn = this.data.products; 22801 prevProduct = false; 22802 for (filterName in this.activeFilters) { 22803 filterConf = this.config.filters[filterName]; 22804 foundProducts = []; 22805 for (index in productsToSearchIn) { 22806 product = productsToSearchIn[index]; 22807 found = true; 22808 22809 switch (filterConf.type) { 22810 case 'vlist': 22811 case 'occurrences': 22812 if (jQuery.isArray(filterConf.field)) { 22813 productValues = []; 22814 for (fieldIndex in filterConf.field) { 22815 if (product[filterConf.field[fieldIndex]]) { 22816 productValues.push(product[filterConf.field[fieldIndex]]); 22817 } 22818 } 22819 } 22820 else { 22821 if (!jQuery.isArray(product[filterConf.field])) { 22822 productValues = [product[filterConf.field]]; 22823 } 22824 else { 22825 productValues = product[filterConf.field]; 22826 } 22827 } 22828 if (productValues.length == 0) { 22829 found = false; 22830 } 22831 foundInValues = false; 22832 for (valueIndex in productValues) { 22833 for (eIndex in this.activeFilters[filterName]['elements']) { 22834 if (jQuery.isArray(this.activeFilters[filterName]['elements'][eIndex])) { 22835 if (jQuery.inArray(String(productValues[valueIndex]), this.activeFilters[filterName]['elements'][eIndex]) >= 0) { 22836 foundInValues = true; 22837 break; 22838 } 22839 } 22840 else { 22841 if (String(productValues[valueIndex]) == this.activeFilters[filterName]['elements'][eIndex]) { 22842 foundInValues = true; 22843 break; 22844 } 22845 } 22846 } 22847 if (foundInValues) { 22848 break; 22849 } 22850 22851 } 22852 if (!foundInValues) { 22853 found = false; 22854 } 22855 22856 break; 22857 case 'range': 22858 if (this.activeFilters[filterName].hasOwnProperty('min')) { 22859 if (product[filterConf.field] < this.activeFilters[filterName]['min']) { 22860 found = false; 22861 } 22862 } 22863 if (this.activeFilters[filterName].hasOwnProperty('max')) { 22864 if (product[filterConf.field] > this.activeFilters[filterName]['max']) { 22865 found = false; 22866 } 22867 } 22868 break; 22869 } 22870 22871 if (found) { 22872 foundProducts.push(product); 22873 } 22874 } 22875 productsToSearchIn = foundProducts; 22876 22877 } 22878 this.foundProducts = foundProducts; 22879 } 22880 22881 if (!disableRerange) { 22882 this.rerangeFilters(); 22883 } 22884 this.config.events.onAfterApplyFilter(this); 22885 this.applySorting(); 22886 this.showSearchResult(); 22887 }; 22888 22889 22890 this.rerangeFilters = function () { 22891 if (jQuery.isEmptyObject(this.activeFilters)) { 22892 $('.products-listing-filter').show(); 22893 $('.products-listing-filter .filter-add').show(); 22894 for (filterName in this.config.filters) { 22895 filterConf = this.config.filters[filterName]; 22896 $('#filter-' + filterName).show(); 22897 switch (filterConf.type) { 22898 case 'range': 22899 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).html($this.formatPrice($this.data[filterName]['min'])); 22900 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).html($this.formatPrice($this.data[filterName]['max'])); 22901 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).data({ 22902 'value': $this.data[filterName]['min'], 22903 'valueMin': $this.data[filterName]['min'], 22904 'valueMax': $this.data[filterName]['max'] 22905 }); 22906 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).data({ 22907 'value': $this.data[filterName]['max'], 22908 'valueMin': $this.data[filterName]['min'], 22909 'valueMax': $this.data[filterName]['max'] 22910 }); 22911 break; 22912 } 22913 } 22914 22915 } 22916 else { 22917 for (filterName in this.config.filters) { 22918 filterConf = this.config.filters[filterName]; 22919 22920 if (!this.activeFilters.hasOwnProperty(filterName)) { 22921 22922 switch (filterConf.type) { 22923 case 'vlist': 22924 case 'occurrences': 22925 visibleElements = 0; 22926 $('#filter-' + filterName + ' .element-' + filterName).each(function (cIndex, element) { 22927 isInFoundProducts = false; 22928 for (pIndex in $this.foundProducts) { 22929 fields = filterConf.field; 22930 if (!jQuery.isArray(fields)) { 22931 fields = new Array(fields); 22932 } 22933 22934 for (fIndex in fields) { 22935 values = $this.foundProducts[pIndex][fields[fIndex]]; 22936 if (!jQuery.isArray(values)) { 22937 values = new Array(values); 22938 } 22939 22940 if (jQuery.inArray(String($(element).data('value')), values) >= 0) { 22941 isInFoundProducts = true; 22942 } 22943 22944 } 22945 } 22946 if (isInFoundProducts) { 22947 $(element).show(); 22948 visibleElements++; 22949 } 22950 else { 22951 $(element).hide(); 22952 } 22953 }); 22954 if (visibleElements > 1) { 22955 $('#filter-' + filterName).show(); 22956 } 22957 else { 22958 $('#filter-' + filterName).hide(); 22959 } 22960 22961 break; 22962 22963 case 'range': 22964 22965 minMaxValues = $this.getMinMaxValuesForRangeFilter(filterConf); 22966// $this.data[filterName]['min'] = minMaxValues.min; 22967// $this.data[filterName]['max'] = minMaxValues.max; 22968 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).html($this.formatPrice(minMaxValues.min)); 22969 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).html($this.formatPrice(minMaxValues.max)); 22970 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).data({ 22971 'value': minMaxValues.min, 22972 'va
22972lueMin': minMaxValues.min, 22973 'valueMax': minMaxValues.max 22974 }); 22975 $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).data({ 22976 'value': minMaxValues.max, 22977 'valueMin': minMaxValues.min, 22978 'valueMax': minMaxValues.max 22979 }); 22980 22981 if (minMaxValues.min == minMaxValues.max) { 22982 $('#filter-' + filterName).hide(); 22983 } 22984 else { 22985 $('#filter-' + filterName).show(); 22986 } 22987 22988 break; 22989 22990 } 22991 22992 } 22993 else { 22994 $('#filter-' + filterName).show(); 22995 $('#filter-' + filterName + ' .element-' + filterName).show(); 22996 } 22997 } 22998 } 22999 }; 23000 23001 23002 this.getMinMaxValuesForRangeFilter = function (filter) { 23003 result = { 23004 min: -1, 23005 max: 0 23006 }; 23007 for (index in this.foundProducts) { 23008 value = this.foundProducts[index][filter.field]; 23009 if (result.min < 0) { 23010 result.min = value; 23011 } 23012 else { 23013 if (value < result.min) { 23014 result.min = value; 23015 } 23016 if (value > result.max) { 23017 result.max = value; 23018 } 23019 } 23020 } 23021 return result; 23022 } 23023 23024 this.findFilterChanges = function (hashFilters) { 23025 result = new Object(); 23026 result.add = new Array(); 23027 result.remove = new Array(); 23028 // not in active filters 23029 if (hashFilters) { 23030 23031 for (filterName in hashFilters) { 23032 hashFilter = hashFilters[filterName]; 23033 filterConf = this.config.filters[filterName]; 23034 switch (filterConf.type) { 23035 case 'vlist': 23036 case 'occurrences': 23037 for (eIndex in hashFilter['elements']) { 23038 element = hashFilter['elements'][eIndex]; 23039 if (!this.activeFilters.hasOwnProperty(filterName) || 23040 jQuery.inArray(element, this.activeFilters[filterName]['elements']) < 0 23041 ) { 23042 $('#filter-' + filterName + ' .filter-elements a').each(function (lIndex, filterLink) { 23043 if (element == $(filterLink).data('value')) { 23044 result.add.push($(filterLink).data()); 23045 } 23046 }); 23047 23048 } 23049 } 23050 break; 23051 case 'range': 23052 23053 break; 23054 } 23055 } 23056 } 23057 23058 // not in hash filters 23059 23060 23061 for (filterName in this.activeFilters) { 23062 filter = this.activeFilters[filterName]; 23063 filterConf = this.config.filters[filterName]; 23064 switch (filterConf.type) { 23065 case 'vlist': 23066 case 'occurrences': 23067 $('.selected-filter-' + filterName).each(function (sIndex, selectedFilter) { 23068 if (!hashFilters.hasOwnProperty(filterName) || 23069 jQuery.inArray($(selectedFilter).data('value'), hashFilters[filterName]['elements']) < 0 23070 ) { 23071 result.remove.push($(selectedFilter)); 23072 } 23073 }); 23074 break; 23075 } 23076 } 23077 23078 return result; 23079 23080 }; 23081 23082 this.showSearchResult = function () { 23083 this.buildProducts(); 23084 this.buildPagination(); 23085 // BBQ 23086 if (this.config.bbqEnabled) { 23087 jQuery.bbq.pushState({ 23088 filter: this.activeFilters 23089 }); 23090 if (String(this.searchParams.start) + 23091 String(this.searchParams.range) + 23092 this.searchParams.presentation + 23093 this.searchParams.sortBy + 23094 this.searchParams.sortOrder != '08gridpriceASC' 23095 ) { 23096 jQuery.bbq.pushState({ 23097 settings: this.searchParams 23098 }); 23099 } 23100 else { 23101 jQuery.bbq.removeState('settings'); 23102 } 23103 } 23104 }; 23105 23106 23107 23108 // product functions - build & bind 23109 this.buildProducts = function () { 23110 this.calc.productsCount = 0; 23111 $(this.config.selectors.productsContainer).empty(); 23112 var index = 0; 23113 for (pIndex in this.foundProducts) { 23114 if (pIndex >= this.searchParams.start && index < this.searchParams.range) { 23115 this.config.events.onBeforeProductBuild(this); 23116 var product = this.foundProducts[pIndex]; 23117 if (typeof (product.products_id) != "undefined") { 23118 var $productTemplate = this.getTemplate(this.config.selectors.templateProduct[this.searchParams.presentation], 'product-' + product.products_id); 23119 $productTemplate.find('.title').html(product.products_short_description ? product.products_short_description : product.products_name); 23120 $productTemplate.find('.description').html(product.products_description); 23121 23122 this.buildProductPrice($productTemplate, jQuery.extend({}, product), $productTemplate.find('.product')); 23123 23124 productImageFilename = this.findFirstProductImage(product); 23125 23126 $productTemplate.find('.product-link').attr('href', '/' + product.url_text); 23127 23128 $productTemplate.find('.image').css({ 23129 'background-image': 'url(/media/images/info/' + productImageFilename + ')' 23130 }); 23131 23132 $productTemplate.find('.product').data(product); 23133 23134 this.buildProductOptions($productTemplate, product); 23135 23136 if (product.ext_discount > 0 && $('#page-index').length > 0) { 23137 $productTemplate.find('.discount').show(); 23138 $productTemplate.find('.product').addClass('with-discount'); 23139 } 23140 23141 23142 $(this.config.selectors.productsAppend[this.searchParams.presentation]).append($productTemplate); 23143 this.calc.productsCount++; 23144 index++; 23145 } 23146 23147 } 23148 } 23149 // event binding 23150 this.bindProductsEvents(); 23151 this.config.events.onAfterProductsBuild(this); 23152 } 23153 23154 this.findFirstProductImage = function (product) { 23155 productImageFilename = 'noimage.png'; 23156 if (product.type != 'master') { 23157 if (product.products_image) { 23158 productImageFilename = product.products_image; 23159 } 23160 } 23161 else { 23162 if (product.children) { 23163 for (cIndex in product.children) { 23164 if (product.children[cIndex].products_image) { 23165 productImageFilename = product.children[cIndex].products_image; 23166 break; 23167 } 23168 } 23169 } 23170 } 23171 return productImageFilename; 23172 }; 23173 23174 this.findProductImages = function ($productData) { 23175 if ($productData.children) { 23176 for (cIndex in $productData.children) { 23177 if ($productData.children[cIndex].products_image) { 23178 return [ 23179 $productData.children[cIndex].products_image, 23180 $productData.children[cIndex].products_image_2, 23181 $productData.children[cIndex].products_image_3, 23182 $productData.children[cIndex].products_image_4, 23183 $productData.children[cIndex].products_image_5 23184 ]; 23185 } 23186 } 23187 } 23188 return []; 23189 }; 23190 23191 23192 this.buildProductPrice = function ($productObject, product, badgePosition) { 23193 23194 $productObject.data('priceBuild', true); 23195 23196 if (!badgePosition) { 23197 badgePosition = $productObject; 23198 } 23199 23200 if (product['special_price']) { 23201 $productObject.find('.price').html('<span class="old">' + (product.hasOwnProperty('price') ? product.price.formated : '') + '</span><span class="new font-highlight">' + product.special_price.formated + '</span>'); 23202 } 23203 else { 23204 23205 $productObject.find('.price').html((product.hasOwnProperty('price') ? product.price.formated : '')); 23206 23207 } 23208 23209 if (product.type == 'master') { 23210 if (product.children) { 23211 var smallestPrice = product.price; 23212 specialPriceCount = 0; 23213 product['child_has_special_price'] = false; 23214 for (cIndex in product.children) { 23215 23216 if (product.children[cIndex].price.plain < smallestPrice.plain) { 23217 smallestPrice = product.children[cIndex].price; 23218 } 23219 if (product.children[cIndex].hasOwnProperty('special_price')) { 23220 if (product.children[cIndex].special_price.plain < smallestPrice.plain) { 23221 smallestPrice = product.children[cIndex].special_price; 23222 } 23223 product['child_has_special_price'] = true; 23224 specialPriceCount++; 23225 } 23226 } 23227 if (specialPriceCount == product.children.length) { 23228 $productObject.find('.price').html('<span class="old">' + product.price.formated + '</span><span class="new font-highlight">' + smallestPrice.formated + '</span>'); 23229 } 23230 else { 23231 if (smallestPrice.plain < product.price.plain) { 23232 $productObject.find('.price').html('ab ' + smallestPrice.formated); 23233 } 23234 } 23235 } 23236 } 23237 23238// if (product.ext_discount == 0) { 23239// if (product['special_price'] || product['child_has_special_price']) { 23240// badgePosition.append('<span class="badge badge-warning badge-special">' + this.config.translations.badges.specialOffer[this.config.language] + '</span>'); 23241// } 23242// else { 23243// if (product['new']) { 23244// badgePosition.append('<span class="badge badge-important badge-new">' + this.config.translations.badges['new'][this.config.language] + '</span>'); 23245// } 23246// } 23247// } 23248 23249 }; 23250 23251 23252 this.buildBundlePrice = function ($bundleTemplate, bundle) { 23253 23254 23255 switch (bundle.bundleType) { 23256 case 'package': 23257 productsPrice = 0; 23258 for (pIndex in bundle.products) { 23259 productsPrice += bundle.products[pIndex]['price']['plain']; 23260 } 23261 $bundleTemplate.find('.price').html('<span class="old">' + this.formatPrice(productsPrice) + '</span><span class="new font-highlight">' + bundle.price.formated + '</span>'); 23262 break; 23263 default: 23264 $bundleTemplate.find('.price').html(bundle.price.formated); 23265 break; 23266 } 23267 23268 23269 23270 23271// if (product.type == 'master') { 23272// if (product.children) { 23273// smallestPrice = product.price; 23274// specialPriceCount = 0; 23275// product['child_has_special_price'] = false; 23276// for (cIndex in product.children) { 23277// 23278// if (product.children[cIndex].price.plain < smallestPrice.plain) { 23279// smallestPrice = product.children[cIndex].price; 23280// } 23281// if (product.children[cIndex].hasOwnProperty('special_price')) { 23282// if (product.children[cIndex].special_price.plain < smallestPrice.plain) { 23283// smallestPrice = product.children[cIndex].special_price; 23284// } 23285// product['child_has_special_price'] = true; 23286// specialPriceCount++; 23287// } 23288// } 23289// if (specialPriceCount == product.children.length) { 23290// $productTemplate.find('.price').html('<span class="old">' + product.price.formated + '</span><span class="new">' + smallestPrice.formated + '</span>'); 23291// } 23292// else { 23293// if (smallestPrice.plain < product.price.plain) { 23294// $productTemplate.find('.price').html('ab ' + smallestPrice.formated); 23295// } 23296// } 23297// } 23298// } 23299 23300 23301 }; 23302 23303 this.buildProductOptions = function ($productTemplate, product) { 23304 if (product.type == 'master') { 23305 for (optionKey in product.options) { 23306 if (product.options[optionKey].length > 0) { 23307 $optionTemplate = this.getTemplate(this.config.selectors.templateProductOptions[this.searchParams.presentation], 'productOptions-' + product.products_id + '-' + optionKey); 23308 $optionTemplate.find('.title').text(this.config.filters[optionKey].title[this.config.language]); 23309 $optionTemplate.data('optionKey', optionKey); 23310 for (vIndex in product.options[optionKey]) { 23311 $optionLink = $('<a href="#" class="' + this.config.classes.optionLink + '">' + product.options[optionKey][vIndex].replace("\\/", '/') + '</a>'); 23312 $optionLink.data({ 23313 optionKey: optionKey, 23314 value: String(product.options[optionKey][vIndex]), 23315 masterId: product.products_id 23316 }); 23317 $optionLink.attr('rel', product.options[optionKey][vIndex]); 23318 $optionTemplate.find('.values').append($optionLink); 23319 } 23320 if (product.options[optionKey].length == 1) { 23321 $optionLink.addClass(this.config.classes.buttonActive); 23322 this.selectProductOption($optionLink.data(), ($productTemplate.hasClass('product') ? $productTemplate : $productTemplate.find('.product')), true); 23323 } 23324 $productTemplate.find(this.config.selectors.productOptions).append($optionTemplate); 23325 } 23326 } 23327 $productTemplate.find('.actions .cart .action').addClass('dropdown-toggle'); 23328
23328 } 23329 else { 23330 $productTemplate.find(this.config.selectors.productOptions).detach(); 23331 } 23332 } 23333 23334 this.bindProductsEvents = function (container) { 23335 23336 23337 if (!container) { 23338 container = $(this.config.selectors.productsContainer); 23339 } 23340 23341 // detail link 23342 var $this = this; 23343 23344 this.config.rootContainer.find(this.config.selectors.productsLinks).each(function (pIndex, productLink) { 23345 product = $(productLink).parents('.product').first(); 23346 $(productLink).bind('click', {context: $this, product: product}, function (event) { 23347 $detailModal = $(event.data.context.config.selectors.productDetail); 23348 if (event.data.product.hasClass('bundle')) { 23349 $detailModal.addClass('bundle'); 23350 } 23351 else { 23352 $detailModal.removeClass('bundle'); 23353 } 23354 23355 event.data.context.openDetailView(event.data.product.data(), $detailModal); 23356 }); 23357 }); 23358 23359 // detail modal 23360 $(this.config.selectors.productDetail).bind('hidden', {context: this}, function (event) { 23361 $(this).removeClass('open'); 23362 //jQuery.bbq.removeState('product'); 23363 if (!$(this).hasClass('bundle')) { 23364 jQuery.bbq.pushState({ 23365 product: 0 23366 }); 23367 } 23368 }); 23369 23370 // add to favourites link 23371 this.config.rootContainer.find(this.config.selectors.productsAddToFavourites).each(function (pIndex, addToFavouritesLink) { 23372 product = $(addToFavouritesLink).parents('.product').first(); 23373 $(addToFavouritesLink).bind('click', {context: $this, product: product}, function (event) { 23374 event.preventDefault(); 23375 event.data.context.addToFavourites(event.data.product.data(), $(event.data.context.config.selectors.favourites)); 23376 }); 23377 }); 23378 23379 23380 // add to cart link 23381 this.config.rootContainer.find(this.config.selectors.productsAddToCart).each(function (pIndex, addToCartLink) { 23382 product = $(addToCartLink).parents('.product').first(); 23383 $(addToCartLink).bind('click', {context: $this, product: product}, function (event) { 23384 event.preventDefault(); 23385 if (event.data.product.data('type') == 'master') { 23386// $optionsContainer = $(event.data.product).find(event.data.context.config.selectors.productOptions); 23387// $optionsContainer.show(); 23388// containerHeight = $optionsContainer.innerHeight(); 23389// $optionsContainer.css({'height':0}); 23390// $optionsContainer.stop().animate({'height':containerHeight}, 200); 23391 } 23392 else { 23393 event.data.context.addToCart(event.data.product.data(), event.data.product); 23394 } 23395 23396 }); 23397 }); 23398 23399 // option links 23400 this.bindProductOptionLinksEvents(container); 23401 23402 }; 23403 23404 23405 this.bindProductOptionLinksEvents = function (context) { 23406 var $this = this; 23407 $(context).find(this.config.selectors.productOptionLinks).each(function (pIndex, optionLink) { 23408 product = $(optionLink).parents('.product').first(); 23409 $(optionLink).bind('touchstart click', {context: $this, product: product}, function (event) { 23410 event.preventDefault(); 23411 if (!$(this).hasClass('disabled')) { 23412 var product = event.data.product; 23413 23414 $(this).addClass(event.data.context.config.classes.buttonActive); 23415 $(this).siblings().removeClass(event.data.context.config.classes.buttonActive); 23416 23417 selectResult = event.data.context.selectProductOption($(this).data(), product, $(this).data('disable') == 'addToCart' ? true : false); 23418 if (!selectResult) { 23419 event.stopPropagation(); 23420 } 23421 23422 event.data.context.disableInvalidOptionCombinations(product, $(optionLink).parents('.option').first().data('optionKey')); 23423 23424 } 23425 23426 }); 23427 }); 23428 }; 23429 23430 // product functions - detail view
23431 this.openDetailView = function ($productData, $detailModal, openBundleProductIndex) { 23432 if (!$detailModal) { 23433 $detailModal = $(this.config.selectors.productDetail); 23434 } 23435 23436 23437 var $this = this; 23438 23439 23440 23441 if (!openBundleProductIndex) { 23442 openBundleProductIndex = 0; 23443 } 23444 $detailModal.data('openBundleProductIndex', openBundleProductIndex); 23445 23446 $detailModal.find('.alert').hide(); 23447 $detailModal.addClass('open'); 23448 $detailModal.data($productData); 23449 $detailModal.find('#bundle-nav').hide(); 23450 23451 // base data 23452 if ($productData.type == 'bundle') { 23453 productTitle = $productData.ssag_name; 23454 23455 $detailModal.find('.model .value').text($productData.products[openBundleProductIndex].products_model); 23456 $detailModal.find('.description').html($productData.products[openBundleProductIndex].products_description); 23457 23458 var selectedBundleOptions = $detailModal.data('selectedBundleOptions'); 23459 if (!selectedBundleOptions) { 23460 selectedBundleOptions = new Object(); 23461 $detailModal.data('selectedBundleOptions', selectedBundleOptions); 23462 } 23463 23464 23465 switch ($productData.bundleType) { 23466 case 'package': 23467 23468 case 'freeAddOn': 23469 $detailModal.find('#bundle-nav').empty(); 23470 $detailModal.find('#bundle-nav').show(); 23471 23472 for (pIndex in $productData.productIds) { 23473 bundleProduct = this.data.products[$productData.productIds[pIndex]]; 23474 $bundleNavItem = $('<li></li>'); 23475 $bundleNavLink = $('<a href="#">' + bundleProduct.products_name + '</a>'); 23476 $bundleNavLink.data({ 23477 'bundle': $productData, 23478 'index': pIndex 23479 }); 23480 $bundleNavItem.append($bundleNavLink); 23481 $detailModal.find('#bundle-nav').append($bundleNavItem); 23482 } 23483 23484 $('#bundle-nav a').bind('click', {context: this}, function (event) { 23485 event.preventDefault(); 23486 $(this).tab('show'); 23487 event.data.context.openDetailView($(this).data('bundle'), false, $(this).data('index')); 23488 }); 23489 23490 23491 $('#bundle-nav a').eq(openBundleProductIndex).tab('show'); 23492 23493 break; 23494 default: 23495 break; 23496 } 23497 23498 currentProduct = this.data.products[$productData.productIds[openBundleProductIndex]]; 23499 this.buildBundlePrice($detailModal, $productData); 23500 } 23501 else { 23502 productTitle = $productData.products_name; 23503 $detailModal.find('.model .value').text($productData.products_model); 23504 $detailModal.find('.description').html($productData.products_description); 23505 var currentProduct = $productData; 23506 if (!$detailModal.hasClass('bundle')) { 23507 this.buildProductPrice($detailModal, $productData, $detailModal.find('.badges')); 23508 } 23509 23510 } 23511 $detailModal.find('.title').text(productTitle); 23512 $detailModal.find('.badges').empty(); 23513 23514 23515 23516 // browser title 23517 document.title = productTitle + ' - ' + this.documentTitle; 23518 23519 // facebook-like 23520 23521 $('#facebook-like').html('<fb:like href="' + location.href + '" width="250" layout="button_count" show_faces="true" send="true"></fb:like>'); 23522 if (typeof FB !== 'undefined') { 23523 FB.XFBML.parse(document.getElementById('facebook-like')); 23524 } 23525 23526 23527 // images 23528 $detailModal.find('.zoom_thumbnails').empty();
23529 $detailModal.find('#zoom_container').empty(); 23530 23531 var detailImages = [ 23532 currentProduct.products_image, 23533 currentProduct.products_image_2, 23534 currentProduct.products_image_3, 23535 currentProduct.products_image_4, 23536 currentProduct.products_image_5 23537 ]; 23538 23539 if (currentProduct.type == 'master') { 23540 detailImages = this.findProductImages(currentProduct); 23541 } 23542 23543 23544// if ($productData.type == 'bundle') { 23545// 23546// if ($productData.ssag_image) { 23547// detailImages = [ 23548// bundle.ssag_image 23549// ]; 23550// } 23551// else { 23552// if ($productData.products.length > 0) { 23553// for (pIndex in $productData.products) { 23554// detailImages = this.findProductImages($productData.products[pIndex]); 23555// if (detailImages) { 23556// break; 23557// } 23558// } 23559// } 23560// } 23561// } 23562 23563 23564 infoImage = { 23565 width: 430, 23566 height: 430 23567 }; 23568 panButtonsShow = false; 23569 zoomButtonsShow = false; 23570 if ($(document).innerWidth() >= 768 && $(document).innerWidth() <= 979) { 23571 infoImage = { 23572 width: 350, 23573 height: 350 23574 }; 23575 } 23576 if ($(document).innerWidth() >= 481 && $(document).innerWidth() <= 767) { 23577 infoImage = { 23578 width: 230, 23579 height: 230 23580 }; 23581 } 23582 if ($(document).innerWidth() <= 768) { 23583 infoImage = { 23584 width: $('#product-detail').innerWidth() - 40, 23585 height: 200 23586 }; 23587 panButtonsShow = false; 23588 zoomButtonsShow = false; 23589 } 23590 23591 if ($(window).innerHeight() <= 800) { 23592// $('#product-detail').css({ 23593// 'margin-top': -300 23594// }); 23595 $('#product-detail .modal-body').css({ 23596 'max-height': $(window).innerHeight() - 220 23597 }); 23598 } 23599 23600 if ($(document).innerWidth() <= 479) { 23601// $('#product-detail').css({ 23602// 'margin-top': -280 23603// }); 23604 $('#product-detail .modal-body').css({ 23605 'max-height': $(window).innerHeight() - 200 23606 }); 23607 } 23608 if ($(document).innerWidth() >= 480 && $(document).innerWidth() <= 768) { 23609// $('#product-detail').css({ 23610// 'margin-top': -130 23611// }); 23612 $('#product-detail .modal-body').css({ 23613 'max-height': $(window).innerHeight() - 180 23614 }); 23615 } 23616 23617 for (iIndex in detailImages) { 23618 if (detailImages[iIndex]) { 23619 $thumbnail = $('<li><a href="#" data-src="/media/images/popup/' + detailImages[iIndex] + '" data-size="' + infoImage.width + ',' + infoImage.height + '" style="background-image:url(/media/images/info/' + detailImages[iIndex] + ')"></a></li>'); 23620 $thumbnail.find('img').data('filename', detailImages[iIndex]); 23621 $thumbnail.find('img').bind('error', function () { 23622 $(this).parents('li').first().detach(); 23623 }); 23624 23625 $thumbnail.bind('click', {src: '/media/images/popup/' + detailImages[iIndex]}, function (event) { 23626 23627 event.preventDefault(); 23628 $(this).parents('.zoom_thumbnails').first().find('li a').removeClass('active'); 23629 $(this).addClass('active'); 23630 //Add your zoom settings here 23631 23632 $('#zoom_container').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({ 23633 image_url: event.data.src, 23634 width: infoImage.width, 23635 height: infoImage.height, 23636 /****************************************** 23637 Enable Responsive settings below if needed. 23638 Max width and height values are optional. 23639 ******************************************/ 23640 responsive: false, 23641 responsive_maintain_ratio: true, 23642 max_WIDTH: '', 23643 max_HEIGHT: '', 23644 pan_BUTTONS_SHOW: panButtonsShow, 23645 zoom_BUTTONS_SHOW: zoomButtonsShow 23646 }); 23647 return false; 23648 23649 }); 23650 $detailModal.find('.zoom_thumbnails').append($thumbnail); 23651 } 23652 } 23653 23654 23655 23656 23657 if ($detailModal.find('.zoom_thumbnails').find('li').length > 0) { 23658 $detailModal.find('.zoom_thumbnails').find('li a').eq(0).trigger('click'); 23659// $('.zoom_thumbnails').find('li a').each(function(tIndex, thumbnail) { 23660// $(thumbnail).live('click', {src: $(this).attr('href'), thumbnail: thumbnail}, function(e) { 23661// $(e.data.thumbnail).addClass('active'); 23662// //Add your zoom settings here 23663// $('#zoom_container').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({ 23664// image_url: e.data.src, 23665// width: 430, 23666// height: 430, 23667// /****************************************** 23668// Enable Responsive settings below if needed. 23669// Max width and height values are optional. 23670// ******************************************/ 23671// responsive: false, 23672// responsive_maintain_ratio: true, 23673// max_WIDTH: '', 23674// max_HEIGHT: '' 23675// }); 23676// return false; 23677// 23678// }); 23679// }).eq(0).trigger('click'); 23680 } 23681 23682 23683 23684 23685 23686 23687 // options 23688 productOptions = false; 23689 if (currentProduct.type == 'master') { 23690 productOptions = currentProduct.options; 23691 $master = currentProduct; 23692 } 23693 else { 23694 if (currentProduct.master) { 23695 productOptions = currentProduct.master.options; 23696 $master = currentProduct.master; 23697 } 23698 } 23699 23700 $detailModal.find(this.config.selectors.productOptions).empty(); 23701 23702 if (productOptions) { 23703 for (optionKey in productOptions) { 23704 23705 if (productOptions[optionKey].length > 0) { 23706 $optionTemplate = this.getTemplate(this.config.selectors.templateProductOptions.detail, 'productOptionsDetail-' + currentProduct.products_id + '-' + optionKey); 23707 $optionTemplate.find('.title').text(this.config.filters[optionKey].title[this.config.language]); 23708 $optionTemplate.data('optionKey', optionKey); 23709 for (vIndex in productOptions[optionKey]) { 23710 $optionLink = $('<a href="#" class="' + this.config.classes.optionLink + '">' + productOptions[optionKey][vIndex].replace("\\/", '/') + '</a>'); 23711 $optionLink.data({ 23712 optionKey: optionKey, 23713 value: productOptions[optionKey][vIndex], 23714 masterId: $master.products_id, 23715 disable: 'addToCart' 23716 }); 23717 $optionTemplate.find('.values').append($optionLink); 23718 } 23719 if (productOptions[optionKey].length == 1) { 23720 $optionLink.addClass(this.config.classes.buttonActive); 23721 this.selectProductOption($optionLink.data(), $detailModal, true, true); 23722 } 23723 23724 $detailModal.find(this.config.selectors.productOptions).append($optionTemplate); 23725 } 23726 } 23727 if (currentProduct.type == 'child') { 23728 for (optionKey in productOptions) { 23729 filterConf = this.config.filters[optionKey]; 23730 fields = filterConf.field; 23731 if (!jQuery.isArray(fields)) { 23732 fields = new Array(fields); 23733 } 23734 for (vIndex in productOptions[optionKey]) { 23735 if (productOptions[optionKey][vIndex] == currentProduct[fields[0]]) { 23736 $optionLink = $('#productOptionsDetail-' + currentProduct.products_id + '-' + optionKey).find('a').eq(vIndex); 23737 $optionLink.addClass(this.config.classes.buttonActive); 23738 this.selectProductOption($optionLink.data(), $detailModal, true, true); 23739 this.disableInvalidOptionCombinations($detailModal, optionKey); 23740 } 23741 } 23742 } 23743 23744 } 23745 } 23746 23747 this.bindProductOptionLinksEvents($detailModal); 23748 23749 if ($productData.type == 'bundle') { 23750 var selectedBundleOptions = $detailModal.data('selectedBundleOptions'); 23751 if (selectedBundleOptions.hasOwnProperty($master.products_id)) { 23752 for (optionKey in productOptions) { 23753 filterConf = this.config.filters[optionKey]; 23754 for (vIndex in productOptions[optionKey]) { 23755 if (selectedBundleOptions[$master.products_id][filterConf.field] == productOptions[optionKey][vIndex]) { 23756 $('#productOptionsDetail-' + $master.products_id + '-' + optionKey).find('a').each(function (aIndex, optionLink) { 23757 if ($(optionLink).data('value') == productOptions[optionKey][vIndex]) { 23758 $(optionLink).addClass($this.config.classes.buttonActive); 23759 } 23760 }); 23761 this.selectProductOption({ 23762 optionKey: optionKey, 23763 value: productOptions[optionKey][vIndex], 23764 masterId: $master.products_id, 23765 disable: 'addToCart' 23766 }, $detailModal, true, true); 23767 } 23768 } 23769 } 23770 } 23771 } 23772 23773 // additional infos 23774 23775 if (this.config.detail.additonalInfos) { 23776 $(this.config.selectors.productDetailAdditionalInfo).empty(); 23777 for (aiIndex in this.config.detail.additonalInfos) { 23778 aInfo = this.config.detail.additonalInfos[aiIndex]; 23779 if (currentProduct[aInfo.field]) { 23780 $infoTemplate = this.getTemplate(this.config.selectors.templateProductDetailInfo, 'product-additional-info-' + currentProduct.products_id + '-' + aInfo.field); 23781 $infoTemplate.find('.title').text(aInfo.title + ': '); 23782 $infoTemplate.find('.value').text(currentProduct[aInfo.field]); 23783 $(this.config.selectors.productDetailAdditionalInfo).append($infoTemplate); 23784 } 23785 } 23786 } 23787 23788 23789 // events 23790 if ($productData.prev) { 23791 $detailModal.find('.navigation-product-prev').unbind('click').bind('click', {context: this, product: $productData.prev}, function (event) { 23792 event.preventDefault();
23793 event.data.context.openDetailView(event.data.product); 23794// $.History.go(event.data.context.getPath()); 23795 }); 23796 $detailModal.find('.navigation-product-prev').removeClass('disabled'); 23797 } 23798 else { 23799 $detailModal.find('.navigation-product-prev').addClass('disabled'); 23800 } 23801 23802 if ($productData.next) { 23803 $detailModal.find('.navigation-product-next').unbind('click').bind('click', {context: this, product: $productData.next}, function (event) { 23804 event.preventDefault(); 23805 event.data.context.openDetailView(event.data.product); 23806// $.History.go(event.data.context.getPath()); 23807 }); 23808 $detailModal.find('.navigation-product-next').removeClass('disabled'); 23809 } 23810 else { 23811 $detailModal.find('.navigation-product-next').addClass('disabled'); 23812 } 23813 23814 $detailModal.find('.btn-fullscreen').live('click', {context: this}, function (event) { 23815 event.preventDefault(); 23816 activeImage = $detailModal.find('.zoom_thumbnails .active a').first(); 23817 23818 $('.fullscreen-element').detach(); 23819 $('body').append('<div id="fullscreen-zoom" class="fullscreen-element"><div class="inner"></div></div>'); 23820 $('body').append('<a id="fullscreen-zoom-close" class="btn btn-danger fullscreen-element" href="#"><i class="icon-remove icon-white"></i></a>'); 23821 $('body').append('<div id="fullscreen-galery" class="fullscreen-element"><h4>' + event.data.context.config.translations.moreImages[event.data.context.config.language] + '</h4></div>'); 23822 $('#fullscreen-zoom .inner').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({ 23823 image_url: $(activeImage).data('src'), 23824 width: $(window).innerWidth(), 23825 height: $(window).innerHeight(), 23826 /****************************************** 23827 Enable Responsive settings below if needed. 23828 Max width and height values are optional. 23829 ******************************************/ 23830 responsive: false, 23831 responsive_maintain_ratio: true, 23832 max_WIDTH: '', 23833 max_HEIGHT: '', 23834 background_COLOR: 'transparent' 23835 }); 23836 $('#fullscreen-galery').append($detailModal.find('.zoom_thumbnails').clone()); 23837 23838 $('#fullscreen-galery .zoom_thumbnails').find('li a').each(function (tIndex, thumbnail) { 23839 $(thumbnail).live('click', {thumbnail: thumbnail}, function (e) { 23840 e.preventDefault(); 23841 $(e.data.thumbnail).addClass('active'); 23842 //Add your zoom settings here 23843 $('#fullscreen-zoom .inner').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({ 23844 image_url: $(e.data.thumbnail).data('src'), 23845 width: $(window).innerWidth(), 23846 height: $(window).innerHeight(), 23847 /****************************************** 23848 Enable Responsive settings below if needed. 23849 Max width and height values are optional. 23850 ******************************************/ 23851 responsive: false, 23852 responsive_maintain_ratio: true, 23853 max_WIDTH: '', 23854 max_HEIGHT: '', 23855 background_COLOR: 'transparent' 23856 }); 23857 return false; 23858 23859 }); 23860 }) 23861 23862 23863 $('#fullscreen-zoom-close').bind('click', function (event) { 23864 event.preventDefault(); 23865 $('.fullscreen-element').detach(); 23866 }); 23867 23868 23869 23870 }); 23871 23872 23873 23874 $(".alert .hide-alert").bind('click', function (event) { 23875 event.preventDefault(); 23876 $alert = $(this).parents('.alert').first(); 23877 $alert.stop().animate({'opacity': 0}, 250, function () { 23878 $alert.hide(); 23879 }); 23880 }); 23881 23882 $detailModal.find(this.config.selectors.productDetailAddToCart).unbind('click').bind('click', {context: this, product: $detailModal}, function (event) { 23883 event.preventDefault(); 23884 product = event.data.product; 23885 productData = $(product).data(); 23886 23887 var qty = 1; 23888 if ($('#product-detail-qty').val() != '' && jQuery.isNumeric($('#product-detail-qty').val())) { 23889 qty = parseInt($('#product-detail-qty').val()); 23890 } 23891 23892 switch (productData.type) { 23893 case 'standalone': 23894 event.data.context.addToCart(productData, $(product), qty); 23895 break; 23896 23897 case 'bundle': 23898 var selectedBundleOptions = $(product).data('selectedBundleOptions'); 23899 if (selectedBundleOptions['allSelected']) { 23900 $("#message-errorAddToCart").hide(); 23901 23902 event.data.context.addToCart(productData, $(product), qty); 23903 } 23904 else { 23905 $('#message-errorAddToCart').find('.message').text(productData.errorBundleNotAllSelected); 23906 $("#message-errorAddToCart").show().css('opacity', 0).stop().animate({'opacity': 1}, 250); 23907 } 23908 break; 23909 23910 default: 23911 $master = productData.master ? productData.master : productData; 23912 23913 23914 allOptionsSelected = true; 23915 if ($master.hasOwnProperty('selectedOptions')) { 23916 for (optionKey in $master['options']) { 23917 if (!$master['selectedOptions'][optionKey]) { 23918 allOptionsSelected = false; 23919 } 23920 } 23921 } 23922 else { 23923 allOptionsSelected = false; 23924 } 23925 23926 23927 if (allOptionsSelected) { 23928 23929 children = event.data.context.findChildrenForSelectedOptions($master, false); 23930 23931 if (children.length >= 1) { 23932 event.data.context.addToCart(children[0], $(product), qty); 23933 23934 } 23935 } 23936 else { 23937 $("#message-selectOptions").show().css('opacity', 0).stop().animate({'opacity': 1}, 250); 23938 } 23939 break; 23940 } 23941 23942 }); 23943 23944 23945 // fb like hack 23946 $detailModal.find('.fb_iframe_widget>span, .fb_iframe_widget iframe').css({ 23947 height: '25px', 23948 width: '100%', 23949 position: 'relative' 23950 }); 23951 23952 23953 23954 // BBQ 23955 if ($productData.type == 'bundle') { 23956 if (this.config.bbqEnabled) { 23957 jQuery.bbq.pushState({ 23958 bundle: $productData.id 23959 }); 23960 jQuery.bbq.removeState('product'); 23961 } 23962 } 23963 else { 23964 if (this.config.bbqEnabled && !$detailModal.hasClass('bundle') && $productData.products_id) { 23965 jQuery.bbq.pushState({ 23966 product: $productData.products_id 23967 }); 23968 23969 } 23970 } 23971 23972 23973 23974 23975 23976 23977 }; 23978 23979 // product functions - options 23980 this.selectProductOption = function (option, product, disableAddToCart, inDetail) { 23981 23982 if (typeof option['optionKey'] != 'undefined') { 23983 23984 productData = $(product).data(); 23985 var isBundle = false; 23986 var bundleIds = new Array(); 23987 if (productData.type == 'bundle') { 23988 isBundle = true; 23989 bundleIds = productData.productIds; 23990 openBundleProductIndex = $(product).data('openBundleProductIndex'); 23991 productData = this.data.products[productData.productIds[openBundleProductIndex]]; 23992 } 23993 23994 23995 $master = productData.master ? productData.master : productData; 23996 if ($master['selectedOptions']) { 23997 selectedOptions = $master['selectedOptions']; 23998 } 23999 else { 24000 selectedOptions = {}; 24001 } 24002 filterConf = this.config.filters[option['optionKey']]; 24003 selectedOptions[option['optionKey']] = option['value']; 24004 24005 $master['selectedOptions'] = selectedOptions; 24006 $(product).data('selectedOptions', selectedOptions); 24007 24008 $detailModal = $(this.config.selectors.productDetail); 24009 if ($(this.config.selectors.productDetailFull).length > 0) { 24010 $detailModal = $(this.config.selectors.productDetailFull); 24011 } 24012 24013 children = this.findChildrenForSelectedOptions(productData, option['optionKey']); 24014 24015 if ((inDetail || $detailModal.hasClass('open') || $('#product-detail-full').length > 0) && filterConf.hasOwnProperty('imageSensitive') && filterConf.imageSensitive) { 24016 24017 24018 if (children.length > 0) { 24019 24020 24021 24022 optionImages = [ 24023 children[0].products_image, 24024 children[0].products_image_2, 24025 children[0].products_image_3, 24026 children[0].products_image_4, 24027 children[0].products_image_5 24028 ]; 24029 24030 24031 $detailModal.find('.zoom_thumbnails').empty(); 24032 for (iIndex in optionImages) { 24033 if (optionImages[iIndex]) { 24034 $thumbnail = $('<li><a href="#" data-src="/media/images/popup/' + optionImages[iIndex] + '" data-size="430,430" style="background-image: url(/media/images/info/' + optionImages[iIndex] + ')"></a></li>'); 24035 $thumbnail.find('img').data('filename', optionImages[iIndex]); 24036 $thumbnail.find('img').bind('error', function () { 24037 $(this).parents('li').first().detach(); 24038 }); 24039 $thumbnail.bind('click', {src: '/media/images/popup/' + optionImages[iIndex]}, function (event) { 24040 24041 event.preventDefault(); 24042 $(this).parents('.zoom_thumbnails').first().find('li a').removeClass('active'); 24043 $(this).addClass('active'); 24044 //Add your zoom settings here 24045 24046 $('#zoom_container').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({ 24047 image_url: event.data.src, 24048 width: infoImage.width, 24049 height: infoImage.height, 24050 /****************************************** 24051 Enable Responsive settings below if needed. 24052 Max width and height values are optional. 24053 ******************************************/ 24054 responsive: false, 24055 responsive_maintain_ratio: true, 24056 max_WIDTH: '', 24057 max_HEIGHT: '', 24058 pan_BUTTONS_SHOW: panButtonsShow, 24059 zoom_BUTTONS_SHOW: zoomButtonsShow 24060 }); 24061 return false; 24062 24063 }); 24064 24065 $detailModal.find('.zoom_thumbnails').append($thumbnail); 24066 } 24067 } 24068 $detailModal.find('.zoom_thumbnails li a').first().trigger('click'); 24069 } 24070 24071 } 24072 24073 // all options selected? 24074 allOptionsSelected = true; 24075 for (optionKey in $master['options']) { 24076 if (!selectedOptions[optionKey]) { 24077 allOptionsSelected = false; 24078 } 24079 } 24080 24081 24082 if (allOptionsSelected) { 24083 foundChild = false; 24084 children = $master['children']; 24085 for (cIndex in children) { 24086 child = children[cIndex]; 24087 childResult = true; 24088 for (optionKey in selectedOptions) { 24089 filterConf = this.config.filters[optionKey]; 24090 fields = filterConf.field; 24091 if (!jQuery.isArray(fields)) { 24092 fields = new Array(fields); 24093 } 24094 optionResult = false; 24095 for (fIndex in fields) { 24096 if (child[fields[fIndex]] == selectedOptions[optionKey]) { 24097 optionResult = true; 24098 } 24099 } 24100 if (!optionResult) { 24101 childResult = false; 24102 } 24103 } 24104 if (childResult) { 24105 foundChild = child; 24106 } 24107 } 24108 24109 24110 if (foundChild) { 24111 24112 if (isBundle) { 24113 var selectedBundleOptions = $(product).data('selectedBundleOptions'); 24114 if (!selectedBundleOptions) { 24115 selectedBundleOptions = new Object(); 24116 } 24117 selectedBundleOptions[bundleIds[openBundleProductIndex]] = foundChild; 24118 var bundleAllSelected = 0; 24119 for (bIndex in bundleIds) { 24120 if (selectedBundleOptions.hasOwnProperty(bundleIds[bIndex]) || this.data.products[bundleIds[bIndex]].type != 'master') { 24121 bundleAllSelected++; 24122 } 24123 } 24124 selectedBundleOptions['allSelected'] = (bundleAllSelected == bundleIds.length); 24125 $(product).data('selectedBundleOptions', selectedBundleOptions); 24126 24127 } 24128 24129 // change price, title, description 24130 if (inDetail || $detailModal.hasClass('open') || $('#product-detail-full').length > 0) { 24131 $(product).find('.product-title').text(foundChild.products_name); 24132 $(product).find('.model .value').text(foundChild.products_model); 24133 $(product).find('.description').html(foundChild.products_description); 24134 24135 $
24135detailModal.find('.badges').empty(); 24136 if (!$detailModal.hasClass('bundle')) { 24137 this.buildProductPrice($detailModal, foundChild, $detailModal.find('.badges')); 24138 } 24139 } 24140 24141 if (!disableAddToCart) { 24142 if (isBundle) { 24143 if (selectedBundleOptions['allSelected']) { 24144 this.addToCart(foundChild, product); 24145 } 24146 else { 24147 if ($(product).hasClass('detail-view')) { 24148 $('#message-errorAddToCart').find('.message').text(productData.errorBundleNotAllSelected); 24149 $("#message-errorAddToCart").show().css('opacity', 0).stop().animate({'opacity': 1}, 250); 24150 } 24151 24152 } 24153 } 24154 else { 24155 this.addToCart(foundChild, product); 24156 } 24157 return true; 24158 } 24159 } 24160 } 24161 } 24162 24163 return false; 24164 24165 }; 24166 24167 24168 this.findChildrenForSelectedOptions = function (product, currentOptionKey) { 24169 result = []; 24170 $master = product.master ? product.master : product; 24171 children = $master['children']; 24172 24173 for (cIndex in children) { 24174 child = children[cIndex]; 24175 childResult = true; 24176 for (optionKey in $master['selectedOptions']) { 24177 24178 if ((typeof optionKey != 'undefined') && (!currentOptionKey || optionKey == currentOptionKey)) { 24179 filterConf = this.config.filters[optionKey]; 24180 fields = filterConf.field; 24181 if (!jQuery.isArray(fields)) { 24182 fields = new Array(fields); 24183 } 24184 optionResult = false; 24185 for (fIndex in fields) { 24186 if (child[fields[fIndex]] == $master['selectedOptions'][optionKey]) { 24187 optionResult = true; 24188 } 24189 } 24190 if (!optionResult) { 24191 childResult = false; 24192 } 24193 } 24194 24195 } 24196 if (childResult) { 24197 result.push(child); 24198 } 24199 } 24200 24201 return result; 24202 } 24203 24204 this.disableInvalidOptionCombinations = function (product, currentOptionKey) { 24205 $this = this; 24206 productData = $(product).data(); 24207 if (productData.type == 'bundle') { 24208 openBundleProductIndex = $(product).data('openBundleProductIndex'); 24209 productData = this.data.products[productData.productIds[openBundleProductIndex]]; 24210 } 24211 $master = productData.master ? productData.master : productData; 24212 if ($master['selectedOptions']) { 24213 children = this.findChildrenForSelectedOptions(productData, currentOptionKey); 24214 $(product).find('.option').not('.template').each(function (oIndex, option) { 24215 24216 if (currentOptionKey != $(option).data('optionKey')) { 24217 filterConf = $this.config.filters[$(option).data('optionKey')]; 24218 fields = filterConf.field; 24219 if (!jQuery.isArray(fields)) { 24220 fields = new Array(fields); 24221 } 24222 foundValues = []; 24223 for (cIndex in children) { 24224 child = children[cIndex]; 24225 for (fIndex in fields) { 24226 if (jQuery.inArray(child[fields[fIndex]], foundValues) < 0) { 24227 foundValues.push(child[fields[fIndex]]); 24228 } 24229 } 24230 } 24231 $(option).find('a').each(function (lIndex, optionLink) {
24232 if (jQuery.inArray($(optionLink).data('value'), foundValues) >= 0) { 24233 $(optionLink).removeClass('disabled'); 24234 } 24235 else { 24236 $(optionLink).addClass('disabled'); 24237 } 24238 }); 24239 } 24240 }); 24241 24242 } 24243 }; 24244 24245 24246 24247 // pagination 24248 this.buildPagination = function () { 24249 24250 if (this.foundProducts.length) { 24251 if (this.foundProducts.length > 1) { 24252 $(this.config.selectors.pagination.resultAmount).html('<span class="' + this.config.classes.resultAmount + '">' + String(this.foundProducts.length) + '</span> ' + this.config.translations.resultAmount.plural[this.config.language]); 24253 } 24254 else { 24255 $(this.config.selectors.pagination.resultAmount).html('<span class="' + this.config.classes.resultAmount + '">' + String(this.foundProducts.length) + '</span> ' + this.config.translations.resultAmount.singular[this.config.language]); 24256 } 24257 } 24258 else { 24259 $(this.config.selectors.pagination.resultAmount).html(this.config.translations.resultAmount.none[this.config.language]); 24260 } 24261 24262 24263 if (this.foundProducts.length > this.searchParams.range) { 24264 24265 $(this.config.selectors.pagination.container).show(); 24266 // pages vars 24267 pages = parseInt(this.foundProducts.length / this.searchParams.range); 24268 if (this.foundProducts.length % this.searchParams.range > 0) { 24269 pages++; 24270 } 24271 firstPage = !(this.searchParams.start); 24272 lastPage = (this.searchParams.start + this.searchParams.range >= this.foundProducts.length); 24273 currentPage = this.searchParams.start / this.searchParams.range; 24274 24275 // activate/deactivate prev/next 24276 if (firstPage) { 24277 $(this.config.selectors.pagination.prev).addClass('disabled'); 24278 } 24279 else { 24280 $(this.config.selectors.pagination.prev).removeClass('disabled'); 24281 $(this.config.selectors.pagination.prev).data('start', this.searchParams.start - this.searchParams.range); 24282 } 24283 if (lastPage) { 24284 $(this.config.selectors.pagination.next).addClass('disabled'); 24285 } 24286 else { 24287 $(this.config.selectors.pagination.next).removeClass('disabled'); 24288 $(this.config.selectors.pagination.next).data('start', this.searchParams.start + this.searchParams.range); 24289 } 24290 // activate/deactivate first/last 24291 24292 if (pages > this.config.pagination.maxPages) { 24293 $(this.config.selectors.pagination.first).show(); 24294 $(this.config.selectors.pagination.last).show(); 24295 if (firstPage) { 24296 $(this.config.selectors.pagination.first).addClass('disabled'); 24297 } 24298 else { 24299 $(this.config.selectors.pagination.first).removeClass('disabled'); 24300 $(this.config.selectors.pagination.first).data('start', 0); 24301 } 24302 if (lastPage) { 24303 $(this.config.selectors.pagination.last).addClass('disabled'); 24304 } 24305 else { 24306 $(this.config.selectors.pagination.last).removeClass('disabled'); 24307 $(this.config.selectors.pagination.last).data('start', (pages - 1) * this.searchParams.range); 24308 } 24309 } 24310 else { 24311 $(this.config.selectors.pagination.first).hide(); 24312 $(this.config.selectors.pagination.last).hide(); 24313 } 24314 // build pages-links 24315 $(this.config.selectors.pagination.pages).empty(); 24316 24317 startPage = currentPage - this.config.pagination.prevNextPages; 24318 24319 if (startPage > pages - this.config.pagination.maxPages) { 24320 startPage = pages - this.config.pagination.maxPages; 24321 } 24322 if (startPage < 0) { 24323 startPage = 0; 24324 } 24325 24326 if (pages > this.config.pagination.maxPages && currentPage > this.config.pagination.maxPages - this.config.pagination.prevNextPages) { 24327 this.addPageLink(0); 24328 $(this.config.selectors.pagination.pages).append('<span class="divider">...</span>'); 24329 } 24330 24331 for (c = startPage, d = 0; c < pages && d < this.config.pagination.maxPages; c++, d++) { 24332 this.addPageLink(c); 24333 } 24334 if (pages > this.config.pagination.maxPages && pages - currentPage > this.config.pagination.maxPages - this.config.pagination.prevNextPages) { 24335 $(this.config.selectors.pagination.pages).append('<span class="divider">...</span>'); 24336 this.addPageLink(pages - 1); 24337 } 24338 24339 24340 // bind link-click event 24341 $(this.config.selectors.pagination.container).find('a').unbind('click').bind('click', { 24342 context: this 24343 }, function (event) { 24344 event.preventDefault(); 24345 if (!$(this).hasClass('disabled')) { 24346 event.data.context.showPage($(this).data('start')); 24347 filtersOffset = $(event.data.context.config.selectors.filtersContainer).offset(); 24348 $(window).scrollTop(filtersOffset.top - 40); 24349 } 24350 }); 24351 24352 } 24353 else { 24354 $(this.config.selectors.pagination.container).hide(); 24355 } 24356 24357 } 24358 24359 this.addPageLink = function (index) { 24360 $pageLink = $('<a href="#" class="btn">' + String(index + 1) + '</a>'); 24361 if (index * this.searchParams.range == this.searchParams.start) { 24362 $pageLink.addClass(this.config.classes.buttonActive); 24363 } 24364 $pageLink.data('start', index * this.searchParams.range); 24365 $(this.config.selectors.pagination.pages).append($pageLink); 24366 }; 24367 24368 this.showPage = function (start) { 24369 this.searchParams.start = start; 24370 this.showSearchResult(); 24371 }; 24372 24373 24374 24375 // configuration functions 24376 this.bindConfigurationLinkEvents = function () { 24377 24378 // sortBy links 24379 $(this.config.selectors.configuration.sortBy).find('a').bind('click', { 24380 context: this 24381 }, function (event) { 24382 event.preventDefault(); 24383 $(event.data.context.config.selectors.configuration.sortBy).find('a').removeClass(event.data.context.config.classes.buttonActive); 24384 $(this).addClass(event.data.context.config.classes.buttonActive); 24385 event.data.context.searchParams.sortBy = $(this).data('value'); 24386 event.data.context.applySorting(); 24387 event.data.context.showSearchResult(); 24388 }); 24389 24390 // sortOrder links 24391 $(this.config.selectors.configuration.sortOrder).find('a').bind('click', { 24392 context: this 24393 }, function (event) { 24394 event.preventDefault(); 24395 $(event.data.context.config.selectors.configuration.sortOrder).find('a').removeClass(event.data.context.config.classes.buttonActive); 24396 $(event.data.context.config.selectors.configuration.sortOrder).find('a i').removeClass(event.data.context.config.classes.buttonActiveIcon); 24397 $(this).addClass(event.data.context.config.classes.buttonActive); 24398 $(this).find('i').addClass(event.data.context.config.classes.buttonActiveIcon); 24399 event.data.context.searchParams.sortOrder = $(this).data('value'); 24400 event.data.context.applySorting(); 24401 event.data.context.showSearchResult(); 24402 }); 24403 24404 // presentation links 24405 $(this.config.selectors.configuration.presentation).find('a').bind('click', { 24406 context: this 24407 }, function (event) { 24408 event.preventDefault(); 24409 $(event.data.context.config.selectors.configuration.presentation).find('a').removeClass(event.data.context.config.classes.buttonActive); 24410 $(event.data.context.config.selectors.configuration.presentation).find('a i').removeClass(event.data.context.config.classes.buttonActiveIcon); 24411 $(this).addClass(event.data.context.config.classes.buttonActive); 24412 $(this).find('i').addClass(event.data.context.config.classes.buttonActiveIcon); 24413 event.data.context.searchParams.presentation = $(this).data('value'); 24414 event.data.context.showSearchResult(); 24415 }); 24416 24417 // resultsPerPage links 24418 $(this.config.selectors.configuration.resultsPerPage).find('a').bind('click', { 24419 context: this 24420 }, function (event) { 24421 event.preventDefault(); 24422 $(event.data.context.config.selectors.configuration.resultsPerPage).find('a').removeClass(event.data.context.config.classes.buttonActive); 24423 $(this).addClass(event.data.context.config.classes.buttonActive); 24424 event.data.context.searchParams.start = 0; 24425 event.data.context.searchParams.range = parseInt($(this).data('value')); 24426 event.data.context.showSearchResult(); 24427 }); 24428 24429 }; 24430 24431 24432 this.applySorting = function () { 24433 this.searchParams.start = 0; 24434 switch (this.searchParams.sortBy) { 24435 case 'name': 24436 this.foundProducts.sort(this.compareByName); 24437 break; 24438 case 'price': 24439 this.foundProducts.sort(this.compareByPrice); 24440 break; 24441 case 'size': 24442 this.foundProducts.sort(this.compareBySize); 24443 break; 24444 case 'color': 24445 this.foundProducts.sort(this.compareByColor); 24446 break; 24447 case 'material': 24448 this.foundProducts.sort(this.compareByMaterial); 24449 break; 24450 } 24451 24452 if (this.searchParams.sortOrder == 'DESC') { 24453 this.foundProducts.reverse(); 24454 } 24455 24456 // assign prev/next 24457 prevProduct = false; 24458 for (pIndex in this.foundProducts) { 24459 this.foundProducts[pIndex]['prev'] = false; 24460 this.foundProducts[pIndex]['next'] = false; 24461 if (prevProduct) { 24462 prevProduct['next'] = this.foundProducts[pIndex]; 24463 this.foundProducts[pIndex]['prev'] = prevProduct; 24464 } 24465 prevProduct = this.foundProducts[pIndex]; 24466 } 24467 24468 }; 24469 24470 // find functions 24471 this.findOneBy = function (field, value) { 24472 for (pIndex in this.data.products) { 24473 if (this.data.products[pIndex][field] == value) { 24474 return this.data.products[pIndex]; 24475 } 24476 } 24477 return false; 24478 }; 24479 24480 24481 // compare functions 24482 24483 this.compareByName = function (first, second) { 24484 if (first['products_name'] < second['products_name']) 24485 return -1; 24486 if (first['products_name'] > second['products_name']) 24487 return 1; 24488 return 0; 24489 }; 24490 24491 this.compareByPrice = function (first, second) { 24492 if (parseInt(first['products_price']) < parseInt(second['products_price'])) 24493 return -1; 24494 if (parseInt(first['products_price']) > parseInt(second['products_price'])) 24495 return 1; 24496 return 0; 24497 }; 24498 24499 this.compareBySize = function (first, second) { 24500 if (jQuery.isNumeric(first['ext_size']) && jQuery.isNumeric(second['ext_size'])) { 24501 if (parseInt(first['ext_size']) < parseInt(second['ext_size'])) 24502 return -1; 24503 if (parseInt(first['ext_size']) > parseInt(second['ext_size'])) 24504 return 1; 24505 } 24506 24507 return 0; 24508 }; 24509 24510 this.compareByColor = function (first, second) { 24511 if (first['ext_color_primary'] < second['ext_color_primary']) 24512 return -1; 24513 if (first['ext_color_primary'] > second['ext_color_primary']) 24514 return 1; 24515 return 0; 24516 }; 24517 24518 this.compareByMaterial = function (first, second) { 24519 if (first['ext_material_primary'] < second['ext_material_primary']) 24520 return -1; 24521 if (first['ext_material_primary'] > second['ext_material_primary']) 24522 return 1; 24523 return 0; 24524 }; 24525 24526 this.compareSizeByIntegerValue = function (first, second) { 24527 if ($(first).data('value') < $(second).data('value')) 24528 return -1; 24529 if ($(first).data('value') > $(second).data('value')) 24530 return 1; 24531 return 0; 24532 }; 24533 24534 this.compareSizeByLetter = function (first, second) { 24535 letters = $this.config.filters.size.letterSizesOrder; 24536 fIndex = jQuery.inArray(first, letters); 24537 sIndex = jQuery.inArray(second, letters); 24538 if (fIndex < sIndex) 24539 return -1; 24540 if (fIndex > sIndex) 24541 return 1; 24542 return 0; 24543 }; 24544 24545 this.compareSizeByShoeSize = function (first, second) { 24546 24547 24548 firstRes = first.split(' '); 24549 secondRes = second.split(' '); 24550 if (firstRes && secondRes) {
24551 if (parseFloat(firstRes[0]) < parseFloat(secondRes[0])) 24552 return -1; 24553 if (parseFloat(firstRes[0]) > parseFloat(secondRes[0])) 24554 return 1; 24555 } 24556 24557 return 0; 24558 }; 24559 24560 24561 // cart functions 24562 this.addToCart = function (product, container, qty) { 24563 24564 24565 $this = this; 24566 if (!qty) { 24567 qty = 1; 24568 } 24569 if (container) { 24570 $(container).append('<div class="mask"></div>'); 24571 $(container).spin(); 24572 } 24573 24574 productData = $(container).data(); 24575 if (productData.type == 'bundle') { 24576 bundleIds = new Array(); 24577 var selectedBundleOptions = $(container).data('selectedBundleOptions'); 24578 for (iIndex in productData.productIds) { 24579 bundleIds.push(selectedBundleOptions[productData.productIds[iIndex]].products_id); 24580 } 24581 var ajaxData = { 24582 action: 'addProduct', 24583 productType: 'bundle', 24584 product: productData.ssag_id, 24585 bundleIds: bundleIds, 24586 qty: qty, 24587 language: this.config.language 24588 }; 24589 } 24590 else { 24591 var ajaxData = { 24592 action: 'addProduct', 24593 productType: 'default', 24594 product: product.products_id, 24595 qty: qty, 24596 language: this.config.language 24597 }; 24598 } 24599 24600 24601 24602 $.ajax('/json.php', { 24603 data: ajaxData, 24604 dataType: 'json', 24605 context: container, 24606 error: function (jqXHR, textStatus, errorThrown) { 24607 if (typeof console != 'undefined') { 24608 24609 } 24610 else { 24611 alert(errorThrown); 24612 } 24613 }, 24614 success: function (data, textStatus, jqXHR) { 24615 24616 $(this).find('.mask').detach(); 24617 $(this).spin(false); 24618 24619 if (data.code == 0) { 24620 // success 24621 if ($(this).hasClass('detail-view')) { 24622 $("#message-productAdded").find('.name').text(data.product.products_name); 24623 $("#message-productAdded").show().css('opacity', 0).stop().animate({'opacity': 1}, 250); 24624 } 24625 else { 24626 $('.product .list-alert').detach(); 24627 $message = $("#message-list-productAdded").clone(true); 24628 $message.attr('id', 'message-list-productAdded-' + $(this).data('products_id')); 24629 $message.find('.name').text(data.product.products_name); 24630 $(this).append($message); 24631 $message.show().css('opacity', 0).stop().animate({'opacity': 1}, 250); 24632 $message.find('.hide-alert').bind('click', function (event) { 24633 event.preventDefault(); 24634 $(this).parents('.alert').first().detach(); 24635 }); 24636 closeMessage = window.setTimeout(function () { 24637 $message.detach(); 24638 }, 2000); 24639 } 24640 24641 $this.refreshCart(data.cart); 24642 24643 } 24644 else { 24645 // error 24646 if ($(this).hasClass('detail-view')) { 24647 $('#message-errorAddToCart').find('.message').text(data.error); 24648 $("#message-errorAddToCart").show().css('opacity', 0).stop().animate({'opacity': 1}, 250); 24649 } 24650 else { 24651 $('.product .list-alert').detach(); 24652 $message = $("#message-list-errorAddToCart").clone(true); 24653 $message.attr('id', 'message-list-errorAddToCart-' + $(this).data('products_id')); 24654 $message.find('.message').text(data.error); 24655 $(this).append($message); 24656 $message.show().css('opacity', 0).stop().animate({'opacity': 1}, 250); 24657 $message.find('.hide-alert').bind('click', function (event) { 24658 event.preventDefault(); 24659 $(this).parents('.alert').first().detach(); 24660 }); 24661 closeMessage = window.setTimeout(function () { 24662 $message.detach(); 24663 }, 4000); 24664 } 24665 } 24666 } 24667 }); 24668 24669 }; 24670 24671 24672 this.removeFromCart = function ($cartProduct) { 24673 $this = this; 24674 $cartProduct.append('<div class="mask"></div>'); 24675 $cartProduct.spin(); 24676 24677 $.ajax('/json.php', { 24678 data: { 24679 action: 'removeProduct', 24680 key: $cartProduct.data('key'), 24681 language: this.config.language 24682 }, 24683 dataType: 'json', 24684 error: function (jqXHR, textStatus, errorThrown) { 24685 if (typeof console != 'undefined') { 24686 24687 } 24688 else { 24689 alert(errorThrown); 24690 } 24691 }, 24692 success: function (data, textStatus, jqXHR) { 24693 24694 $cartProduct.find('.mask').detach(); 24695 $cartProduct.spin(false); 24696 if (data.code == 0) { 24697 // success 24698 $cartProduct.detach(); 24699 $this.refreshCart(data.cart); 24700 24701 } 24702 else { 24703 // error 24704 } 24705 } 24706 }); 24707 24708 }; 24709 24710 24711 this.refreshCart = function (cart) { 24712 // totalCount 24713 if (!cart.content_count) { 24714 cart.content_count = 0; 24715 } 24716 $($this.config.selectors.cart).find('.totalCount').text(cart.content_count); 24717 $($this.config.selectors.cartContent).data('totalCount', cart.content_count); 24718 24719 $('.cartTotal').html(cart.content_total.formated); 24720 24721 24722 // cart content 24723 if (cart.content_count) { 24724 $($this.config.selectors.cartContent).find('.cart
24724-products').empty(); 24725 for (pKey in cart.content) { 24726 cartProduct = cart.content[pKey]; 24727 $cartProductTemplate = $this.getTemplate('cartProduct-template', 'cartProduct-' + pKey); 24728 $cartProductTemplate.find('.link-to-product').attr('href', cartProduct.products_link); 24729 if (cartProduct.products_image) { 24730 $cartProductTemplate.find('.cart-product-image a').css('background-image', 'url(/media/images/thumb/' + cartProduct.products_image.replace('product:', '') + ')'); 24731 } 24732 $cartProductTemplate.find('.qty').text(cartProduct.products_quantity); 24733 $cartProductTemplate.find('.product-name').text(cartProduct.products_name); 24734 $cartProductTemplate.find('.price').html(cartProduct.products_final_price.formated); 24735 $cartProductTemplate.data({ 24736 'key': cartProduct.products_key, 24737 'qty': cartProduct.products_quantity 24738 }); 24739 $($this.config.selectors.cartContent).find('.cart-products').append($cartProductTemplate); 24740 } 24741 24742 $($this.config.selectors.cartContent).find('.cart-taxes').empty(); 24743 for (tKey in cart.content_tax) { 24744 tax = cart.content_tax[tKey]; 24745 $taxTemplate = $('<div class="tax"></div>'); 24746 $taxTemplate.html('MwSt. ' + tax.tax_key + '%: ' + tax.tax_value.formated); 24747 $($this.config.selectors.cartContent).find('.cart-taxes').append($taxTemplate); 24748 } 24749 24750 } 24751 else { 24752 $($this.config.selectors.cartContent).hide(); 24753 } 24754 24755 24756 }; 24757 24758 // favourites functions 24759 this.addToFavourites = function (product, container) { 24760 24761 $this = this; 24762 if ($($this.config.selectors.favourites).data('contentCount') < 10) { 24763 var content = $(container).data('content'); 24764 var favouriteModels = $(container).data('favouriteModels'); 24765 if (!content) { 24766 content = {}; 24767 favouriteModels = []; 24768 } 24769 if (!content.hasOwnProperty(product['products_id'])) { 24770 content[product['products_id']] = product; 24771 favouriteModels.push(product.products_model); 24772 } 24773 $(container).data('content', content); 24774 $(container).data('favouriteModels', favouriteModels); 24775 $this.refreshFavourites(); 24776 } 24777 else { 24778 $('#global-message .message-header').text('Ihre Wunschliste'); 24779 $('#global-message .message').text('Sie können nur max. 10 Artikel in Ihre Wunschliste aufnehmen.'); 24780 $('#global-message').modal('show'); 24781 } 24782 24783 }; 24784 24785 this.removeFromFavourites = function (product, container) { 24786 $this = this; 24787 var content = $(container).data('content'); 24788 if (content.hasOwnProperty(product['products_id'])) { 24789 delete content[product['products_id']]; 24790 } 24791 var newFavouriteModels = new Array(); 24792 var favouriteModels = $(container).data('favouriteModels'); 24793 for (fIndex in favouriteModels) { 24794 if (favouriteModels[fIndex] != product.products_model) { 24795 newFavouriteModels.push(favouriteModels[fIndex]); 24796 } 24797 } 24798 $(container).data('content', content); 24799 $(container).data('favouriteModels', newFavouriteModels); 24800 $this.refreshFavourites(); 24801 }; 24802 24803 this.refreshFavourites = function () { 24804 if ($($this.config.selectors.favourites).data('content')) { 24805 var content = $($this.config.selectors.favourites).data('content'); 24806 var favouriteModels = $($this.config.selectors.favourites).data('favouriteModels'); 24807 } 24808 else { 24809 var content = false; 24810 } 24811 24812 contentCount = 0; 24813 $($this.config.selectors.favouritesContent).find('.favourites-products').empty(); 24814 if (content) { 24815 $($this.config.selectors.favourites).data('show', true); 24816 $($this.config.selectors.favourites).show(); 24817 $(window).trigger('scroll'); 24818 productModels = new Array(); 24819 24820 for (cIndex in content) { 24821 24822 product = content[cIndex]; 24823 if (jQuery.inArray(product.products_model, favouriteModels) >= 0) { 24824 productImage = product.products_image; 24825 if (product.type == 'master') { 24826 if (product.children) { 24827 for (cIndex in product.children) { 24828 if (product.children[cIndex].products_image) { 24829 productImage = product.children[cIndex].products_image; 24830 } 24831 } 24832 } 24833 } 24834 productModels.push(product.products_model); 24835 $productTemplate = $this.getTemplate('favouritesProduct-template', 'favouritesProduct-' + cIndex); 24836 $productTemplate.find('.link-to-product').attr('href', product.products_link); 24837 if (productImage) { 24838 $productTemplate.find('.favourites-product-image a').css('background-image', 'url(/media/images/thumb/' + productImage.replace('product:', '') + ')'); 24839 } 24840 $productTemplate.find('.product-name').text(product.products_name); 24841 $productTemplate.find('.price').html(product.price.formated); 24842 $productTemplate.data(product); 24843 $($this.config.selectors.favouritesContent).find('.favourites-products').append($productTemplate); 24844 contentCount++; 24845 } 24846 24847 } 24848 $($this.config.selectors.favourites).find('.totalCount').text(contentCount); 24849 $.cookie($this.config.favourites.cookieName, productModels.join(','), {expires: 14, path: '/'}) 24850 } 24851 $($this.config.selectors.favourites).data('contentCount', contentCount); 24852 24853 if (contentCount == 0) { 24854 $($this.config.selectors.favourites).data('show', false); 24855 $($this.config.selectors.favourites).hide(); 24856 $($this.config.selectors.favouritesContent).hide(); 24857 $.removeCookie($this.config.favourites.cookieName); 24858 } 24859 24860 }; 24861 24862 24863 // path functions 24864 24865 24866 this.getPath = function () {
24867 return this.getFilterPath() + '/' + this.getSettingsPath() + '/' + this.getDetailPath(); 24868 }; 24869 24870 this.getFilterPath = function () { 24871 path = ''; 24872 for (filterName in this.config.filters) { 24873 if (this.activeFilters.hasOwnProperty(filterName)) { 24874 filterConf = this.config.filters[filterName]; 24875 switch (filterConf.type) { 24876 case 'vlist': 24877 case 'occurrences': 24878 values = ''; 24879 for (elementIndex in this.activeFilters[filterName]['elements']) { 24880 values += (values ? '|' : '') + this.activeFilters[filterName]['elements'][elementIndex]; 24881 } 24882 break; 24883 case 'range': 24884 values = this.activeFilters[filterName]['min'] + ':' + this.activeFilters[filterName]['max']; 24885 break; 24886 } 24887 path += (path ? ';' : '') + filterName + '[' + values + ']'; 24888 } 24889 } 24890 return path; 24891 24892 }; 24893
24894 this.getSettingsPath = function () { 24895 return 'settings[' + String(this.searchParams.start) + '|' + 24896 String(this.searchParams.range) + '|' + 24897 this.searchParams.presentation + '|' + 24898 this.searchParams.sortBy + '|' + 24899 this.searchParams.sortOrder + '|' + 24900 String(this.searchParams.resultsPerPage) + ']'; 24901 }; 24902 24903 this.getDetailPath = function () { 24904 $detailModal = $(this.config.selectors.productDetail); 24905 24906 if ($detailModal.hasClass('open')) { 24907 product = $detailModal.data(); 24908 return 'product[' + String(product.products_id) + ']'; 24909 } 24910 else { 24911 return ''; 24912 } 24913 }; 24914 24915 this.parsePath = function (path) { 24916 24917 24918 pathElements = path.split('/'); 24919 24920 //this.removeAllFilters(); 24921 24922 if (path) { 24923 24924 if (pathElements.length == 3) { 24925 24926 filterPath = pathElements[0]; 24927 settingsPath = pathElements[1]; 24928 detailPath = pathElements[2]; 24929 24930// // parse filter path 24931// filterPathElements = filterPath.split(';'); 24932// for (pathElementsIndex = 0; pathElementsIndex < filterPathElements.length; pathElementsIndex++) { 24933// var findCommandRE = /^([a-zA-Z]+)\((.+)\)$/; 24934// cResult = findCommandRE.exec(filterPathElements[pathElementsIndex]); 24935// 24936// if (cResult && cResult.length == 3) { 24937// if (this.config.filters.hasOwnProperty(cResult[1])) { 24938// filterName = cResult[1]; 24939// filterConf = this.config.filters[filterName]; 24940// switch (filterConf.type) { 24941// case 'vlist': 24942// case 'occurrences': 24943// filterValues = cResult[2].split('|'); 24944// for (filterValuesIndex = 0; filterValuesIndex < filterValues.length; filterValuesIndex++) { 24945// 24946// this.addFilter(filterName, filterValues[filterValuesIndex]); 24947// this.selectFilter(filterName, filterValues[filterValuesIndex]); 24948// this.checkFilter(filterName, filterValues[filterValuesIndex]); 24949// } 24950// break; 24951// case 'range': 24952// values = cResult[2].split(':'); 24953// sliderElement = $('#filter-' + filterName).find('.range-slider'); 24954// filterValues = { 24955// start: values[0], 24956// end: values[1] 24957// } 24958// this.addRangeFilter(filterName, filterValues.start, filterValues.end); 24959// 24960// amountFunction = $(sliderElement).data('amountFunction'); 24961// $('#filter-' + filterName).find('.range-amount').html(amountFunction(this, filterValues.start, filterValues.end)); 24962// 24963// $(sliderElement).slider('values', 0, filterValues.start); 24964// $(sliderElement).slider('values', 1, filterValues.end); 24965// filterConf.onChange(this); 24966// 24967// break; 24968// } 24969// } 24970// 24971// } 24972// 24973// } 24974// 24975// // parse settings path 24976// findSettingsRE = /^settings\(([a-z]+)\|([a-zA-Z]+)\|([a-zA-Z]+)\|([0-9]+)\|([0-9]+)\)$/; 24977// cResult = findSettingsRE.exec(settingsPath); 24978// if (cResult && cResult.length == 6) { 24979// this.config.settings.presentation = cResult[1]; 24980// this.config.settings.sorting.field = cResult[2]; 24981// this.config.settings.sorting.order = cResult[3]; 24982// this.config.settings.start = parseInt(cResult[4]); 24983// this.config.settings.resultsPerPage = parseInt(cResult[5]);
24984// 24985// // apply settings 24986// this.applySettings(); 24987// 24988// 24989// } 24990 24991 24992 // parse detail view 24993 findProductRE = /^product\[([0-9]+)\]$/; 24994 cResult = findProductRE.exec(detailPath); 24995 if (cResult && cResult.length == 2) { 24996 24997 productId = cResult[1]; 24998 product = this.findInObjectArray(this.data.products, 'products_id', productId); 24999 if (product) { 25000 this.openDetailView(product); 25001 $(this.config.selectors.productDetail).modal('show'); 25002 } 25003 } 25004 else { 25005 if ($(this.config.selectors.productDetail).hasClass('open')) { 25006 $(this.config.selectors.productDetail).modal('hide'); 25007 } 25008 } 25009 25010 } 25011 25012 25013 25014 } 25015 25016 25017 }; 25018 25019 25020 // template functions 25021 this.getTemplate = function (id, newId) { 25022 $template = $('#' + id).clone(); 25023 $template.removeClass('template'); 25024 $template.attr('id', newId); 25025 return $template; 25026 }; 25027 25028 // helper functions 25029 this.formatPrice = function (price) { 25030 return '€ ' + number_format(price, 2, ',', '.').replace(',00', ',-'); 25031 } 25032 25033 this.findInObjectArray = function (source, field, value) { 25034 for (index in source) { 25035 if (source[index][field] == value) { 25036 return source[index]; 25037 } 25038 } 25039 return false; 25040 } 25041 25042 // run init function 25043 this.init(); 25044 25045 }; 25046 25047 25048 /* ------------------------------------------------------------------------------------------------- 25049 * NeundreiviertelSmartObjects Declaration 25050 * ------------------------------------------------------------------------------------------------- 25051 */ 25052 25053 25054 $('.neundreiviertel-smart-objects').each(function (oIndex, objectContainer) { 25055 smartObjectsConfig = { 25056 baseUrl: 'http://www.veryzofcin.com/', 25057 language: $('meta[name=language]').first().attr('content'), 25058 view: $(objectContainer).data('view'), 25059 rootContainer: $(objectContainer), 25060 favourites: { 25061 cookieName: 'veryZofcin-favourites' 25062 } 25063 }; 25064 if ($(objectContainer).data('currentCategoryId')) { 25065 smartObjectsConfig.currentCategoryId = $(objectContainer).data('currentCategoryId'); 25066 } 25067 switch ($(objectContainer).data('view')) { 25068 case 'search': 25069 case 'cart': 25070 smartObjectsConfig.selectors = { 25071 productsContainer: '#globalSearch-box-products', 25072 productsAppend: { 25073 grid: '#globalSearch-box-products .row-fluid:last', 25074 list: '#globalSearch-box-products' 25075 } 25076 }; 25077 case 'favourites': 25078 case 'detail': 25079 smartObjectsConfig.bbqEnabled = false; 25080 break; 25081 } 25082 ; 25083 25084 $(objectContainer).data('smartObjects', new NeundreiviertelSmartObjects(smartObjectsConfig)); 25085 }); 25086 25087 25088 25089}); 25090 25091jQuery(document).ready(function() { 25092 25093 25094 25095 /* ------------------------------------------------------------------------------------------------- 25096 * spinner 25097 * ------------------------------------------------------------------------------------------------- 25098 */ 25099 25100 (function($) { 25101 $.fn.spin = function(opts, color) { 25102 var presets = { 25103 "tiny": { 25104 lines: 8, 25105 length: 2, 25106 width: 2, 25107 radius: 3 25108 }, 25109 "small": { 25110 lines: 8, 25111 length: 4, 25112 width: 3, 25113 radius: 5 25114 }, 25115 "large": { 25116 lines: 10, 25117 length: 8, 25118 width: 4, 25119 radius: 8 25120 } 25121 }; 25122 if (Spinner) { 25123 return this.each(function() { 25124 var $this = $(this), 25125 data = $this.data(); 25126 25127 if (data.spinner) { 25128 data.spinner.stop(); 25129 delete data.spinner; 25130 } 25131 if (opts !== false) { 25132 if (typeof opts === "string") { 25133 if (opts in presets) { 25134 opts = presets[opts]; 25135 } else { 25136 opts = {}; 25137 } 25138 if (color) { 25139 opts.color = color; 25140 } 25141 } 25142 data.spinner = new Spinner($.extend({ 25143 color: $this.css('color') 25144 }, opts)).spin(this); 25145 } 25146 }); 25147 } else { 25148 throw "Spinner class not available."; 25149 } 25150 }; 25151 })(jQuery); 25152 25153 25154 /* ------------------------------------------------------------------------------------------------- 25155 * Navigation (Superfish) 25156 * ------------------------------------------------------------------------------------------------- 25157 */ 25158 25159 jQuery('ul.sf-menu').superfish({ 25160 delay: 1000, 25161 animation: {opacity: 'show', height: 'show'}, 25162 speed: 'fast',
25163 autoArrows: false 25164 }); 25165 25166 /* 25167 * Slider 25168 */ 25169 25170 25171 $('#slideshow').rhinoslider({ 25172 effect: 'fade', 25173 showTime: 5000, 25174 effectTime: 500, 25175 controlsPrevNext: false, 25176 controlsPlayPause: false, 25177 autoPlay: true, 25178 showBullets: 'always', 25179 changeBullets: 'before', 25180 showControls: 'never', 25181 styles: '' 25182 }); 25183 25184 25185 /* 25186 * EqualHeight 25187 */ 25188 setEqualHeight = function() { 25189 $('.row.equal-height, .row-fluid.equal-height').each(function(rIndex, row) { 25190 spanSelector = '[class^="span"], [class*=" span"]'; 25191 maxHeight = 0; 25192 $(row).children(spanSelector).css({ 25193 'height': 'auto' 25194 }); 25195 $(row).children(spanSelector).each(function(sIndex, span) { 25196 if ($(span).height() > maxHeight) { 25197 maxHeight = $(span).height(); 25198 } 25199 }); 25200 $(row).children(spanSelector).css({ 25201 'height': maxHeight 25202 }); 25203 }); 25204 } 25205 setEqualHeight(); 25206 25207 25208 25209 25210 25211 /* 25212 * sidenav 25213 */ 25214 $('.nav-tabs a').mouseover(function(event) { 25215 event.preventDefault(); 25216 $(this).tab('show'); 25217 }) 25218 25219 25220 25221 /* 25222 * select buttons 25223 */ 25224 $('.btn-selector').bind('click', function(event) { 25225 event.preventDefault(); 25226 $(this).find('input[type="radio"]').first().attr('checked', true); 25227 $(this).parents('form').first().find('.btn-selector').removeClass('btn-danger'); 25228 $(this).addClass('btn-danger'); 25229 }); 25230 25231 25232 25233 /* ------------------------------------------------------------------------------------------------- 25234 * Nav on phones 25235 * ------------------------------------------------------------------------------------------------- 25236 */ 25237 25238 if ($(document).innerWidth() <= 767) { 25239 if ($('#page-home').length == 0) { 25240 $('#navMain').before('<a href="#" id="show-navMain" class="btn btn-primary btn-block">Menü</a>'); 25241 $('#navMain').hide(); 25242 $('#show-navMain').bind('click', function(event) { 25243 event.preventDefault(); 25244 $('#navMain').show(); 25245 $(this).detach(); 25246 }); 25247 25248 if ($('#filter-wrap').length > 0) { 25249 $('#filter-wrap').before('<a href="#" id="show-filter" class="btn btn-primary btn-block">Filter</a>'); 25250 $('#filter-wrap').hide(); 25251 $('#show-filter').bind('click', function(event) { 25252 event.preventDefault(); 25253 $('#filter-wrap').show(); 25254 $(this).detach(); 25255 }); 25256 } 25257 } 25258 } 25259 25260 /* ------------------------------------------------------------------------------------------------- 25261 * searchbox 25262 * ------------------------------------------------------------------------------------------------- 25263 */ 25264 25265 $('#globalSearch').removeClass('hide'); 25266 25267 25268 $('#searchbox-toggle').bind('click', function(event) { 25269 event.preventDefault(); 25270 $('#globalSearch').submit(); 25271// if ($('#globalSearch').hasClass('hide')) { 25272// 25273// $('#globalSearch').css('opacity',0); 25274// $('#globalSearch').stop().animate({ 25275// 'opacity': 1 25276// },300); 25277// $('#globalSearch-query').focus(); 25278// } 25279// else { 25280// $('#globalSearch').stop().animate({ 25281// 'opacity': 0 25282// },300, function() { 25283// $('#globalSearch').addClass('hide'); 25284// }); 25285// 25286// } 25287 }); 25288 25289 25290 /* ------------------------------------------------------------------------------------------------- 25291 * language-content 25292 * ------------------------------------------------------------------------------------------------- 25293 */ 25294 25295 $('.language-content').each(function(cIndex, content) { 25296 $(content).html($(content).data($('body').data('language'))); 25297 });
25298 25299 25300 $('#dropdownMenuLanguage').on('click', function(event) { 25301 event.preventDefault(); 25302 }); 25303 25304 25305 /* ------------------------------------------------------------------------------------------------- 25306 * welcome 25307 * ------------------------------------------------------------------------------------------------- 25308 */ 25309 25310 if ($('#welcome').length > 0) { 25311 25312 $(window).on('resize', function() { 25313 $('#welcome').height($(window).height()); 25314 }); 25315 $(window).trigger('resize'); 25316 25317 var hideHeaderValue = -222; 25318 if ($(document).innerWidth() <= 767) { 25319 hideHeaderValue = -537; 25320 } 25321 if ($(document).innerWidth() > 767) { 25322 $('#header-container').css({ 25323 'position':'fixed', 25324 'width': '100%', 25325 'top': hideHeaderValue 25326 }); 25327 25328 $(window).bind('scroll', function(event) { 25329 if ($(window).scrollTop() > 300) { 25330 $('#header-container').stop().animate({ 25331 'top': 0, 25332 }, 300); 25333 } 25334 else { 25335 $('#header-container').stop().animate({ 25336 'top': hideHeaderValue, 25337 }, 300); 25338 } 25339 }); 25340 } 25341 } 25342 25343 /* ------------------------------------------------------------------------------------------------- 25344 * navMobile 25345 * ------------------------------------------------------------------------------------------------- 25346 */ 25347 25348 $('#navMobile').multilevelpushmenu({ 25349 overlapWidth: 0, 25350 backText: 'zurück', 25351 collapsed: true, 25352 onItemClick: function() { 25353 25354 var event = arguments[0], 25355 $menuLevelHolder = arguments[1], 25356 $item = arguments[2], 25357 options = arguments[3], 25358 title = $menuLevelHolder.find( 'h3:first' ).text(), 25359 href = $item.find( 'a:first' ).attr('href'), 25360 linkId = $item.find( 'a:first' ).attr('id'), 25361 target = $item.find( 'a:first' ).attr('target'); 25362 if (linkId == 'button-sale-mobile') { 25363 $('#button-sale').trigger('click'); 25364 } 25365 else { 25366 if ($item.find('a:first').hasClass('scrollclass')) { 25367 if ($('#page_3').length) { 25368 href = ''; 25369 } 25370 25371 } 25372 if (href) { 25373 if (target) { 25374 window.open(href,target); 25375 } else { 25376 window.location.href = href; 25377 } 25378 } 25379 } 25380 $('#navMobileCollapse').find('.fa-close').removeClass('fa-close').addClass('fa-bars'); 25381 $('#navMobileCollapse').removeClass('active'); 25382 $('#navMobile').multilevelpushmenu('collapse'); 25383// console.log('<br />Item <i>' + options + ' ' + itemName + '</i>' + ' on <i>' + title + '</i> menu level clicked!' ) 25384 }, 25385 }); 25386 25387 $('#navMobileCollapse').on('click', function (event) { 25388 event.preventDefault(); 25389 if ($(this).hasClass('active')) { 25390 $(this).find('.fa-close').removeClass('fa-close').addClass('fa-bars'); 25391 $(this).removeClass('active'); 25392 $('#navMobile').multilevelpushmenu('collapse'); 25393 } 25394 else { 25395 $(this).find('.fa-bars').removeClass('fa-bars').addClass('fa-close'); 25396 $(this).addClass('active'); 25397 $('#navMobile').multilevelpushmenu('expand'); 25398 } 25399 25400 }); 25401 25402});
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.