PageSourceSearch

https://www.druni.es/blog/wp-content/plugins/colabwp/assets/js/colabwp-frontend.js?ver=2.3

js druni.es collected 2026-10-01 12:14:51 UTC 12,086 bytes, 377 lines download raw bytes

1/**
2 * Archivo: assets/js/colabwp-frontend.js
3 * Descripción: Scripts específicos para el frontend
4 */
5
6jQuery(document).ready(function($) {
7    //console.log('colabwp-frontend.js cargado');
8    
9    // Obtener traducciones
10    var i18n = window.colabwp_i18n || {
11        showing: 'Showing',
12        of: 'of',
13        show_more_posts: 'Show more posts',
14        hide_posts: 'Hide Posts',
15        view_posts: 'View Posts',
16        no_image: 'No image',
17        loading: 'Loading...',
18        error_loading: 'Error loading posts',
19        posts: 'posts',
20        post: 'post',
21        collaborated: 'collaborated'
22    };
23    
24    // Solo inicializar posts si hay contenedores en la página
25    function initializePostsContainers() {
26        var $containers = $('.colabwp-posts-container');
27        
28        if ($containers.length > 0) {
29            //console.log('Contenedores de posts encontrados:', $containers.length);
30            $containers.each(function() {
31                initColaboradorPosts($(this));
32            });
33        }
34    }
35    
36    // Función para inicializar posts de un colaborador
37    function initColaboradorPosts($container) {
38        var postsData = $container.attr('data-posts');
39        var totalPosts = parseInt($container.attr('data-total') || '0');
40        var uniqueId = $container.attr('data-unique-id');
41        
42        if (!postsData || totalPosts === 0) {
43            return;
44        }
45        
46        var posts = [];
47        try {
48            posts = JSON.parse(postsData);
49        } catch (e) {
50            console.error('Error parsing posts JSON:', e);
51            return;
52        }
53        
54        var postsPerPage = 10;
55        var currentPage = 0;
56        var showingCount = 0;
57        
58        var $grid = $('#posts-grid-' + uniqueId);
59        var $loadMoreBtn = $('#load-more-' + uniqueId);
60        var $progressInfo = $('#progress-' + uniqueId);
61        var $loadMoreContainer = $loadMoreBtn.parent();
62        
63        // Ocultar controles si hay pocos posts
64        if (totalPosts <= postsPerPage) {
65            $progressInfo.hide();
66            $loadMoreContainer.hide();
67        }
68        
69        // Función para crear HTML de post
70        function createPostHTML(post) {
71            var imageHTML = '';
72            if (post.image && post.image !== '') {
73                imageHTML = '<img src="' + post.image + '" alt="' + escapeHtml(post.title) + '">';
74            } else {
75                imageHTML = '<div class="no-image">
75' + i18n.no_image + '</div>';
76            }
77            
78            return '<a href="' + post.url + '" class="colabwp-post-item" rel="nofollow noreferrer noopener">' +
79                '<div class="colabwp-post-image' + (post.image ? '' : ' no-image') + '">' +
80                    imageHTML +
81                '</div>' +
82                '<div class="colabwp-post-content">' +
83                    '<p class="colabwp-post-title">' + escapeHtml(post.title) + '</p>' +
84                '</div>' +
85            '</a>';
86        }
87        
88        // Función para escapar HTML
89        function escapeHtml(text) {
90            if (!text) return '';
91            var map = {
92                '&': '&amp;',
93                '<': '&lt;',
94                '>': '&gt;',
95                '"': '&quot;',
96                "'": '&#039;'
97            };
98            return String(text).replace(/[&<>"']/g, function(m) { return map[m]; });
99        }
100        
101        // Función para mostrar posts
102        function showPosts() {
103            var startIndex = currentPage * postsPerPage;
104            var endIndex = Math.min(startIndex + postsPerPage, posts.length);
105            
106            for (var i = startIndex; i < endIndex; i++) {
107                if (posts[i]) {
108                    var postHTML = createPostHTML(posts[i]);
109                    $grid.append(postHTML);
110                }
111            }
112            
113            showingCount = endIndex;
114            updateProgress();
115            
116            if (endIndex >= posts.length) {
117                $loadMoreContainer.hide();
118            }
119            
120            currentPage++;
121        }
122        
123        // Función para actualizar progreso
124        function updateProgress() {
125            if (totalPosts <= postsPerPage) return;
126            
127            var percentage = Math.round((showingCount / totalPosts) * 100);
128            
129            $progressInfo.find('.current-count').text(showingCount);
130            $progressInfo.find('.colabwp-progress-fill').css('width', percentage + '%');
131        }
132        
133        // Event listener para botón mostrar más
134        $loadMoreBtn.on('click', function(e) {
135            e.preventDefault();
136            showPosts();
137        });
138        
139        // Mostrar primeros posts
140        showPosts();
141    }
142    
143    // Scroll suave para badges de posts
144    $(document).on('click', '.colabwp-scroll-to-posts', function(e) {
145        e.preventDefault();
146        var target = $($(this).attr('href'));
147        if (target.length) {
148            $('html, body').animate({
149                scrollTop: target.offset().top - 50
150            }, 800);
151        }
152    });
153    
154    // Inicializar al cargar
155    initializePostsContainers();
156    
157    // Re-inicializar si se añaden nuevos elementos dinámicamente
158    window.reinitColabwpPosts = function() {
159        initializePostsContainers();
160    };
161});
162
163// Función global para inicializar carrusel
164window.colabwpInitCarousel = function(carouselId) {
165    var $ = jQuery;
166    var $wrapper = $('#' + carouselId);
167    if (!$wrapper.length || $wrapper.data('carousel-initialized')) return;
168    
169    var $container = $wrapper.find('.colabwp-carousel-container');
170    var $track = $wrapper.find('.colabwp-carousel-track');
171    var $inner = $wrapper.find('.colabwp-carousel-inner');
172    var $items = $wrapper.find('.colabwp-carousel-item');
173    var $prevBtn = $wrapper.find('.colabwp-carousel-prev');
174    var $nextBtn = $wrapper.find('.colabwp-carousel-next');
175    var $dots = $('#dots-' + carouselId);
176    var $dotButtons = $dots.find('.colabwp-carousel-dot');
177    
178    if ($items.length === 0) return;
179    
180    var currentIndex = 0;
181    var itemsToShow = 3;
182    var itemsToScroll = 1;
183    var maxIndex = 0;
184    var isMobile = false;
185    
186    function calculateItemsToShow() {
187        var windowWidth = $(window).width();
188        if (windowWidth <= 480) {
189            itemsToShow = 1;
190            isMobile = true;
191        } else if (windowWidth <= 768) {
192            itemsToShow = 2;
193            isMobile = true;
194        } else if (windowWidth <= 992) {
195            itemsToShow = 2;
196            isMobile = false;
197        } else {
198            itemsToShow = 3;
199            isMobile = false;
200        }
201        
202        maxIndex = Math.max(0, $items.length - itemsToShow);
203        
204        if (currentIndex > maxIndex) {
205            currentIndex = maxIndex;
206        }
207        
208        updateNavigationVisibility();
209        updateDotsVisibility();
210    }
211    
212    function updateNavigationVisibility() {
213        if (isMobile) return;
214        
215        if ($items.length <= itemsToShow) {
216            $prevBtn.addClass('hidden');
217            $nextBtn.addClass('hidden');
218            return;
219        }
220        
221        if (currentIndex === 0) {
222            $prevBtn.addClass('hidden');
223        } else {
224            $prevBtn.removeClass('hidden');
225        }
226        
227        if (currentIndex >= maxIndex) {
228            $nextBtn.addClass('hidden');
229        } else {
230            $nextBtn.removeClass('hidden');
231        }
232    }
233    
234    function updateDotsVisibility() {
235        if (!$dots.length) return;
236        
237        $dotButtons.hide().removeClass('active');
238        
239        var dotsNeeded = Math.ceil($items.length / itemsToShow);
240        for (var i = 0; i < dotsNeeded; i++) {
241            $dotButtons.eq(i).show();
242        }
243        
244        var activeDotIndex = Math.floor(currentIndex / itemsToShow);
245        $dotButtons.eq(activeDotIndex).addClass('active');
246    }
247    
248    function updateCarousel() {
249        var itemWidth = $items.first().outerWidth();
250        var gap = parseInt($inner.css('gap')) || 25;
251        var translateX = -(currentIndex * (itemWidth + gap));
252        
253        $inner.css('transform', 'translateX(' + translateX + 'px)');
254        
255        updateNavigationVisibility();
256        updateDots();
257    }
258    
259    function updateDots() {
260        if (!$dots.length) return;
261        
262        $dotButtons.removeClass('active');
263        
264        var activeDotIndex = Math.floor(currentIndex / itemsToShow);
265        $dotButtons.eq(activeDotIndex).addClass('active');
266    }
267    
268    $prevBtn.on('click', function() {
269        if (currentIndex > 0) {
270            currentIndex -= itemsToScroll;
271            if (currentIndex < 0) currentIndex = 0;
272            updateCarousel();
273        }
274    });
275    
276    $nextBtn.on('click', function() {
277        if (currentIndex < maxIndex) {
278            currentIndex += itemsToScroll;
279            if (currentIndex > maxIndex) currentIndex = maxIndex;
280            updateCarousel();
281        }
282    });
283    
284    $dotButtons.on('click', function() {
285        var dotIndex = $(this).data('index');
286        
287        if (isMobile) {
288            currentIndex = dotIndex * itemsToShow;
289            if (currentIndex > maxIndex) currentIndex = maxIndex;
290        } else {
291            currentIndex = dotIndex;
292        }
293        
294        updateCarousel();
295    });
296    
297    var touchStartX = 0;
298    var touchEndX = 0;
299    var isDragging = false;
300    
301    $track.on('touchstart', function(e) {
302        touchStartX = e.originalEvent.touches[0].clientX;
303        isDragging = true;
304    });
305    
306    $track.on('touchmove', function(e) {
307        if (!isDragging) return;
308        touchEndX = e.originalEvent.touches[0].clientX;
309    });
310    
311    $track.on('touchend', function(e) {
312        if (!isDragging) return;
313        isDragging = false;
314        
315        var swipeDistance = touchStartX - touchEndX;
316        var threshold = 50;
317        
318        if (Math.abs(swipeDistance) > threshold) {
319            if (swipeDistance > 0 && currentIndex < maxIndex) {
320                if (isMobile) {
321                    currentIndex = Math.min(currentIndex + itemsToShow, maxIndex);
322                } else {
323                    currentIndex = Math.min(currentIndex + itemsToScroll, maxIndex);
324                }
325                updateCarousel();
326            } else if (swipeDistance < 0 && currentIndex > 0) {
327                if (isMobile) {
328                    currentIndex = Math.max(currentIndex - itemsToShow, 0);
329                } else {
330                    currentIndex = Math.max(currentIndex - itemsToScroll, 0);
331                }
332                updateCarousel();
333            }
334        }
335    });
336    
337    $(document).on('keydown', function(e) {
338        if (isMobile) return;
339        
340        var carouselTop = $wrapper.offset().top;
341        var carouselBottom = carouselTop + $wrapper.height();
342        var viewportTop = $(window).scrollTop();
343        var viewportBottom = viewportTop + $(window).height();
344        
345        if (carouselBottom > viewportTop && carouselTop < viewportBottom) {
346            if (e.key === 'ArrowLeft' && currentIndex > 0) {
347                e.preventDefault();
348                currentIndex -= itemsToScroll;
349                if (currentIndex < 0) currentIndex = 0;
350                updateCarousel();
351            } else if (e.key === 'ArrowRight' && currentIndex < maxIndex) {
352                e.preventDefault();
353                currentIndex += itemsToScroll;
354                if (currentIndex > maxIndex) currentIndex = maxIndex;
355                updateCarousel();
356            }
357        }
358    });
359    
360    var resizeTimer;
361    $(window).on('resize', function() {
362        clearTimeout(resizeTimer);
363        resizeTimer = setTimeout(function() {
364            calculateItemsToShow();
365            updateCarousel();
366        }, 250);
367    });
368    
369    calculateItemsToShow();
370    updateCarousel();
371    
372    if ($prevBtn.data('initial-hidden') === true && currentIndex === 0) {
373        $prevBtn.addClass('hidden');
374    }
375    
376    $wrapper.data('carousel-initialized', true);
377};

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.