PageSourceSearch

https://www.booknook.biz/modules/mod_jaimagehotspot/assets/elements/popover/jquery.webui-popover.js

js booknook.biz collected 2026-10-02 17:26:25 UTC 51,573 bytes, 1,233 lines download raw bytes

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>&nbsp;</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.