1/*! 2 * jQuery Popup Overlay 3 * 4 * @version 1.7.4 5 * @requires jQuery v1.7.1+ 6 * @link http://vast-engineering.github.com/jquery-popup-overlay/ 7 */ 8;(function ($) { 9 10 var $window = $(window); 11 var options = {}; 12 var zindexvalues = []; 13 var lastclicked = []; 14 var scrollbarwidth; 15 var bodymarginright = null; 16 var opensuffix = '_open'; 17 var closesuffix = '_close'; 18 var stack = []; 19 var transitionsupport = null; 20 var opentimer; 21 var iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent); 22 23 var methods = { 24 25 _init: function (el) { 26 var $el = $(el); 27 var options = $el.data('popupoptions'); 28 lastclicked[el.id] = false; 29 zindexvalues[el.id] = 0; 30 31 if (!$el.data('popup-initialized')) { 32 $el.attr('data-popup-initialized', 'true'); 33 methods._initonce(el); 34 } 35 36 if (options.autoopen) { 37 setTimeout(function() { 38 methods.show(el, 0); 39 }, 0); 40 } 41 }, 42 43 _initonce: function (el) { 44 var $el = $(el); 45 var $body = $('body'); 46 var $wrapper; 47 var options = $el.data('popupoptions'); 48 var css; 49 50 bodymarginright = parseInt($body.css('margin-right'), 10); 51 transitionsupport = document.body.style.webkitTransition !== undefined || 52 document.body.style.MozTransition !== undefined || 53 document.body.style.msTransition !== undefined || 54 document.body.style.OTransition !== undefined || 55 document.body.style.transition !== undefined; 56 57 if (options.type == 'tooltip') { 58 options.background = false; 59 options.scrolllock = false; 60 } 61 62 if (options.backgroundactive) { 63 options.background = false; 64 options.blur = false; 65 options.scrolllock = false; 66 } 67 68 if (options.scrolllock) { 69 // Calculate the browser's scrollbar width dynamically 70 var parent; 71 var child; 72 if (typeof scrollbarwidth === 'undefined') { 73 parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'); 74 child = parent.children(); 75 scrollbarwidth = child.innerWidth() - child.height(99).innerWidth(); 76 parent.remove(); 77 } 78 } 79 80 if (!$el.attr('id')) { 81 $el.attr('id', 'j-popup-' + parseInt((Math.random() * 100000000), 10)); 82 } 83 84 $el.addClass('popup_content'); 85 86 $body.prepend(el); 87 88 $el.wrap('<div id="' + el.id + '_wrapper" class="popup_wrapper" />'); 89 90 $wrapper = $('#' + el.id + '_wrapper'); 91 92 $wrapper.css({ 93 opacity: 0, 94 visibility: 'hidden', 95 position: 'absolute' 96 }); 97 98 // Make div clickable in iOS 99 if (iOS) { 100 $wrapper.css('cursor', 'pointer'); 101 } 102 103 if (options.type == 'overlay') { 104 $wrapper.css('overflow','auto'); 105 } 106 107 $el.css({ 108 opacity: 0, 109 visibility: 'hidden', 110 display: 'inline-block' 111 }); 112 113 if (options.setzindex && !options.autozindex) { 114 $wrapper.css('z-index', '100001'); 115 } 116 117 if (!options.outline) { 118 $el.css('outline', 'none'); 119 } 120 121 if (options.transition) { 122 $el.css('transition', options.transition); 123 $wrapper.css('transition', options.transition); 124 } 125 126 // Hide popup content from screen readers initially 127 $el.attr('aria-hidden', true); 128 129 if ((options.background) && (!$('#' + el.id + '_background').length)) { 130 131 $body.prepend('<div id="' + el.id + '_background" class="popup_background"></div>'); 132 133 var $background = $('#' + el.id + '_background'); 134 135 $background.css({ 136 opacity: 0, 137 visibility: 'hidden', 138 backgroundColor: options.color, 139 position: 'fixed', 140 top: 0, 141 right: 0, 142 bottom: 0, 143 left: 0 144 }); 145 146 if (options.setzindex && !options.autozindex) { 147 $background.css('z-index', '100000'); 148 } 149 150 if (options.transition) { 151 $background.css('transition', options.transition); 152 } 153 } 154 155 if (options.type == 'overlay') { 156 $el.css({ 157 textAlign: 'left', 158 /*position: 'relative',*/ 159 verticalAlign: 'middle' 160 }); 161 162 css = { 163 position: 'fixed', 164 width: '100%', 165 height: '100%', 166 top: 0, 167 left: 0, 168 textAlign: 'center' 169 }; 170 171 if(options.backgroundactive){ 172 css.position = 'relative'; 173 css.height = '0'; 174 css.overflow = 'visible'; 175 } 176 177 $wrapper.css(css); 178 179 // CSS vertical align helper 180 $wrapper.append('<div class="popup_align" />'); 181 182 $('.popup_align').css({ 183 display: 'inline-block', 184 verticalAlign: 'middle', 185 height: '100%' 186 }); 187 } 188 189 // Add WAI ARIA role to announce dialog to screen readers 190 $el.attr('role', 'dialog'); 191 192 var openelement = (options.openelement) ? options.openelement : ('.' + el.id + opensuffix); 193 194 $(openelement).each(function (i, item) { 195 $(item).attr('data-popup-ordinal', i); 196 197 if (!item.id) { 198 $(item).attr('id', 'open_' + parseInt((Math.random() * 100000000), 10)); 199 } 200 }); 201 202 // Set aria-labelledby (if aria-label or aria-labelledby is not set in html) 203 if (!($el.attr('aria-labelledby') || $el.attr('aria-label'))) { 204 $el.attr('aria-labelledby', $(openelement).attr('id')); 205 } 206 207 // Show and hide tooltips on hover 208 if(options.action == 'hover'){ 209 options.keepfocus = false; 210 211 // Handler: mouseenter, focusin 212 $(openelement).on('mouseenter', function (event) { 213 methods.show(el, $(this).data('popup-ordinal')); 214 }); 215 216 // Handler: mouseleave, focusout 217 $(openelement).on('mouseleave', function (event) { 218 methods.hide(el); 219 }); 220 221 } else { 222 223 // Handler: Show popup when clicked on `open` element 224 $(document).on('click', openelement, function (event) { 225 event.preventDefault(); 226 227 var ord = $(this).data('popup-ordinal'); 228 setTimeout(function() { // setTimeout is to allow `close` method to finish (for issues with multiple tooltips) 229 methods.show(el, ord); 230 }, 0); 231 }); 232 } 233 234 if (options.detach) { 235 $el.hide().detach(); 236 } else { 237 $wrapper.hide(); 238 } 239 }, 240 241 /** 242 * Show method 243 * 244 * @param {object} el - popup instance DOM node 245 * @param {number} ordinal - order number of an `open` element 246 */ 247 show: function (el, ordinal) { 248 var $el = $(el); 249 250 if ($el.data('popup-visible')) return; 251 252 // Initialize if not initialized. Required for: $('#popup').popup('show') 253 if (!$el.data('popup-initialized')) { 254 methods._init(el); 255 } 256 $el.attr('data-popup-initialized', 'true'); 257 258 var $body = $('body'); 259 var options = $el.data('popupoptions'); 260 var $wrapper = $('#' + el.id + '_wrapper'); 261 var $background = $('#' + el.id + '_background'); 262 263 // `beforeopen` callback event 264 callback(el, ordinal, options.beforeopen); 265 266 // Remember last clicked place 267 lastclicked[el.id] = ordinal; 268 269 // Add popup id to popup stack 270 setTimeout(function() {
271 stack.push(el.id); 272 }, 0); 273 274 // Calculating maximum z-index 275 if (options.autozindex) { 276 277 var elements = document.getElementsByTagName('*'); 278 var len = elements.length; 279 var maxzindex = 0; 280 281 for(var i=0; i<len; i++){ 282 283 var elementzindex = $(elements[i]).css('z-index'); 284 285 if(elementzindex !== 'auto'){ 286 287 elementzindex = parseInt(elementzindex, 10); 288 289 if(maxzindex < elementzindex){ 290 maxzindex = elementzindex; 291 } 292 } 293 } 294 295 zindexvalues[el.id] = maxzindex; 296 297 // Add z-index to the background 298 if (options.background) { 299 if (zindexvalues[el.id] > 0) { 300 $('#' + el.id + '_background').css({ 301 zIndex: (zindexvalues[el.id] + 1) 302 }); 303 } 304 } 305 306 // Add z-index to the wrapper 307 if (zindexvalues[el.id] > 0) { 308 $wrapper.css({ 309 zIndex: (zindexvalues[el.id] + 2) 310 }); 311 } 312 } 313 314 if (options.detach) { 315 $wrapper.prepend(el); 316 $el.show(); 317 } else { 318 $wrapper.show(); 319 } 320 321 opentimer = setTimeout(function() { 322 $wrapper.css({ 323 visibility: 'visible', 324 opacity: 1 325 }); 326 327 $('html').addClass('popup_visible').addClass('popup_visible_' + el.id); 328 $el.addClass('popup_content_visible'); 329 }, 20); // 20ms required for opening animation to occur in FF 330 331 // Disable background layer scrolling when popup is opened 332 if (options.scrolllock) { 333 $body.css('overflow', 'hidden'); 334 if ($body.height() > $window.height()) { 335 $body.css('margin-right', bodymarginright + scrollbarwidth); 336 } 337 } 338 339 if(options.backgroundactive){ 340 //calculates the vertical align 341 $el.css({ 342 top:( 343 $window.height() - ( 344 $el.get(0).offsetHeight + 345 parseInt($el.css('margin-top'), 10) + 346 parseInt($el.css('margin-bottom'), 10) 347 ) 348 )/2 +'px', 349 }); 350 } 351 352 $el.css({ 353 'visibility': 'visible', 354 'opacity': 1 355 }); 356 357 // Show background 358 if (options.background) { 359 $background.css({ 360 'visibility': 'visible', 361 'opacity': options.opacity 362 }); 363 364 // Fix IE8 issue with background not appearing 365 setTimeout(function() { 366 $background.css({ 367 'opacity': options.opacity 368 }); 369 }, 0); 370 } 371 372 $el.data('popup-visible', true); 373 374 // Position popup 375 methods.reposition(el, ordinal); 376 377 // Remember which element had focus before opening a popup 378 $el.data('focusedelementbeforepopup', document.activeElement); 379 380 // Handler: Keep focus inside dialog box 381 if (options.keepfocus) { 382 // Make holder div focusable 383 $el.attr('tabindex', -1); 384 385 // Focus popup or user specified element. 386 // Initial timeout of 50ms is set to give some time to popup to show after clicking on 387 // `open` element, and after animation is complete to prevent background scrolling. 388 setTimeout(function() { 389 if (options.focuselement === 'closebutton') { 390 $('#' + el.id + ' .' + el.id + closesuffix + ':first').focus(); 391 } else if (options.focuselement) { 392 $(options.focuselement).focus(); 393 } else { 394 $el.focus(); 395 } 396 }, options.focusdelay); 397 398 } 399 400 // Hide main content from screen readers 401 $(options.pagecontainer).attr('aria-hidden', true); 402 403 // Reveal popup content to screen readers 404 $el.attr('aria-hidden', false); 405 406 callback(el, ordinal, options.onopen); 407 408 if (transitionsupport) { 409 $wrapper.one('transitionend', function() { 410 callback(el, ordinal, options.opentransitionend); 411 }); 412 } else { 413 callback(el, ordinal, options.opentransitionend); 414 } 415 }, 416 417 /** 418 * Hide method 419 * 420 * @param {object} el - popup instance DOM node 421 */ 422 hide: function (el) { 423 if(opentimer) clearTimeout(opentimer); 424 425 var $body = $('body'); 426 var $el = $(el); 427 var options = $el.data('popupoptions'); 428 var $wrapper = $('#' + el.id + '_wrapper'); 429 var $background = $('#' + el.id + '_background'); 430 431 $el.data('popup-visible', false); 432 433 434 if (stack.length === 1) { 435 $('html').removeClass('popup_visible').removeClass('popup_visible_' + el.id); 436 } else { 437 if($('html').hasClass('popup_visible_' + el.id)) { 438 $('html').removeClass('popup_visible_' + el.id); 439 } 440 } 441 442 // Remove last opened popup from the stack 443 stack.pop(); 444 445 if($('html').hasClass('popup_content_visible')) { 446 $el.removeClass('popup_content_visible'); 447 } 448 449 if (options.keepfocus) { 450 // Focus back on saved element 451 setTimeout(function() { 452 if ($($el.data('focusedelementbeforepopup')).is(':visible')) { 453 $el.data('focusedelementbeforepopup').focus(); 454 } 455 }, 0); 456 } 457 458 // Hide popup 459 $wrapper.css({ 460 'visibility': 'hidden', 461 'opacity': 0 462 }); 463 $el.css({ 464 'visibility': 'hidden', 465 'opacity': 0 466 }); 467 468 // Hide background 469 if (options.background) { 470 $background.css({ 471 'visibility': 'hidden', 472 'opacity': 0 473 }); 474 } 475 476 // Reveal main content to screen readers 477 $(options.pagecontainer).attr('aria-hidden', false); 478 479 // Hide popup content from screen readers 480 $el.attr('aria-hidden', true); 481 482 // `onclose` callback event 483 callback(el, lastclicked[el.id], options.onclose); 484 485 if (transitionsupport && $el.css('transition-duration') !== '0s') { 486 $el.one('transitionend', function(e) { 487 488 if (!($el.data('popup-visible'))) { 489 if (options.detach) { 490 $el.hide().detach(); 491 } else { 492 $wrapper.hide(); 493 } 494 } 495 496 // Re-enable scrolling of background layer 497 if (options.scrolllock) { 498 setTimeout(function() { 499 $body.css({ 500 overflow: 'visible', 501 'margin-right': bodymarginright 502 }); 503 }, 10); // 10ms added for CSS transition in Firefox which doesn't like overflow:auto 504 } 505 506 callback(el, lastclicked[el.id], options.closetransitionend); 507 }); 508 } else { 509 if (options.detach) { 510 $el.hide().detach(); 511 } else { 512 $wrapper.hide(); 513 } 514 515 // Re-enable scrolling of background layer 516 if (options.scrolllock) { 517 setTimeout(function() { 518 $body.css({ 519 overflow: 'visible', 520 'margin-right': bodymarginright 521 }); 522 }, 10); // 10ms added for CSS transition in Firefox which doesn't like overflow:auto 523 } 524 525 callback(el, lastclicked[el.id], options.closetransitionend); 526 } 527 528 }, 529 530 /** 531 * Toggle method 532 * 533 * @param {object} el - popup instance DOM node 534 * @param {number} ordinal - order number of an `open` element 535 */ 536 toggle: function (el, ordinal) { 537 if ($(el).data('popup-visible')) { 538 methods.hide(el); 539 } else { 540 setTimeout(function() { 541 methods.show(el, ordinal); 542 }, 0); 543 } 544 }, 545 546 /** 547 * Reposition method 548 * 549 * @param {object} el - popup instance DOM node 550 * @param {number} ordinal - order number of an `open` element 551 */ 552 reposition: function (el, ordinal) { 553 var $el = $(el); 554 var options = $el.data('popupoptions'); 555 var $wrapper = $('#' + el.id + '_wrapper'); 556 var $background = $('#' + el.id + '_background'); 557 558 ordinal = ordinal || 0; 559 560 // Tooltip type 561 if (options.type == 'tooltip') { 562 $wrapper.css({ 563 'position': 'absolute' 564 }); 565 566 var $tooltipanchor; 567 if (options.tooltipanchor) { 568 $tooltipanchor = $(options.tooltipanchor); 569 } else if (options.openelement) { 570 $tooltipanchor = $(options.openelement).filter('[data-popup-ordinal="' + ordinal + '"]'); 571 } else { 572 $tooltipanchor = $('.' + el.id + opensuffix + '[data-popup-ordinal="' + ordinal + '"]'); 573 } 574 575 var linkOffset = $tooltipanchor.offset(); 576 577 // Horizontal position for tooltip 578 if (options.horizontal == 'right') { 579 $wrapper.css('left', linkOffset.left + $tooltipanchor.outerWidth() + options.offsetleft); 580 } else if (options.horizontal == 'leftedge') { 581 $wrapper.css('left', linkOffset.left + $tooltipanchor.outerWidth() - $tooltipanchor.outerWidth() + options.offsetleft); 582 } else if (options.horizontal == 'left') { 583 $wrapper.css('right', $window.width() - linkOffset.left - options.offsetleft); 584 } else if (options.horizontal == 'rightedge') { 585 $wrapper.css('right', $window.width() - linkOffset.left - $tooltipanchor.outerWidth() - options.offsetleft); 586 } else { 587 $wrapper.css('left', linkOffset.left + ($tooltipanchor.outerWidth() / 2) - ($el.outerWidth() / 2) - parseFloat($el.css('marginLeft')) + options.offsetleft); 588 } 589 590 // Vertical position for tooltip 591 if (options.vertical == 'bottom') { 592 $wrapper.css('top', linkOffset.top + $tooltipanchor.outerHeight() + options.offsettop); 593 } else if (options.vertical == 'bottomedge') { 594 $wrapper.css('top', linkOffset.top + $tooltipanchor.outerHeight() - $el.outerHeight() + options.offsettop); 595 }
595 else if (options.vertical == 'top') { 596 $wrapper.css('bottom', $window.height() - linkOffset.top - options.offsettop); 597 } else if (options.vertical == 'topedge') { 598 $wrapper.css('bottom', $window.height() - linkOffset.top - $el.outerHeight() - options.offsettop); 599 } else { 600 $wrapper.css('top', linkOffset.top + ($tooltipanchor.outerHeight() / 2) - ($el.outerHeight() / 2) - parseFloat($el.css('marginTop')) + options.offsettop); 601 } 602 603 // Overlay type 604 } else if (options.type == 'overlay') { 605 606 // Horizontal position for overlay 607 if (options.horizontal) { 608 $wrapper.css('text-align', options.horizontal); 609 } else { 610 $wrapper.css('text-align', 'center'); 611 } 612 613 // Vertical position for overlay 614 if (options.vertical) { 615 $el.css('vertical-align', options.vertical); 616 } else { 617 $el.css('vertical-align', 'middle'); 618 } 619 } 620 } 621 622 }; 623 624 /** 625 * Callback event calls 626 * 627 * @param {object} el - popup instance DOM node 628 * @param {number} ordinal - order number of an `open` element 629 * @param {function} func - callback function 630 */ 631 var callback = function (el, ordinal, func) { 632 var options = $(el).data('popupoptions'); 633 var openelement = (options.openelement) ? options.openelement : ('.' + el.id + opensuffix); 634 var elementclicked = $(openelement + '[data-popup-ordinal="' + ordinal + '"]'); 635 if (typeof func == 'function') { 636 func.call($(el), el, elementclicked); 637 } 638 }; 639 640 // Hide popup if ESC key is pressed 641 $(document).on('keydown', function (event) { 642 if(stack.length) { 643 var elementId = stack[stack.length - 1]; 644 var el = document.getElementById(elementId); 645 646 if ($(el).data('popupoptions').escape && event.keyCode == 27) { 647 methods.hide(el); 648 } 649 } 650 }); 651 652 // Hide popup on click 653 $(document).on('click', function (event) { 654 if(stack.length) { 655 var elementId = stack[stack.length - 1]; 656 var el = document.getElementById(elementId); 657 var closeButton = ($(el).data('popupoptions').closeelement) ? $(el).data('popupoptions').closeelement : ('.' + el.id + closesuffix); 658 659 // Click on Close button 660 if ($(event.target).closest(closeButton).length) { 661 event.preventDefault(); 662 methods.hide(el); 663 } 664 665 // Click outside of popup 666 if ($(el).data('popupoptions').blur && !$(event.target).closest('#' + elementId).length && event.which !== 2) { 667 668 methods.hide(el); 669 670 if ($(el).data('popupoptions').type === 'overlay') { 671 event.preventDefault(); // iOS will trigger click on the links below the overlay when clicked on the overlay if we don't prevent default action 672 } 673 } 674 } 675 }); 676 677 // Keep keyboard focus inside of popup 678 $(document).on('focusin', function(event) { 679 if(stack.length) { 680 var elementId = stack[stack.length - 1]; 681 var el = document.getElementById(elementId); 682 683 if ($(el).data('popupoptions').keepfocus) { 684 if (!el.contains(event.target)) { 685 event.stopPropagation(); 686 el.focus(); 687 } 688 } 689 } 690 }); 691 692 /** 693 * Plugin API 694 */ 695 $.fn.popup = function (customoptions) { 696 return this.each(function () { 697 698 $el = $(this); 699 700 if (typeof customoptions === 'object') { // e.g. $('#popup').popup({'color':'blue'}) 701 var opt = $.extend({}, $.fn.popup.defaults, customoptions); 702 $el.data('popupoptions', opt); 703 options = $el.data('popupoptions'); 704 705 methods._init(this); 706 707 } else if (typeof customoptions === 'string') { // e.g. $('#popup').popup('hide') 708 if (!($el.data('popupoptions'))) { 709 $el.data('popupoptions', $.fn.popup.defaults); 710 options = $el.data('popupoptions'); 711 } 712 713 methods[customoptions].call(this, this); 714 715 } else { // e.g. $('#popup').popup() 716 if (!($el.data('popupoptions'))) { 717 $el.data('popupoptions', $.fn.popup.defaults); 718 options = $el.data('popupoptions'); 719 } 720 721 methods._init(this); 722 723 } 724 725 }); 726 }; 727 728 $.fn.popup.defaults = { 729 type: 'overlay', 730 autoopen: false, 731 background: true, 732 backgroundactive: false, 733 color: 'black', 734 opacity: '0.5', 735 horizontal: 'center', 736 vertical: 'middle', 737 offsettop: 0, 738 offsetleft: 0, 739 escape: true, 740 blur: true, 741 setzindex: true,
742 autozindex: false, 743 scrolllock: false, 744 keepfocus: true, 745 focuselement: null, 746 focusdelay: 50, 747 outline: false, 748 pagecontainer: null, 749 detach: false, 750 openelement: null, 751 closeelement: null, 752 transition: null, 753 tooltipanchor: null, 754 beforeopen: null, 755 onclose: null, 756 onopen: null, 757 opentransitionend: null, 758 closetransitionend: null 759 }; 760 761})(jQuery);
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.