1 2/* ======================================================= 3 * 4 * Media Boxes 5 * Version: 2.6 6 * By David Blanco 7 * 8 * Contact: http://codecanyon.net/user/davidbo90 9 * Created: March 11, 2014 10 * 11 * Copyright (c) 2013, David Blanco. All rights reserved. 12 * Available only in http://codecanyon.net/ 13 * 14 * --------------------------------- 15 * CONTENTS 16 * --------------------------------- 17 * 18 * [1] SETUP 19 * [2] GRID METHODS 20 * [3] EXTENGIN ISOTOPE 21 * [4] FILTERING ISOTOPE 22 * [5] LOAD MORE BOXES 23 * [6] FILTER 24 * [7] SEARCH 25 * [8] SORT 26 * [9] THUMBNAIL OVERLAY EFFECT 27 * [10] MAGNIFIC POPUP 28 * [11] DEEP LINKING 29 * [12] SOCIAL IN MAGNIFIC POPUP 30 * 31 * ======================================================= */ 32 33 34// convert divs into images 35(function( window, $, undefined ){ 36 37 var MediaBoxes = function(container, options){ 38 39 /* ====================================================================== * 40 [1] SETUP 41 * ====================================================================== */ 42 43 /* SETTINGS */ 44 var settings = $.extend({}, $.fn.mediaBoxes.defaults, options); 45 46 /* VARS */ 47 var $container = $(container).addClass('media-boxes-container'); 48 var itemSelector = '.media-box'; 49 var boxImageSelector = '.media-box-image'; 50 var itemClass = 'media-box'; /* same as itemSelector but without the '.' */ 51 var itemHiddenClass = 'media-box-hidden'; 52 var animation = Modernizr.csstransitions?'transition':'animate'; /* CSS3 transition or jQuery animate depending on the browser support */ 53 var filters = {}; 54 var loadingsCounter = 0; /* When there's more than one loading at the same time */ 55 56 if( settings.overlayEasing == 'default' ){ 57 settings.overlayEasing = (animation=='transition')?'_default':'swing'; /* 'default' is for CSS3 and 'swing' for jQuery animate */ 58 } 59 60 /* LOAD MORE BUTTON */ 61 var loadMoreButton = $('<div class="media-boxes-load-more media-boxes-load-more-button"></div>').insertAfter($container); 62 63 /* Sort the resolutions from lower to higher */ 64 settings.resolutions.sort(function(a,b){ return a.maxWidth - b.maxWidth; }); 65 66 /* Save the settings in the container */ 67 $container.data('settings', settings); 68 69 /* Fix the margins for the container (for horizontal and vertical space) */ 70 $container 71 .css({ 72 'margin-left' : -settings.horizontalSpaceBetweenBoxes, 73 //'margin-top' : -settings.verticalSpaceBetweenBoxes, 74 }); 75 76 /* Hide all boxes */ 77 $container.find(itemSelector).removeClass(itemClass).addClass(itemHiddenClass); 78 79 /* default sort selected */ 80 var defSortElem = $(settings.sortContainer).find(settings.sort).filter('.selected'); 81 var defSort = defSortElem.attr('data-sort-by'); 82 var defAsc = getSortDirection(defSortElem); 83 84 /* Add the sizer for defining the width of isotope */ 85 $container.append('<div class="media-boxes-grid-sizer"></div>'); 86 87 /* Initialize isotope plugin */ 88 $container.isotopeMB({ 89 itemSelector : itemSelector, 90 //transitionDuration: '0.3s', 91 //filter: combineFilters(filters), 92 masonry: { 93 columnWidth: '.media-boxes-grid-sizer' 94 }, 95 getSortData: settings.getSortData, 96 sortBy: defSort, 97 sortAscending: defAsc, 98 }); 99 100 //updateFilterClasses(); /* this is used for the popup, so it does show the images depending on the filter */ 101 102 /* ====================================================================== * 103 [2] GRID METHODS 104 * ====================================================================== */ 105 106 /* ****** Add the trigger for the magnific popup ****** */ 107 function addPopupTrigger(container){ 108 109 container.find(itemSelector+', .'+itemHiddenClass).find(boxImageSelector+':not([data-popupTrigger])').each(function(){ 110 var boxImage = $(this); 111 var popupDiv = boxImage.find('div[data-popup]').eq(0); /* only one popup allowed */ 112 113 boxImage.attr('data-popupTrigger', 'yes'); 114 115 var type = 'mfp-image'; 116 if(popupDiv.data('type') == 'iframe'){ 117 type = 'mfp-iframe'; 118 }else if(popupDiv.data('type') == 'inline'){ 119 type = 'mfp-inline'; 120 }else if(popupDiv.data('type') == 'ajax'){ 121 type = 'mfp-ajax'; 122 } 123 124 var popupTrigger = boxImage.find('.mb-open-popup').addBack('.mb-open-popup'); 125 popupTrigger.attr('data-mfp-src', popupDiv.data('popup')).addClass(type); 126 if(popupDiv.attr('title') != undefined){ 127 popupTrigger.attr('mfp-title', popupDiv.attr('title')); 128 } 129 }); 130 131 } 132 133 /* ****** Convert the divs with the URL specified to real images ****** */ 134 function convertDivsIntoImages(container, imagesWithDimensions){ 135 container.find(itemSelector).find(boxImageSelector+':not([data-imageconverted])').each(function(){ 136 var boxImage = $(this); 137 var thumbnailDiv = boxImage.find('div[data-thumbnail]').eq(0); /* only one thumb allowed */ 138 var popupDiv = boxImage.find('div[data-popup]').eq(0); /* only one popup allowed */ 139 var thumbSrc = thumbnailDiv.data('thumbnail'); 140 141 if(thumbnailDiv[0] == undefined){ /* if you haven't sepcified a thumbnail then take the image */ 142 thumbnailDiv = popupDiv; 143 thumbSrc = popupDiv.data('popup'); 144 } 145 146 if( imagesWithDimensions == false && container.data('settings').waitForAllThumbsNoMatterWhat == false ){ 147 if( thumbnailDiv.data('width') == undefined && thumbnailDiv.data('height') == undefined ){ 148 /* Then we are good to go since we don't want images with dimenssions specified */ 149 }else{ 150 return; 151 /* If you are here then nothing after this will be executed */ 152 } 153 } 154 155 boxImage.attr('data-imageconverted', 'yes'); 156 157 var thumbTitle = thumbnailDiv.attr('title'); 158 if(thumbTitle == undefined){ 159 thumbTitle = thumbSrc; 160 } 161 var imgHTML = $('<img title="'+ thumbTitle +'" src="'+ thumbSrc +'" />'); 162 163 if(imagesWithDimensions == true){ 164 /* If the dmienssions are specified in the images then ignore them in the imagesLoaded plugin when you insert new items */ 165 imgHTML.attr('data-dont-wait-for-me', 'yes'); 166 167 thumbnailDiv.addClass('image-with-dimensions'); 168 169 if( container.data('settings').waitUntilThumbLoads ){ 170 imgHTML.hide(); 171 } 172 } 173
174 thumbnailDiv.addClass('media-box-thumbnail-container').prepend(imgHTML); 175 }); 176 177 if(imagesWithDimensions == true){ 178 179 /* FadeIn the thumbnail or show broken thumbnail */ 180 function fadeInOrBroken(image){ 181 var $image = $(image.img); 182 var thumbnailDiv = $image.parents('.image-with-dimensions'); 183 184 if(thumbnailDiv[0] == undefined){ /* If is undefined it means that it has already been loaded or broken so skip it */ 185 return; 186 } 187 188 if( image.isLoaded ){ 189 $image.fadeIn(400, function(){ /* This will only be trigger if you hide the image above (if the "waitUntilThumbLoads" settings is true) */ 190 thumbnailDiv.removeClass('image-with-dimensions'); 191 }); 192 }else{ 193 thumbnailDiv.removeClass('image-with-dimensions'); 194 $image.hide(); /* hide image since you are going to show a broken logo */ 195 thumbnailDiv.addClass('broken-image-here'); 196 } 197 } 198 199 /* FadeIn thumbnails that have dimensions specified if you want to show them after they have been loaded */ 200 container.find('.image-with-dimensions').imagesLoadedMB() 201 .always(function(instance){ 202 203 /* In case the progress event don't get to show the images (this happens sometimes when you refresh the page) */ 204 for(index in instance.images){ 205 var image = instance.images[index]; 206 fadeInOrBroken(image); 207 } 208 209 }) 210 .progress(function(instance, image) { 211 212 fadeInOrBroken(image); 213 214 }); 215 216 } 217 218 } 219 220 function setDimensionsToImageContainer(container){ 221 container.find(itemSelector).each(function(){ 222 var box = $(this); 223 224 var boxImage = box.find(boxImageSelector); 225 var thumbnailDiv = boxImage.find('div[data-thumbnail]').eq(0); /* only one thumb allowed */ 226 var popupDiv = boxImage.find('div[data-popup]').eq(0); /* only one popup allowed */ 227 228 if(thumbnailDiv[0] == undefined){ /* if you haven't sepcified a thumbnail then take the image */ 229 thumbnailDiv = popupDiv; 230 } 231 232 var display = box.css('display'); 233 if(display == 'none'){// If it is hidden, display to 'none' wont give you the right height so you need to do this trick 234 box.css('margin-top', 99999999999999).show(); 235 } 236 237 boxImage.width( thumbnailDiv.width() ); 238 boxImage.height( thumbnailDiv.height() ); 239 240 if(display == 'none'){ 241 box.css('margin-top', 0).hide(); 242 } 243 }); 244 } 245 246 /* ****** Calculate the right dimensions for the thumbnails ****** */ 247 function setStaticDimensionsOfThumbnails(container){ 248 249 container.find(itemSelector).find(boxImageSelector).each(function(){ 250 var boxImage = $(this); 251 var thumbnailDiv = boxImage.find('div[data-thumbnail]').eq(0); /* only one thumb allowed */ 252 var popupDiv = boxImage.find('div[data-popup]').eq(0); /* only one popup allowed */ 253 254 if(thumbnailDiv[0] == undefined){ /* if you haven't sepcified a thumbnail then take the image */ 255 thumbnailDiv = popupDiv; 256 } 257 258 var imgWidth = parseFloat( thumbnailDiv.data('width') ); 259 var imgHeight = parseFloat( thumbnailDiv.data('height') ); 260 261 var newWidth = boxImage.parents(itemSelector).width() - container.data('settings').horizontalSpaceBetweenBoxes; 262 var newHeight = (imgHeight * newWidth)/imgWidth; 263 264 thumbnailDiv.css('width', newWidth); 265 266 /* Set the height only to those thumbs with width and height specified */ 267 if( thumbnailDiv.data('width') != undefined || thumbnailDiv.data('height') != undefined ){ 268 thumbnailDiv.css('height', Math.floor(newHeight)); 269 } 270 }); 271 272 } 273 274 /* ****** Set the width of the columns according to the settings specified ****** */ 275 function setColumnWidth(container, columnWidth, columns){ 276 var mediaBoxes = container.find(itemSelector); 277 var newWidth; 278 var percentage = false;
279 280 if( columnWidth == 'auto' ){ 281 if(percentage){ 282 newWidth = 100/columns+'%'; 283 }else{ 284 newWidth = Math.floor( (container.width()-1)/columns ); // minus 1px because some resolutions don't fit perfectly 285 } 286 }else{ 287 newWidth = columnWidth; 288 } 289 290 /* the width that the isotope logic will use for each column of the grid */ 291 container.find('.media-boxes-grid-sizer').css( 'width' , newWidth ); 292 293 mediaBoxes.each(function(index){ 294 var $this = $(this); 295 var boxColumns = $this.data('columns'); 296 297 /* check for the number of columns on each box */ 298 if(boxColumns != undefined && parseInt(columns)>=parseInt(boxColumns)){ 299 if(percentage){ 300 $this.css( 'width' , parseFloat(100/columns)*boxColumns+'%' ); 301 }else{ 302 $this.css( 'width' , newWidth*parseInt(boxColumns) ); 303 } 304 }else{ 305 if(percentage){ 306 $this.css( 'width' , 100/columns+'%' ); 307 }else{ 308 $this.css( 'width' , newWidth ); 309 } 310 } 311 }); 312 } 313 314 /* ****** Get viewport dimensions ****** */ 315 function viewport() { 316 var e = window, a = 'inner'; 317 if (!('innerWidth' in window )) { 318 a = 'client'; 319 e = document.documentElement || document.body; 320 } 321 return { width : e[ a+'Width' ] , height : e[ a+'Height' ] }; 322 } 323 324 /* ****** Get and set the correct columnWidth for the current resolution ****** */ 325 function getAndSetColumnWidth(container){ 326 var resolutionFound = false; 327 for (var key in container.data('settings').resolutions) { 328 var value = container.data('settings').resolutions[key]; 329 330 if( value.maxWidth >= viewport().width ){ 331 setColumnWidth(container, value.columnWidth, value.columns); 332 resolutionFound = true; 333 break; 334 } 335 } 336 337 /* If there wasn't a match then use the default one */ 338 if( resolutionFound == false ){ 339 setColumnWidth(container, container.data('settings').columnWidth, container.data('settings').columns); 340 } 341 } 342 343 /* ****** Add div with margins (for horizontal and vertical space) ****** */ 344 function addWrapperForMargins(container){ 345 var wrapper = $('<div class="media-box-container"></div') 346 .css({ 347 'margin-left' : container.data('settings').horizontalSpaceBetweenBoxes, 348 'margin-bottom' : container.data('settings').verticalSpaceBetweenBoxes 349 }); 350 351 var boxes = container.find(itemSelector+':not([data-wrapper-added])').attr('data-wrapper-added', 'yes'); 352 353 boxes.wrapInner( wrapper ); 354 } 355 356 /* ****** Set the overlay depending on the overlay effect before the hover event is trigger ****** */ 357 function setupOverlayForHoverEffect(container){ 358 if( container.data('settings').thumbnailOverlay == false ) return; 359 360 var boxes = container.find(itemSelector+':not([data-set-overlay-for-hover-effect])').attr('data-set-overlay-for-hover-effect', 'yes'); 361 362 /* Add extra divs for vertical aliognment */ 363 boxes.find('.thumbnail-overlay').wrapInner( "<div class='aligment'><div class='aligment'></div></div>" ); 364 365 boxes.each(function(){ 366 367 var box = $(this); 368 var boxImage = box.find(boxImageSelector); 369 var effect = container.data('settings').overlayEffect; 370 if(boxImage.data('overlay-effect') != undefined){ 371 effect = boxImage.data('overlay-effect'); 372 } 373 374 /* Add wrapper for some effects */ 375 if( effect == 'push-up' || effect == 'push-down' || effect == 'push-up-100%' || effect == 'push-down-100%' ){ 376 377 var thumbnailDiv = boxImage.find('.media-box-thumbn
377ail-container'); 378 var thumbnailOverlay = boxImage.find('.thumbnail-overlay').css('position', 'relative'); 379 if( effect == 'push-up-100%' || effect == 'push-down-100%' ){/* set the height of the overlay to the same of the thumbnail */ 380 thumbnailOverlay.outerHeight( thumbnailDiv.outerHeight(false) ); 381 } 382 var heightOverlay = thumbnailOverlay.outerHeight(false); 383 384 385 386 var wrapper = $('<div class="wrapper-for-some-effects"></div'); 387 388 if( effect == 'push-up' || effect == 'push-up-100%' ){ 389 thumbnailOverlay.appendTo(boxImage); 390 }else if( effect == 'push-down' || effect == 'push-down-100%' ){ 391 thumbnailOverlay.prependTo(boxImage); 392 wrapper.css('margin-top', -heightOverlay); 393 } 394 395 boxImage.wrapInner( wrapper ); 396 397 } 398 /* Set some CSS style for this effects */ 399 else if( effect == 'reveal-top' || effect == 'reveal-top-100%' ){ 400 401 box.addClass('position-reveal-effect'); 402 403 var overlay = box.find('.thumbnail-overlay').css('top', 0); 404 if( effect == 'reveal-top-100%' ){ 405 overlay.css('height', '100%'); 406 } 407 408 }else if( effect == 'reveal-bottom' || effect == 'reveal-bottom-100%' ){ 409 410 box.addClass('position-reveal-effect').addClass('position-bottom-reveal-effect'); 411 412 var overlay = box.find('.thumbnail-overlay').css('bottom', 0); 413 if( effect == 'reveal-bottom-100%' ){ 414 overlay.css('height', '100%'); 415 } 416 417 }else if( effect.substr(0, 9) == 'direction'){ // 'direction-aware', 'direction-aware-fade', 'direction-right', 'direction-left', 'direction-top', 'direction-bottom' 418 419 /* Set the height to 100% if not it would be just the default height of the overlay */ 420 box.find('.thumbnail-overlay').css('height', '100%'); 421 422 }else if( effect == 'fade' ){ 423 424 var thumbOverlay = box.find('.thumbnail-overlay').hide(); 425 thumbOverlay.css({ 426 'height' : '100%', 427 'top' : '0', 428 'left' : '0', 429 }); 430 thumbOverlay.find('.fa').css({ scale : 1.4 }); 431 432 } 433 434 }); 435 436 } 437 438 function hideOverlaysOnResize(container){ 439 var boxes = container.find(itemSelector); 440 441 boxes.each(function(){ 442 var box = $(this); 443 var boxImage = box.find(boxImageSelector); 444 var effect = container.data('settings').overlayEffect; 445 if(boxImage.data('overlay-effect') != undefined){ 446 effect = boxImage.data('overlay-effect'); 447 } 448 449 if( effect.substr(0, 9) == 'direction' ){ 450 boxImage.find('.thumbnail-overlay').hide(); 451 } 452 }); 453 454 /* reload isotope for the new width */ 455 container.isotopeMB('layout'); 456 } 457 458 /* ====================================================================== * 459 [3] EXTENDING ISOTOPE 460 * ====================================================================== */ 461 462 /* ****** Extending Isotope on resize event ****** */ 463 $.extend( IsotopeMB.prototype, { 464 resize : function() { 465 /* Hack for setting the right sizes of the column */ 466 var container = $(this.element); 467 getAndSetColumnWidth(container); 468 setStaticDimensionsOfThumbnails(container); 469 setDimensionsToImageContainer(container); 470 hideOverlaysOnResize(container); 471 /* End hack */ 472
473 // don't trigger if size did not change 474 // or if resize was unbound. See #9 475 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 476 return; 477 } 478 479 this.layout(); 480 } 481 }); 482 483 /* ****** Extending Isotope so when it does set the container width the plugin can refresh the lazy load feature ****** */ 484 $.extend( IsotopeMB.prototype, { 485 _setContainerMeasure : function( measure, isWidth ) { 486 if ( measure === undefined ) { 487 return; 488 } 489 490 var elemSize = this.size; 491 // add padding and border width if border box 492 if ( elemSize.isBorderBox ) { 493 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 494 elemSize.borderLeftWidth + elemSize.borderRightWidth : 495 elemSize.paddingBottom + elemSize.paddingTop + 496 elemSize.borderTopWidth + elemSize.borderBottomWidth; 497 } 498 499 measure = Math.max( measure, 0 ); 500 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 501 502 /* Hack to refresh the waypoint */ 503 var container = $(this.element); 504 $.waypoints('refresh'); 505 container.addClass('lazy-load-ready'); 506 /* End hack */ 507 508 /* Remove this class since the grid has been resized due to the filtering system */ 509 container.removeClass('filtering-isotope'); 510 /* End Remove this class */ 511 } 512 }); 513 514 /* ****** Extending Isotope so when you insert items they got the right settings (like columnWidth, staticDimensions, convertDivsIntoImages, etc.) ****** */ 515 $.extend( IsotopeMB.prototype, { 516 insert : function( elems, callback ) { 517 var items = this.addItems( elems ); 518 if ( !items.length ) { 519 return; 520 } 521 522 /* Snippet (the insertBefore method so it is always ordered) */ 523 var container = $(this.element); 524 var firstHiddenBox = container.find('.'+itemHiddenClass)[0]; 525 // append item elements 526 var i, item; 527 var len = items.length; 528 for ( i=0; i < len; i++ ) { 529 item = items[i]; 530 if(firstHiddenBox != undefined){ 531 this.element.insertBefore( item.element, firstHiddenBox ); 532 }else{ 533 this.element.appendChild( item.element ); 534 } 535 } 536 /* End Snippet */ 537 538 var isotopeDefaultLogic = function(){ 539 // filter new stuff 540 /* 541 // this way adds hides new filtered items with NO transition 542 // so user can't see if new hidden items have been inserted 543 var filteredInsertItems; 544 this._noTransition( function() { 545 filteredInsertItems = this._filter( items ); 546 // hide all new items 547 this.hide( filteredInsertItems ); 548 }); 549 // */ 550 // this way hides new filtered items with transition 551 // so user at least sees that something has been added 552 var filteredInsertItems = this._filter( items ); 553 // hide all newitems 554 this._noTransition( function() { 555 this.hide( filteredInsertItems ); 556 }); 557 // */ 558 // set flag 559 for ( i=0; i < len; i++ ) { 560 items[i].isLayoutInstant = true; 561 } 562 this.arrange(); 563 // reset flag 564 for ( i=0; i < len; i++ ) { 565 delete items[i].isLayoutInstant; 566 } 567 this.reveal( filteredInsertItems ); 568 } 569 570 /* ======== Hack when inserting new boxes so they are properly converted ======== */ 571 var checkForBrokenImages = function(image){ 572 var $image = $(image.img); 573 var thumbnailDiv = $image.parents('div[data-thumbnail], div[data-popup]'); 574 575 if( image.isLoaded == false ){ 576 $image.hide(); 577 thumbnailDiv.addClass('broken-image-here'); 578 } 579 } 580 581 582 583 var instance = this; 584 585 /* Set the vertical and horizontal space between boxes */ 586 addWrapperForMargins(container); 587 588 /* Set the columnWidth and set the static dimensions of the images that have it specified */ 589 getAndSetColumnWidth(container); 590 setStaticDimensionsOfThumbnails(container); 591 592 addPopupTrigger(container); 593 594 convertDivsIntoImages(container, false); /* only the ones that have NO width and height */ 595 596 container.find('img:not([data-dont-wait-for-me])').imagesLoadedMB() 597 .always(function(){ 598 if( settings.waitForAllThumbsNoMatterWhat == false ){ 599 convertDivsIntoImages(container, true); /* the ones left that have width and height */ 600 } 601 602 /* Add the class to show the box */ 603 container.find(itemSelector).addClass('media-box-loaded'); 604 605 /* Now you can call the default logic of the insert method from Isotope */ 606 isotopeDefaultLogic.call(instance); 607 608 setDimensionsToImageContainer(container); /* set the same dimensions of the thumbnail to the container (for caption purposes) */ 609 610 setupOverlayForHoverEffect(container); 611 612 /* Callback for inserting items */ 613 if (typeof callback === 'function'){ 614 callback(); 615 } 616 617 /* In case the progress event don't get to check for broken images (this happens sometimes when you refresh the page) */ 618 for(index in instance.images){ 619 var image = instance.images[index]; 620 checkForBrokenImages(image); 621 } 622 }) 623 .progress(function( instance, image ) { 624 /* For broken images */ 625 checkForBrokenImages(image); 626 }); 627 628 /* ======== End Hack ======== */ 629 } 630 }); 631 632 /* ====================================================================== * 633 [4] FILTERING ISOTOPE 634 * ====================================================================== */ 635 636 function updateFilterClasses(){ 637 var boxes = $container.find(itemSelector+', .'+itemHiddenClass); 638 639 var filter = getCurrentFilter(); 640 boxes.filter( filter ).removeClass('hidden-media-boxes-by-filter').addClass('visible-media-boxes-by-filter'); 641 boxes.not( filter ).addClass('hidden-media-boxes-by-filter').removeClass('visible-media-boxes-by-filter'); 642 } 643 644 function filterTheBoxes( filterValue, filterGroup ){ 645 /* Add a class until it resizes the grid */ 646 $container.addClass('filtering-isotope'); 647 648 // Combined the filters and filter isotope 649 goAndFilterIsotope(filterValue, filterGroup); 650 651 // update some CSS classes 652 updateFilterClasses(); 653 654 // Fix some details, like the loading button, the minBoxesPerFilter 655 seeItFiltered(); 656 } 657 658 function seeItFiltered(){ 659 // fix load more button 660 if( getLoadingBoxesInCurrentFilter().length > 0 ){ 661 loading(); 662 }else{ 663 fixLoadMoreButton(); 664 } 665 666 if( checkMinBoxesPerFilter() ){ 667 /* it will load the missing boxes */ 668 } 669 } 670 671 function goAndFilterIsotope(filterValue, filterGroup){ 672 // set filter for group 673 filters[ filterGroup ] = filterValue; 674 675 // set filters for Isotope 676 $container.isotopeMB({ filter: combineFilters(filters) }); 677 } 678 679 function combineFilters( filters ) { 680 //Remove undefined values 681 for ( var prop in filters ) {
682 var filter = filters[ prop ]; 683 if(filter == undefined){ 684 filters[ prop ] = '*'; 685 } 686 } 687 688 var longerFilter = ''; // i.e. navigation-bar 689 for ( var prop in filters ) { 690 var filter = filters[ prop ]; 691 692 if(longerFilter == ''){ 693 longerFilter = prop; 694 }else if( longerFilter.split(',').length < filter.split(',').length ){ 695 longerFilter = prop; 696 } 697 } 698 699 var combinedFilters = filters[longerFilter]; // i.e. .images, .sounds 700 for ( var prop in filters ) { 701 if(prop == longerFilter)continue; 702 703 var filterSplit = filters[ prop ].split(','); 704 for(var i=0; i<filterSplit.length; i++){ 705 706 var largerFilterSplit = combinedFilters.split(','); 707 var newFilter = []; 708 for(var j=0; j<largerFilterSplit.length; j++){ 709 if(largerFilterSplit[j] == '*' && filterSplit[i] == '*'){ 710 filterSplit[i] = ''; 711 }else{ 712 if(filterSplit[i] == '*'){ 713 filterSplit[i] = ''; 714 } 715 if(largerFilterSplit[j] == '*'){ 716 largerFilterSplit[j] = ''; 717 } 718 } 719 720 721 newFilter.push( largerFilterSplit[j]+filterSplit[i] ); 722 } 723 combinedFilters = newFilter.join(','); 724 } 725 } 726 727 return combinedFilters; 728 } 729 730 /* ====================================================================== * 731 [5] LOAD MORE BOXES 732 * ====================================================================== */ 733 734 function checkMinBoxesPerFilter(){ 735 736 var boxesInCurrentCategory = getBoxesInCurrentFilter().length; 737 738 /* Also check if there's boxes waiting to get load from that category, because maybe there isn't and there's no case to try to load them */ 739 if( boxesInCurrentCategory < settings.minBoxesPerFilter && hiddenBoxesWaitingToLoad().length > 0 ){ 740 /* Load the boxes that are missing */ 741 loadMore( settings.minBoxesPerFilter - boxesInCurrentCategory ); 742 743 return true; 744 } 745 746 return false; 747 } 748 749 function getBoxesInCurrentFilter(){ 750 var boxes = $container.find(itemSelector); 751 var filter = getCurrentFilter(); 752 if( filter != '*' ){ 753 boxes = boxes.filter( filter ); 754 } 755 756 return boxes; 757 } 758 759 function getLoadingBoxesInCurrentFilter(){ 760 var boxes = getBoxesInCurrentFilter().not('.media-box-loaded'); 761 762 return boxes; 763 } 764 765 function getCurrentFilter(){ 766 var filter = $container.data('isotopeMB').options.filter; 767 if( filter == '' || filter == undefined ){ 768 filter = '*'; 769 } 770 771 return filter; 772 } 773 774 function hiddenBoxesWaitingToLoad(ignoreFilter){ /* Number of hidden boxes waiting to get load, depending on the filter */ 775 var boxes = $container.find('.'+itemHiddenClass); 776 777 var filter = getCurrentFilter(); 778 if( filter != '*' && ignoreFilter == undefined){ 779 boxes = boxes.filter( filter ); 780 } 781 782 return boxes; 783 } 784 785 function loading(){ 786 loadMoreButton.html(settings.LoadingWord); 787 loadMoreButton.removeClass('media-boxes-load-more'); 788 loadMoreButton.addClass('media-boxes-loading'); 789 } 790 791 function startLoading(){ 792 loadingsCounter++; 793 794 loading(); 795 } 796 797 function finishLoading(){ 798 loadingsCounter--; 799 if(loadingsCounter == 0){ 800 fixLoadMoreButton(); 801 } 802 } 803 804 function fixLoadMoreButton(){
805 loadMoreButton.removeClass('media-boxes-load-more'); 806 loadMoreButton.removeClass('media-boxes-loading'); 807 loadMoreButton.removeClass('media-boxes-no-more-entries'); 808 809 if( hiddenBoxesWaitingToLoad().length > 0 ){ 810 loadMoreButton.html(settings.loadMoreWord); 811 loadMoreButton.addClass('media-boxes-load-more'); 812 }else{ 813 loadMoreButton.html(settings.noMoreEntriesWord); 814 loadMoreButton.addClass('media-boxes-no-more-entries'); 815 } 816 } 817 818 function loadMore( boxesToLoad, ignoreFilter){ 819 if( loadMoreButton.hasClass('media-boxes-no-more-entries') == true ){ /* Only if it is the "load more" button or the "loading...", no the "no more entries" button */ 820 return; 821 } 822 823 /* Loading... */ 824 startLoading(); 825 826 /* The new boxes */ 827 var newBoxes = []; 828 829 /* Boxes that will be loaded as part of isotope */ 830 hiddenBoxesWaitingToLoad(ignoreFilter).each(function(index){ 831 var $this = $(this); 832 if( (index+1) <= boxesToLoad){ 833 $this.removeClass(itemHiddenClass).addClass(itemClass); 834 $this.hide(); 835 newBoxes.push(this); 836 } 837 }); 838 839 $container.isotopeMB( 'insert', $(newBoxes), function(){ 840 /* Fix Load More Button */ 841 finishLoading(); 842 843 /* Force a relayout of Isotope */ 844 $container.isotopeMB('layout'); 845 846 // == START CUSTOMIZATION REMEMBER: deepLinking:false , id of target1, target2 , hiddenStyle:{opacity:0,transform:"scale(0.001)"} 847 /*if(firstTime == true && location.hash.substr(0, 2) == '#-'){ 848 var hash = location.href.split('#-')[1]; 849 var scrollTo = $container.find('#'+hash); 850 851 if(scrollTo[0] != undefined){ 852 setTimeout(function(){ 853 $("body, html").animate({ 854 scrollTop: scrollTo.offset().top 855 }, 600); 856 }, 500); 857 } 858 }*/ 859 // == END CUSTOMIZATION 860 }); 861 } 862 loadMore( settings.boxesToLoadStart, true); 863 864 /* Load more boxes when you click the button */ 865 loadMoreButton.on('click', function(){ 866 loadMore( settings.boxesToLoad ); 867 }); 868 869 870 if( settings.lazyLoad ){ 871 872 /* Load more boxes when you reach the bottom of the grid */ 873 $container.waypoint(function(direction) { 874 if( $container.hasClass('lazy-load-ready') ){ 875 if( direction == 'down' && $container.hasClass('filtering-isotope') == false){ 876 $container.removeClass('lazy-load-ready'); 877 loadMore( settings.boxesToLoad ); 878 } 879 } 880 }, { 881 context: window, 882 continuous: true, 883 enabled: true, 884 horizontal: false, 885 offset: 'bottom-in-view', 886 triggerOnce: false, 887 }); 888 889 } 890 891 /* ====================================================================== * 892 [6] FILTER 893 * ====================================================================== */ 894 895 var filterContainer = $(settings.filterContainer); 896 897 filterContainer.find(settings.filter).on('click', function(e){ 898 var $this = $(this); 899 900 /* Remove selected class from others */ 901 var filterContainer = $this.parents(settings.filterContainer); 902 filterContainer.find(settings.filter).removeClass('selected'); 903 904 /* Add class of selected */ 905 $this.addClass('selected'); 906 907 /* Filter isotope */ 908 var filterValue = $this.attr('data-filter'); 909 var filterId = "filter"; 910 if (filterContainer.data("id") != undefined) { 911 filterId = filterContainer.data("id") 912 } 913 filterTheBoxes( filterValue , filterId ); 914 915 e.preventDefault(); 916 }); 917 918 /* DEFAULT FILTERS SELECTED */ 919 filterContainer.each(function(){ 920 var $this = $(this); 921 var f = $this.find(settings.filter).filter('.selected'); 922 if(f[0]==undefined)return; 923 924 /* Filter isotope */ 925 var filterValue = f.attr('data-filter'); 926 var filterId = "filter"; 927 if ($this.data("id") != undefined) { 928 filterId = $this.data("id") 929 } 930 931 //filters[ filterId ] = filterValue; 932 goAndFilterIsotope(filterValue, filterId); 933 }); 934 935 seeItFiltered(); 936
937 //var defFilter = filterContainer.find(settings.filter).filter('.selected').attr('data-filter'); 938 //filters[ 'filter' ] = defFilter; 939 940 /* default search selected */ 941 search( $(settings.search).val() ); 942 943 /* ====================================================================== * 944 [7] SEARCH 945 * ====================================================================== */ 946 947 function search(value){ 948 if(value == undefined) return; 949 950 var allBoxes = $container.find('.'+itemClass+', .'+itemHiddenClass); 951 if(value == ''){ 952 /* If there's nothing in the input text field then show all the boxes */ 953 allBoxes.addClass('search-match'); 954 }else{ 955 allBoxes.removeClass('search-match'); 956 957 $container.find(settings.searchTarget).each(function(){ 958 var $this = $(this); 959 var box = $this.parents('.'+itemClass+', .'+itemHiddenClass); 960 if( $this.text().toLowerCase().indexOf(value.toLowerCase()) !== -1 ){ 961 box.addClass('search-match'); 962 } 963 }); 964 } 965 966 setTimeout( function() { 967 filterTheBoxes('.search-match', 'search'); 968 }, 100 ); 969 } 970 971 $(settings.search).on('keyup', function(){ 972 var value = $(this).val(); 973 974 search( value ); 975 }); 976 977 /* ====================================================================== * 978 [8] SORTING 979 * ====================================================================== */ 980 981 function getSortDirection($this){ 982 var direction = $this.data('sort-ascending'); 983 if(direction == undefined){ 984 direction = true; 985 } 986 987 if($this.data('sort-toggle') && $this.data('sort-toggle') == true){ 988 $this.data('sort-ascending', !direction); 989 } 990 991 return direction; 992 } 993 994 $(settings.sortContainer).find(settings.sort).on('click', function(e){ 995 var $this = $(this); 996 997 /* Remove selected class from others */ 998 $this.parents(settings.sortContainer).find(settings.sort).removeClass('selected'); 999 1000 /* Add class of selected */ 1001 $this.addClass('selected'); 1002 1003 /* Sort isotope */ 1004 var sortValue = $this.attr('data-sort-by'); 1005 $container.isotopeMB({ sortBy: sortValue, sortAscending: getSortDirection($this) }); 1006 1007 e.preventDefault(); 1008 }); 1009 1010 1011 /* ====================================================================== * 1012 [9] THUMBNAIL OVERLAY EFFECT 1013 * ====================================================================== */ 1014 1015 function hideWhenDone(element){ 1016 if( element.attr('data-stop') != undefined ){ 1017 element.hide(); 1018 element.removeAttr('data-stop'); 1019 } 1020 } 1021 1022 $container.on( 'mouseenter.hoverdir, mouseleave.hoverdir', boxImageSelector, function(event){ 1023 if( settings.thumbnailOverlay == false ) return; 1024 1025 var boxImage = $(this); 1026 var effect = settings.overlayEffect; 1027 if(boxImage.data('overlay-effect') != undefined){ 1028 effect = boxImage.data('overlay-effect'); 1029 } 1030 1031 var eventType = event.type; 1032 var thumbnailDiv = boxImage.find('.media-box-thumbnail-container'); 1033 var thumbnailOverlay = boxImage.find('.thumbnail-overlay') ; 1034 var heightOverlay = thumbnailOverlay.outerHeight(false); 1035 1036 /* The effects */ 1037 if( effect == 'push-up' || effect == 'push-up-100%' ){ 1038 var wrapper = boxImage.find('div.wrapper-for-some-effects'); 1039 1040 if( eventType === 'mouseenter' ) { 1041 wrapper.stop().show()[animation]({ 'margin-top': -heightOverlay }, settings.overlaySpeed, settings.overlayEasing); 1042 }else{ 1043 wrapper.stop()[animation]({ 'margin-top': 0 }, settings.overlaySpeed, settings.overlayEasing); 1044 } 1045 } 1046 1047 else if( effect == 'push-down' || effect == 'push-down-100%' ){ 1048 var wrapper = boxImage.find('div.wrapper-for-some-effects'); 1049 1050 if( eventType === 'mouseenter' ) { 1051 wrapper.stop().show()[animation]({ 'margin-top': 0 }, settings.overlaySpeed, settings.overlayEasing); 1052 }else{ 1053 wrapper.stop()[animation]({ 'margin-top': -heightOverlay }, settings.overlaySpeed, settings.overlayEasing); 1054 } 1055 } 1056 1057 else if( effect == 'reveal-top' || effect == 'reveal-top-100%' ){ 1058 if( eventType === 'mouseenter' ) { 1059 thumbnailDiv.stop().show()[animation]({ 'margin-top': he
1059ightOverlay }, settings.overlaySpeed, settings.overlayEasing); 1060 }else{ 1061 thumbnailDiv.stop()[animation]({ 'margin-top': 0 }, settings.overlaySpeed, settings.overlayEasing); 1062 } 1063 } 1064 1065 else if( effect == 'reveal-bottom' || effect == 'reveal-bottom-100%' ){ 1066 if( eventType === 'mouseenter' ) { 1067 thumbnailDiv.stop().show()[animation]({ 'margin-top': -heightOverlay }, settings.overlaySpeed, settings.overlayEasing); 1068 }else{ 1069 thumbnailDiv.stop()[animation]({ 'margin-top': 0 }, settings.overlaySpeed, settings.overlayEasing); 1070 } 1071 } 1072 1073 else if( effect.substr(0, 9) == 'direction' ){ // 'direction-aware', 'direction-aware-fade', 'direction-right', 'direction-left', 'direction-top', 'direction-bottom' 1074 var direction = _getDir( boxImage, { x : event.pageX, y : event.pageY } ); 1075 1076 if( effect == 'direction-top' ){ 1077 direction = 0; 1078 }else if( effect == 'direction-bottom' ){ 1079 direction = 2; 1080 }else if( effect == 'direction-right' ){ 1081 direction = 1; 1082 }else if( effect == 'direction-left' ){ 1083 direction = 3 1084 } 1085 1086 var cssPos = _getPosition( direction, boxImage ); 1087 1088 if( eventType == 'mouseenter' ){ 1089 thumbnailOverlay.css( { 'left' : cssPos.from, 'top' : cssPos.to } ); 1090 1091 thumbnailOverlay.stop().show().fadeTo(0, 1, function(){ 1092 $(this).stop()[animation]({ 'left' : 0, 'top' : 0 }, settings.overlaySpeed, settings.overlayEasing); 1093 }); 1094 }else{ 1095 if( effect == 'direction-aware-fade' ){ 1096 thumbnailOverlay.fadeOut(700); 1097 }else{ 1098 thumbnailOverlay.stop()[animation]({ 'left' : cssPos.from, 'top' : cssPos.to }, settings.overlaySpeed, settings.overlayEasing ); 1099 } 1100 } 1101 } 1102 1103 else if( effect == 'fade' ){ 1104 1105 if( eventType == 'mouseenter' ){ 1106 thumbnailOverlay.stop().fadeOut(0); 1107 thumbnailOverlay.fadeIn( settings.overlaySpeed ); 1108 }else{ 1109 thumbnailOverlay.stop().fadeIn(0); 1110 thumbnailOverlay.fadeOut( settings.overlaySpeed ); 1111 } 1112 1113 /* Effect of the icons */ 1114 var icons = thumbnailOverlay.find('.fa'); 1115 if( eventType == 'mouseenter' ){ 1116 icons.css({ scale: 1.4 }); 1117 icons[animation]({ scale: 1 }, 200); 1118 }else{ 1119 icons.css({ scale: 1 }); 1120 icons[animation]({ scale: 1.4 }, 200); 1121 } 1122 } 1123 1124 1125 }); 1126 1127 1128 /* ****** Methods for the direction-aware hover effect ****** */ 1129 1130 var _getDir = function( $el, coordinates ) { 1131 /** the width and height of the current div **/ 1132 var w = $el.width(), 1133 h = $el.height(), 1134 1135 /** calculate the x and y to get an angle to the center of the div from that x and y. **/ 1136 /** gets the x value relative to the center of the DIV and "normalize" it **/ 1137 x = ( coordinates.x - $el.offset().left - ( w/2 )) * ( w > h ? ( h/w ) : 1 ), 1138 y = ( coordinates.y - $el.offset().top - ( h/2 )) * ( h > w ? ( w/h ) : 1 ), 1139 1140 /** the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123);**/ 1141 /** first calculate the angle of the point, 1142 add 180 deg to get rid of the negative values 1143 divide by 90 to get the quadrant 1144 add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/ 1145 direction = Math.round( ( ( ( Math.atan2(y, x) * (180 / Math.PI) ) + 180 ) / 90 ) + 3 ) % 4; 1146 1147 return direction; 1148 1149 }; 1150 1151 var _getPosition = function( direction, $el ) { 1152 var fromLeft, fromTop; 1153 switch( direction ) { 1154 case 0: 1155 // from top 1156 if ( !settings.reverse ) { 1157 fromLeft = 0, fromTop = - $el.height() 1158 }else { 1159 fromLeft = 0, fromTop = - $el.height() 1160 } 1161 break; 1162 case 1: 1163 // from right 1164 if ( !settings.reverse ) { 1165 fromLeft = $el.width() , fromTop = 0 1166 }else { 1167 fromLeft = - $el.width() , fromTop = 0 1168 } 1169 break; 1170 case 2: 1171 // from bottom 1172 if ( !settings.reverse ) { 1173 fromLeft = 0 , fromTop = $el.height() 1174 } 1175 else { 1176 fromLeft = 0, fromTop = - $el.height() 1177 } 1178 break; 1179 case 3: 1180 // from left 1181 if ( !settings.reverse ) { 1182 fromLeft = -$el.width() , fromTop = 0 1183 } 1184 else { 1185 fromLeft = $el.width(), fromTop = 0 1186 } 1187 break; 1188 }; 1189 return { from : fromLeft, to: fromTop }; 1190 }; 1191 1192 1193 /* ====================================================================== * 1194 [10] MAGNIFIC POPUP 1195 * ====================================================================== */ 1196 1197 var delegate = '.mb-open-popup[data-mfp-src]'; 1198 1199 if(settings.considerFilteringInPopup){ 1200 delegate = itemSelector+':not(.hidden-media-boxes-by-filter) .mb-open-popup[data-mfp-src], .'+itemHiddenClass+':not(.hidden-media-boxes-by-filter) .mb-open-popup[data-mfp-src]'; 1201 } 1202 if(settings.showOnlyLoadedBoxesInPopup){ 1203 delegate = itemSelector+':visible .mb-open-popup[data-mfp-src]'; 1204 } 1205 1206 if(settings.magnificPopup){ 1207 1208 $container.magnificPopup({ 1209 delegate: delegate, // child items selector, by clicking on it popup will open 1210 type: 'image', 1211 removalDelay : 200, 1212 closeOnContentClick : false, 1213 alignTop: settings.alignTop, 1214 preload: settings.preload, 1215 mainClass : 'my-mfp-slide-bottom', 1216 gallery:{ 1217 enabled:settings.gallery 1218 }, 1219 closeMarkup : '<button title="%title%" class="mfp-close"></button>', 1220 titleSrc: 'title', 1221 iframe : { 1222 patterns : { 1223 youtube: { 1224 index: 'youtube.com/', // String that detects type of video (in this case YouTube). Simply via url.indexOf(index). 1225 1226 id: 'v=', // String that splits URL in a two parts, second part should be %id% 1227 // Or null - full URL will be returned 1228 // Or a function that should return %id%, for example: 1229 // id: function(url) { return 'parsed id'; } 1230 1231 src: 'https://www.youtube.com/embed/%id%?autoplay=1' // URL that will be set as a source for iframe. 1232 }, 1233 vimeo: { 1234 index: 'vimeo.com/', 1235 id: '/', 1236 src: 'https://player.vimeo.com/video/%id%?autoplay=1' 1237 }, 1238 }, 1239 markup : '<div class="mfp-iframe-scaler">'+ 1240 '<div class="mfp-close"></div>'+ 1241 '<iframe class="mfp-iframe" frameborder="0" allowfullscreen></iframe>'+ 1242 '<div class="mfp-bottom-bar" style="margin-top:4px;"><div class="mfp-title"></div><div class="mfp-counter"></div></div>'+ 1243 '</div>' 1244 }, 1245 callbacks : { 1246 change : function() { 1247 var item = $(this.currItem.el); 1248 setTimeout(function(){ 1249 if(item.attr('mfp-title') != undefined){ 1250 $('.mfp-title').html(item.attr('mfp-title')); 1251 }else{ 1252 $('.mfp-title').html(''); 1253 } 1254 1255 // ==== SOCIAL BUTTONS ==== // 1256 1257 var FullURL = location.href; // the url of your page 1258 var URLWithoutHash = location.href.replace(location.hash,""); // the url of your page without the hashtag 1259 var imageURL = item.attr('data-mfp-src'); // the image URL 1260 1261 // which URL do you want to share of the 3 options above? 1262 var sharingURL = FullURL; 1263 1264 1265 var social = "<div class='media-boxes-social-container'>"; 1266 if(settings.facebook != undefined){//FB 1267 social+="<div class='media-boxes-facebook fa fa-facebook-square' data-url='"+sharingURL+"'></div>"; 1268 } 1269 if(settings.twitter != undefined){//Twitter 1270 social+="<div class='media-boxes-twitter fa fa-twitter-square' data-url='"+sharingURL+"'></div>"; 1271 } 1272 if(settings.googleplus != undefined){//Google+ 1273 social+="<div class='media-boxes-googleplus fa fa-google-plus-square' data-url='"+sharingURL+"'></div>"; 1274 } 1275 if(settings.pinterest != undefined){//Pintrest 1276 social+="<div class='media-boxes-pinterest fa fa-pinterest-square' data-url='"+sharingURL+"'></div>"; 1277 } 1278 social+="</div>"; 1279 1280 var oldHTML = $('.mfp-title').html(); 1281 $('.mfp-title').html(oldHTML+social); 1282 1283 // ==== END SOCIAL BUTTONS ==== // 1284 1285 1286 }, 5); 1287 1288 if(settings.deepLinking){ 1289 location.hash = '#!' + item.attr('data-mfp-src') + '||' + item.parents('.media-boxes-container').attr('id'); /* with the "src" of the image and the "id" of the container */ 1290 } 1291 }, 1292 beforeOpen: function() { 1293 this.container.data('scrollTop', parseInt($(window).scrollTop())); 1294 }, 1295 open: function(){ 1296 $('html, body').scrollTop( this.container.data('scrollTop') ); 1297 }, 1298 close: function () { 1299 if(settings.deepLinking){ 1300 window.location.hash = '#!'; 1301 } 1302 }, 1303 }, 1304 }); 1305 1306 } 1307 1308 /* ====================================================================== * 1309 [11] DEEP LINKING 1310 * ====================================================================== */ 1311 1312 if(settings.deepLinking){ 1313 1314 function urlFromHash() { 1315 if (location.hash.substr(0, 2) != '#!') { 1316 return null; 1317 } 1318 // why not location.hash? => http://stackoverflow.com/q/4835784/298479 1319 var hash = location.href.split('#!')[1]; 1320 var id = hash.split('||')[1]; 1321 var src = hash.split('||')[0]; 1322 return { 1323 hash: hash, 1324 id: id, 1325 src: src 1326 }; 1327 } 1328 1329 var hashUrl = urlFromHash(); 1330 if (hashUrl) { 1331 $container.filter('[id="' + hashUrl.id + '"]').find('.mb-open-popup[data-mfp-src="' + hashUrl.src + '"]').trigger('click'); 1332 } 1333 1334 function doHash() { 1335 var mp = $.magnificPopup.instance; 1336 if (!mp) { 1337 // this check is not needed in this example, but in some cases you might delay everything before 1338 // this event e.g. until something else finished loading - in that case hashchange might trigger before 1339 return; 1340 } 1341 1342 var url = urlFromHash(); 1343 if (!url && mp.isOpen) { 1344 // no url => close popup 1345 mp.close(); 1346 } else if (url) { 1347 if ( mp.isOpen && mp.currItem && mp.currItem.el.parents('.media-boxes-container').attr('id') == url.id ) { 1348 if( mp.currItem.el.attr('data-mfp-src') != url.src ){ 1349 // open => only update if necessary 1350 var index = null; 1351 $.each(mp.items, function (i, item) { 1352 var jqItem = item.parsed ? item.el : $(item); 1353 if (jqItem.attr('data-mfp-src') == url.src) { 1354 index = i; 1355 return false;
1356 } 1357 }); 1358 if (index !== null) { 1359 mp.goTo(index); 1360 } 1361 }else{ 1362 // is already in the correct one 1363 } 1364 }else{ 1365 // not open or doesn't match the right one => simply click the matching link 1366 $container.filter('[id="' + url.id + '"]').find('.mb-open-popup[data-mfp-src="' + url.src + '"]').trigger('click'); 1367 } 1368 } 1369 } 1370 1371 if (window.addEventListener) { 1372 window.addEventListener("hashchange", doHash, false); 1373 } else if (window.attachEvent) { 1374 window.attachEvent("onhashchange", doHash); 1375 } 1376 1377 } 1378 1379 /* ====================================================================== * 1380 [12] SOCIAL IN MAGNIFIC POPUP 1381 * ====================================================================== */ 1382 1383 // OPEN WINDOWS FOR SHARING :D 1384 var openWindow = function(url){ 1385 var w = window.open(url, "ftgw", "location=1,status=1,scrollbars=1,width=600,height=400"); 1386 w.moveTo((screen.width / 2) - (300), (screen.height / 2) - (200)); 1387 } 1388 1389 //FACEBOOK SHARE 1390 $('body').on('click', 'div.media-boxes-facebook', function(){ 1391 var $this = $(this); 1392 var url = encodeURIComponent($this.data('url')); 1393 url = 'https://www.facebook.com/sharer/sharer.php?u=' + url; 1394 openWindow(url); 1395 }); 1396 //TWITTER SHARE 1397 $('body').on('click', 'div.media-boxes-twitter', function(){ 1398 var $this = $(this); 1399 var url = encodeURIComponent($this.data('url')); 1400 url = "https://twitter.com/intent/tweet?url=&text=" + url; 1401 openWindow(url); 1402 }); 1403 //GOOGLE PLUS 1404 $('body').on('click', 'div.media-boxes-googleplus', function(){ 1405 var $this = $(this); 1406 var url = encodeURIComponent($this.data('url')); 1407 url = 'https://plus.google.com/share?url=' + url 1408 openWindow(url); 1409 }); 1410 //PINTREST 1411 $('body').on('click', 'div.media-boxes-pinterest', function(){ 1412 var $this = $(this); 1413 var url = encodeURIComponent($this.data('url')); 1414 url = 'http://pinterest.com/pin/create/button/?url=' + url + '&media=' + url; 1415 openWindow(url); 1416 }); 1417 1418 1419 1420 1421 1422 1423 1424 return this; 1425 1426 };//END OF FUSION OBJECT 1427 1428 1429 $.fn.mediaBoxes = function(options) { 1430 1431 return this.each(function(key, value){ 1432 var element = $(this); 1433 // Return early if this element already has a plugin instance 1434 if (element.data('mediaBoxes')) return element.data('mediaBoxes'); 1435 // Pass options to plugin constructor 1436 var mediaBoxes = new MediaBoxes(this, options); 1437 // Store plugin object in this element's data 1438 element.data('mediaBoxes', mediaBoxes); 1439 }); 1440 1441 }; 1442 1443 //Default settings 1444 $.fn.mediaBoxes.defaults = { 1445 boxesToLoadStart: 8, 1446 boxesToLoad: 4, 1447 minBoxesPerFilter: 0, 1448 lazyLoad: true, 1449 horizontalSpaceBetweenBoxes: 15, 1450 verticalSpaceBetweenBoxes: 15, 1451 columnWidth: 'auto', 1452 columns: 4, 1453 resolutions: [ 1454 { 1455 maxWidth: 960, 1456 columnWidth: 'auto', 1457 columns: 3, 1458 }, 1459 { 1460 maxWidth: 650, 1461 columnWidth: 'auto', 1462 columns: 2, 1463 }, 1464 { 1465 maxWidth: 450, 1466 columnWidth: 'auto', 1467 columns: 1, 1468 }, 1469 ], 1470 filterContainer: '#filter', 1471 filter: 'a', 1472 search: '', // i.e. #search 1473 searchTarget: '.media-box-title', 1474 sortContainer: '', // i.e. #sort 1475 sort: 'a', 1476 getSortData: { 1477 title: '.media-box-title', 1478 text: '.media-box-text', 1479 }, 1480 waitUntilThumbLoads: true, // When they have dimensions specified 1481 waitForAllThumbsNoMatterWhat: false, // Wait for all the thumbnails to load even if they got dimensions specified 1482 thumbnailOverlay: true, //Show the overlay on mouse over 1483 overlayEffect: 'fade', // 'push-up', 'push-down', 'push-up-100%', 'push-down-100%', 'reveal-top', 'reveal-bottom', 'reveal-top-100%', 'reveal-bottom-100%', 'direction-aware', 'direction-aware-fade', 'direction-right', 'direction-left', 'direction-top', 'direction-bottom', 'fade' 1484 overlaySpeed: 200, 1485 overlayEasing: 'default', 1486 showOnlyLoadedBoxesInPopup: false, 1487 considerFilteringInPopup: true, 1488 deepLinking: true, 1489 gallery: true, 1490 LoadingWord: 'Loading...',
1491 loadMoreWord: 'Load More', 1492 noMoreEntriesWord: 'No More Entries', 1493 alignTop: false, 1494 preload: [0,2], 1495 magnificPopup: true, 1496 1497 //some sharing hidden options :D 1498 /*facebook: true, 1499 twitter: true, 1500 googleplus: true, 1501 pinterest: true,*/ 1502 }; 1503 1504 1505 1506 1507 /* DROP DOWN PLUGIN */ 1508 1509 (function(){ 1510 1511 1512 /* CHECK FOR MOBILE BROWSER */ 1513 function isMobileBrowser() { 1514 var check = false; 1515 (function(a){ 1516 if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) 1517 check = true 1518 } 1519 )(navigator.userAgent||navigator.vendor||window.opera); 1520 return check; 1521 } 1522 1523 function start($wrapper){ 1524 var $menu = $wrapper.find('.media-boxes-drop-down-menu'); 1525 var $header = $wrapper.find('.media-boxes-drop-down-header'); 1526 1527 function mouseout(){ 1528 $menu.hide(); 1529 }; 1530 1531 function mouseover(){ 1532 $menu.show(); 1533 }; 1534 1535 function updateHeader(){ 1536 var $selectedDefault = $menu.find( '.selected' ); 1537 var $selected = $selectedDefault.length ? $selectedDefault.parents('li') : $menu.children().first(); 1538 1539 1540 $header.html( $selected.clone().find('a').append('<span class="fa fa-sort-desc"></span>').end().html() ); 1541 } 1542 updateHeader(); 1543 1544 function click(e){ 1545 e.preventDefault(); 1546 e.stopPropagation(); 1547 1548 $(this).parents('li').siblings('li').find('a').removeClass('selected').end().end().find('a').addClass('selected'); 1549 updateHeader(); 1550 1551 //mouseout(); 1552 } 1553 1554 if(isMobileBrowser()){ 1555 1556 function clickToggle(e){ 1557 e.stopPropagation(); 1558 1559 if($menu.is(":visible")){ 1560 mouseout(); 1561 }else{ 1562 mouseover(); 1563 } 1564 } 1565 1566 $('body').on('click', function(){ 1567 if($menu.is(":visible")){ 1568 mouseout(); 1569 } 1570 }) 1571 1572 $header 1573 .bind('click', clickToggle); 1574 1575 $menu.find('> li > *') 1576 .bind('click', click); 1577 }else{ 1578 $header 1579 .bind('mouseout', mouseout) 1580 .bind('mouseover', mouseover); 1581 1582 $menu.find('> li > *') 1583 .bind('mouseout', mouseout) 1584 .bind('mouseover', mouseover) 1585 .bind('click', click); 1586 } 1587 1588 $header.on('click', 'a', function(e){ 1589 e.preventDefault(); 1590 //return false;
1591 }); 1592 1593 } 1594 1595 1596 $('.media-boxes-drop-down').each(function(){ 1597 start($(this)); 1598 }); 1599 1600 })(); 1601 1602 1603 1604})( window, 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.