vendor: 2,436 bytes, lines 1-68
1/*! 2 * baguetteBox.js 3 * @author feimosi 4 * @version %%INJECT_VERSION%% 5 * @url https://github.com/feimosi/baguetteBox.js 6 */ 7 8/* global define, module */ 9 10(function (root, factory) { 11 'use strict'; 12 if (typeof define === 'function' && define.amd) { 13 define(factory); 14 } else if (typeof exports === 'object') { 15 module.exports = factory(); 16 } else { 17 root.baguetteBox = factory(); 18 } 19}(this, function () { 20 'use strict'; 21 22 // SVG shapes used on the buttons 23 var leftArrow = '<svg width="44" height="60">' + 24 '<polyline points="30 10 10 30 30 50" stroke="rgba(255,255,255,0.5)" stroke-width="4"' + 25 'stroke-linecap="butt" fill="none" stroke-linejoin="round"/>' + 26 '</svg>', 27 rightArrow = '<svg width="44" height="60">' + 28 '<polyline points="14 10 34 30 14 50" stroke="rgba(255,255,255,0.5)" stroke-width="4"' + 29 'stroke-linecap="butt" fill="none" stroke-linejoin="round"/>' + 30 '</svg>', 31 closeX = '<svg width="30" height="30">' + 32 '<g stroke="rgb(160,160,160)" stroke-width="4">' + 33 '<line x1="5" y1="5" x2="25" y2="25"/>' + 34 '<line x1="5" y1="25" x2="25" y2="5"/>' + 35 '</g></svg>'; 36 // Global options and their defaults 37 var options = {}, 38 defaults = { 39 captions: true, 40 buttons: 'auto', 41 fullScreen: false, 42 noScrollbars: false, 43 bodyClass: 'baguetteBox-open', 44 titleTag: false, 45 async: false, 46 preload: 2, 47 animation: 'slideIn', 48 afterShow: null, 49 afterHide: null, 50 onChange: null, 51 overlayBackgroundColor: 'rgba(0,0,0,.8)' 52 }; 53 // Object containing information about features compatibility 54 var supports = {}; 55 // DOM Elements references 56 var overlay, slider, previousButton, nextButton, closeButton; 57 // An array with all images in the current gallery 58 var currentGallery = []; 59 // Current image index inside the slider 60 var currentIndex = 0; 61 // Visibility of the overlay 62 var isOverlayVisible = false; 63 // Touch event start position (for slide gesture) 64 var touch = {}; 65 // If set to true ignore touch events because animation was already fired 66 var touchFlag = false; 67 // Regex pattern to match image files 68 var regex = /.+\.(gif|jpe?g|png|webp
vendor: 12,738 bytes, lines 68-401
68)/i; 69 // Object of all used galleries 70 var data = {}; 71 // Array containing temporary images DOM elements 72 var imagesElements = []; 73 // The last focused element before opening the overlay 74 var documentLastFocus = null; 75 var overlayClickHandler = function(event) { 76 // Close the overlay when user clicks directly on the background 77 if (event.target.id.indexOf('baguette-img') !== -1) { 78 hideOverlay(); 79 } 80 }; 81 var previousButtonClickHandler = function(event) { 82 event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // eslint-disable-line no-unused-expressions 83 showPreviousImage(); 84 }; 85 var nextButtonClickHandler = function(event) { 86 event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // eslint-disable-line no-unused-expressions 87 showNextImage(); 88 }; 89 var closeButtonClickHandler = function(event) { 90 event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // eslint-disable-line no-unused-expressions 91 hideOverlay(); 92 }; 93 var touchstartHandler = function(event) { 94 touch.count++; 95 if (touch.count > 1) { 96 touch.multitouch = true; 97 } 98 // Save x and y axis position 99 touch.startX = event.changedTouches[0].pageX; 100 touch.startY = event.changedTouches[0].pageY; 101 }; 102 var touchmoveHandler = function(event) { 103 // If action was already triggered or multitouch return 104 if (touchFlag || touch.multitouch) { 105 return; 106 } 107 event.preventDefault ? event.preventDefault() : event.returnValue = false; // eslint-disable-line no-unused-expressions 108 var touchEvent = event.touches[0] || event.changedTouches[0]; 109 // Move at least 40 pixels to trigger the action 110 if (touchEvent.pageX - touch.startX > 40) { 111 touchFlag = true; 112 showPreviousImage(); 113 } else if (touchEvent.pageX - touch.startX < -40) { 114 touchFlag = true; 115 showNextImage(); 116 // Move 100 pixels up to close the overlay 117 } else if (touch.startY - touchEvent.pageY > 100) { 118 hideOverlay(); 119 } 120 }; 121 var touchendHandler = function() { 122 touch.count--; 123 if (touch.count <= 0) { 124 touch.multitouch = false; 125 } 126 touchFlag = false; 127 }; 128 var contextmenuHandler = function() { 129 touchendHandler(); 130 }; 131 132 var trapFocusInsideOverlay = function(event) { 133 if (overlay.style.display === 'block' && (overlay.contains && !overlay.contains(event.target))) { 134 event.stopPropagation(); 135 initFocus(); 136 } 137 }; 138 139 // forEach polyfill for IE8 140 // http://stackoverflow.com/a/14827443/1077846 141 /* eslint-disable */ 142 if (![].forEach) { 143 Array.prototype.forEach = function(callback, thisArg) { 144 for (var i = 0; i < this.length; i++) { 145 callback.call(thisArg, this[i], i, this); 146 } 147 }; 148 } 149 150 // filter polyfill for IE8 151 // https://gist.github.com/eliperelman/1031656 152 if (![].filter) { 153 Array.prototype.filter = function(a, b, c, d, e) { 154 c = this; 155 d = []; 156 for (e = 0; e < c.length; e++) 157 a.call(b, c[e], e, c) && d.push(c[e]); 158 return d; 159 }; 160 } 161 /* eslint-enable */ 162 163 // Script entry point 164 function run(selector, userOptions) { 165 // Fill supports object 166 supports.transforms = testTransformsSupport(); 167 supports.svg = testSvgSupport(); 168 supports.passiveEvents = testPassiveEventsSupport(); 169 170 buildOverlay(); 171 removeFromCache(selector); 172 return bindImageClickListeners(selector, userOptions); 173 } 174 175 function bindImageClickListeners(selector, userOptions) { 176 // For each gallery bind a click event to every image inside it 177 var galleryNodeList = document.querySelectorAll(selector); 178 var selectorData = { 179 galleries: [], 180 nodeList: galleryNodeList 181 }; 182 data[selector] = selectorData; 183 184 [].forEach.call(galleryNodeList, function(galleryElement) { 185 if (userOptions && userOptions.filter) { 186 regex = userOptions.filter; 187 } 188 189 // Get nodes from gallery elements or single-element galleries 190 var tagsNodeList = []; 191 if (galleryElement.tagName === 'A') { 192 tagsNodeList = [galleryElement]; 193 } else { 194 tagsNodeList = galleryElement.getElementsByTagName('a'); 195 } 196 197 // Filter 'a' elements from those not linking to images 198 tagsNodeList = [].filter.call(tagsNodeList, function(element) { 199 if (element.className.indexOf(userOptions && userOptions.ignoreClass) === -1) { 200 return regex.test(element.href); 201 } 202 }); 203 if (tagsNodeList.length === 0) { 204 return; 205 } 206 207 var gallery = []; 208 [].forEach.call(tagsNodeList, function(imageElement, imageIndex) { 209 var imageElementClickHandler = function(event) { 210 event.preventDefault ? event.preventDefault() : event.returnValue = false; // eslint-disable-line no-unused-expressions 211 prepareOverlay(gallery, userOptions); 212 showOverlay(imageIndex); 213 }; 214 var imageItem = { 215 eventHandler: imageElementClickHandler, 216 imageElement: imageElement 217 }; 218 bind(imageElement, 'click', imageElementClickHandler); 219 gallery.push(imageItem); 220 }); 221 selectorData.galleries.push(gallery); 222 }); 223 224 return selectorData.galleries; 225 } 226 227 function clearCachedData() { 228 for (var selector in data) { 229 if (data.hasOwnProperty(selector)) { 230 removeFromCache(selector); 231 } 232 } 233 } 234 235 function removeFromCache(selector) { 236 if (!data.hasOwnProperty(selector)) { 237 return; 238 } 239 var galleries = data[selector].galleries; 240 [].forEach.call(galleries, function(gallery) { 241 [].forEach.call(gallery, function(imageItem) { 242 unbind(imageItem.imageElement, 'click', imageItem.eventHandler); 243 }); 244 245 if (currentGallery === gallery) { 246 currentGallery = []; 247 } 248 }); 249 250 delete data[selector]; 251 } 252 253 function buildOverlay() { 254 overlay = getByID('baguetteBox-overlay'); 255 // Check if the overlay already exists 256 if (overlay) { 257 slider = getByID('baguetteBox-slider'); 258 previousButton = getByID('previous-button'); 259 nextButton = getByID('next-button'); 260 closeButton = getByID('close-button'); 261 return; 262 } 263 // Create overlay element 264 overlay = create('div'); 265 overlay.setAttribute('role', 'dialog'); 266 overlay.id = 'baguetteBox-overlay'; 267 document.getElementsByTagName('body')[0].appendChild(overlay); 268 // Create gallery slider element 269 slider = create('div'); 270 slider.id = 'baguetteBox-slider'; 271 overlay.appendChild(slider); 272 // Create all necessary buttons 273 previousButton = create('button'); 274 previousButton.setAttribute('type', 'button'); 275 previousButton.id = 'previous-button'; 276 previousButton.setAttribute('aria-label', 'Previous'); 277 previousButton.innerHTML = supports.svg ? leftArrow : '<'; 278 overlay.appendChild(previousButton); 279 280 nextButton = create('button'); 281 nextButton.setAttribute('type', 'button'); 282 nextButton.id = 'next-button'; 283 nextButton.setAttribute('aria-label', 'Next'); 284 nextButton.innerHTML = supports.svg ? rightArrow : '>'; 285 overlay.appendChild(nextButton); 286 287 closeButton = create('button'); 288 closeButton.setAttribute('type', 'button'); 289 closeButton.id = 'close-button'; 290 closeButton.setAttribute('aria-label', 'Close'); 291 closeButton.innerHTML = supports.svg ? closeX : '×'; 292 overlay.appendChild(closeButton); 293 294 previousButton.className = nextButton.className = closeButton.className = 'baguetteBox-button'; 295 296 bindEvents(); 297 } 298 299 function keyDownHandler(event) { 300 switch (event.keyCode) { 301 case 37: // Left arrow 302 showPreviousImage(); 303 break; 304 case 39: // Right arrow 305 showNextImage(); 306 break; 307 case 27: // Esc 308 hideOverlay(); 309 break; 310 case 36: // Home 311 showFirstImage(event); 312 break; 313 case 35: // End 314 showLastImage(event); 315 break; 316 } 317 } 318 319 function bindEvents() { 320 var passiveEvent = supports.passiveEvents ? { passive: false } : null; 321 var nonPassiveEvent = supports.passiveEvents ? { passive: true } : null; 322 323 bind(overlay, 'click', overlayClickHandler); 324 bind(previousButton, 'click', previousButtonClickHandler); 325 bind(nextButton, 'click', nextButtonClickHandler); 326 bind(closeButton, 'click', closeButtonClickHandler); 327 bind(slider, 'contextmenu', contextmenuHandler); 328 bind(overlay, 'touchstart', touchstartHandler, nonPassiveEvent); 329 bind(overlay, 'touchmove', touchmoveHandler, passiveEvent); 330 bind(overlay, 'touchend', touchendHandler); 331 bind(document, 'focus', trapFocusInsideOverlay, true); 332 } 333 334 function unbindEvents() { 335 var passiveEvent = supports.passiveEvents ? { passive: false } : null; 336 var nonPassiveEvent = supports.passiveEvents ? { passive: true } : null; 337 338 unbind(overlay, 'click', overlayClickHandler); 339 unbind(previousButton, 'click', previousButtonClickHandler); 340 unbind(nextButton, 'click', nextButtonClickHandler); 341 unbind(closeButton, 'click', closeButtonClickHandler); 342 unbind(slider, 'contextmenu', contextmenuHandler); 343 unbind(overlay, 'touchstart', touchstartHandler, nonPassiveEvent); 344 unbind(overlay, 'touchmove', touchmoveHandler, passiveEvent); 345 unbind(overlay, 'touchend', touchendHandler); 346 unbind(document, 'focus', trapFocusInsideOverlay, true); 347 } 348 349 function prepareOverlay(gallery, userOptions) { 350 // If the same gallery is being opened prevent from loading it once again 351 if (currentGallery === gallery) { 352 return; 353 } 354 currentGallery = gallery; 355 // Update gallery specific options 356 setOptions(userOptions); 357 // Empty slider of previous contents (more effective than .innerHTML = "") 358 while (slider.firstChild) { 359 slider.removeChild(slider.firstChild); 360 } 361 imagesElements.length = 0; 362 363 var imagesFiguresIds = []; 364 var imagesCaptionsIds = []; 365 // Prepare and append images containers and populate figure and captions IDs arrays 366 for (var i = 0, fullImage; i < gallery.length; i++) { 367 fullImage = create('div'); 368 fullImage.className = 'full-image'; 369 fullImage.id = 'baguette-img-' + i; 370 imagesElements.push(fullImage); 371 372 imagesFiguresIds.push('baguetteBox-figure-' + i); 373 imagesCaptionsIds.push('baguetteBox-figcaption-' + i); 374 slider.appendChild(imagesElements[i]); 375 } 376 overlay.setAttribute('aria-labelledby', imagesFiguresIds.join(' ')); 377 overlay.setAttribute('aria-describedby', imagesCaptionsIds.join(' ')); 378 } 379 380 function setOptions(newOptions) { 381 if (!newOptions) { 382 newOptions = {}; 383 } 384 // Fill options object 385 for (var item in defaults) { 386 options[item] = defaults[item]; 387 if (typeof newOptions[item] !== 'undefined') { 388 options[item] = newOptions[item]; 389 } 390 } 391 /* Apply new options */ 392 // Change transition for proper animation 393 slider.style.transition = slider.style.webkitTransition = (options.animation === 'fadeIn' ? 'opacity .4s ease' : 394 options.animation === 'slideIn' ? '' : 'none'); 395 // Hide buttons if necessary 396 if (options.buttons === 'auto' && ('ontouchstart' in window || currentGallery.length === 1)) { 397 options.buttons = false; 398 } 399 // Set buttons style to hide or display them 400 previousButton.style.display = nextButton.style.display = (options.buttons ? '' : 'none'); 401 // Set
vendor: 12,720 bytes, lines 401-793
401overlay color 402 try { 403 overlay.style.backgroundColor = options.overlayBackgroundColor; 404 } catch (e) { 405 // Silence the error and continue 406 } 407 } 408 409 function showOverlay(chosenImageIndex) { 410 if (options.noScrollbars) { 411 document.documentElement.style.overflowY = 'hidden'; 412 document.body.style.overflowY = 'scroll'; 413 } 414 if (overlay.style.display === 'block') { 415 return; 416 } 417 418 bind(document, 'keydown', keyDownHandler); 419 currentIndex = chosenImageIndex; 420 touch = { 421 count: 0, 422 startX: null, 423 startY: null 424 }; 425 loadImage(currentIndex, function() { 426 preloadNext(currentIndex); 427 preloadPrev(currentIndex); 428 }); 429 430 updateOffset(); 431 overlay.style.display = 'block'; 432 if (options.fullScreen) { 433 enterFullScreen(); 434 } 435 // Fade in overlay 436 setTimeout(function() { 437 overlay.className = 'visible'; 438 if (options.bodyClass && document.body.classList) { 439 document.body.classList.add(options.bodyClass); 440 } 441 if (options.afterShow) { 442 options.afterShow(); 443 } 444 }, 50); 445 if (options.onChange) { 446 options.onChange(currentIndex, imagesElements.length); 447 } 448 documentLastFocus = document.activeElement; 449 initFocus(); 450 isOverlayVisible = true; 451 } 452 453 function initFocus() { 454 if (options.buttons) { 455 previousButton.focus(); 456 } else { 457 closeButton.focus(); 458 } 459 } 460 461 function enterFullScreen() { 462 if (overlay.requestFullscreen) { 463 overlay.requestFullscreen(); 464 } else if (overlay.webkitRequestFullscreen) { 465 overlay.webkitRequestFullscreen(); 466 } else if (overlay.mozRequestFullScreen) { 467 overlay.mozRequestFullScreen(); 468 } 469 } 470 471 function exitFullscreen() { 472 if (document.exitFullscreen) { 473 document.exitFullscreen(); 474 } else if (document.mozCancelFullScreen) { 475 document.mozCancelFullScreen(); 476 } else if (document.webkitExitFullscreen) { 477 document.webkitExitFullscreen(); 478 } 479 } 480 481 function hideOverlay() { 482 if (options.noScrollbars) { 483 document.documentElement.style.overflowY = 'auto'; 484 document.body.style.overflowY = 'auto'; 485 } 486 if (overlay.style.display === 'none') { 487 return; 488 } 489 490 unbind(document, 'keydown', keyDownHandler); 491 // Fade out and hide the overlay 492 overlay.className = ''; 493 setTimeout(function() { 494 overlay.style.display = 'none'; 495 if (document.fullscreen) { 496 exitFullscreen(); 497 } 498 if (options.bodyClass && document.body.classList) { 499 document.body.classList.remove(options.bodyClass); 500 } 501 if (options.afterHide) { 502 options.afterHide(); 503 } 504 documentLastFocus && documentLastFocus.focus(); 505 isOverlayVisible = false; 506 }, 500); 507 } 508 509 function loadImage(index, callback) { 510 var imageContainer = imagesElements[index]; 511 var galleryItem = currentGallery[index]; 512 513 // Return if the index exceeds prepared images in the overlay 514 // or if the current gallery has been changed / closed 515 if (typeof imageContainer === 'undefined' || typeof galleryItem === 'undefined') { 516 return; 517 } 518 519 // If image is already loaded run callback and return 520 if (imageContainer.getElementsByTagName('img')[0]) { 521 if (callback) { 522 callback(); 523 } 524 return; 525 } 526 527 // Get element reference, optional caption and source path 528 var imageElement = galleryItem.imageElement; 529 var thumbnailElement = imageElement.getElementsByTagName('img')[0]; 530 var imageCaption = typeof options.captions === 'function' ? 531 options.captions.call(currentGallery, imageElement) : 532 imageElement.getAttribute('data-caption') || imageElement.title; 533 var imageSrc = getImageSrc(imageElement); 534 535 // Prepare figure element 536 var figure = create('figure'); 537 figure.id = 'baguetteBox-figure-' + index; 538 figure.innerHTML = '<div class="baguetteBox-spinner">' + 539 '<div class="baguetteBox-double-bounce1"></div>' + 540 '<div class="baguetteBox-double-bounce2"></div>' + 541 '</div>'; 542 // Insert caption if available 543 if (options.captions && imageCaption) { 544 var figcaption = create('figcaption'); 545 figcaption.id = 'baguetteBox-figcaption-' + index; 546 figcaption.innerHTML = imageCaption; 547 figure.appendChild(figcaption); 548 } 549 imageContainer.appendChild(figure); 550 551 // Prepare gallery img element 552 var image = create('img'); 553 image.onload = function() { 554 // Remove loader element 555 var spinner = document.querySelector('#baguette-img-' + index + ' .baguetteBox-spinner'); 556 figure.removeChild(spinner); 557 if (!options.async && callback) { 558 callback(); 559 } 560 }; 561 image.setAttribute('src', imageSrc); 562 image.alt = thumbnailElement ? thumbnailElement.alt || '' : ''; 563 if (options.titleTag && imageCaption) { 564 image.title = imageCaption; 565 } 566 figure.appendChild(image); 567 568 // Run callback 569 if (options.async && callback) { 570 callback(); 571 } 572 } 573 574 // Get image source location, mostly used for responsive images 575 function getImageSrc(image) { 576 // Set default image path from href 577 var result = image.href; 578 // If dataset is supported find the most suitable image 579 if (image.dataset) { 580 var srcs = []; 581 // Get all possible image versions depending on the resolution 582 for (var item in image.dataset) { 583 if (item.substring(0, 3) === 'at-' && !isNaN(item.substring(3))) { 584 srcs[item.replace('at-', '')] = image.dataset[item]; 585 } 586 } 587 // Sort resolutions ascending 588 var keys = Object.keys(srcs).sort(function(a, b) { 589 return parseInt(a, 10) < parseInt(b, 10) ? -1 : 1; 590 }); 591 // Get real screen resolution 592 var width = window.innerWidth * window.devicePixelRatio; 593 // Find the first image bigger than or equal to the current width 594 var i = 0; 595 while (i < keys.length - 1 && keys[i] < width) { 596 i++; 597 } 598 result = srcs[keys[i]] || result; 599 } 600 return result; 601 } 602 603 // Return false at the right end of the gallery 604 function showNextImage() { 605 return show(currentIndex + 1); 606 } 607 608 // Return false at the left end of the gallery 609 function showPreviousImage() { 610 return show(currentIndex - 1); 611 } 612 613 // Return false at the left end of the gallery 614 function showFirstImage(event) { 615 if (event) { 616 event.preventDefault(); 617 } 618 return show(0); 619 } 620 621 // Return false at the right end of the gallery 622 function showLastImage(event) { 623 if (event) { 624 event.preventDefault(); 625 } 626 return show(currentGallery.length - 1); 627 } 628 629 /** 630 * Move the gallery to a specific index 631 * @param `index` {number} - the position of the image 632 * @param `gallery` {array} - gallery which should be opened, if omitted assumes the currently opened one 633 * @return {boolean} - true on success or false if the index is invalid 634 */ 635 function show(index, gallery) { 636 if (!isOverlayVisible && index >= 0 && index < gallery.length) { 637 prepareOverlay(gallery, options); 638 showOverlay(index); 639 return true; 640 } 641 if (index < 0) { 642 if (options.animation) { 643 bounceAnimation('left'); 644 } 645 return false; 646 } 647 if (index >= imagesElements.length) { 648 if (options.animation) { 649 bounceAnimation('right'); 650 } 651 return false; 652 } 653 654 currentIndex = index; 655 loadImage(currentIndex, function() { 656 preloadNext(currentIndex); 657 preloadPrev(currentIndex); 658 }); 659 updateOffset(); 660 661 if (options.onChange) { 662 options.onChange(currentIndex, imagesElements.length); 663 } 664 665 return true; 666 } 667 668 /** 669 * Triggers the bounce animation 670 * @param {('left'|'right')} direction - Direction of the movement 671 */ 672 function bounceAnimation(direction) { 673 slider.className = 'bounce-from-' + direction; 674 setTimeout(function() { 675 slider.className = ''; 676 }, 400); 677 } 678 679 function updateOffset() { 680 var offset = -currentIndex * 100 + '%'; 681 if (options.animation === 'fadeIn') { 682 slider.style.opacity = 0; 683 setTimeout(function() { 684 supports.transforms ? 685 slider.style.transform = slider.style.webkitTransform = 'translate3d(' + offset + ',0,0)' 686 : slider.style.left = offset; 687 slider.style.opacity = 1; 688 }, 400); 689 } else { 690 supports.transforms ? 691 slider.style.transform = slider.style.webkitTransform = 'translate3d(' + offset + ',0,0)' 692 : slider.style.left = offset; 693 } 694 } 695 696 // CSS 3D Transforms test 697 function testTransformsSupport() { 698 var div = create('div'); 699 return typeof div.style.perspective !== 'undefined' || typeof div.style.webkitPerspective !== 'undefined'; 700 } 701 702 // Inline SVG test 703 function testSvgSupport() { 704 var div = create('div'); 705 div.innerHTML = '<svg/>'; 706 return (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg'; 707 } 708 709 // Borrowed from https://github.com/seiyria/bootstrap-slider/pull/680/files 710 /* eslint-disable getter-return */ 711 function testPassiveEventsSupport() { 712 var passiveEvents = false; 713 try { 714 var opts = Object.defineProperty({}, 'passive', { 715 get: function() { 716 passiveEvents = true; 717 } 718 }); 719 window.addEventListener('test', null, opts); 720 } catch (e) { /* Silence the error and continue */ } 721 722 return passiveEvents; 723 } 724 /* eslint-enable getter-return */ 725 726 function preloadNext(index) { 727 if (index - currentIndex >= options.preload) { 728 return; 729 } 730 loadImage(index + 1, function() { 731 preloadNext(index + 1); 732 }); 733 } 734 735 function preloadPrev(index) { 736 if (currentIndex - index >= options.preload) { 737 return; 738 } 739 loadImage(index - 1, function() { 740 preloadPrev(index - 1); 741 }); 742 } 743 744 function bind(element, event, callback, options) { 745 if (element.addEventListener) { 746 element.addEventListener(event, callback, options); 747 } else { 748 // IE8 fallback 749 element.attachEvent('on' + event, function(event) { 750 // `event` and `event.target` are not provided in IE8 751 event = event || window.event; 752 event.target = event.target || event.srcElement; 753 callback(event); 754 }); 755 } 756 } 757 758 function unbind(element, event, callback, options) { 759 if (element.removeEventListener) { 760 element.removeEventListener(event, callback, options); 761 } else { 762 // IE8 fallback 763 element.detachEvent('on' + event, callback); 764 } 765 } 766 767 function getByID(id) { 768 return document.getElementById(id); 769 } 770 771 function create(element) { 772 return document.createElement(element); 773 } 774 775 function destroyPlugin() { 776 unbindEvents(); 777 clearCachedData(); 778 unbind(document, 'keydown', keyDownHandler); 779 document.getElementsByTagName('body')[0].removeChild(document.getElementById('baguetteBox-overlay')); 780 data = {}; 781 currentGallery = []; 782 currentIndex = 0; 783 } 784 785 return { 786 run: run, 787 show: show, 788 showNext: showNextImage, 789 showPrevious: showPreviousImage, 790 hide: hideOverlay, 791 destroy: destroyPlugin 792 }; 793}));
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.