vendor: 1,516 bytes, lines 1-42
1/* 2 * webui popover plugin - v1.2.17 3 * A lightWeight popover plugin with jquery ,enchance the popover plugin of bootstrap with some awesome new features. It works well with bootstrap ,but bootstrap is not necessary! 4 * https://github.com/sandywalker/webui-popover 5 * 6 * Made by Sandy Duan 7 * Under MIT License 8 */ 9(function(window, document, undefined) { 10 'use strict'; 11 (function(factory) { 12 if (typeof define === 'function' && define.amd) { 13 // Register as an anonymous AMD module. 14 define(['jquery'], factory); 15 } else if (typeof exports === 'object') { 16 // Node/CommonJS 17 module.exports = factory(require('jquery')); 18 } else { 19 // Browser globals 20 factory(window.jQuery); 21 } 22 }(function($) { 23 // Create the defaults once 24 var pluginName = 'webuiPopover'; 25 var pluginClass = 'webui-popover'; 26 var pluginType = 'webui.popover'; 27 var defaults = { 28 placement: 'auto', 29 container: null, 30 width: 'auto', 31 height: 'auto', 32 trigger: 'click', //hover,click,sticky,manual 33 style: '', 34 selector: false, // jQuery selector, if a selector is provided, popover objects will be delegated to the specified. 35 delay: { 36 show: null, 37 hide: 300 38 }, 39 async: { 40 type: 'GET', 41 data: {}, 42 dataType: 'html
vendor: 10,728 bytes, lines 42-330
42', 43 before: null, //function(that, xhr, settings){} 44 success: null, //function(that, xhr){} 45 error: null //function(that, xhr, data){} 46 }, 47 cache: true, 48 multi: false, 49 arrow: true, 50 title: '', 51 content: '', 52 closeable: false, 53 padding: true, 54 url: '', 55 type: 'html', 56 direction: '', // ltr,rtl 57 animation: null, 58 template: '<div class="webui-popover">' + 59 '<div class="webui-arrow"></div>' + 60 '<div class="webui-popover-inner">' + 61 '<a href="#" class="close"></a>' + 62 '<h3 class="webui-popover-title"></h3>' + 63 '<div class="webui-popover-content"><i class="icon-refresh"></i> <p> </p></div>' + 64 '</div>' + 65 '</div>', 66 backdrop: false, 67 dismissible: true, 68 onShow: null, 69 onHide: null, 70 abortXHR: true, 71 autoHide: false, 72 offsetTop: 0, 73 offsetLeft: 0, 74 iframeOptions: { 75 frameborder: '0', 76 allowtransparency: 'true', 77 id: '', 78 name: '', 79 scrolling: '', 80 onload: '', 81 height: '', 82 width: '' 83 }, 84 hideEmpty: false 85 }; 86 87 var rtlClass = pluginClass + '-rtl'; 88 var _srcElements = []; 89 var backdrop = $('<div class="webui-popover-backdrop"></div>'); 90 var _globalIdSeed = 0; 91 var _isBodyEventHandled = false; 92 var _offsetOut = -2000; // the value offset out of the screen 93 var $document = $(document); 94 95 var toNumber = function(numeric, fallback) { 96 return isNaN(numeric) ? (fallback || 0) : Number(numeric); 97 }; 98 99 var getPopFromElement = function($element) { 100 return $element.data('plugin_' + pluginName); 101 }; 102 103 var hideAllPop = function() { 104 var pop = null; 105 for (var i = 0; i < _srcElements.length; i++) { 106 pop = getPopFromElement(_srcElements[i]); 107 if (pop) { 108 pop.hide(true); 109 } 110 } 111 $document.trigger('hiddenAll.' + pluginType); 112 }; 113 114 var hideOtherPops = function(currentPop) { 115 var pop = null; 116 for (var i = 0; i < _srcElements.length; i++) { 117 pop = getPopFromElement(_srcElements[i]); 118 if (pop && pop.id !== currentPop.id) { 119 pop.hide(true); 120 } 121 } 122 $document.trigger('hiddenAll.' + pluginType); 123 }; 124 125 var isMobile = ('ontouchstart' in document.documentElement) && (/Mobi/.test(navigator.userAgent)); 126 127 var pointerEventToXY = function(e) { 128 var out = { 129 x: 0, 130 y: 0 131 }; 132 if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') { 133 var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 134 out.x = touch.pageX; 135 out.y = touch.pageY; 136 } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'click') { 137 out.x = e.pageX; 138 out.y = e.pageY; 139 } 140 return out; 141 }; 142 143 144 145 // The actual plugin constructor 146 function WebuiPopover(element, options) { 147 this.$element = $(element); 148 if (options) { 149 if ($.type(options.delay) === 'string' || $.type(options.delay) === 'number') { 150 options.delay = { 151 show: options.delay, 152 hide: options.delay 153 }; // bc break fix 154 } 155 } 156 this.options = $.extend({}, defaults, options); 157 this._defaults = defaults; 158 this._name = pluginName; 159 this._targetclick = false; 160 this.init(); 161 _srcElements.push(this.$element); 162 return this; 163 164 } 165 166 WebuiPopover.prototype = { 167 //init webui popover 168 init: function() { 169 if (this.$element[0] instanceof document.constructor && !this.options.selector) { 170 throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!'); 171 } 172 173 if (this.getTrigger() !== 'manual') { 174 //init the event handlers 175 if (isMobile) { 176 this.$element.off('touchend', this.options.selector).on('touchend', this.options.selector, $.proxy(this.toggle, this)); 177 } else if (this.getTrigger() === 'click') { 178 this.$element.off('click', this.options.selector).on('click', this.options.selector, $.proxy(this.toggle, this)); 179 } else if (this.getTrigger() === 'hover') { 180 this.$element 181 .off('mouseenter mouseleave click', this.options.selector) 182 .on('mouseenter', this.options.selector, $.proxy(this.mouseenterHandler, this)) 183 .on('mouseleave', this.options.selector, $.proxy(this.mouseleaveHandler, this)); 184 } 185 } 186 this._poped = false; 187 this._inited = true; 188 this._opened = false; 189 this._idSeed = _globalIdSeed; 190 this.id = pluginName + this._idSeed; 191 // normalize container 192 this.options.container = $(this.options.container || document.body).first(); 193 194 if (this.options.backdrop) { 195 backdrop.appendTo(this.options.container).hide(); 196 } 197 _globalIdSeed++; 198 if (this.getTrigger() === 'sticky') { 199 this.show(); 200 } 201 202 if (this.options.selector) { 203 this._options = $.extend({}, this.options, { 204 selector: '' 205 }); 206 } 207 208 }, 209 /* api methods and actions */ 210 destroy: function() { 211 var index = -1; 212 213 for (var i = 0; i < _srcElements.length; i++) { 214 if (_srcElements[i] === this.$element) { 215 index = i; 216 break; 217 } 218 } 219 220 _srcElements.splice(index, 1); 221 222 223 this.hide(); 224 this.$element.data('plugin_' + pluginName, null); 225 if (this.getTrigger() === 'click') { 226 this.$element.off('click'); 227 } else if (this.getTrigger() === 'hover') { 228 this.$element.off('mouseenter mouseleave'); 229 } 230 if (this.$target) { 231 this.$target.remove(); 232 } 233 }, 234 getDelegateOptions: function() { 235 var options = {}; 236 237 this._options && $.each(this._options, function(key, value) { 238 if (defaults[key] !== value) { 239 options[key] = value; 240 } 241 }); 242 return options; 243 }, 244 /* 245 param: force boolean value, if value is true then force hide the popover 246 param: event dom event, 247 */ 248 hide: function(force, event) { 249 250 if (!force && this.getTrigger() === 'sticky') { 251 return; 252 } 253 if (!this._opened) { 254 return; 255 } 256 if (event) { 257 event.preventDefault(); 258 event.stopPropagation(); 259 } 260 261 if (this.xhr && this.options.abortXHR === true) { 262 this.xhr.abort(); 263 this.xhr = null; 264 } 265 266 267 var e = $.Event('hide.' + pluginType); 268 this.$element.trigger(e, [this.$target]); 269 if (this.$target) { 270 this.$target.removeClass('in').addClass(this.getHideAnimation()); 271 var that = this; 272 setTimeout(function() { 273 that.$target.hide(); 274 if (!that.getCache()) { 275 that.$target.remove(); 276 //that.getTriggerElement.removeAttr('data-target'); 277 } 278 }, that.getHideDelay()); 279 } 280 if (this.options.backdrop) { 281 backdrop.hide(); 282 } 283 this._opened = false; 284 this.$element.trigger('hidden.' + pluginType, [this.$target]); 285 286 if (this.options.onHide) { 287 this.options.onHide(this.$target); 288 } 289 290 }, 291 resetAutoHide: function() { 292 var that = this; 293 var autoHide = that.getAutoHide(); 294 if (autoHide) { 295 if (that.autoHideHandler) { 296 clearTimeout(that.autoHideHandler); 297 } 298 that.autoHideHandler = setTimeout(function() { 299 that.hide(); 300 }, autoHide); 301 } 302 }, 303 delegate: function(eventTarget) { 304 var self = $(eventTarget).data('plugin_' + pluginName); 305 if (!self) { 306 self = new WebuiPopover(eventTarget, this.getDelegateOptions()); 307 $(eventTarget).data('plugin_' + pluginName, self); 308 } 309 return self; 310 }, 311 toggle: function(e) { 312 var self = this; 313 if (e) { 314 e.preventDefault(); 315 e.stopPropagation(); 316 if (this.options.selector) { 317 self = this.delegate(e.currentTarget); 318 } 319 } 320 self[self.getTarget().hasClass('in') ? 'hide' : 'show'](); 321 }, 322 hideAll: function() { 323 hideAllPop(); 324 }, 325 hideOthers: function() { 326 hideOtherPops(this); 327 }, 328 /*core method ,show popover */ 329 show: function() { 330
vendor: 3,561 bytes, lines 330-423
330// console.log('popup prevent tap '+pinchDuration); 331 if (pinchDuration) 332 return; 333 if (this._opened) { 334 return; 335 } 336 //removeAllTargets(); 337 var 338 $target = this.getTarget().removeClass().addClass(pluginClass).addClass(this._customTargetClass); 339 if (!this.options.multi) { 340 this.hideOthers(); 341 } 342 343 // use cache by default, if not cache setted , reInit the contents 344 if (!this.getCache() || !this._poped || this.content === '') { 345 this.content = ''; 346 this.setTitle(this.getTitle()); 347 if (!this.options.closeable) { 348 $target.find('.close').off('click').remove(); 349 } 350 if (!this.isAsync()) { 351 this.setContent(this.getContent()); 352 } else { 353 this.setContentASync(this.options.content); 354 } 355 356 if (this.canEmptyHide() && this.content === '') { 357 return; 358 } 359 $target.show(); 360 } 361 362 this.displayContent(); 363 364 if (this.options.onShow) { 365 this.options.onShow($target); 366 } 367 368 this.bindBodyEvents(); 369 if (this.options.backdrop) { 370 backdrop.show(); 371 } 372 this._opened = true; 373 this.resetAutoHide(); 374 }, 375 displayContent: function() { 376 var 377 //element postion 378 elementPos = this.getElementPosition(), 379 //target postion 380 $target = this.getTarget().removeClass().addClass(pluginClass).addClass(this._customTargetClass), 381 //target content 382 $targetContent = this.getContentElement(), 383 //target Width 384 targetWidth = $target[0].offsetWidth, 385 //target Height 386 targetHeight = $target[0].offsetHeight, 387 //placement 388 placement = 'bottom', 389 e = $.Event('show.' + pluginType); 390 391 if (this.canEmptyHide()) { 392 393 var content = $targetContent.children().html(); 394 if (content !== null && content.trim().length === 0) { 395 return; 396 } 397 } 398 399 //if (this.hasContent()){ 400 this.$element.trigger(e, [$target]); 401 //} 402 // support width as data attribute 403 var optWidth = this.$element.data('width') || this.options.width; 404 if (optWidth === '') { 405 optWidth = this._defaults.width; 406 } 407 408 if (optWidth !== 'auto') { 409 $target.width(optWidth); 410 } 411 412 // support height as data attribute 413 var optHeight = this.$element.data('height') || this.options.height; 414 if (optHeight === '') { 415 optHeight = this._defaults.height; 416 } 417 418 if (optHeight !== 'auto') { 419 $targetContent.height(optHeight); 420 } 421 422 if (this.options.style) { 423 this.$target.addClass(
vendor: 11,944 bytes, lines 423-710
423this.options.style); 424 } 425 426 //check rtl 427 if (this.options.direction === 'rtl' && !$targetContent.hasClass(rtlClass)) { 428 $targetContent.addClass(rtlClass); 429 } 430 431 //init the popover and insert into the document body 432 if (!this.options.arrow) { 433 $target.find('.webui-arrow').remove(); 434 } 435 $target.detach().css({ 436 top: _offsetOut, 437 left: _offsetOut, 438 display: 'block' 439 }); 440 441 if (this.getAnimation()) { 442 $target.addClass(this.getAnimation()); 443 } 444 $target.appendTo(this.options.container); 445 446 447 placement = this.getPlacement(elementPos); 448 449 //This line is just for compatible with knockout custom binding 450 this.$element.trigger('added.' + pluginType); 451 452 this.initTargetEvents(); 453 454 if (!this.options.padding) { 455 if (this.options.height !== 'auto') { 456 $targetContent.css('height', $targetContent.outerHeight()); 457 } 458 this.$target.addClass('webui-no-padding'); 459 } 460 461 // add maxHeight and maxWidth support by [email protected] 2016/10/1 462 if (this.options.maxHeight) { 463 $targetContent.css('maxHeight', this.options.maxHeight); 464 } 465 466 if (this.options.maxWidth) { 467 $targetContent.css('maxWidth', this.options.maxWidth); 468 } 469 // end 470 471 targetWidth = $target[0].offsetWidth; 472 targetHeight = $target[0].offsetHeight; 473 474 var postionInfo = this.getTargetPositin(elementPos, placement, targetWidth, targetHeight); 475 476 this.$target.css(postionInfo.position).addClass(placement).addClass('in'); 477 478 if (this.options.type === 'iframe') { 479 var $iframe = $target.find('iframe'); 480 var iframeWidth = $target.width(); 481 var iframeHeight = $iframe.parent().height(); 482 483 if (this.options.iframeOptions.width !== '' && this.options.iframeOptions.width !== 'auto') { 484 iframeWidth = this.options.iframeOptions.width; 485 } 486 487 if (this.options.iframeOptions.height !== '' && this.options.iframeOptions.height !== 'auto') { 488 iframeHeight = this.options.iframeOptions.height; 489 } 490 491 $iframe.width(iframeWidth).height(iframeHeight); 492 } 493 494 if (!this.options.arrow) { 495 this.$target.css({ 496 'margin': 0 497 }); 498 } 499 if (this.options.arrow) { 500 var $arrow = this.$target.find('.webui-arrow'); 501 $arrow.removeAttr('style'); 502 503 //prevent arrow change by content size 504 if (placement === 'left' || placement === 'right') { 505 $arrow.css({ 506 top: this.$target.height() / 2 507 }); 508 } else if (placement === 'top' || placement === 'bottom') { 509 $arrow.css({ 510 left: this.$target.width() / 2 511 }); 512 } 513 514 if (postionInfo.arrowOffset) { 515 //hide the arrow if offset is negative 516 if (postionInfo.arrowOffset.left === -1 || postionInfo.arrowOffset.top === -1) { 517 $arrow.hide(); 518 } else { 519 $arrow.css(postionInfo.arrowOffset); 520 } 521 } 522 523 } 524 this._poped = true; 525 this.$element.trigger('shown.' + pluginType, [this.$target]); 526 }, 527 528 isTargetLoaded: function() { 529 return this.getTarget().find('i.glyphicon-refresh').length === 0; 530 }, 531 532 /*getter setters */ 533 getTriggerElement: function() { 534 return this.$element; 535 }, 536 getTarget: function() { 537 if (!this.$target) { 538 var id = pluginName + this._idSeed; 539 this.$target = $(this.options.template) 540 .attr('id', id); 541 this._customTargetClass = this.$target.attr('class') !== pluginClass ? this.$target.attr('class') : null; 542 this.getTriggerElement().attr('data-target', id); 543 } 544 if (!this.$target.data('trigger-element')) { 545 this.$target.data('trigger-element', this.getTriggerElement()); 546 } 547 return this.$target; 548 }, 549 removeTarget: function() { 550 this.$target.remove(); 551 this.$target = null; 552 this.$contentElement = null; 553 }, 554 getTitleElement: function() { 555 return this.getTarget().find('.' + pluginClass + '-title'); 556 }, 557 getContentElement: function() { 558 if (!this.$contentElement) { 559 this.$contentElement = this.getTarget().find('.' + pluginClass + '-content'); 560 } 561 return this.$contentElement; 562 }, 563 getTitle: function() { 564 return this.$element.attr('data-title') || this.options.title || this.$element.attr('title'); 565 }, 566 getUrl: function() { 567 return this.$element.attr('data-url') || this.options.url; 568 }, 569 getAutoHide: function() { 570 return this.$element.attr('data-auto-hide') || this.options.autoHide; 571 }, 572 getOffsetTop: function() { 573 return toNumber(this.$element.attr('data-offset-top')) || this.options.offsetTop; 574 }, 575 getOffsetLeft: function() { 576 return toNumber(this.$element.attr('data-offset-left')) || this.options.offsetLeft; 577 }, 578 getCache: function() { 579 var dataAttr = this.$element.attr('data-cache'); 580 if (typeof(dataAttr) !== 'undefined') { 581 switch (dataAttr.toLowerCase()) { 582 case 'true': 583 case 'yes': 584 case '1': 585 return true; 586 case 'false': 587 case 'no': 588 case '0': 589 return false; 590 } 591 } 592 return this.options.cache; 593 }, 594 getTrigger: function() { 595 return this.$element.attr('data-trigger') || this.options.trigger; 596 }, 597 getDelayShow: function() { 598 var dataAttr = this.$element.attr('data-delay-show'); 599 if (typeof(dataAttr) !== 'undefined') { 600 return dataAttr; 601 } 602 return this.options.delay.show === 0 ? 0 : this.options.delay.show || 100; 603 }, 604 getHideDelay: function() { 605 var dataAttr = this.$element.attr('data-delay-hide'); 606 if (typeof(dataAttr) !== 'undefined') { 607 return dataAttr; 608 } 609 return this.options.delay.hide === 0 ? 0 : this.options.delay.hide || 100; 610 }, 611 getAnimation: function() { 612 var dataAttr = this.$element.attr('data-animation'); 613 return dataAttr || this.options.animation; 614 }, 615 getHideAnimation: function() { 616 var ani = this.getAnimation(); 617 return ani ? ani + '-out' : 'out'; 618 }, 619 setTitle: function(title) { 620 var $titleEl = this.getTitleElement(); 621 if (title) { 622 //check rtl 623 if (this.options.direction === 'rtl' && !$titleEl.hasClass(rtlClass)) { 624 $titleEl.addClass(rtlClass); 625 } 626 $titleEl.html(title); 627 } else { 628 $titleEl.remove(); 629 } 630 }, 631 hasContent: function() { 632 return this.getContent(); 633 }, 634 canEmptyHide: function() { 635 return this.options.hideEmpty && this.options.type === 'html'; 636 }, 637 getIframe: function() { 638 var $iframe = $('<iframe></iframe>').attr('src', this.getUrl()); 639 var self = this; 640 $.each(this._defaults.iframeOptions, function(opt) { 641 if (typeof self.options.iframeOptions[opt] !== 'undefined') { 642 $iframe.attr(opt, self.options.iframeOptions[opt]); 643 } 644 }); 645 646 return $iframe; 647 }, 648 getContent: function() { 649 if (this.getUrl()) { 650 switch (this.options.type) { 651 case 'iframe': 652 this.content = this.getIframe(); 653 break; 654 case 'html': 655 try { 656 this.content = $(this.getUrl()); 657 if (!this.content.is(':visible')) { 658 this.content.show(); 659 } 660 } catch (error) { 661 throw new Error('Unable to get popover content. Invalid selector specified.'); 662 } 663 break; 664 } 665 } else if (!this.content) { 666 var content = ''; 667 if ($.isFunction(this.options.content)) { 668 content = this.options.content.apply(this.$element[0], [this]); 669 } else { 670 content = this.options.content; 671 } 672 this.content = this.$element.attr('data-content') || content; 673 if (!this.content) { 674 var $next = this.$element.next(); 675 676 if ($next && $next.hasClass(pluginClass + '-content')) { 677 this.content = $next; 678 } 679 } 680 } 681 return this.content; 682 }, 683 setContent: function(content) { 684 var $target = this.getTarget(); 685 var $ct = this.getContentElement(); 686 if (typeof content === 'string') { 687 $ct.html(content); 688 } else if (content instanceof $) { 689 $ct.html(''); 690 //Don't want to clone too many times. 691 if (!this.options.cache) { 692 content.clone(true, true).removeClass(pluginClass + '-content').appendTo($ct); 693 } else { 694 content.removeClass(pluginClass + '-content').appendTo($ct); 695 } 696 } 697 this.$target = $target; 698 }, 699 isAsync: function() { 700 return this.options.type === 'async'; 701 }, 702 setContentASync: function(content) { 703 var that = this; 704 if (this.xhr) { 705 return; 706 } 707 this.xhr = $.ajax({ 708 url: this.getUrl(), 709 type: this.options.async.type, 710
vendor: 13,023 bytes, lines 710-985
710data: this.options.async.data, 711 dataType: this.options.async.dataType, 712 cache: this.getCache(), 713 beforeSend: function(xhr, settings) { 714 if (that.options.async.before) { 715 that.options.async.before(that, xhr, settings); 716 } 717 }, 718 success: function(data) { 719 that.bindBodyEvents(); 720 if (content && $.isFunction(content)) { 721 that.content = content.apply(that.$element[0], [data]); 722 } else { 723 that.content = data; 724 } 725 // move this to success function. 726// that.setContent(that.content); 727// var $targetContent = that.getContentElement(); 728// $targetContent.removeAttr('style'); 729// that.displayContent(); 730 if (that.options.async.success) { 731 that.options.async.success(that, data); 732 } 733 }, 734 complete: function() { 735 that.xhr = null; 736 }, 737 error: function(xhr, data) { 738 if (that.options.async.error) { 739 that.options.async.error(that, xhr, data); 740 } 741 } 742 }); 743 }, 744 745 bindBodyEvents: function() { 746 if (_isBodyEventHandled) { 747 return; 748 } 749 if (this.options.dismissible && this.getTrigger() === 'click') { 750 if (isMobile) { 751 $document.off('touchstart.webui-popover').on('touchstart.webui-popover', $.proxy(this.bodyTouchStartHandler, this)); 752 } else { 753 $document.off('keyup.webui-popover').on('keyup.webui-popover', $.proxy(this.escapeHandler, this)); 754 $document.off('click.webui-popover').on('click.webui-popover', $.proxy(this.bodyClickHandler, this)); 755 } 756 } else if (this.getTrigger() === 'hover') { 757 $document.off('touchend.webui-popover') 758 .on('touchend.webui-popover', $.proxy(this.bodyClickHandler, this)); 759 } 760 }, 761 762 /* event handlers */ 763 mouseenterHandler: function(e) { 764 var self = this; 765 766 if (e && this.options.selector) { 767 self = this.delegate(e.currentTarget); 768 } 769 770 if (self._timeout) { 771 clearTimeout(self._timeout); 772 } 773 self._enterTimeout = setTimeout(function() { 774 if (!self.getTarget().is(':visible')) { 775 self.show(); 776 } 777 }, this.getDelayShow()); 778 }, 779 mouseleaveHandler: function() { 780 var self = this; 781 clearTimeout(self._enterTimeout); 782 //key point, set the _timeout then use clearTimeout when mouse leave 783 self._timeout = setTimeout(function() { 784 self.hide(); 785 }, this.getHideDelay()); 786 }, 787 escapeHandler: function(e) { 788 if (e.keyCode === 27) { 789 this.hideAll(); 790 } 791 }, 792 bodyTouchStartHandler: function(e) { 793 var self = this; 794 var $eventEl = $(e.currentTarget); 795 $eventEl.on('touchend', function(e) { 796 self.bodyClickHandler(e); 797 $eventEl.off('touchend'); 798 }); 799 $eventEl.on('touchmove', function() { 800 $eventEl.off('touchend'); 801 }); 802 }, 803 bodyClickHandler: function(e) { 804 _isBodyEventHandled = true; 805 var canHide = true; 806 for (var i = 0; i < _srcElements.length; i++) { 807 var pop = getPopFromElement(_srcElements[i]); 808 if (pop && pop._opened) { 809 var offset = pop.getTarget().offset(); 810 var popX1 = offset.left; 811 var popY1 = offset.top; 812 var popX2 = offset.left + pop.getTarget().width(); 813 var popY2 = offset.top + pop.getTarget().height(); 814 var pt = pointerEventToXY(e); 815 var inPop = pt.x >= popX1 && pt.x <= popX2 && pt.y >= popY1 && pt.y <= popY2; 816 if (inPop) { 817 canHide = false; 818 break; 819 } 820 } 821 } 822 if (canHide) { 823 hideAllPop(); 824 } 825 }, 826 827 /* 828 targetClickHandler: function() { 829 this._targetclick = true; 830 }, 831 */ 832 833 //reset and init the target events; 834 initTargetEvents: function() { 835 if (this.getTrigger() === 'hover') { 836 this.$target 837 .off('mouseenter mouseleave') 838 .on('mouseenter', $.proxy(this.mouseenterHandler, this)) 839 .on('mouseleave', $.proxy(this.mouseleaveHandler, this)); 840 } 841 this.$target.find('.close').off('click').on('click', $.proxy(this.hide, this, true)); 842 //this.$target.off('click.webui-popover').on('click.webui-popover', $.proxy(this.targetClickHandler, this)); 843 }, 844 /* utils methods */ 845 //caculate placement of the popover 846 getPlacement: function(pos) { 847 var 848 placement, 849 container = this.options.container, 850 clientWidth = container.innerWidth(), 851 clientHeight = container.innerHeight(), 852 scrollTop = jQuery(window).scrollTop(), 853 scrollLeft = jQuery(window).scrollLeft(), 854 pageX = Math.max(0, pos.left - scrollLeft), 855 pageY = Math.max(0, pos.top - scrollTop); 856 //arrowSize = 20; 857 858 //if placement equals autoï¼caculate the placement by element information; 859 if (typeof(this.options.placement) === 'function') { 860 placement = this.options.placement.call(this, this.getTarget()[0], this.$element[0]); 861 } else { 862 placement = this.$element.data('placement') || this.options.placement; 863 } 864 865 var isH = placement === 'horizontal'; 866 var isV = placement === 'vertical'; 867 var detect = placement === 'auto' || isH || isV; 868 869 if (detect) { 870 if (pageX < clientWidth / 3) { 871 if (pageY < clientHeight / 3) { 872 placement = isH ? 'right-bottom' : 'bottom-right'; 873 } else if (pageY < clientHeight * 2 / 3) { 874 if (isV) { 875 placement = pageY <= clientHeight / 2 ? 'bottom-right' : 'top-right'; 876 } else { 877 placement = 'right'; 878 } 879 } else { 880 placement = isH ? 'right-top' : 'top-right'; 881 } 882 //placement= pageY>targetHeight+arrowSize?'top-right':'bottom-right'; 883 } else if (pageX < clientWidth * 2 / 3) { 884 if (pageY < clientHeight / 3) { 885 if (isH) { 886 placement = pageX <= clientWidth / 2 ? 'right-bottom' : 'left-bottom'; 887 } else { 888 placement = 'bottom'; 889 } 890 } else if (pageY < clientHeight * 2 / 3) { 891 if (isH) { 892 placement = pageX <= clientWidth / 2 ? 'right' : 'left'; 893 } else { 894 placement = pageY <= clientHeight / 2 ? 'bottom' : 'top'; 895 } 896 } else { 897 if (isH) { 898 placement = pageX <= clientWidth / 2 ? 'right-top' : 'left-top'; 899 } else { 900 placement = 'top'; 901 } 902 } 903 } else { 904 //placement = pageY>targetHeight+arrowSize?'top-left':'bottom-left'; 905 if (pageY < clientHeight / 3) { 906 placement = isH ? 'left-bottom' : 'bottom-left'; 907 } else if (pageY < clientHeight * 2 / 3) { 908 if (isV) { 909 placement = pageY <= clientHeight / 2 ? 'bottom-left' : 'top-left'; 910 } else { 911 placement = 'left'; 912 } 913 } else { 914 placement = isH ? 'left-top' : 'top-left'; 915 } 916 } 917 } else if (placement === 'auto-top') { 918 if (pageX < clientWidth / 3) { 919 placement = 'top-right'; 920 } else if (pageX < clientWidth * 2 / 3) { 921 placement = 'top'; 922 } else { 923 placement = 'top-left'; 924 } 925 } else if (placement === 'auto-bottom') { 926 if (pageX < clientWidth / 3) { 927 placement = 'bottom-right'; 928 } else if (pageX < clientWidth * 2 / 3) { 929 placement = 'bottom'; 930 } else { 931 placement = 'bottom-left'; 932 } 933 } else if (placement === 'auto-left') { 934 if (pageY < clientHeight / 3) { 935 placement = 'left-top'; 936 } else if (pageY < clientHeight * 2 / 3) { 937 placement = 'left'; 938 } else { 939 placement = 'left-bottom'; 940 } 941 } else if (placement === 'auto-right') { 942 if (pageY < clientHeight / 3) { 943 placement = 'right-bottom'; 944 } else if (pageY < clientHeight * 2 / 3) { 945 placement = 'right'; 946 } else { 947 placement = 'right-top'; 948 } 949 } 950 return placement; 951 }, 952 getElementPosition: function() { 953 // If the container is the body or normal conatiner, just use $element.offset() 954 var elRect = this.$element[0].getBoundingClientRect(); 955 var container = this.options.container; 956 var cssPos = container.css('position'); 957 958 if (container.is(document.body) || cssPos === 'static') { 959 return $.extend({}, this.$element.offset(), { 960 width: this.$element[0].offsetWidth || elRect.width, 961 height: this.$element[0].offsetHeight || elRect.height 962 }); 963 // Else fixed container need recalculate the position 964 } else if (cssPos === 'fixed') { 965 var containerRect = container[0].getBoundingClientRect(); 966 return { 967 top: elRect.top - containerRect.top + jQuery(window).scrollTop(), 968 left: elRect.left - containerRect.left + jQuery(window).scrollLeft(), 969 width: elRect.width, 970 height: elRect.height 971 }; 972 } else if (cssPos === 'relative') { 973 return { 974 top: this.$element.offset().top - container.offset().top, 975 left: this.$element.offset().left - container.offset().left, 976 width: this.$element[0].offsetWidth || elRect.width, 977 height: this.$element[0].offsetHeight || elRect.height 978 }; 979 } 980 }, 981 982 getTargetPositin: function(elementPos, placement, targetWidth, targetHeight) { 983 var pos = elementPos, 984 container = this.options.container, 985 //clientWidth = container.innerWidth(),
986 //clientHeight = container.innerHeight(), 987 elementW = this.$element.outerWidth(), 988 elementH = this.$element.outerHeight(), 989 scrollTop = document.documentElement.scrollTop + jQuery(window).scrollTop(), 990 scrollLeft = document.documentElement.scrollLeft + jQuery(window)
vendor: 10,438 bytes, lines 990-1233
990.scrollLeft(), 991 position = {}, 992 arrowOffset = null, 993 arrowSize = this.options.arrow ? 20 : 0, 994 padding = 10, 995 fixedW = elementW < arrowSize + padding ? arrowSize : 0, 996 fixedH = elementH < arrowSize + padding ? arrowSize : 0, 997 refix = 0, 998 pageH = document.documentElement.clientHeight + scrollTop, 999 pageW = document.documentElement.clientWidth + scrollLeft; 1000 1001 var validLeft = pos.left + pos.width / 2 - fixedW > 0; 1002 var validRight = pos.left + pos.width / 2 + fixedW < pageW; 1003 var validTop = pos.top + pos.height / 2 - fixedH > 0; 1004 var validBottom = pos.top + pos.height / 2 + fixedH < pageH; 1005 1006 1007 switch (placement) { 1008 case 'bottom': 1009 position = { 1010 top: pos.top + pos.height, 1011 left: pos.left + pos.width / 2 - targetWidth / 2 1012 }; 1013 break; 1014 case 'top': 1015 position = { 1016 top: pos.top - targetHeight, 1017 left: pos.left + pos.width / 2 - targetWidth / 2 1018 }; 1019 break; 1020 case 'left': 1021 position = { 1022 top: pos.top + pos.height / 2 - targetHeight / 2, 1023 left: pos.left - targetWidth 1024 }; 1025 break; 1026 case 'right': 1027 position = { 1028 top: pos.top + pos.height / 2 - targetHeight / 2, 1029 left: pos.left + pos.width 1030 }; 1031 break; 1032 case 'top-right': 1033 position = { 1034 top: pos.top - targetHeight, 1035 left: validLeft ? pos.left - fixedW : padding 1036 }; 1037 arrowOffset = { 1038 left: validLeft ? Math.min(elementW, targetWidth) / 2 + fixedW : _offsetOut 1039 }; 1040 break; 1041 case 'top-left': 1042 refix = validRight ? fixedW : -padding; 1043 position = { 1044 top: pos.top - targetHeight, 1045 left: pos.left - targetWidth + pos.width + refix 1046 }; 1047 arrowOffset = { 1048 left: validRight ? targetWidth - Math.min(elementW, targetWidth) / 2 - fixedW : _offsetOut 1049 }; 1050 break; 1051 case 'bottom-right': 1052 position = { 1053 top: pos.top + pos.height, 1054 left: validLeft ? pos.left - fixedW : padding 1055 }; 1056 arrowOffset = { 1057 left: validLeft ? Math.min(elementW, targetWidth) / 2 + fixedW : _offsetOut 1058 }; 1059 break; 1060 case 'bottom-left': 1061 refix = validRight ? fixedW : -padding; 1062 position = { 1063 top: pos.top + pos.height, 1064 left: pos.left - targetWidth + pos.width + refix 1065 }; 1066 arrowOffset = { 1067 left: validRight ? targetWidth - Math.min(elementW, targetWidth) / 2 - fixedW : _offsetOut 1068 }; 1069 break; 1070 case 'right-top': 1071 refix = validBottom ? fixedH : -padding; 1072 position = { 1073 top: pos.top - targetHeight + pos.height + refix, 1074 left: pos.left + pos.width 1075 }; 1076 arrowOffset = { 1077 top: validBottom ? targetHeight - Math.min(elementH, targetHeight) / 2 - fixedH : _offsetOut 1078 }; 1079 break; 1080 case 'right-bottom': 1081 position = { 1082 top: validTop ? pos.top - fixedH : padding, 1083 left: pos.left + pos.width 1084 }; 1085 arrowOffset = { 1086 top: validTop ? Math.min(elementH, targetHeight) / 2 + fixedH : _offsetOut 1087 }; 1088 break; 1089 case 'left-top': 1090 refix = validBottom ? fixedH : -padding; 1091 position = { 1092 top: pos.top - targetHeight + pos.height + refix, 1093 left: pos.left - targetWidth 1094 }; 1095 arrowOffset = { 1096 top: validBottom ? targetHeight - Math.min(elementH, targetHeight) / 2 - fixedH : _offsetOut 1097 }; 1098 break; 1099 case 'left-bottom': 1100 position = { 1101 top: validTop ? pos.top - fixedH : padding, 1102 left: pos.left - targetWidth 1103 }; 1104 arrowOffset = { 1105 top: validTop ? Math.min(elementH, targetHeight) / 2 + fixedH : _offsetOut 1106 }; 1107 break; 1108 1109 } 1110 position.top += this.getOffsetTop(); 1111 position.left += this.getOffsetLeft(); 1112 1113 return { 1114 position: position, 1115 arrowOffset: arrowOffset 1116 }; 1117 } 1118 }; 1119 $.fn[pluginName] = function(options, noInit) { 1120 var results = []; 1121 var $result = this.each(function() { 1122 1123 var webuiPopover = $.data(this, 'plugin_' + pluginName); 1124 if (!webuiPopover) { 1125 if (!options) { 1126 webuiPopover = new WebuiPopover(this, null); 1127 } else if (typeof options === 'string') { 1128 if (options !== 'destroy') { 1129 if (!noInit) { 1130 webuiPopover = new WebuiPopover(this, null); 1131 results.push(webuiPopover[options]()); 1132 } 1133 } 1134 } else if (typeof options === 'object') { 1135 webuiPopover = new WebuiPopover(this, options); 1136 } 1137 $.data(this, 'plugin_' + pluginName, webuiPopover); 1138 } else { 1139 if (options === 'destroy') { 1140 webuiPopover.destroy(); 1141 } else if (typeof options === 'string') { 1142 results.push(webuiPopover[options]()); 1143 } 1144 } 1145 }); 1146 return (results.length) ? results : $result; 1147 }; 1148 1149 //Global object exposes to window. 1150 var webuiPopovers = (function() { 1151 var _hideAll = function() { 1152 hideAllPop(); 1153 }; 1154 var _create = function(selector, options) { 1155 options = options || {}; 1156 $(selector).webuiPopover(options); 1157 }; 1158 var _isCreated = function(selector) { 1159 var created = true; 1160 $(selector).each(function(i, item) { 1161 created = created && $(item).data('plugin_' + pluginName) !== undefined; 1162 }); 1163 return created; 1164 }; 1165 var _show = function(selector, options) { 1166 if (options) { 1167 $(selector).webuiPopover(options).webuiPopover('show'); 1168 } else { 1169 $(selector).webuiPopover('show'); 1170 } 1171 }; 1172 var _hide = function(selector) { 1173 $(selector).webuiPopover('hide'); 1174 }; 1175 1176 var _setDefaultOptions = function(options) { 1177 defaults = $.extend({}, defaults, options); 1178 }; 1179 1180 var _updateContent = function(selector, content) { 1181 var pop = $(selector).data('plugin_' + pluginName); 1182 if (pop) { 1183 var cache = pop.getCache(); 1184 pop.options.cache = false; 1185 pop.options.content = content; 1186 if (pop._opened) { 1187 pop._opened = false; 1188 pop.show(); 1189 } else { 1190 if (pop.isAsync()) { 1191 pop.setContentASync(content); 1192 } else { 1193 pop.setContent(content); 1194 } 1195 } 1196 pop.options.cache = cache; 1197 } 1198 }; 1199 1200 var _updateContentAsync = function(selector, url) { 1201 var pop = $(selector).data('plugin_' + pluginName); 1202 if (pop) { 1203 var cache = pop.getCache(); 1204 var type = pop.options.type; 1205 pop.options.cache = false; 1206 pop.options.url = url; 1207 1208 if (pop._opened) { 1209 pop._opened = false; 1210 pop.show(); 1211 } else { 1212 pop.options.type = 'async'; 1213 pop.setContentASync(pop.content); 1214 } 1215 pop.options.cache = cache; 1216 pop.options.type = type; 1217 } 1218 }; 1219 1220 return { 1221 show: _show, 1222 hide: _hide, 1223 create: _create, 1224 isCreated: _isCreated, 1225 hideAll: _hideAll, 1226 updateContent: _updateContent, 1227 updateContentAsync: _updateContentAsync, 1228 setDefaultOptions: _setDefaultOptions 1229 }; 1230 })(); 1231 window.WebuiPopovers = webuiPopovers; 1232 })); 1233})(window, document);
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.