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