@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.
- package/bb-contents.js +140 -29
- 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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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
|
-
|
|
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
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
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
|