1(function($) { 2 if (!$) throw 'MagicToolboxGallery: jQuery is not detected!'; 3 if ($.fn.MagicToolboxGallery) { return; } 4 5 var GALLERY_CLASS = 'MagicToolboxGallery'; 6 var MAIN_CONTAINER = 'MagicToolboxContainer'; 7 var SLIDES_CONTAINER = 'MagicToolboxMainContainer'; 8 var SELECTORS_CONTAINER = 'MagicToolboxSelectorsContainer'; 9 var ACTIVE_CLASS = 'mt-gallery-active'; 10 var PRIVATE_DATA_OPTIONS = 'data-mt-gallery-options'; 11 12 var OPTIONS = { startSlide: 0 }; 13 14 function detectSlide(index, node) { 15 var firstChild = $($(node)[0].firstChild), 16 result = { 17 index: index, 18 id: firstChild.attr('id') 19 }; 20 21 if (firstChild.hasClass('MagicZoom')) { // TODO 22 result.type = 'MagicZoom'; 23 } else if (firstChild.hasClass('MagicZoomPlus')) { 24 result.type = 'MagicZoomPlus'; 25 } 26 27 return result; 28 } 29 30 function getSelectorIndex(node, arr) { 31 var result = 0; 32 33 for (var i = 0; i < arr.length; i++) { 34 if (arr[i][0] === node) { 35 result = i; 36 break; 37 } 38 } 39 40 return result; 41 } 42 43 var SlideInstance = function (node, options) { 44 var self = this; 45 this.node = $(node); 46 this.node.addClass('mtb-gallery-slide'); 47 48 this.tool = $($(this.node)[0].firstChild); 49 50 this.options = $.extend({ 51 index: 0, 52 id: null, 53 type: null // null || MagicThumb || MagicZoom || MagicZoomPlus 54 }, options); 55 56 this.thumbUrl = { thumbnail: { url: null } }; 57 this.selectors = $([]); 58 this.isActive = false; 59 this.activeSelector = null; 60 this.selectorState = 0;
60 // 0 - not loded, 1 - loading, 2 - loaded 61 62 if (!this.options.type) { 63 if (this.tool[0].tagName.toLowerCase() === 'iframe') { 64 this.node.addClass('mt-gallery-video'); 65 } 66 } 67 68 this.mouseDownHandler = function (e) { 69 var element = $(this); 70 if (!self.options.type) { 71 e.stopPropagation(); 72 e.preventDefault(); 73 } 74 75 setTimeout(function() { 76 $(self).trigger('selectorAction', { 77 slideIndex: self.options.index, 78 selectorIndex: element.data('galleryIndex') 79 }); 80 }, 90); 81 }; 82 }; 83 84 SlideInstance.prototype = $.extend(SlideInstance.prototype, { 85 stopVideo: function() { 86 if (!this.options.type) { 87 var src = this.tool.attr('src'); 88 this.tool.attr('src', ''); 89 this.tool.attr('src', src); 90 } 91 }, 92 93 loadSelector: function (node) { 94 var self = this, img = null; 95 if (!this.options.type && !this.selectorState) { 96 try { 97 img = $(node).find('img')[0]; 98 } catch (e) {} 99 100 if (img) { 101 this.selectorState = 2; 102 this.thumbUrl.thumbnail.url = $(img).attr('src'); 103 } else { 104 this.selectorState = 1; 105 this.tool.MagicToolboxGalleryGetVideoImage(function(data) { 106 if (data) { self.thumbUrl = data } 107 self.selectorState = 2; 108 if (self.selectors.length) { 109 self.selectors.each(function(index, selector) { 110 self.setSelectorImage(selector); 111 }); 112 } 113 }, true); 114 } 115 } 116 }, 117 118 setSelectorImage: function (node) { 119 var img, attr, thumbName = 'thumbnail'; 120 node = $(node); 121 if (this.thumbUrl.thumbnail.url && !$(node).find('img').length) { 122 img = $('<img>'); 123 124 attr = node.attr('data-max-width'); 125 if (typeof attr !== typeof undefined && attr !== false) { 126 if (this.thumbUrl.medium) { 127 if (parseInt(attr) > this.thumbUrl.thumbnail.width) { thumbName = 'medium'; } 128 } 129 img.css('max-width', attr + 'px'); 130 } 131 132 attr = node.attr('data-max-height'); 133 if (typeof attr !== typeof undefined && attr !== false) { 134 img.css('max-height', attr + 'px'); 135 } 136 137 img.attr('src', this.thumbUrl[thumbName].url); 138 } 139 140 if (img) { node.append(img); } 141 }, 142 143 activateSlide: function (selectorIndex) { 144 if (!this.isActive) { 145 this.isActive = true; 146 this.node.addClass(ACTIVE_CLASS); 147 } 148 149 if (!this.activeSelector || !this.isSelectorActive(selectorIndex)) { 150 this.deactivateSlector(); 151 if (selectorIndex !== null) { 152 this.activateSlector(this.selectors[selectorIndex]); 153 } 154 } 155 }, 156 157 deactivateSlide: function () { 158 if (this.isActive) { 159 this.isActive = false; 160 this.node.removeClass(ACTIVE_CLASS); 161 this.stopVideo(); 162 this.deactivateSlector(); 163 } 164 }, 165 166 activateSlector: function (selector) { 167 if (!this.activeSelector) { 168 $(selector).addClass(ACTIVE_CLASS); 169 this.activeSelector = selector; 170 } 171 }, 172 173 deactivateSlector: function () { 174 if (this.activeSelector) { 175 this.activeSelector.removeClass(ACTIVE_CLASS); 176 this.activeSelector = null; 177 } 178 }, 179 180 isSelectorActive: function (selectorIndex) { 181 var result = false;
182 183 if (selectorIndex !== null && this.activeSelector) { 184 result = (this.activeSelector.data('galleryIndex') === selectorIndex); 185 } 186 187 return result; 188 }, 189 190 isSelectorFromHere: function (node) { 191 var result = false, id; 192 193 if (this.options.type) { 194 id = $(node).attr('data-zoom-id'); 195 } else { 196 id = $(node).attr('data-video-id') || $(node).attr('id'); 197 } 198 199 if (id === this.options.id) { 200 result = true; 201 } 202 203 return result; 204 }, 205 206 addSelector: function (node) { 207 var self = this; 208 node = $(node); 209 210 node.data('galleryIndex', this.selectors.length); 211 212 this.loadSelector(node); 213 this.setSelectorImage(node); 214 215 node.on('click', function (e) { 216 e.stopPropagation(); 217 e.preventDefault(); 218 }); 219 220 node[0].addEventListener('mousedown', this.mouseDownHandler, true); 221 222 this.selectors.push(node); 223 }, 224 225 detectStartSelector: function () { 226 var i, result = null, l = this.selectors.length; 227 228 if (l < 2 || !this.options.type) { 229 result = 0; 230 } else { 231 for (i = 0; i < l; i++) { 232 if (this.selectors[i].attr('href') === this.tool.attr('href')) { 233 result = i; 234 break; 235 } 236 } 237 } 238 239 return result; 240 }, 241 242 destroy: function () { 243 this.deactivateSlide(); 244 245 $(this.selectors).each(function(index, selector) { 246 $(selector).data('galleryIndex', null); 247 $(selector).off('click'); 248 $(selector)[0].removeEventListener('mousedown', this.mouseDownHandler, true); 249 }); 250 this.selectors = []; 251 } 252 }); 253 254 var Instance = function(node, options) { 255 var self = this, tmp; 256 257 this.options = $.extend({}, OPTIONS, options, $(node).attr(PRIVATE_DATA_OPTIONS) || {}); 258 this.slideNodes = $($(node).find('.' + SLIDES_CONTAINER)[0]).children(); 259 this.selectorsNodes = $(node).find('.' + SELECTORS_CONTAINER + ' div:first-child').children(); 260 261 // TODO 262 // tmp = $(node).find('.' + SELECTORS_CONTAINER + ' div:first-child'); 263 // if (tmp.hasClass('MagicScroll')) { 264 // this.selectorsNodes = tmp.find('.mcs-item'); 265 // } else { 266 // this.selectorsNodes = tmp.children(); 267 // } 268 269 if (!this.slideNodes.length) { 270 this.slideNodes = $(node).children().not('.' + SELECTORS_CONTAINER); 271 } 272 273 this.activeSlide = null; 274 275 this.slideInstances = this.slideNodes.map(function(index, node) { 276 var slide = new SlideInstance(node, detectSlide(index, node)); 277 278 $(slide).on('selectorAction', function (e, data) { 279 self.activateSlide(data.slideIndex, data.selectorIndex); 280 }); 281 282 return slide; 283 }); 284 285 this.selectorsNodes.each(function(index, selector) { 286 for (var i = 0; i < self.slideInstances.length; i++) { 287 if (self.slideInstances[i].isSelectorFromHere(selector)) { 288 self.slideInstances[i].addSelector(selector); 289 break; 290 } 291 } 292 }); 293 294 this.activateSlide(this.options.startSlide, this.slideInstances[this.options.startSlide].detectStartSelector()); 295 }; 296 297 Instance.prototype = $.extend(Instance.prototype, { 298 activateSlide: function (slideIndex, selectorIndex) { 299 var slide; 300 301 if ($.isNumeric(slideIndex)) { 302 slideIndex = parseInt(slideIndex); 303 if (slideIndex > -1 && slideIndex < this.slideInstances.length) { 304 slide = this.slideInstances[slideIndex]; 305 if ($.isNumeric(selectorIndex)) { 306 selectorIndex = parseInt(selectorIndex); 307 } else { 308 selectorIndex = null; 309 } 310 311 if (this.activeSlide !== slide || !this.activeSlide.isSelectorActive(selectorIndex)) { 312 if (this.activeSlide) { 313 this.activeSlide.deactivateSlide(); 314 } 315 slide.activateSlide(selectorIndex); 316 this.activeSlide = slide; 317 } 318 } 319 } 320 }, 321 322 destroy: function () { 323 this.slideInstances.each(function(index, slide) { 324 $(slide).off('selectorAction'); 325 slide.destroy(); 326 }); 327 } 328 }); 329 330 $.fn.MagicToolboxGallery = function (options) { 331 if (!options) { options = {}; } 332 333 return this.each(function() { 334 if (!$(this).data(GALLERY_CLASS)) { 335 $(this).data(GALLERY_CLASS, new Instance(this, options)); 336 } 337 338 return this; 339 }); 340 }; 341 342 $.fn.MagicToolboxGalleryDestroy = function () { 343 return this.each(function() { 344 if ($(this).data(GALLERY_CLASS)) { 345 $(this).data(GALLERY_CLASS).destroy(); 346 $(this).data(GALLERY_CLASS, null); 347 } 348 return this; 349 }); 350 }; 351 352 $.fn.MagicToolboxGalleryGetVideoImage = function (callback, getAll) { 353 var sources = {}; 354 355 var youtubeImgs = { 356 'thumb1': '1.jpg', // 120x90 357 'thumb2': '2.jpg', // 120x90 358 'thumb3': '3.jpg', // 120x90 359 'def0': '0.jpg', // 480x360 360 'def1': 'default.jpg', // 120x90 361 'middleQuality': 'mqdefault.jpg', // 320x180 362 'highQuality': 'hqdefault.jpg', // 480x360 363 'maxSize': 'maxresdefault.jpg' // 1920x1080 364 }; 365 366 function getType(str) { 367 var result = null, format; 368 369 if (/youtube/.test(str) || /youtu\.be/.test(str)) { 370 result = 'youtube'; 371 } else if (/vimeo/.test(str)){ 372 result = 'vimeo'; 373 } 374 375 return result; 376 } 377 378 function getYouTobeId(url) { 379 var result = null; 380 381 url = url.replace(/(>|<)/gi,'').split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); 382 if(url[2] !== undefined) { 383 url = url[2].split(/[^0-9a-z_\-]/i); 384 if (url.length && url[0]) { 385 result = url[0]; 386 } 387 } 388 389 return result; 390 } 391 392 function getVimeoId(url) { 393 var result = null; 394 395 url = url.match(/(?:https?:\/\/)?(?:www.)?(?:player.)?vimeo.com\/(?:[a-z]*\/)*([0-9]{6,11})[?]?.*/)[1]; 396 if (url) { result = url; } 397 398 return result; 399 } 400 401 function getSrc (url, cb) { 402 var type, thumbUrl = null, id, xhttp; 403 404 if (url) { 405 if (sources[url]) { 406 if (getAll) { 407 if (sources[url].all) { 408 cb(sources[url].all); 409 return; 410 } 411 } else { 412 if (sources[url].url) { 413 cb(sources[url].url); 414 return; 415 } else if (sources[url].all) { 416 cb(sources[url].all.thumbnail.url); 417 return; 418 } 419 } 420 } 421 type = getType(url); 422 if (type === 'youtube') { 423 id = getYouTobeId(url); 424 if (id) { 425 if (getAll) { 426 thumbUrl = { 427 thumbnail: { 428 url: 'https://img.youtube.com/vi/' + id + '/' + youtubeImgs.def1, 429 width: 120, 430 height: 90 431 }, 432 medium: { 433 url: 'https://img.youtube.com/vi/' + id + '/' + youtubeImgs.def0, 434 width: 480, 435 height: 360 436 } 437 }; 438 } else { 439 // thumbUrl = 'https://img.youtube.com/vi/' + id + '/' + youtubeImgs.thumb1; 440 thumbUrl = 'https://img.youtube.com/vi/' + id + '/' + youtubeImgs.def1; 441 } 442 } 443 if (!sources[url]) { sources[url] = {}; } 444 445 if (getAll) { 446 sources[url].all = thumbUrl; 447 } else { 448 sources[url].url = thumbUrl; 449 } 450 451 cb(thumbUrl); 452 } else { 453 id = getVimeoId(url); 454 if (id) { 455 thumbUrl = 'https://vimeo.com/api/v2/video/' + id + '.json'; 456 457 xhttp = new XMLHttpRequest(); 458 xhttp.open("GET", thumbUrl, true); 459 460 xhttp.onreadystatechange = function() { 461 var imgUrl = null, obj; 462 if (xhttp.readyState === 4) { 463 if (xhttp.status === 200) { 464 try { 465 if (getAll) { 466 obj = JSON.parse(xhttp.responseText)[0]; 467 imgUrl = { 468 thumbnail: { 469 url: obj.thumbnail_small, 470 width: 100, 471 height: 75 472 }, 473 medium: { 474 url: obj.thumbnail_medium, 475 width: 200, 476 height: 150 477 } 478 }; 479 } else { 480 imgUrl = (JSON.parse(xhttp.responseText)[0]).thumbnail_small; 481 } 482 } catch (e) {} 483 484 if (imgUrl) { 485 if (!sources[url]) { sources[url] = {}; } 486 487 if (getAll) { 488 sources[url].all = imgUrl; 489 } else { 490 sources[url].url = imgUrl; 491 } 492 } 493 494 cb(imgUrl); 495 } else { 496 cb(imgUrl); 497 } 498 } 499 }; 500 501 xhttp.send(true); 502 } else { 503 cb(thumbUrl); 504 } 505 } 506 } else { 507 cb(thumbUrl); 508 } 509 } 510 511 return this.each(function() { 512 if (this.tagName.toLowerCase() === 'iframe') { 513 getSrc($(this).attr('src'), function(thumbUrl) { callback(thumbUrl); }); 514 } else { 515 callback(null); 516 } 517 return this; 518 }); 519 }; 520 521 $(document).ready(function() { $('.MagicToolboxContainer.' + GALLERY_CLASS).MagicToolboxGallery(); }); 522})(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.