@bebranded/bb-contents 1.0.80-beta → 1.0.82-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 +404 -28
- package/package.json +1 -1
package/bb-contents.js
CHANGED
|
@@ -34,15 +34,13 @@
|
|
|
34
34
|
}
|
|
35
35
|
window._bbContentsInitialized = true;
|
|
36
36
|
|
|
37
|
-
// Log de démarrage
|
|
38
|
-
console.log('
|
|
39
|
-
console.log('🔍 [BB Contents] User Agent:', navigator.userAgent);
|
|
40
|
-
console.log('🔍 [BB Contents] Safari détecté:', /^((?!chrome|android).)*safari/i.test(navigator.userAgent));
|
|
37
|
+
// Log de démarrage simple
|
|
38
|
+
console.log('bb-contents | v1.0.82-beta');
|
|
41
39
|
|
|
42
40
|
// Configuration
|
|
43
41
|
const config = {
|
|
44
|
-
version: '1.0.
|
|
45
|
-
debug:
|
|
42
|
+
version: '1.0.82-beta',
|
|
43
|
+
debug: false, // Debug désactivé pour rendu propre
|
|
46
44
|
prefix: 'bb-', // utilisé pour générer les sélecteurs (data-bb-*)
|
|
47
45
|
youtubeEndpoint: null, // URL du worker YouTube (à définir par l'utilisateur)
|
|
48
46
|
i18n: {
|
|
@@ -247,7 +245,7 @@
|
|
|
247
245
|
subtree: true
|
|
248
246
|
});
|
|
249
247
|
|
|
250
|
-
|
|
248
|
+
this.utils.log('MutationObserver actif');
|
|
251
249
|
}
|
|
252
250
|
};
|
|
253
251
|
|
|
@@ -255,14 +253,14 @@
|
|
|
255
253
|
bbContents.modules = {
|
|
256
254
|
// Module Marquee - Version simplifiée et robuste
|
|
257
255
|
marquee: {
|
|
258
|
-
|
|
259
|
-
|
|
256
|
+
detect: function(scope) {
|
|
257
|
+
const s = scope || document;
|
|
260
258
|
return s.querySelector(bbContents._attrSelector('marquee')) !== null;
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
init: function(root) {
|
|
262
|
+
const scope = root || document;
|
|
263
|
+
if (scope.closest && scope.closest('[data-bb-disable]')) return;
|
|
266
264
|
const elements = scope.querySelectorAll(bbContents._attrSelector('marquee'));
|
|
267
265
|
|
|
268
266
|
console.log('🔍 [MARQUEE] Éléments trouvés:', elements.length);
|
|
@@ -273,9 +271,8 @@
|
|
|
273
271
|
if (element.bbProcessed || element.hasAttribute('data-bb-marquee-processed')) {
|
|
274
272
|
return;
|
|
275
273
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
console.log(`🔍 [MARQUEE] Initialisation ${index + 1}/${elements.length}`);
|
|
274
|
+
element.bbProcessed = true;
|
|
275
|
+
|
|
279
276
|
|
|
280
277
|
// Récupérer les options
|
|
281
278
|
const speed = bbContents._getAttr(element, 'bb-marquee-speed') || '100';
|
|
@@ -357,7 +354,6 @@
|
|
|
357
354
|
// Calculer les dimensions
|
|
358
355
|
const contentSize = isVertical ? mainBlock.offsetHeight : mainBlock.offsetWidth;
|
|
359
356
|
|
|
360
|
-
console.log(`🔍 [MARQUEE] Animation démarrée - contentSize: ${contentSize}px, isVertical: ${isVertical}`);
|
|
361
357
|
|
|
362
358
|
if (contentSize === 0) {
|
|
363
359
|
console.log('⚠️ [MARQUEE] Contenu vide, retry dans 200ms');
|
|
@@ -367,7 +363,6 @@
|
|
|
367
363
|
|
|
368
364
|
// Détection Safari
|
|
369
365
|
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
370
|
-
console.log(`🔍 [MARQUEE] Safari détecté: ${isSafari}`);
|
|
371
366
|
|
|
372
367
|
const gapSize = parseInt(gap);
|
|
373
368
|
const step = (parseFloat(speed) * (isVertical ? 1.5 : 0.8)) / 60;
|
|
@@ -389,14 +384,12 @@
|
|
|
389
384
|
initSafariAnimation: function(element, scrollContainer, mainBlock, options) {
|
|
390
385
|
const { speed, direction, gap, isVertical, useAutoHeight, contentSize, gapSize } = options;
|
|
391
386
|
|
|
392
|
-
console.log(`🔍 [MARQUEE] Safari Animation - direction: ${direction}, isVertical: ${isVertical}, contentSize: ${contentSize}`);
|
|
393
387
|
|
|
394
388
|
// SOLUTION SAFARI : Forcer le chargement des images avant animation
|
|
395
389
|
const images = mainBlock.querySelectorAll('img');
|
|
396
390
|
let imagesLoaded = 0;
|
|
397
391
|
const totalImages = images.length;
|
|
398
392
|
|
|
399
|
-
console.log(`🔍 [MARQUEE] Safari - ${totalImages} images détectées`);
|
|
400
393
|
|
|
401
394
|
// Forcer le chargement de toutes les images
|
|
402
395
|
images.forEach(img => {
|
|
@@ -406,17 +399,14 @@
|
|
|
406
399
|
}
|
|
407
400
|
img.onload = () => {
|
|
408
401
|
imagesLoaded++;
|
|
409
|
-
console.log(`🖼️ [MARQUEE] Safari - Image ${imagesLoaded}/${totalImages} chargée`);
|
|
410
402
|
};
|
|
411
403
|
img.onerror = () => {
|
|
412
404
|
imagesLoaded++;
|
|
413
|
-
console.log(`❌ [MARQUEE] Safari - Image ${imagesLoaded}/${totalImages} erreur de chargement`);
|
|
414
405
|
};
|
|
415
406
|
});
|
|
416
407
|
|
|
417
408
|
// SOLUTION SAFARI MOBILE SIMPLE : Attendre plus longtemps
|
|
418
409
|
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
|
419
|
-
console.log(`🔍 [MARQUEE] Safari - Mobile détecté: ${isMobile}`);
|
|
420
410
|
|
|
421
411
|
// Timeout plus long sur mobile pour laisser le temps aux images de se charger
|
|
422
412
|
const maxWaitTime = isMobile ? 5000 : 3000; // 5 secondes sur mobile
|
|
@@ -497,7 +487,7 @@
|
|
|
497
487
|
let currentPosition;
|
|
498
488
|
if (direction === (isVertical ? 'bottom' : 'right')) {
|
|
499
489
|
currentPosition = -(finalContentSize + gapSize);
|
|
500
|
-
|
|
490
|
+
} else {
|
|
501
491
|
currentPosition = 0;
|
|
502
492
|
}
|
|
503
493
|
|
|
@@ -521,7 +511,7 @@
|
|
|
521
511
|
console.log(`🔄 [MARQUEE] Safari RESET bottom/right: ${currentPosition} → ${-(finalContentSize + gapSize)}`);
|
|
522
512
|
currentPosition = -(finalContentSize + gapSize);
|
|
523
513
|
}
|
|
524
|
-
|
|
514
|
+
} else {
|
|
525
515
|
currentPosition -= step;
|
|
526
516
|
if (currentPosition <= -(2 * (finalContentSize + gapSize))) {
|
|
527
517
|
console.log(`🔄 [MARQUEE] Safari RESET top/left: ${currentPosition} → ${-(finalContentSize + gapSize)}`);
|
|
@@ -619,6 +609,392 @@
|
|
|
619
609
|
}
|
|
620
610
|
},
|
|
621
611
|
|
|
612
|
+
// Module Share (Partage Social)
|
|
613
|
+
share: {
|
|
614
|
+
// Configuration des réseaux
|
|
615
|
+
networks: {
|
|
616
|
+
twitter: function(data) {
|
|
617
|
+
return 'https://twitter.com/intent/tweet?url=' +
|
|
618
|
+
encodeURIComponent(data.url) +
|
|
619
|
+
'&text=' + encodeURIComponent(data.text);
|
|
620
|
+
},
|
|
621
|
+
facebook: function(data) {
|
|
622
|
+
return 'https://facebook.com/sharer/sharer.php?u=' +
|
|
623
|
+
encodeURIComponent(data.url);
|
|
624
|
+
},
|
|
625
|
+
linkedin: function(data) {
|
|
626
|
+
// LinkedIn - URL de partage officielle (2024+)
|
|
627
|
+
return 'https://www.linkedin.com/sharing/share-offsite/?url=' + encodeURIComponent(data.url);
|
|
628
|
+
},
|
|
629
|
+
whatsapp: function(data) {
|
|
630
|
+
return 'https://wa.me/?text=' +
|
|
631
|
+
encodeURIComponent(data.text + ' ' + data.url);
|
|
632
|
+
},
|
|
633
|
+
telegram: function(data) {
|
|
634
|
+
return 'https://t.me/share/url?url=' +
|
|
635
|
+
encodeURIComponent(data.url) +
|
|
636
|
+
'&text=' + encodeURIComponent(data.text);
|
|
637
|
+
},
|
|
638
|
+
email: function(data) {
|
|
639
|
+
return 'mailto:?subject=' +
|
|
640
|
+
encodeURIComponent(data.text) +
|
|
641
|
+
'&body=' + encodeURIComponent(data.text + ' ' + data.url);
|
|
642
|
+
},
|
|
643
|
+
copy: function(data) {
|
|
644
|
+
return 'copy:' + data.url;
|
|
645
|
+
},
|
|
646
|
+
native: function(data) {
|
|
647
|
+
return 'native:' + JSON.stringify(data);
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
|
|
651
|
+
// Détection
|
|
652
|
+
detect: function(scope) {
|
|
653
|
+
const s = scope || document;
|
|
654
|
+
return s.querySelector(bbContents._attrSelector('share')) !== null;
|
|
655
|
+
},
|
|
656
|
+
|
|
657
|
+
// Initialisation
|
|
658
|
+
init: function(root) {
|
|
659
|
+
const scope = root || document;
|
|
660
|
+
if (scope.closest && scope.closest('[data-bb-disable]')) return;
|
|
661
|
+
const elements = scope.querySelectorAll(bbContents._attrSelector('share'));
|
|
662
|
+
|
|
663
|
+
elements.forEach(function(element) {
|
|
664
|
+
// Vérifier si déjà traité
|
|
665
|
+
if (element.bbProcessed) return;
|
|
666
|
+
element.bbProcessed = true;
|
|
667
|
+
|
|
668
|
+
// Récupérer les données
|
|
669
|
+
const network = bbContents._getAttr(element, 'bb-share');
|
|
670
|
+
const customUrl = bbContents._getAttr(element, 'bb-url');
|
|
671
|
+
const customText = bbContents._getAttr(element, 'bb-text');
|
|
672
|
+
|
|
673
|
+
// Valeurs par défaut sécurisées
|
|
674
|
+
const data = {
|
|
675
|
+
url: bbContents.utils.isValidUrl(customUrl) ? customUrl : window.location.href,
|
|
676
|
+
text: bbContents.utils.sanitize(customText || document.title || 'Découvrez ce site')
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
// Gestionnaire de clic
|
|
680
|
+
element.addEventListener('click', function(e) {
|
|
681
|
+
e.preventDefault();
|
|
682
|
+
bbContents.modules.share.share(network, data, element);
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
// Accessibilité
|
|
686
|
+
if (element.tagName !== 'BUTTON' && element.tagName !== 'A') {
|
|
687
|
+
element.setAttribute('role', 'button');
|
|
688
|
+
element.setAttribute('tabindex', '0');
|
|
689
|
+
|
|
690
|
+
// Support clavier
|
|
691
|
+
element.addEventListener('keydown', function(e) {
|
|
692
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
693
|
+
e.preventDefault();
|
|
694
|
+
bbContents.modules.share.share(network, data, element);
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
element.style.cursor = 'pointer';
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
bbContents.utils.log('Module Share initialisé:', elements.length, 'éléments');
|
|
703
|
+
},
|
|
704
|
+
|
|
705
|
+
// Fonction de partage
|
|
706
|
+
share: function(network, data, element) {
|
|
707
|
+
const networkFunc = this.networks[network];
|
|
708
|
+
|
|
709
|
+
if (!networkFunc) {
|
|
710
|
+
console.error('[BB Contents] Réseau non supporté:', network);
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const shareUrl = networkFunc(data);
|
|
715
|
+
|
|
716
|
+
// Cas spécial : copier le lien
|
|
717
|
+
if (shareUrl.startsWith('copy:')) {
|
|
718
|
+
const url = shareUrl.substring(5);
|
|
719
|
+
// Copie silencieuse (pas de feedback visuel)
|
|
720
|
+
this.copyToClipboard(url, element, true);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Cas spécial : partage natif (Web Share API)
|
|
725
|
+
if (shareUrl.startsWith('native:')) {
|
|
726
|
+
const shareData = JSON.parse(shareUrl.substring(7));
|
|
727
|
+
this.nativeShare(shareData, element);
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// Ouvrir popup de partage
|
|
732
|
+
const width = 600;
|
|
733
|
+
const height = 400;
|
|
734
|
+
const left = (window.innerWidth - width) / 2;
|
|
735
|
+
const top = (window.innerHeight - height) / 2;
|
|
736
|
+
|
|
737
|
+
window.open(
|
|
738
|
+
shareUrl,
|
|
739
|
+
'bbshare',
|
|
740
|
+
'width=' + width + ',height=' + height + ',left=' + left + ',top=' + top + ',noopener,noreferrer'
|
|
741
|
+
);
|
|
742
|
+
|
|
743
|
+
bbContents.utils.log('Partage sur', network, data);
|
|
744
|
+
},
|
|
745
|
+
|
|
746
|
+
// Copier dans le presse-papier
|
|
747
|
+
copyToClipboard: function(text, element, silent) {
|
|
748
|
+
const isSilent = !!silent;
|
|
749
|
+
// Méthode moderne
|
|
750
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
751
|
+
navigator.clipboard.writeText(text).then(function() {
|
|
752
|
+
if (!isSilent) {
|
|
753
|
+
bbContents.modules.share.showFeedback(element, '✓ ' + (bbContents.config.i18n.copied || 'Lien copié !'));
|
|
754
|
+
}
|
|
755
|
+
}).catch(function() {
|
|
756
|
+
bbContents.modules.share.fallbackCopy(text, element, isSilent);
|
|
757
|
+
});
|
|
758
|
+
} else {
|
|
759
|
+
// Fallback pour environnements sans Clipboard API
|
|
760
|
+
this.fallbackCopy(text, element, isSilent);
|
|
761
|
+
}
|
|
762
|
+
},
|
|
763
|
+
|
|
764
|
+
// Fallback copie
|
|
765
|
+
fallbackCopy: function(text, element, silent) {
|
|
766
|
+
const isSilent = !!silent;
|
|
767
|
+
// Pas de UI si silencieux (exigence produit)
|
|
768
|
+
if (isSilent) return;
|
|
769
|
+
try {
|
|
770
|
+
// Afficher un prompt natif pour permettre à l'utilisateur de copier manuellement
|
|
771
|
+
// (solution universelle sans execCommand)
|
|
772
|
+
window.prompt('Copiez le lien ci-dessous (Ctrl/Cmd+C) :', text);
|
|
773
|
+
} catch (err) {
|
|
774
|
+
// Dernier recours: ne rien faire
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
|
|
778
|
+
// Partage natif (Web Share API)
|
|
779
|
+
nativeShare: function(data, element) {
|
|
780
|
+
// Vérifier si Web Share API est disponible
|
|
781
|
+
if (navigator.share) {
|
|
782
|
+
navigator.share({
|
|
783
|
+
title: data.text,
|
|
784
|
+
url: data.url
|
|
785
|
+
}).then(function() {
|
|
786
|
+
bbContents.utils.log('Partage natif réussi');
|
|
787
|
+
}).catch(function(error) {
|
|
788
|
+
if (error.name !== 'AbortError') {
|
|
789
|
+
console.error('[BB Contents] Erreur partage natif:', error);
|
|
790
|
+
// Fallback vers copie si échec
|
|
791
|
+
bbContents.modules.share.copyToClipboard(data.url, element, false);
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
} else {
|
|
795
|
+
// Fallback si Web Share API non disponible
|
|
796
|
+
bbContents.utils.log('Web Share API non disponible, fallback vers copie');
|
|
797
|
+
this.copyToClipboard(data.url, element, false);
|
|
798
|
+
}
|
|
799
|
+
},
|
|
800
|
+
|
|
801
|
+
// Feedback visuel
|
|
802
|
+
showFeedback: function(element, message) {
|
|
803
|
+
const originalText = element.textContent;
|
|
804
|
+
element.textContent = message;
|
|
805
|
+
element.style.pointerEvents = 'none';
|
|
806
|
+
|
|
807
|
+
setTimeout(function() {
|
|
808
|
+
element.textContent = originalText;
|
|
809
|
+
element.style.pointerEvents = '';
|
|
810
|
+
}, 2000);
|
|
811
|
+
}
|
|
812
|
+
},
|
|
813
|
+
|
|
814
|
+
// Module Current Year (Année courante)
|
|
815
|
+
currentYear: {
|
|
816
|
+
detect: function(scope) {
|
|
817
|
+
const s = scope || document;
|
|
818
|
+
return s.querySelector(bbContents._attrSelector('current-year')) !== null;
|
|
819
|
+
},
|
|
820
|
+
init: function(root) {
|
|
821
|
+
const scope = root || document;
|
|
822
|
+
if (scope.closest && scope.closest('[data-bb-disable]')) return;
|
|
823
|
+
const elements = scope.querySelectorAll(bbContents._attrSelector('current-year'));
|
|
824
|
+
|
|
825
|
+
const year = String(new Date().getFullYear());
|
|
826
|
+
elements.forEach(function(element) {
|
|
827
|
+
if (element.bbProcessed) return;
|
|
828
|
+
element.bbProcessed = true;
|
|
829
|
+
|
|
830
|
+
const customFormat = bbContents._getAttr(element, 'bb-current-year-format');
|
|
831
|
+
const prefix = bbContents._getAttr(element, 'bb-current-year-prefix');
|
|
832
|
+
const suffix = bbContents._getAttr(element, 'bb-current-year-suffix');
|
|
833
|
+
|
|
834
|
+
if (customFormat && customFormat.includes('{year}')) {
|
|
835
|
+
element.textContent = customFormat.replace('{year}', year);
|
|
836
|
+
} else if (prefix || suffix) {
|
|
837
|
+
element.textContent = prefix + year + suffix;
|
|
838
|
+
} else {
|
|
839
|
+
element.textContent = year;
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
bbContents.utils.log('Module CurrentYear initialisé:', elements.length, 'éléments');
|
|
844
|
+
}
|
|
845
|
+
},
|
|
846
|
+
|
|
847
|
+
// Module Reading Time (Temps de lecture)
|
|
848
|
+
readingTime: {
|
|
849
|
+
detect: function(scope) {
|
|
850
|
+
const s = scope || document;
|
|
851
|
+
return s.querySelector(bbContents._attrSelector('reading-time')) !== null;
|
|
852
|
+
},
|
|
853
|
+
init: function(root) {
|
|
854
|
+
const scope = root || document;
|
|
855
|
+
if (scope.closest && scope.closest('[data-bb-disable]')) return;
|
|
856
|
+
const elements = scope.querySelectorAll(bbContents._attrSelector('reading-time'));
|
|
857
|
+
|
|
858
|
+
elements.forEach(function(element) {
|
|
859
|
+
if (element.bbProcessed) return;
|
|
860
|
+
element.bbProcessed = true;
|
|
861
|
+
|
|
862
|
+
const targetSelector = bbContents._getAttr(element, 'bb-reading-time-target');
|
|
863
|
+
const speedAttr = bbContents._getAttr(element, 'bb-reading-time-speed');
|
|
864
|
+
const imageSpeedAttr = bbContents._getAttr(element, 'bb-reading-time-image-speed');
|
|
865
|
+
const format = bbContents._getAttr(element, 'bb-reading-time-format') || '{minutes} min';
|
|
866
|
+
|
|
867
|
+
const wordsPerMinute = Number(speedAttr) > 0 ? Number(speedAttr) : 230;
|
|
868
|
+
const secondsPerImage = Number(imageSpeedAttr) > 0 ? Number(imageSpeedAttr) : 12;
|
|
869
|
+
|
|
870
|
+
// Validation des valeurs
|
|
871
|
+
if (isNaN(wordsPerMinute) || wordsPerMinute <= 0) {
|
|
872
|
+
bbContents.utils.log('Vitesse de lecture invalide, utilisation de la valeur par défaut (230)');
|
|
873
|
+
}
|
|
874
|
+
if (isNaN(secondsPerImage) || secondsPerImage < 0) {
|
|
875
|
+
bbContents.utils.log('Temps par image invalide, utilisation de la valeur par défaut (12)');
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
let sourceNode = element;
|
|
879
|
+
if (targetSelector) {
|
|
880
|
+
const found = document.querySelector(targetSelector);
|
|
881
|
+
if (found) sourceNode = found;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const text = (sourceNode.textContent || '').trim();
|
|
885
|
+
const wordCount = text ? (text.match(/\b\w+\b/g) || []).length : 0;
|
|
886
|
+
|
|
887
|
+
// Compter les images dans le contenu ciblé
|
|
888
|
+
const images = sourceNode.querySelectorAll('img');
|
|
889
|
+
const imageCount = images.length;
|
|
890
|
+
const imageTimeInMinutes = (imageCount * secondsPerImage) / 60;
|
|
891
|
+
|
|
892
|
+
let minutesFloat = (wordCount / wordsPerMinute) + imageTimeInMinutes;
|
|
893
|
+
let minutes = Math.ceil(minutesFloat);
|
|
894
|
+
|
|
895
|
+
if ((wordCount > 0 || imageCount > 0) && minutes < 1) minutes = 1; // affichage minimal 1 min si contenu non vide
|
|
896
|
+
if (wordCount === 0 && imageCount === 0) minutes = 0;
|
|
897
|
+
|
|
898
|
+
const output = format.replace('{minutes}', String(minutes));
|
|
899
|
+
element.textContent = output;
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
bbContents.utils.log('Module ReadingTime initialisé:', elements.length, 'éléments');
|
|
903
|
+
}
|
|
904
|
+
},
|
|
905
|
+
|
|
906
|
+
// Module Favicon (Favicon Dynamique)
|
|
907
|
+
favicon: {
|
|
908
|
+
originalFavicon: null,
|
|
909
|
+
|
|
910
|
+
// Détection
|
|
911
|
+
detect: function(scope) {
|
|
912
|
+
const s = scope || document;
|
|
913
|
+
return s.querySelector(bbContents._attrSelector('favicon')) !== null;
|
|
914
|
+
},
|
|
915
|
+
|
|
916
|
+
// Initialisation
|
|
917
|
+
init: function(root) {
|
|
918
|
+
const scope = root || document;
|
|
919
|
+
if (scope.closest && scope.closest('[data-bb-disable]')) return;
|
|
920
|
+
|
|
921
|
+
// Chercher les éléments avec bb-favicon ou bb-favicon-dark
|
|
922
|
+
const elements = scope.querySelectorAll(bbContents._attrSelector('favicon') + ', ' + bbContents._attrSelector('favicon-dark'));
|
|
923
|
+
if (elements.length === 0) return;
|
|
924
|
+
|
|
925
|
+
// Sauvegarder le favicon original
|
|
926
|
+
const existingLink = document.querySelector("link[rel*='icon']");
|
|
927
|
+
if (existingLink) {
|
|
928
|
+
this.originalFavicon = existingLink.href;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// Collecter les URLs depuis tous les éléments
|
|
932
|
+
let faviconUrl = null;
|
|
933
|
+
let darkUrl = null;
|
|
934
|
+
|
|
935
|
+
elements.forEach(function(element) {
|
|
936
|
+
const light = bbContents._getAttr(element, 'bb-favicon') || bbContents._getAttr(element, 'favicon');
|
|
937
|
+
const dark = bbContents._getAttr(element, 'bb-favicon-dark') || bbContents._getAttr(element, 'favicon-dark');
|
|
938
|
+
|
|
939
|
+
if (light) faviconUrl = light;
|
|
940
|
+
if (dark) darkUrl = dark;
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
// Appliquer la logique
|
|
944
|
+
if (faviconUrl && darkUrl) {
|
|
945
|
+
this.setupDarkMode(faviconUrl, darkUrl);
|
|
946
|
+
} else if (faviconUrl) {
|
|
947
|
+
this.setFavicon(faviconUrl);
|
|
948
|
+
bbContents.utils.log('Favicon changé:', faviconUrl);
|
|
949
|
+
}
|
|
950
|
+
},
|
|
951
|
+
|
|
952
|
+
// Helper: Récupérer ou créer un élément favicon
|
|
953
|
+
getFaviconElement: function() {
|
|
954
|
+
let favicon = document.querySelector('link[rel="icon"]') ||
|
|
955
|
+
document.querySelector('link[rel="shortcut icon"]');
|
|
956
|
+
if (!favicon) {
|
|
957
|
+
favicon = document.createElement('link');
|
|
958
|
+
favicon.rel = 'icon';
|
|
959
|
+
document.head.appendChild(favicon);
|
|
960
|
+
}
|
|
961
|
+
return favicon;
|
|
962
|
+
},
|
|
963
|
+
|
|
964
|
+
// Changer le favicon
|
|
965
|
+
setFavicon: function(url) {
|
|
966
|
+
if (!url) return;
|
|
967
|
+
|
|
968
|
+
// Ajouter un timestamp pour forcer le rafraîchissement du cache
|
|
969
|
+
const cacheBuster = '?v=' + Date.now();
|
|
970
|
+
const urlWithCacheBuster = url + cacheBuster;
|
|
971
|
+
|
|
972
|
+
const favicon = this.getFaviconElement();
|
|
973
|
+
favicon.href = urlWithCacheBuster;
|
|
974
|
+
},
|
|
975
|
+
|
|
976
|
+
// Support dark mode (méthode simplifiée et directe)
|
|
977
|
+
setupDarkMode: function(lightUrl, darkUrl) {
|
|
978
|
+
// Fonction pour mettre à jour le favicon selon le mode sombre
|
|
979
|
+
const updateFavicon = function(e) {
|
|
980
|
+
const darkModeOn = e ? e.matches : window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
981
|
+
const selectedUrl = darkModeOn ? darkUrl : lightUrl;
|
|
982
|
+
bbContents.modules.favicon.setFavicon(selectedUrl);
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
// Initialiser le favicon au chargement de la page
|
|
986
|
+
updateFavicon();
|
|
987
|
+
|
|
988
|
+
// Écouter les changements du mode sombre
|
|
989
|
+
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
990
|
+
if (typeof darkModeMediaQuery.addEventListener === 'function') {
|
|
991
|
+
darkModeMediaQuery.addEventListener('change', updateFavicon);
|
|
992
|
+
} else if (typeof darkModeMediaQuery.addListener === 'function') {
|
|
993
|
+
darkModeMediaQuery.addListener(updateFavicon);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
},
|
|
997
|
+
|
|
622
998
|
// Module YouTube Feed
|
|
623
999
|
youtube: {
|
|
624
1000
|
// Détection des bots pour éviter les appels API inutiles
|
|
@@ -932,8 +1308,8 @@
|
|
|
932
1308
|
// Debug: logger la qualité utilisée (en mode debug seulement)
|
|
933
1309
|
if (bbContents.config.debug) {
|
|
934
1310
|
// Thumbnail optimisée
|
|
935
|
-
|
|
936
|
-
|
|
1311
|
+
}
|
|
1312
|
+
} else {
|
|
937
1313
|
// Aucune thumbnail disponible
|
|
938
1314
|
}
|
|
939
1315
|
}
|