@bebranded/bb-contents 1.1.11 → 1.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bb-contents.js +83 -11
  2. package/package.json +1 -1
package/bb-contents.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * BeBranded Contents
3
3
  * Contenus additionnels français pour Webflow
4
- * @version 1.1.11
4
+ * @version 1.1.13
5
5
  * @author BeBranded
6
6
  * @license MIT
7
7
  * @website https://www.bebranded.xyz
@@ -10,7 +10,7 @@
10
10
  'use strict';
11
11
 
12
12
  // Version du script
13
- const BB_CONTENTS_VERSION = '1.1.11';
13
+ const BB_CONTENTS_VERSION = '1.1.13';
14
14
 
15
15
  // Créer l'objet temporaire pour la configuration si il n'existe pas
16
16
  if (!window._bbContentsConfig) {
@@ -289,7 +289,40 @@
289
289
  const s = scope || document;
290
290
  return s.querySelector(bbContents._attrSelector('marquee')) !== null;
291
291
  },
292
-
292
+
293
+ // Détecte si un bloc contient des dropdowns (Webflow ou structure similaire)
294
+ _hasDropdownInBlock: function(block) {
295
+ if (!block || !block.querySelector) return false;
296
+ return block.querySelector('.w-dropdown') !== null ||
297
+ block.querySelector('[class*="dropdown"]') !== null;
298
+ },
299
+
300
+ // Active le comportement hover pour les dropdowns dans un bloc du marquee (items indépendants)
301
+ _enableMarqueeDropdowns: function(block) {
302
+ if (!block || !block.querySelectorAll) return;
303
+ const items = block.querySelectorAll('.bb-marquee_item, [role="listitem"]');
304
+ const itemList = items.length ? items : block.querySelectorAll(':scope > *');
305
+ itemList.forEach(function(item) {
306
+ const dropdowns = item.querySelectorAll('.w-dropdown, [class*="dropdown"]');
307
+ dropdowns.forEach(function(dropdown) {
308
+ const list = dropdown.querySelector('.w-dropdown-list, [class*="dropdown-list"], [class*="dropdown_list"]');
309
+ if (!list) return;
310
+ item.style.overflow = 'visible';
311
+ dropdown.style.overflow = 'visible';
312
+ let leaveTimer;
313
+ dropdown.addEventListener('mouseenter', function() {
314
+ clearTimeout(leaveTimer);
315
+ dropdown.classList.add('w--open');
316
+ });
317
+ dropdown.addEventListener('mouseleave', function() {
318
+ leaveTimer = setTimeout(function() {
319
+ dropdown.classList.remove('w--open');
320
+ }, 150);
321
+ });
322
+ });
323
+ });
324
+ },
325
+
293
326
  init: function(root) {
294
327
  const scope = root || document;
295
328
  if (scope.closest && scope.closest('[data-bb-disable]')) return;
@@ -334,7 +367,7 @@
334
367
  (parentOverflowX === 'visible' || parentOverflowX === '') &&
335
368
  (parentOverflowY === 'visible' || parentOverflowY === '');
336
369
  const mainContainerOverflow = isParentOverflowVisible ? 'visible' : 'hidden';
337
-
370
+
338
371
  mainContainer.style.cssText = `
339
372
  position: relative;
340
373
  width: 100%;
@@ -361,7 +394,9 @@
361
394
 
362
395
  const mainBlock = document.createElement('div');
363
396
  mainBlock.innerHTML = originalHTML;
364
-
397
+ const hasDropdowns = this._hasDropdownInBlock(mainBlock);
398
+ if (hasDropdowns) mainContainer.style.overflow = 'visible';
399
+
365
400
  // Précharger toutes les images avant clonage
366
401
  const preloadAllImagesFirst = function(block) {
367
402
  return new Promise(function(resolve) {
@@ -652,7 +687,15 @@
652
687
  if (itemHeight > maxHeight) maxHeight = itemHeight;
653
688
  });
654
689
  if (maxHeight === 0) maxHeight = mainBlock.offsetHeight || scrollContainer.offsetHeight;
655
- if (maxHeight > 0) mainContainer.style.height = maxHeight + 'px';
690
+ if (maxHeight > 0) {
691
+ const extraForDropdowns = hasDropdowns ? 280 : 0;
692
+ mainContainer.style.height = (maxHeight + extraForDropdowns) + 'px';
693
+ }
694
+ if (hasDropdowns) {
695
+ this._enableMarqueeDropdowns(mainBlock);
696
+ this._enableMarqueeDropdowns(repeatBlock1);
697
+ this._enableMarqueeDropdowns(repeatBlock2);
698
+ }
656
699
  });
657
700
  });
658
701
  } else {
@@ -660,6 +703,11 @@
660
703
  scrollContainer.appendChild(repeatBlock1);
661
704
  scrollContainer.appendChild(repeatBlock2);
662
705
  mainContainer.appendChild(scrollContainer);
706
+ if (hasDropdowns) {
707
+ this._enableMarqueeDropdowns(mainBlock);
708
+ this._enableMarqueeDropdowns(repeatBlock1);
709
+ this._enableMarqueeDropdowns(repeatBlock2);
710
+ }
663
711
  }
664
712
  element.innerHTML = '';
665
713
  element.appendChild(mainContainer);
@@ -706,7 +754,24 @@
706
754
  element.innerHTML = '';
707
755
  element.appendChild(mainContainer);
708
756
  element.setAttribute('data-bb-marquee-processed', 'true');
709
-
757
+ if (hasDropdowns) {
758
+ this._enableMarqueeDropdowns(mainBlock);
759
+ this._enableMarqueeDropdowns(repeatBlock1);
760
+ this._enableMarqueeDropdowns(repeatBlock2);
761
+ }
762
+ if (!isVertical && hasDropdowns) {
763
+ requestAnimationFrame(function() {
764
+ let items = mainBlock.querySelectorAll('.bb-marquee_item, [role="listitem"]');
765
+ if (items.length === 0) items = mainBlock.querySelectorAll(':scope > *');
766
+ let maxHeight = 0;
767
+ items.forEach(function(item) {
768
+ const h = item.offsetHeight;
769
+ if (h > maxHeight) maxHeight = h;
770
+ });
771
+ if (maxHeight === 0) maxHeight = mainBlock.offsetHeight || scrollContainer.offsetHeight;
772
+ if (maxHeight > 0) mainContainer.style.height = (maxHeight + 280) + 'px';
773
+ });
774
+ }
710
775
  const initDelay = isVertical ? 500 : 300;
711
776
  setTimeout(() => {
712
777
  this.initAnimation(element, scrollContainer, mainBlock, {
@@ -2427,22 +2492,29 @@
2427
2492
  // OPTIMISATION: Cache partagé par configuration (sans videoCount ni skip)
2428
2493
  const baseCacheKey = `youtube_${groupConfig.channelIds}_${groupConfig.allowShorts}_${groupConfig.language}`;
2429
2494
  const cachedData = this.cache.get(baseCacheKey);
2495
+ const minItemsNeeded = skip + videoCount;
2430
2496
 
2431
- if (cachedData && cachedData.items) {
2432
- // Données YouTube récupérées du cache (économie API) — cache.get retourne la réponse API directement
2497
+ if (cachedData && cachedData.items && cachedData.items.length >= minItemsNeeded) {
2498
+ // Cache suffisant pour cette grid
2433
2499
  const limitedData = this.applySkipAndLimit(cachedData, skip, videoCount);
2434
2500
  this.generateYouTubeFeed(container, template, limitedData, groupConfig.allowShorts, groupConfig.language);
2435
2501
  return;
2436
2502
  }
2503
+ if (cachedData && cachedData.items && cachedData.items.length < minItemsNeeded) {
2504
+ // Cache insuffisant (ex. première grid seule en DOM a rempli le cache) → invalider pour refetch
2505
+ try { localStorage.removeItem(baseCacheKey); } catch (e) {}
2506
+ }
2437
2507
 
2438
2508
  if (this.isRequestActive(baseCacheKey)) {
2439
2509
  const checkActive = () => {
2440
2510
  if (!this.isRequestActive(baseCacheKey)) {
2441
- // L'autre appel est terminé, vérifier le cache
2442
2511
  const newCachedData = this.cache.get(baseCacheKey);
2443
- if (newCachedData && newCachedData.items) {
2512
+ if (newCachedData && newCachedData.items && newCachedData.items.length >= minItemsNeeded) {
2444
2513
  const limitedData = this.applySkipAndLimit(newCachedData, skip, videoCount);
2445
2514
  this.generateYouTubeFeed(container, template, limitedData, groupConfig.allowShorts, groupConfig.language);
2515
+ } else if (newCachedData && newCachedData.items && newCachedData.items.length < minItemsNeeded) {
2516
+ try { localStorage.removeItem(baseCacheKey); } catch (e) {}
2517
+ this.initElement(element, groupConfig, videoCount, skip);
2446
2518
  } else {
2447
2519
  container.innerHTML = '<div style="padding: 20px; text-align: center; color: #6b7280;">Erreur de chargement</div>';
2448
2520
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bebranded/bb-contents",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "description": "Contenus additionnels français pour Webflow",
5
5
  "main": "bb-contents.js",
6
6
  "scripts": {