1(function(factory) { 2 3 if (typeof define === 'function' && define.amd) { 4 define(['jquery'], factory); 5 } else if (typeof module === 'object' && module.exports) { 6 module.exports = factory(require('jquery')); 7 } else { 8 factory(jQuery); 9 } 10 11}(function($) { 12 13 var instanceNum = 0, 14 $html = $('html'), 15 $document = $(document), 16 $window = $(window); 17 18 function SimpleLightbox(options) { 19 20 this.init.apply(this, arguments); 21 22 } 23 24 SimpleLightbox.defaults = { 25 26 // add custom classes to lightbox elements 27 elementClass: '', 28 elementLoadingClass: 'slbLoading', 29 htmlClass: 'slbActive', 30 closeBtnClass: '', 31 nextBtnClass: '', 32 prevBtnClass: '', 33 loadingTextClass: '', 34 35 // customize / localize controls captions 36 closeBtnCaption: 'Close', 37 nextBtnCaption: 'Next', 38 prevBtnCaption: 'Previous', 39 loadingCaption: 'Loading...', 40 41 bindToItems: true, // set click event handler to trigger lightbox on provided $items 42 closeOnOverlayClick: true, 43 closeOnEscapeKey: true, 44 nextOnImageClick: true, 45 showCaptions: true, 46 47 captionAttribute: 'title', // choose data source for library to glean image caption from 48 urlAttribute: 'href', // where to expect large image 49 50 startAt: 0, // start gallery at custom index 51 loadingTimeout: 100, // time after loading element will appear 52 53 appendTarget: 'body', // append elsewhere if needed 54 55 beforeSetContent: null, // convenient hooks for extending library behavoiur 56 beforeClose: null, 57 beforeDestroy: null, 58 59 videoRegex: new RegExp(/youtube.com|vimeo.com/) // regex which tests load url for iframe content 60 61 }; 62 63 $.extend(SimpleLightbox.prototype, { 64 65 init: function(options) { 66 67 this.options = $.extend({}, SimpleLightbox.defaults, options); 68 this.ens = '.slb' + (++instanceNum); 69 this.items = []; 70 this.captions = []; 71 72 var self = this; 73 74 if (this.options.$items) { 75 76 this.$items = this.options.$items; 77 78 this.$items.each(function() { 79 80 var $item = $(this); 81 82 self.items.push($item.attr(self.options.urlAttribute)); 83 self.captions.push($item.attr(self.options.captionAttribute)); 84 85 }); 86 87 this.options.bindToItems && this.$items.on('click' + this.ens, function(e) { 88 89 e.preventDefault(); 90 self.showPosition(self.$items.index($(e.currentTarget))); 91 92 }); 93 94 } else if (this.options.items) { 95 96 this.items = this.options.items; 97 98 } 99 100 if (this.options.captions) { 101 this.captions = this.options.captions; 102 } 103 104 }, 105 106 next: function() { 107 108 return this.showPosition(this.currentPosition + 1); 109 110 }, 111 112 prev: function() { 113 114 return this.showPosition(this.currentPosition - 1); 115 116 }, 117 118 normalizePosition: function(position) { 119 120 if (position >= this.items.length) { 121 position = 0; 122 } else if (position < 0) { 123 position = this.items.length - 1; 124 } 125 126 return position; 127 128 }, 129 130 showPosition: function(position) { 131 132 var self = this; 133 134 this.currentPosition = this.normalizePosition(position); 135 136 return this.setupLightboxHtml().prepareItem(this.currentPosition, this.setContent).show(); 137 138 }, 139 140 loading: function(on) { 141 142 var self = this; 143 144 if (on) { 145 146 this.loadingTimeout = setTimeout(function() { 147 148 self.$el.addClass(self.options.elementLoadingClass); 149 150 self.$content.html('<p class="slbLoadingText ' + self.options.loadingTextClass + '">' + self.options.loadingCaption + '</p>'); 151 self.show(); 152 153 }, this.options.loadingTimeout); 154 155 } else { 156 157 this.$el && this.$el.removeClass(this.options.elementLoadingClass); 158 clearTimeout(this.loadingTimeout); 159 160 } 161 162 }, 163 164 prepareItem: function(position, callback) { 165 166 var self = this, 167 url = this.items[position]; 168 169 this.loading(true); 170 171 if (this.options.videoRegex.test(url)) { 172 173 callback.call(self, $('<div class="slbIframeCont"><iframe class="slbIframe" frameborder="0" allowfullscreen src="' + url + '"></iframe></div>')); 174 175 } else { 176 177 var $imageCont = $('<div class="slbImageWrap"><img class="slbImage" src="' + url + '" /></div>'); 178 179 this.$currentImage = $imageCont.find('.slbImage'); 180 181 if (this.options.showCaptions && this.captions[position]) { 182 $imageCont.append('<div class="slbCaption">' + this.captions[position] + '</div>'); 183 } 184 185 this.loadImage(url, function() { 186 187 self.setImageDimensions(); 188 189 callback.call(self, $imageCont); 190 191 self.loadImage(self.items[self.normalizePosition(self.currentPosition + 1)]); 192 193 }); 194 195 } 196 197 return this; 198 199 }, 200 201 loadImage: function(url, callback) { 202 203 if (!this.options.videoRegex.test(url)) { 204 205 var image = new Image(); 206 callback && (image.onload = callback); 207 image.src = url; 208 209 } 210 211 }, 212 213 setupLightboxHtml: function() { 214 215 var o = this.options; 216 217 if (!this.$el) { 218 219 this.$el = $( 220 '<div class="slbElement ' + o.elementClass + '">' + 221 '<div class="slbOverlay"></div>' + 222 '<div class="slbWrapOuter">' + 223 '<div class="slbWrap">' + 224 '<div class="slbContentOuter">' + 225 '<div class="slbContent"></div>' + 226 '<button type="button" title="' + o.closeBtnCaption + '" class="slbCloseBtn ' + o.closeBtnClass + '">x</button>' + 227 '</div>' + 228 '</div>' + 229 '</div>' + 230 '</div>' 231 ); 232 233 if (this.items.length > 1) { 234 235 $( 236 '<div class="slbArrows">' + 237 '<button type="button" title="' + o.prevBtnCaption + '" class="prev slbArrow' + o.prevBtnClass + '">' + o.prevBtnCaption + '</button>' + 238 '<button type="button" title="' + o.nextBtnCaption + '" class="next slbArrow' + o.nextBtnClass + '">' + o.nextBtnCaption + '</button>' + 239 '</div>' 240 ).appendTo(this.$el.find('.slbContentOuter')); 241 242 } 243 244 this.$content = this.$el.find('.slbContent'); 245 246 } 247 248 this.$content.empty(); 249 250 return this; 251 252 }, 253 254 show: function() { 255 256 if (!this.modalInDom) { 257 258 this.$el.appendTo($(this.options.appendTarget)); 259 $html.addClass(this.options.htmlClass); 260 this.setupLightboxEvents(); 261 262 this.modalInDom = true; 263 264 } 265 266 return this; 267 268 }, 269 270 setContent: function(content) { 271 272 var $content = $(content); 273 274 this.loading(false); 275 276 this.setupLightboxHtml(); 277 this.options.beforeSetContent && this.options.beforeSetContent($content, this); 278 this.$content.html($content); 279 280 return this; 281 282 }, 283 284 setImageDimensions: function() { 285 286 this.$currentImage && this.$currentImage.css('max-height', $window.height() + 'px'); 287 288 }, 289 290 setupLightboxEvents: function() { 291 292 var self = this; 293 294 if (!this.lightboxEventsSetuped) { 295
296 this.$el.on('click' + this.ens, function(e) { 297 298 var $target = $(e.target); 299 300 if ($target.is('.slbCloseBtn') || (self.options.closeOnOverlayClick && $target.is('.slbWrap'))) { 301 302 self.close(); 303 304 } else if ($target.is('.slbArrow')) { 305 306 $target.hasClass('next') ? self.next() : self.prev(); 307 308 } else if (self.options.nextOnImageClick && self.items.length > 1 && $target.is('.slbImage')) { 309 310 self.next(); 311 312 } 313 314 }); 315 316 $document.on('keyup' + this.ens, function(e) { 317 318 self.options.closeOnEscapeKey && e.keyCode === 27 && self.close(); 319 320 if (self.items.length > 1) { 321 (e.keyCode === 39 || e.keyCode === 68) && self.next(); 322 (e.keyCode === 37 || e.keyCode === 65) && self.prev(); 323 } 324 325 }); 326 327 $window.on('resize' + this.ens, function() { 328 329 self.setImageDimensions(); 330 331 }); 332 333 this.lightboxEventsSetuped = true; 334 335 } 336 337 }, 338 339 close: function() { 340 341 if (this.modalInDom) { 342 343 this.options.beforeClose && this.options.beforeClose(this); 344 345 this.$el && this.$el.off(this.ens); 346 $document.off(this.ens); 347 $window.off(this.ens); 348 this.lightboxEventsSetuped = false; 349 350 this.$el.detach(); 351 $html.removeClass(this.options.htmlClass); 352 this.modalInDom = false; 353 } 354 355 }, 356 357 destroy: function() { 358 359 this.close(); 360 this.options.beforeDestroy && this.options.beforeDestroy(this); 361 this.$items && this.$items.off(this.ens); 362 this.$el && this.$el.remove(); 363 364 } 365 366 }); 367 368 SimpleLightbox.open = function(options) { 369 370 var instance = new SimpleLightbox(options); 371 372 return options.content ? instance.setContent(options.content).show() : instance.showPosition(instance.options.startAt); 373 374 }; 375 376 $.fn.simpleLightbox = function(options) { 377 378 var lightboxInstance, 379 $items = this; 380 381 return this.each(function() { 382 if (!$.data(this, 'simpleLightbox')) { 383 lightboxInstance = lightboxInstance || new SimpleLightbox($.extend({}, options, {$items: $items})); 384 $.data(this, 'simpleLightbox', lightboxInstance); 385 } 386 }); 387 388 }; 389 390 $.simpleLightbox = $.SimpleLightbox = SimpleLightbox; 391 392 return $; 393 394}));
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.