1/*! jQuery slidePanel - v0.2.2 - 2015-10-14 2 * https://github.com/amazingSurge/jquery-slidePanel 3 * Copyright (c) 2015 amazingSurge; Licensed GPL */ 4(function($, document, window, undefined) { 5 "use strict"; 6 7 var SlidePanel = $.slidePanel = function() { 8 SlidePanel.show.apply(this, arguments); 9 }; 10 11 if (!Date.now) { 12 Date.now = function() { 13 return new Date().getTime(); 14 }; 15 } 16 17 function getTime() { 18 if (typeof window.performance !== 'undefined' && window.performance.now) { 19 return window.performance.now(); 20 } else { 21 return Date.now(); 22 } 23 } 24 25 var vendors = ['webkit', 'moz']; 26 for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { 27 var vp = vendors[i]; 28 window.requestAnimationFrame = window[vp + 'RequestAnimationFrame']; 29 window.cancelAnimationFrame = (window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame']); 30 } 31 if (/iP(ad|hone|od).*OS (6|7|8)/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) { 32 var lastTime = 0; 33 window.requestAnimationFrame = function(callback) { 34 var now = getTime(); 35 var nextTime = Math.max(lastTime + 16, now); 36 return setTimeout(function() { 37 callback(lastTime = nextTime); 38 }, 39 nextTime - now); 40 }; 41 window.cancelAnimationFrame = clearTimeout; 42 } 43 44 var Support = (function() { 45 var style = $('<support>').get(0).style, 46 prefixes = ['webkit', 'Moz', 'O', 'ms'], 47 events = { 48 transition: { 49 end: { 50 WebkitTransition: 'webkitTransitionEnd', 51 MozTransition: 'transitionend', 52 OTransition: 'oTransitionEnd', 53 transition: 'transitionend' 54 } 55 }, 56 animation: { 57 end: { 58 WebkitAnimation: 'webkitAnimationEnd', 59 MozAnimation: 'animationend', 60 OAnimation: 'oAnimationEnd', 61 animation: 'animationend' 62 } 63 } 64 }, 65 tests = { 66 csstransforms: function() { 67 return !!test('transform'); 68 }, 69 csstransforms3d: function() { 70 return !!test('perspective'); 71 }, 72 csstransitions: function() { 73 return !!test('transition'); 74 }, 75 cssanimations: function() { 76 return !!test('animation'); 77 } 78 }; 79 80 function test(property, prefixed) { 81 var result = false, 82 upper = property.charAt(0).toUpperCase() + property.slice(1); 83 84 if (style[property] !== undefined) { 85 result = property; 86 } 87 if (!result) { 88 $.each(prefixes, function(i, prefix) { 89 if (style[prefix + upper] !== undefined) { 90 result = '-' + prefix.toLowerCase() + '-' + upper; 91 return false; 92 } 93 }); 94 } 95 96 if (prefixed) { 97 return result; 98 } 99 if (result) { 100 return true; 101 } else { 102 return false; 103 } 104 } 105 106 function prefixed(property) { 107 return test(property, true); 108 } 109 var support = {}; 110 if (tests.csstransitions()) { 111 /* jshint -W053 */ 112 support.transition = new String(prefixed('transition')) 113 support.transition.end = events.transition.end[support.transition]; 114 } 115 116 if (tests.cssanimations()) { 117 /* jshint -W053 */ 118 support.animation = new String(prefixed('animation')) 119 support.animation.end = events.animation.end[support.animation]; 120 } 121 122 if (tests.csstransforms()) { 123 /* jshint -W053 */ 124 support.transform = new String(prefixed('transform')); 125 support.transform3d = tests.csstransforms3d(); 126 } 127 128 if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) { 129 support.touch = true; 130 } else { 131 support.touch = false;
132 } 133 134 if (window.PointerEvent || window.MSPointerEvent) { 135 support.pointer = true; 136 } else { 137 support.pointer = false; 138 } 139 140 support.prefixPointerEvent = function(pointerEvent) { 141 return window.MSPointerEvent ? 142 'MSPointer' + pointerEvent.charAt(9).toUpperCase() + pointerEvent.substr(10) : 143 pointerEvent; 144 } 145 146 return support; 147 })(); 148 149 function isPercentage(n) { 150 return typeof n === 'string' && n.indexOf('%') != -1; 151 } 152 153 function isPx(n) { 154 return typeof n === 'string' && n.indexOf('px') != -1; 155 } 156 157 function convertMatrixToArray(value) { 158 if (value && (value.substr(0, 6) == "matrix")) { 159 return value.replace(/^.*\((.*)\)$/g, "$1").replace(/px/g, '').split(/, +/); 160 } 161 return false; 162 } 163 164 function getHashCode(object) { 165 if (typeof object !== 'string') { 166 object = JSON.stringify(object); 167 } 168 169 var hash = 0, 170 i, chr, len; 171 if (object.length === 0) return hash; 172 for (i = 0, len = object.length; i < len; i++) { 173 chr = object.charCodeAt(i); 174 hash = ((hash << 5) - hash) + chr; 175 hash |= 0; // Convert to 32bit integer 176 } 177 178 return hash; 179 } 180 181 function easingBezier(mX1, mY1, mX2, mY2) { 182 function a(aA1, aA2) { 183 return 1.0 - 3.0 * aA2 + 3.0 * aA1; 184 } 185 186 function b(aA1, aA2) { 187 return 3.0 * aA2 - 6.0 * aA1; 188 } 189 190 function c(aA1) { 191 return 3.0 * aA1; 192 } 193 194 // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. 195 function calcBezier(aT, aA1, aA2) { 196 return ((a(aA1, aA2) * aT + b(aA1, aA2)) * aT + c(aA1)) * aT; 197 } 198 199 // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. 200 function getSlope(aT, aA1, aA2) { 201 return 3.0 * a(aA1, aA2) * aT * aT + 2.0 * b(aA1, aA2) * aT + c(aA1); 202 } 203 204 function getTForX(aX) { 205 // Newton raphson iteration 206 var aGuessT = aX; 207 for (var i = 0; i < 4; ++i) { 208 var currentSlope = getSlope(aGuessT, mX1, mX2); 209 if (currentSlope === 0.0) return aGuessT; 210 var currentX = calcBezier(aGuessT, mX1, mX2) - aX; 211 aGuessT -= currentX / currentSlope; 212 } 213 return aGuessT; 214 } 215 216 if (mX1 === mY1 && mX2 === mY2) { 217 return { 218 css: 'linear', 219 fn: function(aX) { 220 return aX; 221 } 222 }; 223 } else { 224 return { 225 css: 'cubic-bezier(' + mX1 + ',' + mY1 + ',' + mX2 + ',' + mY2 + ')', 226 fn: function(aX) { 227 return calcBezier(getTForX(aX), mY1, mY2); 228 } 229 } 230 } 231 } 232 233 var Easings = { 234 'ease': easingBezier(0.25, 0.1, 0.25, 1.0), 235 'linear': easingBezier(0.00, 0.0, 1.00, 1.0), 236 'ease-in': easingBezier(0.42, 0.0, 1.00, 1.0), 237 'ease-out': easingBezier(0.00, 0.0, 0.58, 1.0), 238 'ease-in-out': easingBezier(0.42, 0.0, 0.58, 1.0) 239 }; 240 241 SlidePanel.options = { 242 skin: null, 243 244 classes: { 245 base: 'slidePanel', 246 show: 'slidePanel-show', 247 loading: 'slidePanel-loading', 248 content: 'slidePanel-content', 249 dragging: 'slidePanel-dragging', 250 willClose: 'slidePanel-will-close' 251 }, 252 253 closeSelector: null, 254 255 template: function(options) { 256 return '<div class="' + options.classes.base + ' ' + options.classes.base + '-' + options.direction + '">' + 257 '<div class="' + options.classes.content + '"></div>' + 258 '</div>'; 259 }, 260 261 loading: { 262 appendTo: 'panel', // body, panel 263 template: function(options) { 264 return '<div class="' + options.classes.loading + '"></div>'; 265 }, 266 showCallback: function(options) { 267 this.$el.addClass(options.classes.loading + '-show'); 268 }, 269 hideCallback: function(options) { 270 this.$el.removeClass(options.classes.loading + '-show'); 271 } 272 }, 273 274 contentFilter: function(content, object) { 275 return content; 276 }, 277 278 useCssTransforms3d: true, 279 useCssTransforms: true, 280 useCssTransitions: true, 281 282 dragTolerance: 150, 283 284 mouseDragHandler: null, 285 mouseDrag: true, 286 touchDrag: true, 287 pointerDrag: true, 288 289 direction: 'right', // top, bottom, left, right 290 duration: '500', 291 easing: 'ease', // linear, ease-in, ease-out, ease-in-out 292 293 // callbacks 294 beforeLoad: $.noop, // Before loading 295 afterLoad: $.noop, // After loading 296 beforeShow: $.noop, // Before opening 297 afterShow: $.noop, // After opening 298 onChange: $.noop, // On changing 299 beforeChange: $.noop, // Before changing 300 beforeHide: $.noop, // Before closing 301 afterHide: $.noop, // After closing 302 beforeDrag: $.noop, // Before drag 303 afterDrag: $.noop // After drag 304 }; 305 306 // View 307 function View() { 308 return this.initialize.apply(this, Array.prototype.slice.call(arguments)); 309 } 310 311 $.extend(View.prototype, { 312 initialize: function(options) { 313 this.options = options; 314 this._instance = null; 315 this._showed = false;
316 this._isLoading = false; 317 318 this.build(); 319 }, 320 321 setLength: function() { 322 switch (this.options.direction) { 323 case 'top': 324 case 'bottom': 325 this._length = this.$panel.outerHeight(); 326 break; 327 case 'left': 328 case 'right': 329 this._length = this.$panel.outerWidth(); 330 break; 331 } 332 }, 333 334 build: function() { 335 if (this._builded) return; 336 337 var options = this.options; 338 339 var html = options.template.call(this, options); 340 var self = this; 341 342 this.$panel = $(html).appendTo('body'); 343 if (options.skin) { 344 this.$panel.addClass(options.skin); 345 } 346 this.$content = this.$panel.find('.' + this.options.classes.content); 347 348 if (options.closeSelector) { 349 this.$panel.on('click', options.closeSelector, function() { 350 self.hide(); 351 return false; 352 }); 353 } 354 this.loading = new Loading(this); 355 356 this.setLength(); 357 this.setPosition(this.getHidePosition()); 358 359 if (options.mouseDrag || options.touchDrag || options.pointerDrag) { 360 this.drag = new Drag(this); 361 } 362 363 this._builded = true; 364 }, 365 366 getHidePosition: function() { 367 var options = this.options; 368 369 if (options.useCssTransforms || options.useCssTransforms3d) { 370 switch (options.direction) { 371 case 'top': 372 case 'left': 373 return '-100'; 374 case 'bottom': 375 case 'right': 376 return '100'; 377 } 378 } else { 379 switch (options.direction) { 380 case 'top': 381 case 'bottom': 382 return parseFloat(-(this._length / $(window).height()) * 100, 10); 383 case 'left': 384 case 'right': 385 return parseFloat(-(this._length / $(window).width()) * 100, 10); 386 } 387 } 388 }, 389 390 empty: function() { 391 this._instance = null; 392 this.$content.empty(); 393 }, 394 395 load: function(object) { 396 var self = this; 397 var options = object.options; 398 var previous = this._instance; 399 400 _SlidePanel.trigger(this, 'beforeLoad', object); 401 this.empty(); 402 403 function setContent(content) { 404 content = options.contentFilter.call(this, content, object); 405 self.$content.html(content); 406 self.hideLoading(); 407 408 self._instance = object; 409 410 _SlidePanel.trigger(self, 'afterLoad', object); 411 } 412 413 if (object.content) { 414 setContent(object.content); 415 } else if (object.url) { 416 this.showLoading(); 417 418 $.ajax(object.url, object.settings || {}).done(function(data) { 419 setContent(data); 420 }); 421 } else { 422 setContent(''); 423 } 424 }, 425 426 showLoading: function() { 427 var self = this; 428 this.loading.show(function() { 429 self._isLoading = true; 430 }); 431 }, 432 433 hideLoading: function() { 434 var self = this; 435 this.loading.hide(function() { 436 self._isLoading = false; 437 }); 438 }, 439 440 show: function(callback) { 441 this.build(); 442 443 _SlidePanel.enter('show'); 444 _SlidePanel.trigger(this, 'beforeShow'); 445 446 $('html').addClass(this.options.classes.base + '-html'); 447 this.$panel.addClass(this.options.classes.show); 448 449 var self = this; 450 Animate.do(this, 0, function() { 451 self._showed = true; 452 _SlidePanel.trigger(self, 'afterShow'); 453 454 if ($.isFunction(callback)) { 455 callback.call(self); 456 } 457 }); 458 }, 459 460 change: function(object) { 461 _SlidePanel.trigger(this, 'beforeShow'); 462 463 _SlidePanel.trigger(this, 'onChange', object, this._instance); 464 465 this.load(object); 466 467 _SlidePanel.trigger(this, 'afterShow'); 468 }, 469 470 revert: function(callback) { 471 var self = this; 472 Animate.do(this, 0, function() { 473 if ($.isFunction(callback)) { 474 callback.call(self); 475 } 476 }); 477 }, 478 479 hide: function(callback) { 480 _SlidePanel.leave('show'); 481 _SlidePanel.trigger(this, 'beforeHide'); 482 483 var self = this; 484 485 Animate.do(this, this.getHidePosition(), function() { 486 self.$panel.removeClass(self.options.classes.show); 487 self._showed = false;
488 self._instance = null; 489 490 if (_SlidePanel._current === self) { 491 _SlidePanel._current = null; 492 } 493 494 if (!_SlidePanel.is('show')) { 495 $('html').removeClass(self.options.classes.base + '-html'); 496 } 497 498 if ($.isFunction(callback)) { 499 callback.call(self); 500 } 501 502 _SlidePanel.trigger(self, 'afterHide'); 503 }); 504 }, 505 506 makePositionStyle: function(value) { 507 var property, x = '0', 508 y = '0'; 509 510 if (!isPercentage(value) && !isPx(value)) { 511 value = value + '%'; 512 } 513 514 if (this.options.useCssTransforms && Support.transform) { 515 if (this.options.direction === 'left' || this.options.direction === 'right') { 516 x = value; 517 } else { 518 y = value; 519 } 520 521 property = Support.transform.toString(); 522 523 if (this.options.useCssTransforms3d && Support.transform3d) { 524 value = "translate3d(" + x + "," + y + ",0)"; 525 } else { 526 value = "translate(" + x + "," + y + ")"; 527 } 528 } else { 529 property = this.options.direction; 530 } 531 var temp = {}; 532 temp[property] = value; 533 return temp; 534 }, 535 536 getPosition: function(px) { 537 var value; 538 539 if (this.options.useCssTransforms && Support.transform) { 540 value = convertMatrixToArray(this.$panel.css(Support.transform)); 541 if (!value) { 542 return 0; 543 } 544 545 if (this.options.direction === 'left' || this.options.direction === 'right') { 546 value = value[12] || value[4]; 547 548 } else { 549 value = value[13] || value[5]; 550 } 551 } else { 552 value = this.$panel.css(this.options.direction); 553 554 value = parseFloat(value.replace('px', '')); 555 } 556 557 if (px !== true) { 558 value = (value / this._length) * 100; 559 } 560 561 return parseFloat(value, 10); 562 }, 563 564 setPosition: function(value) { 565 var style = this.makePositionStyle(value); 566 this.$panel.css(style); 567 } 568 }); 569 570 // Loading 571 function Loading() { 572 return this.initialize.apply(this, Array.prototype.slice.call(arguments)); 573 }; 574 575 $.extend(Loading.prototype, { 576 initialize: function(view) { 577 this._view = view; 578 this.build(); 579 }, 580 581 build: function() { 582 if (this._builded) return; 583 584 var options = this._view.options; 585 var html = options.loading.template.call(this, options); 586 this.$el = $(html); 587 588 switch (options.loading.appendTo) { 589 case 'panel': 590 this.$el.appendTo(this._view.$panel); 591 break; 592 case 'body': 593 this.$el.appendTo('body'); 594 break; 595 default: 596 this.$el.appendTo(options.loading.appendTo); 597 } 598 599 this._builded = true; 600 }, 601 602 show: function(callback) { 603 this.build(); 604 var options = this._view.options; 605 options.loading.showCallback.call(this, options); 606 607 if ($.isFunction(callback)) { 608 callback.call(this); 609 } 610 }, 611 612 hide: function(callback) { 613 var options = this._view.options; 614 options.loading.hideCallback.call(this, options); 615 616 if ($.isFunction(callback)) { 617 callback.call(this); 618 } 619 } 620 }); 621 622 var Animate = { 623 prepareTransition: function($el, property, duration, easing, delay) { 624 var temp = []; 625 if (property) { 626 temp.push(property); 627 } 628 if (duration) { 629 if ($.isNumeric(duration)) { 630 duration = duration + 'ms'; 631 } 632 temp.push(duration); 633 } 634 if (easing) { 635 temp.push(easing); 636 } else { 637 temp.push(this.easing.css); 638 } 639 if (delay) { 640 temp.push(delay); 641 } 642 $el.css(Support.transition, temp.join(' ')); 643 }, 644 do: function(view, value, callback) { 645 _SlidePanel.enter('animating'); 646 647 var duration = view.options.duration, 648 easing = view.options.easing || 'ease'; 649 650 var self = this, 651 style = view.makePositionStyle(value); 652 for (var property in style) { 653 break; 654 } 655 656 if (view.options.useCssTransitions && Support.transition) { 657 setTimeout(function() { 658 self.prepareTransition(view.$panel, property, duration, easing); 659 }, 20); 660 661 view.$panel.one(Support.transition.end, function() { 662 if ($.isFunction(callback)) { 663 callback(); 664 } 665 666 view.$panel.css(Support.transition, ''); 667 668 _SlidePanel.leave('animating'); 669 }); 670 setTimeout(function() { 671 view.setPosition(value); 672 }, 20); 673 } else { 674 var startTime = getTime(); 675 var start = view.getPosition(); 676 var end = value; 677 678 var run = function(time) { 679 var percent = (time - startTime) / view.options.duration; 680 681 if (percent > 1) { 682 percent = 1; 683 } 684 685 percent = Easings[easing].fn(percent); 686 687 var current = parseFloat(start + percent * (end - start), 10); 688 689 view.setPosition(current); 690 691 if (percent === 1) { 692 window.cancelAnimationFrame(self._frameId); 693 self._frameId = null; 694 695 if ($.isFunction(callback)) { 696 callback(); 697 } 698 699 _SlidePanel.leave('animating'); 700 } else { 701 self._frameId = window.requestAnimationFrame(run); 702 } 703 }; 704 705 self._frameId = window.requestAnimationFrame(run); 706 } 707 } 708 } 709 710 // Drag 711 function Drag() { 712 return this.initialize.apply(this, Array.prototype.slice.call(arguments)); 713 } 714 715 $.extend(Drag.prototype, { 716 initialize: function(view) { 717 this._view = view; 718 this.options = view.options; 719 this._drag = { 720 time: null, 721 pointer: null 722 }; 723 724 this.bindEvents(); 725 }, 726 bindEvents: function() { 727 var self = this; 728 var options = this.options, 729 $panel = this._view.$panel; 730 731 if (options.mouseDrag) { 732 $panel.on(_SlidePanel.eventName('mousedown'), $.proxy(this.onDragStart, this)); 733 $panel.on(_SlidePanel.eventName('dragstart selectstart'), function() { 734 if (options.mouseDragHandler) { 735 if (!$(event.target).is(options.mouseDragHandler) && !($(event.target).parents(options.mouseDragHandler).length > 0)) { 736 return; 737 } 738 } 739 return false 740 }); 741 } 742 743 if (options.touchDrag && Support.touch) { 744 $panel.on(_SlidePanel.eventName('touchstart'), $.proxy(this.onDragStart, this)); 745 $panel.on(_SlidePanel.eventName('touchcancel'), $.proxy(this.onDragEnd, this)); 746 } 747 748 if (options.pointerDrag && Support.pointer) { 749 $panel.on(_SlidePanel.eventName(Support.prefixPointerEvent('pointerdown')), $.proxy(this.onDragStart, this)); 750 $panel.on(_SlidePanel.eventName(Support.prefixPointerEvent('pointercancel')), $.proxy(this.onDragEnd, this)); 751 } 752 }, 753 754 /** 755 * Handles `touchstart` and `mousedown` events. 756 */ 757 onDragStart: function(event) { 758 var self = this; 759 760 if (event.which === 3) { 761 return; 762 } 763 764 var options = this.options; 765 766 this._view.$panel.addClass(this.options.classes.dragging); 767 768 this._position = this._view.getPosition(true); 769 770 this._drag.time = new Date().getTime(); 771 this._drag.pointer = this.pointer(event); 772 773 var callback = function() { 774 _SlidePanel.enter('dragging'); 775 _SlidePanel.trigger(self._view, 'beforeDrag'); 776 } 777 778 if (options.mouseDrag) { 779 if (options.mouseDragHandler) { 780 if (!$(event.target).is(options.mouseDragHandler) && !($(event.target).parents(options.mouseDragHandler).length > 0)) { 781 return; 782 } 783 } 784 785 $(document).on(_SlidePanel.eventName('mouseup'), $.proxy(this.onDragEnd, this)); 786 787 $(document).one(_SlidePanel.eventName('mousemove'), $.proxy(function() { 788 $(document).on(_SlidePanel.eventName('mousemove'), $.proxy(this.onDragMove, this)); 789 790 callback(); 791 }, this)); 792 } 793 794 if (options.touchDrag && Support.touch) { 795 $(document).on(_SlidePanel.eventName('touchend'), $.proxy(this.onDragEnd, this)); 796 797 $(document).one(_SlidePanel.eventName('touchmove'), $.proxy(function() { 798 $(document).on(_SlidePanel.eventName('touchmove'), $.proxy(this.onDragMove, this)); 799 800 callback(); 801 }, this)); 802 } 803 804 if (options.pointerDrag && Support.pointer) { 805 $(document).on(_SlidePanel.eventName(Support.prefixPointerEvent('pointerup')), $.proxy(this.onDragEnd, this)); 806 807 $(document).one(_SlidePanel.eventName(Support.prefixPointerEvent('pointermove')), $.proxy(function() { 808 $(document).on(_SlidePanel.eventName(Support.prefixPointerEvent('pointermove')), $.proxy(this.onDragMove, this)); 809 810 callback(); 811 }, this)); 812 } 813 814 $(document).on(_SlidePanel.eventName('blur'), $.proxy(this.onDragEnd, this)); 815 816 event.preventDefault(); 817 }, 818 819 /** 820 * Handles the `touchmove` and `mousemove` events. 821 */ 822 onDragMove: function(event) { 823 var distance = this.distance(this._drag.pointer, this.pointer(event)); 824 825 if (!_SlidePanel.is('dragging')) { 826 return; 827 } 828 829 if (Math.abs(distance) > this.options.dragTolerance) { 830 if (this._willClose !== true) { 831 this._willClose = true; 832 this._view.$panel.addClass(this.options.classes.willClose); 833 } 834 } else { 835 if (this._willClose !== false) { 836 this._willClose = false;
837 this._view.$panel.removeClass(this.options.classes.willClose); 838 } 839 } 840 841 if (!_SlidePanel.is('dragging')) { 842 return; 843 } 844 845 event.preventDefault(); 846 this.move(distance); 847 }, 848 849 /** 850 * Handles the `touchend` and `mouseup` events. 851 */ 852 onDragEnd: function(event) { 853 var distance = this.distance(this._drag.pointer, this.pointer(event)); 854 855 $(document).off(_SlidePanel.eventName('mousemove mouseup touchmove touchend pointermove pointerup MSPointerMove MSPointerUp blur')); 856 857 this._view.$panel.removeClass(this.options.classes.dragging); 858 859 if (this._willClose === true) { 860 this._willClose = false; 861 this._view.$panel.removeClass(this.options.classes.willClose); 862 } 863 864 if (!_SlidePanel.is('dragging')) { 865 return; 866 } 867 868 _SlidePanel.leave('dragging'); 869 870 _SlidePanel.trigger(this._view, 'afterDrag'); 871 872 if (Math.abs(distance) < this.options.dragTolerance) { 873 this._view.revert(); 874 } else { 875 _SlidePanel.hide(); 876 } 877 }, 878 879 /** 880 * Gets unified pointer coordinates from event. 881 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 882 */ 883 pointer: function(event) { 884 var result = { 885 x: null, 886 y: null 887 }; 888 889 event = event.originalEvent || event || window.event; 890 891 event = event.touches && event.touches.length ? 892 event.touches[0] : event.changedTouches && event.changedTouches.length ? 893 event.changedTouches[0] : event; 894 895 if (event.pageX) { 896 result.x = event.pageX; 897 result.y = event.pageY; 898 } else { 899 result.x = event.clientX; 900 result.y = event.clientY; 901 } 902 903 return result; 904 }, 905 906 /**distance 907 * Gets the distance of two pointer. 908 */ 909 distance: function(first, second) { 910 var d = this.options.direction; 911 if (d === 'left' || d === 'right') { 912 return second.x - first.x; 913 } else { 914 return second.y - first.y; 915 } 916 }, 917 918 move: function(value) { 919 var position = this._position + value; 920 921 if (this.options.direction === 'right' || this.options.direction === 'bottom') { 922 if (position < 0) { 923 return; 924 } 925 } else { 926 if (position > 0) { 927 return; 928 } 929 } 930 931 if (!this.options.useCssTransforms && !this.options.useCssTransforms3d) { 932 if (this.options.direction === 'right' || this.options.direction === 'bottom') { 933 position = -position; 934 } 935 } 936 937 this._view.setPosition(position + 'px'); 938 } 939 }); 940 941 // Instance 942 function Instance() { 943 return this.initialize.apply(this, Array.prototype.slice.call(arguments)); 944 }; 945 946 $.extend(Instance.prototype, { 947 initialize: function(object) { 948 var options = arguments[1] || {}; 949 950 if (typeof object === 'string') { 951 object = { 952 url: object 953 }; 954 } else if (object && object.nodeType == 1) { 955 var $element = $(object); 956 957 object = { 958 url: $element.attr('href'), 959 settings: $element.data('settings') || {}, 960 options: $element.data() || {} 961 } 962 } 963 964 if (object && object.options) { 965 object.options = $.extend(true, options, object.options); 966 } else { 967 object.options = options; 968 } 969 970 object.options = $.extend(true, {}, SlidePanel.options, object.options); 971 972 $.extend(this, object); 973 974 return this; 975 } 976 }); 977 978 var _SlidePanel = { 979 // Current state information. 980 _states: {}, 981 _views: {}, 982 _current: null, 983 984 /** 985 * Checks whether the carousel is in a specific state or not. 986 */ 987 is: function(state) { 988 return this._states[state] && this._states[state] > 0; 989 }, 990 991 /** 992 * Enters a state. 993 */ 994 enter: function(state) { 995 if (this._states[state] === undefined) { 996 this._states[state] = 0; 997 } 998 999 this._states[state]++; 1000 }, 1001 1002 /** 1003 * Leaves a state. 1004 */ 1005 leave: function(state) { 1006 this._states[state]--; 1007 }, 1008 1009 trigger: function(view, event) { 1010 var method_arguments = Array.prototype.slice.call(arguments, 2), 1011 data = [view].concat(method_arguments); 1012 1013 // event 1014 $(document).trigger('slidePanel::' + event, data); 1015 if ($.isFunction(view.options[event])) { 1016 view.options[event].apply(view, method_arguments); 1017 } 1018 }, 1019 1020 eventName: function(events) { 1021 if (typeof events !== 'string' || events === '') { 1022 return '.slidepanel'; 1023 } 1024 events = events.split(' '); 1025 1026 var length = events.length; 1027 for (var i = 0; i < length; i++) { 1028 events[i] = events[i] + '.slidepanel'; 1029 } 1030 return events.join(' '); 1031 }, 1032 1033 show: function(object) { 1034 if (!(object instanceof Instance)) { 1035 switch (arguments.length) { 1036 case 0: 1037 object = new Instance(); 1038 break; 1039 case 1: 1040 object = new Instance(arguments[0]); 1041 break; 1042 case 2: 1043 object = new Instance(arguments[0], arguments[1]); 1044 break; 1045 } 1046 } 1047 1048 var view = this.getView(object.options); 1049 var self = this; 1050 var callback = function() { 1051 view.show(); 1052 view.load(object); 1053 self._current = view; 1054 } 1055 if (null !== this._current) { 1056 if (view === this._current) { 1057 this._current.change(object); 1058 } else { 1059 this._current.hide(callback); 1060 } 1061 } else { 1062 callback(); 1063 } 1064 }, 1065 1066 getView: function(options) { 1067 var code = getHashCode(options); 1068 1069 if (this._views.hasOwnProperty(code)) { 1070 return this._views[code]; 1071 } 1072 1073 return this._views[code] = new View(options); 1074 }, 1075 1076 hide: function(object) { 1077 if (object) { 1078 var view = this.getView(object.options); 1079 view.hide(); 1080 } else { 1081 if (this._current !== null) { 1082 var self = this; 1083 this._current.hide(); 1084 } 1085 } 1086 } 1087 }; 1088 1089 $.extend(SlidePanel, { 1090 is: function(state) { 1091 return _SlidePanel.is(state); 1092 }, 1093 1094 show: function(object, options) { 1095 _SlidePanel.show.apply(_SlidePanel, arguments); 1096 return this; 1097 }, 1098 1099 hide: function() { 1100 _SlidePanel.hide.apply(_SlidePanel, arguments); 1101 return this; 1102 } 1103 }); 1104 1105 $.fn.slidePanel = function(options) { 1106 if (typeof options === 'string') { 1107 var method = options; 1108 var method_arguments = Array.prototype.slice.call(arguments, 1); 1109 1110 return this.each(function() { 1111 var instance = $.data(this, 'slidePanel'); 1112 1113 if (!(instance instanceof Instance)) { 1114 instance = new Instance(this, method_arguments); 1115 $.data(this, 'slidePanel', instance); 1116 } 1117 1118 switch (method) { 1119 case 'hide': 1120 _SlidePanel.hide(instance); 1121 break; 1122 case 'show': 1123 _SlidePanel.show(instance); 1124 break; 1125 } 1126 }); 1127 } else { 1128 return this.each(function() { 1129 if (!$.data(this, 'slidePanel')) { 1130 $.data(this, 'slidePanel', new Instance(this, options)); 1131 1132 $(this).on('click', function(e) { 1133 var instance = $.data(this, 'slidePanel'); 1134 _SlidePanel.show(instance); 1135 1136 e.preventDefault(); 1137 e.stopPropagation(); 1138 }); 1139 } 1140 }); 1141 } 1142 }; 1143 1144})(jQuery, document, window);
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.