@bebranded/bb-contents 1.0.31-beta → 1.0.33-beta

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 +140 -29
  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.0.31-beta
4
+ * @version 1.0.33-beta
5
5
  * @author BeBranded
6
6
  * @license MIT
7
7
  * @website https://www.bebranded.xyz
@@ -17,7 +17,7 @@
17
17
 
18
18
  // Configuration
19
19
  const config = {
20
- version: '1.0.31-beta',
20
+ version: '1.0.33-beta',
21
21
  debug: false, // Désactivé par défaut pour une console propre
22
22
  prefix: 'bb-', // utilisé pour générer les sélecteurs (data-bb-*)
23
23
  i18n: {
@@ -31,6 +31,8 @@
31
31
  modules: {},
32
32
  _observer: null,
33
33
  _reinitScheduled: false,
34
+ _initRetryCount: 0,
35
+ _maxInitRetries: 3,
34
36
 
35
37
  // Utilitaires
36
38
  utils: {
@@ -100,6 +102,47 @@
100
102
 
101
103
  // Activer l'observer DOM pour contenu dynamique
102
104
  this.setupObserver();
105
+
106
+ // Vérifier et réinitialiser les éléments non initialisés
107
+ this.checkAndReinitFailedElements();
108
+ },
109
+
110
+ // Nouvelle méthode pour vérifier et réinitialiser les éléments échoués
111
+ checkAndReinitFailedElements: function() {
112
+ const scope = document.querySelector('[data-bb-scope]') || document;
113
+ let needsReinit = false;
114
+
115
+ // Vérifier les marquees non initialisés
116
+ const marqueeElements = scope.querySelectorAll('[bb-marquee]:not([data-bb-marquee-processed])');
117
+ if (marqueeElements.length > 0) {
118
+ bbContents.utils.log('Marquees non initialisés détectés:', marqueeElements.length);
119
+ needsReinit = true;
120
+ }
121
+
122
+ // Vérifier les autres modules si nécessaire
123
+ Object.keys(this.modules).forEach(function(moduleName) {
124
+ const module = bbContents.modules[moduleName];
125
+ if (module.checkFailed && module.checkFailed(scope)) {
126
+ bbContents.utils.log('Module', moduleName, 'a des éléments échoués');
127
+ needsReinit = true;
128
+ }
129
+ });
130
+
131
+ // Réinitialiser si nécessaire et si on n'a pas dépassé le nombre max de tentatives
132
+ if (needsReinit && this._initRetryCount < this._maxInitRetries) {
133
+ this._initRetryCount++;
134
+ bbContents.utils.log('Tentative de réinitialisation', this._initRetryCount, '/', this._maxInitRetries);
135
+
136
+ setTimeout(() => {
137
+ this.init();
138
+ }, 500 * this._initRetryCount); // Délai progressif
139
+ }
140
+ },
141
+
142
+ // Méthode publique pour forcer la réinitialisation
143
+ reinit: function() {
144
+ this._initRetryCount = 0;
145
+ this.init();
103
146
  },
104
147
 
105
148
  // Observer DOM pour contenu dynamique
@@ -307,13 +350,20 @@
307
350
  }
308
351
  },
309
352
 
