1/** 2 * Tiktok 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 Tiktok sliders with responsive settings 15jQuery(document).ready(function($) { 16 $('.dsf_tt_slider_wrapper').each(function() { 17 let $this = $(this); 18 /** 19 * Get spacing values from data attributes 20 * Default to 20px if not specified or invalid 21 */ 22 let spacingDesktop = parseInt($this.data('spacing-desktop')) || 20; 23 let spacingTablet = parseInt($this.data('spacing-tablet')) || 20; 24 let spacingMobile = parseInt($this.data('spacing-mobile')) || 20; 25 26 /** 27 * Get column count settings from data attributes 28 * These will be used in the responsive configuration 29 */ 30 let columnDesktop = $this.data('desktop-column'); 31 let columnTablet = $this.data('tablet-column'); 32 let columnPhone = $this.data('phone-column'); 33 34 /** 35 * Initialize Owl Carousel with responsive settings 36 */ 37 $this.find('.owl-carousel.dsf_tt_slider').owlCarousel({ 38 items: 1, // Default number of items 39 loop: true, // Infinite looping 40 nav: true, // Show navigation arrows 41 dots: true, // Show pagination dots 42 autoplay: false, // Disable auto-play by default 43 autoplayTimeout: 3000, // Auto-play interval if enabled 44 navText: ['<span class="prev-arrow">â¹</span>', '<span class="next-arrow">âº</span>'], // Custom arrow icons 45 46 /** 47 * Responsive breakpoint configuration 48 */ 49 responsive: { 50 // Phone viewport 51 0: { 52 items: columnPhone || 1, // Default to 1 item on phone 53 margin: spacingMobile // Use mobile spacing 54 }, 55 // Tablet viewport 56 768: { 57 items: columnTablet || 2, // Default to 2 items on tablet 58 margin: spacingTablet // Use tablet spacing 59 }, 60 // Desktop viewport 61 981: { 62 items: columnDesktop || 3, // Default to 3 items on desktop 63 margin: spacingDesktop // Use desktop spacing 64 } 65 } 66 }); 67 }); 68}); 69 70// Store the next page cursor per container 71// let nextCursor = {}; 72 73/** 74 * Tiktok Popup Modal Functionality 75 * 76 * Handles: 77 * - Post click events 78 * - Media type detection and rendering 79 * - Popup content population 80 * - Popup show/hide functionality 81 */ 82jQuery(document).ready(function ($) { 83 /** 84 * Event delegation for post clicks (works with dynamically added posts) 85 */ 86 $(document).on("click", ".dsf_tt_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("Tiktok data object not found:", postObject); 94 return; 95 } 96 97 // Find the specific post data 98 let postData = window[postObject].media.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 popupLeft = $(".dsf_tt_popup_left"); 109 let popupRight = $(".dsf_tt_popup_right"); 110 let popupVideoContainer = popupLeft.find(".dsf_popup_video_container"); 111 112 // Clear previous content 113 popupVideoContainer.empty().hide(); 114 // User information 115 popupRight.find(".dsf_tt_popup_date").text(postData.create_time || ""); 116 117 let caption = postData.video_description || ""; 118 caption = caption.replace(/\n/g, "<br>"); 119 120 popupRight.find(".dsf_tt_popup_caption").html(caption); 121 122 // Engagement metrics 123 popupRight.find(".dsf_tt_like_count .like-count") 124 .text(postData.like_count ?? "0"); 125 126 popupRight.find(".dsf_tt_comment_count .comment-count") 127 .text(postData.comment_count ?? "0"); 128 129 popupRight.find(".dsf_tt_views_count .views-count") 130 .text(postData.view_count ?? "0"); 131 132 if (postData.embed_link) { 133 popupVideoContainer.html(` 134 <div class="dsf-tiktok-embed"> 135 <iframe 136 src="${postData.embed_link}?autoplay=1&referrer=off" 137 frameborder="0" 138 allow="autoplay; encrypted-media; fullscreen; picture-in-picture" 139 allowfullscreen 140 ></iframe> 141 </div> 142 `).show(); 143 } 144 // Show the popup 145 $(".dsf_tt_popup").fadeIn(function () { 146 $("body").addClass("dsf-popup-open"); //Add class when popup opens 147 }); 148 });
149 150 /** 151 * Popup close handlers 152 */ 153 $(document).on("click", ".dsf_tt_popup_close", function () { 154 $(".dsf_tt_popup").fadeOut(function () { 155 stopVideoPlayback(); 156 $("body").removeClass("dsf-popup-open"); // Remove class when popup closes 157 }); 158 }); 159 160 $(document).on("click", function (e) { 161 if ($(e.target).hasClass("dsf_tt_popup")) { 162 stopVideoPlayback(); 163 $(".dsf_tt_popup").fadeOut(function () { 164 $("body").removeClass("dsf-popup-open"); // Remove class when popup closes 165 }); 166 } 167 }); 168 169 /** 170 * Helper function to stop video playback by removing the iframe 171 */ 172 function stopVideoPlayback() { 173 let popupVideoContainer = $(".dsf_popup_video_container"); 174 popupVideoContainer.empty(); 175 } 176}); 177 178 jQuery(document).ready(function ($) { 179 $(".dsf_tt_post_caption").each(function () { 180 let text = $(this).text(); 181 // Replace the literal <br /> (or <br>) text with actual line breaks 182 text = text.replace(/<br\s*\/?>/gi, "<br>"); 183 $(this).html(text); 184 }); 185}); 186 187/** 188 * Masonry Grid Layout Initialization 189 * 190 * Sets up the masonry layout for grid displays 191 */ 192 193jQuery(document).ready(function ($) { 194 var $grid = $('.dsf_tt_grid_masonry'); 195 196 // wait until images are loaded 197 $grid.imagesLoaded(function () { 198 $grid.masonry({ 199 itemSelector: '.dsf_tt_feed_item', 200 columnWidth: '.grid-sizer', 201 gutter: '.gutter-sizer', 202 percentPosition: true 203 }); 204 }); 205});
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.