PageSourceSearch

https://www.laverdad.es/contentfactory/post/wp-content/themes/cms-native/js/baguetteBox.js?343

js laverdad.es collected 2026-09-24 06:24:05 UTC 28,123 bytes, 796 lines download raw bytes

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

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.