310
- // Module Marquee - Version live 1.0.0 avec protections
353
+ // Module Marquee - Version live 1.0.33-beta avec améliorations d'initialisation
311
354
  marquee: {
312
355
  detect: function(scope) {
313
356
  const s = scope || document;
314
357
  return s.querySelector(bbContents._attrSelector('marquee')) !== null;
315
358
  },
316
359
 
360
+ // Nouvelle méthode pour vérifier les éléments échoués
361
+ checkFailed: function(scope) {
362
+ const s = scope || document;
363
+ const failedElements = s.querySelectorAll('[bb-marquee]:not([data-bb-marquee-processed])');
364
+ return failedElements.length > 0;
365
+ },
366
+
317
367
  init: function(root) {
318
368
  const scope = root || document;
319
369
  if (scope.closest && scope.closest('[data-bb-disable]')) return;
@@ -399,28 +449,38 @@
399
449
  // Marquer l'élément comme traité par le module marquee
400
450
  element.setAttribute('data-bb-marquee-processed', 'true');
401
451
 
402
- // Fonction pour initialiser l'animation
403
- const initAnimation = () => {
452
+ // Fonction pour initialiser l'animation avec retry amélioré
453
+ const initAnimation = (retryCount = 0) => {
404
454
  // Attendre que le contenu soit dans le DOM
405
455
  requestAnimationFrame(() => {
406
456
  const contentWidth = mainBlock.offsetWidth;
407
457
  const contentHeight = mainBlock.offsetHeight;
408
458
 
409
- // Debug
410
- bbContents.utils.log('Debug - Largeur du contenu:', contentWidth, 'px', 'Hauteur:', contentHeight, 'px', 'Enfants:', mainBlock.children.length, 'Vertical:', isVertical, 'Direction:', direction);
459
+ // Debug amélioré
460
+ bbContents.utils.log('Debug - Largeur du contenu:', contentWidth, 'px', 'Hauteur:', contentHeight, 'px', 'Enfants:', mainBlock.children.length, 'Vertical:', isVertical, 'Direction:', direction, 'Tentative:', retryCount + 1);
411
461
 
412
- // Si pas de contenu, réessayer
462
+ // Si pas de contenu, réessayer avec délai progressif
413
463
  if ((isVertical && contentHeight === 0) || (!isVertical && contentWidth === 0)) {
414
- bbContents.utils.log('Contenu non prêt, nouvelle tentative dans 200ms');
415
- setTimeout(initAnimation, 200);
416
- return;
464
+ if (retryCount < 5) {
465
+ bbContents.utils.log('Contenu non prêt, nouvelle tentative dans', (200 + retryCount * 100), 'ms');
466
+ setTimeout(() => initAnimation(retryCount + 1), 200 + retryCount * 100);
467
+ return;
468
+ } else {
469
+ bbContents.utils.log('Échec d\'initialisation après 5 tentatives');
470
+ return;
471
+ }
417
472
  }
418
473
 
419
474
  // Pour le vertical, s'assurer qu'on a une hauteur minimale
420
475
  if (isVertical && contentHeight < 50) {
421
- bbContents.utils.log('Hauteur insuffisante pour le marquee vertical (' + contentHeight + 'px), nouvelle tentative dans 200ms');
422
- setTimeout(initAnimation, 200);
423
- return;
476
+ if (retryCount < 5) {
477
+ bbContents.utils.log('Hauteur insuffisante pour le marquee vertical (' + contentHeight + 'px), nouvelle tentative dans', (200 + retryCount * 100), 'ms');
478
+ setTimeout(() => initAnimation(retryCount + 1), 200 + retryCount * 100);
479
+ return;
480
+ } else {
481
+ bbContents.utils.log('Échec d\'initialisation - hauteur insuffisante après 5 tentatives');
482
+ return;
483
+ }
424
484
  }
425
485
 
426
486
  if (isVertical) {
@@ -519,8 +579,9 @@
519
579
  });
520
580
  };
521
581
 
522
- // Démarrer l'initialisation
523
- setTimeout(initAnimation, isVertical ? 300 : 100);
582
+ // Démarrer l'initialisation avec délai adaptatif
583
+ const initDelay = isVertical ? 300 : 100;
584
+ setTimeout(() => initAnimation(0), initDelay);
524
585
  });
525
586
 
526
587
  bbContents.utils.log('Module Marquee initialisé:', elements.length, 'éléments');
@@ -608,6 +669,7 @@
608
669
  const channelId = bbContents._getAttr(element, 'bb-youtube-channel');
609
670
  const videoCount = bbContents._getAttr(element, 'bb-youtube-video-count') || '10';
610
671
  const allowShorts = bbContents._getAttr(element, 'bb-youtube-allow-shorts') === 'true';
672
+ const language = bbContents._getAttr(element, 'bb-youtube-language') || 'fr';
611
673
  const endpoint = bbContents.config.youtubeEndpoint;
612
674
 
613
675
  if (!channelId) {
@@ -647,12 +709,12 @@
647
709
  element.setAttribute('data-bb-youtube-processed', 'true');
648
710
 
649
711
  // Vérifier le cache d'abord
650
- const cacheKey = `youtube_${channelId}_${videoCount}_${allowShorts}`;
712
+ const cacheKey = `youtube_${channelId}_${videoCount}_${allowShorts}_${language}`;
651
713
  const cachedData = this.cache.get(cacheKey);
652
714
 
653
715
  if (cachedData) {
654
716
  bbContents.utils.log('Données YouTube récupérées du cache (économie API)');
655
- this.generateYouTubeFeed(container, template, cachedData, allowShorts);
717
+ this.generateYouTubeFeed(container, template, cachedData, allowShorts, language);
656
718
  return;
657
719
  }
658
720
 
@@ -676,7 +738,7 @@
676
738
  this.cache.set(cacheKey, data);
677
739
  bbContents.utils.log('Données YouTube mises en cache pour 24h (économie API)');
678
740
 
679
- this.generateYouTubeFeed(container, template, data, allowShorts);
741
+ this.generateYouTubeFeed(container, template, data, allowShorts, language);
680
742
  })
681
743
  .catch(error => {
682
744
  bbContents.utils.log('Erreur dans le module youtube:', error);
@@ -699,7 +761,7 @@
699
761
  });
700
762
  },
701
763
 
