1/** 2 * Dribbble Feed Slider and Popup Functionality 3 * 4 * Handles: 5 * - Responsive slider/carousel initialization 6 * - Popup modal for post details 7 * - Masonry grid layout 8 * - Media type handling (images, videos, carousels) 9 * 10 * @since 1.0.0 11 * @package DiviSocialFeed 12 */ 13 14// Initialize Dribbble sliders with responsive settings 15jQuery(document).ready(function ($) { 16 $('.dsf_drb_slider_wrapper').each(function () { 17 let $this = $(this); 18 19 /** 20 * Get spacing values from data attributes 21 * Default to 20px if not specified or invalid 22 */ 23 let spacingDesktop = parseInt($this.data('spacing-desktop')) || 20; 24 let spacingTablet = parseInt($this.data('spacing-tablet')) || 20; 25 let spacingMobile = parseInt($this.data('spacing-mobile')) || 20; 26 27 /** 28 * Get column count settings from data attributes 29 * These will be used in the responsive configuration 30 */ 31 let columnDesktop = $this.data('desktop-column'); 32 let columnTablet = $this.data('tablet-column'); 33 let columnPhone = $this.data('phone-column'); 34 35 /** 36 * Initialize Owl Carousel with responsive settings 37 */ 38 $this.find('.owl-carousel.dsf_drb_slider').owlCarousel({ 39 items: 1, // Default number of items 40 loop: true, // Infinite looping 41 nav: true, // Show navigation arrows 42 dots: true, // Show pagination dots 43 autoplay: false, // Disable auto-play by default 44 autoplayTimeout: 3000, // Auto-play interval if enabled 45 navText: ['<span class="prev-arrow">â¹</span>', '<span class="next-arrow">âº</span>'], // Custom arrow icons 46 47 /** 48 * Responsive breakpoint configuration 49 */ 50 responsive: { 51 // Phone viewport 52 0: { 53 items: columnPhone || 1, // Default to 1 item on phone 54 margin: spacingMobile // Use mobile spacing 55 }, 56 // Tablet viewport 57 768: { 58 items: columnTablet || 2, // Default to 2 items on tablet 59 margin: spacingTablet // Use tablet spacing 60 }, 61 // Desktop viewport 62 981: { 63 items: columnDesktop || 3, // Default to 3 items on desktop 64 margin: spacingDesktop // Use desktop spacing 65 } 66 } 67 }); 68 }); 69}); 70 71 72/** 73 * Dribbble Popup Modal Functionality 74 * 75 * Handles: 76 * - Post click events 77 * - Media type detection and rendering 78 * - Popup content population 79 * - Popup show/hide functionality 80 */ 81 82jQuery(document).ready(function ($) { 83 /** 84 * Event delegation for post clicks (works with dynamically added posts) 85 */ 86 $(document).on("click", ".dsf_drb_feed_item", function () { 87 // Get post identification data 88 let postId = $(this).data("id"); 89 let postObject = $(this).data("object"); 90 91 // Validate post data object exists 92 if (typeof window[postObject] === "undefined") { 93 console.error("Dribbble data object not found:", postObject); 94 return; 95 } 96 97 // Find the specific post data 98 let postData = window[postObject].shots.find(post => String(post.id) === String(postId)); 99 100 if (!postData) { 101 console.error("Post data not found for ID:", postId); 102 return; 103 } 104 105 /** 106 * Cache DOM elements for popup 107 */ 108 let popupContainer = $(".dsf_drb_popup_container"); 109 let popupLeft = $(".dsf_drb_popup_left"); 110 let popupRight = $(".dsf_drb_popup_right"); 111 let popupImage = popupLeft.find("img"); 112 113 // Access profile data 114 let profileData = window[postObject].profile || {}; 115 116 117 // Update image 118 if (popupImage.length) { 119 let mediaUrl = 120 postData.images?.hidpi || 121 postData.images?.two_x || 122 postData.images?.teaser || 123 ""; 124 125 if (mediaUrl) { 126 popupImage.attr("src", mediaUrl).show(); 127 } 128 } 129 130 // Update "View original" button link 131 let popupButton = popupRight.find(".dsf_drb_popup_button"); 132 if (popupButton.length && postData.html_url) { 133 popupButton.attr("href", postData.html_url); 134 } 135 136 popupRight.find(".dsf_drb_popup_data").text(postData.published || ""); 137 popupRight.find(".dsf_drb_popup_title").text(postData.title || ""); 138 139 // Show the popup 140 $(".dsf_drb_popup").fadeIn(function () { 141 $("body").addClass("dsf-popup-open"); //Add class when popup opens 142 }); 143 });
144 145 /** 146 * Popup close handlers 147 */ 148 $(document).on("click", ".dsf_drb_popup_close", function () { 149 $(".dsf_drb_popup").fadeOut(function () { 150 $("body").removeClass("dsf-popup-open"); // Remove class when popup closes 151 }); 152 }); 153 154 $(document).on("click", function (e) { 155 if ($(e.target).hasClass("dsf_drb_popup")) { 156 $(".dsf_drb_popup").fadeOut(function () { 157 $("body").removeClass("dsf-popup-open"); // Remove class when popup closes 158 }); 159 } 160 }); 161}); 162 163/** 164 * Masonry Grid Layout Initialization 165 * 166 * Sets up the masonry layout for grid displays 167 */ 168 169jQuery(document).ready(function ($) { 170 var $grid = $('.dsf_drb_grid_masonry'); 171 172 // wait until images are loaded 173 $grid.imagesLoaded(function () { 174 $grid.masonry({ 175 itemSelector: '.dsf_drb_feed_item', 176 columnWidth: '.grid-sizer', 177 gutter: '.gutter-sizer', 178 percentPosition: true 179 }); 180 }); 181});
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.