702
- generateYouTubeFeed: function(container, template, data, allowShorts) {
764
+ generateYouTubeFeed: function(container, template, data, allowShorts, language = 'fr') {
703
765
  if (!data.items || data.items.length === 0) {
704
766
  container.innerHTML = '<div style="padding: 20px; text-align: center; color: #6b7280;">Aucune vidéo trouvée</div>';
705
767
  return;
@@ -728,7 +790,7 @@
728
790
  clone.style.display = ''; // Rendre visible
729
791
 
730
792
  // Remplir les données
731
- this.fillVideoData(clone, videoId, snippet);
793
+ this.fillVideoData(clone, videoId, snippet, language);
732
794
 
733
795
  // Ajouter au conteneur
734
796
  container.appendChild(clone);
@@ -737,7 +799,7 @@
737
799
  bbContents.utils.log(`YouTube Feed généré: ${videos.length} vidéos`);
738
800
  },
739
801
 
740
- fillVideoData: function(element, videoId, snippet) {
802
+ fillVideoData: function(element, videoId, snippet, language = 'fr') {
741
803
  // Remplir le lien directement sur l'élément (link block)
742
804
  if (element.tagName === 'A' || element.hasAttribute('bb-youtube-item')) {
743
805
  element.href = `https://www.youtube.com/watch?v=${videoId}`;
@@ -802,7 +864,7 @@
802
864
  // Remplir la date
803
865
  const date = element.querySelector('[bb-youtube-date]');
804
866
  if (date) {
805
- date.textContent = this.formatDate(snippet.publishedAt);
867
+ date.textContent = this.formatDate(snippet.publishedAt, language);
806
868
  }
807
869
 
808
870
  // Remplir le nom de la chaîne
@@ -812,17 +874,54 @@
812
874
  }
813
875
  },
814
876
 
815
- formatDate: function(dateString) {
877
+ formatDate: function(dateString, language = 'fr') {
816
878
  const date = new Date(dateString);
817
879
  const now = new Date();
818
880
  const diffTime = Math.abs(now - date);
819
881
  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
820
882
 
821
- if (diffDays === 1) return 'Il y a 1 jour';
822
- if (diffDays < 7) return `Il y a ${diffDays} jours`;
823
- if (diffDays < 30) return `Il y a ${Math.floor(diffDays / 7)} semaines`;
824
- if (diffDays < 365) return `Il y a ${Math.floor(diffDays / 30)} mois`;
825
- return `Il y a ${Math.floor(diffDays / 365)} ans`;
883
+ // Traductions
884
+ const translations = {
885
+ fr: {
886
+ day: 'jour',
887
+ days: 'jours',
888
+ week: 'semaine',
889
+ weeks: 'semaines',
890
+ month: 'mois',
891
+ months: 'mois',
892
+ year: 'an',
893
+ years: 'ans',
894
+ ago: 'Il y a'
895
+ },
896
+ en: {
897
+ day: 'day',
898
+ days: 'days',
899
+ week: 'week',
900
+ weeks: 'weeks',
901
+ month: 'month',
902
+ months: 'months',
903
+ year: 'year',
904
+ years: 'years',
905
+ ago: 'ago'
906
+ }
907
+ };
908
+
909
+ const t = translations[language] || translations.fr;
910
+
911
+ if (diffDays === 1) return `${t.ago} 1 ${t.day}`;
912
+ if (diffDays < 7) return `${t.ago} ${diffDays} ${t.days}`;
913
+
914
+ const weeks = Math.floor(diffDays / 7);
915
+ if (weeks === 1) return `${t.ago} 1 ${t.week}`;
916
+ if (diffDays < 30) return `${t.ago} ${weeks} ${t.weeks}`;
917
+
918
+ const months = Math.floor(diffDays / 30);
919
+ if (months === 1) return `${t.ago} 1 ${t.month}`;
920
+ if (diffDays < 365) return `${t.ago} ${months} ${t.months}`;
921
+
922
+ const years = Math.floor(diffDays / 365);
923
+ if (years === 1) return `${t.ago} 1 ${t.year}`;
924
+ return `${t.ago} ${years} ${t.years}`;
826
925
  },
827
926
 
828
927
  // Fonction pour décoder les entités HTML
@@ -885,6 +984,18 @@
885
984
  bbContents.init();
886
985
  }, 100);
887
986
  }
987
+
988
+ // Initialisation différée supplémentaire pour les cas difficiles
989
+ window.addEventListener('load', function() {
990
+ setTimeout(function() {
991
+ // Vérifier s'il y a des éléments non initialisés
992
+ const unprocessedMarquees = document.querySelectorAll('[bb-marquee]:not([data-bb-marquee-processed])');
993
+ if (unprocessedMarquees.length > 0) {
994
+ bbContents.utils.log('Éléments marquee non initialisés détectés après load, réinitialisation...');
995
+ bbContents.reinit();
996
+ }
997
+ }, 1000);
998
+ });
888
999
  }
889
1000
 
890
1001
  // Initialisation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bebranded/bb-contents",
3
- "version": "1.0.31-beta",
3
+ "version": "1.0.33-beta",
4
4
  "description": "Contenus additionnels français pour Webflow",
5
5
  "main": "bb-contents.js",
6
6
  "scripts": {