@bebranded/bb-contents 1.0.44-beta → 1.0.46-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 +145 -102
  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.44-beta
4
+ * @version 1.0.46-beta
5
5
  * @author BeBranded
6
6
  * @license MIT
7
7
  * @website https://www.bebranded.xyz
@@ -9,6 +9,11 @@
9
9
  (function() {
10
10
  'use strict';
11
11
 
12
+ // Créer l'objet temporaire pour la configuration si il n'existe pas
13
+ if (!window._bbContentsConfig) {
14
+ window._bbContentsConfig = {};
15
+ }
16
+
12
17
  // Protection contre le double chargement
13
18
  if (window.bbContents) {
14
19
  console.warn('BeBranded Contents est déjà chargé');
@@ -17,7 +22,7 @@
17
22
 
18
23
  // Configuration
19
24
  const config = {
20
- version: '1.0.44-beta',
25
+ version: '1.0.46-beta',
21
26
  debug: true, // Activé temporairement pour debug
22
27
  prefix: 'bb-', // utilisé pour générer les sélecteurs (data-bb-*)
23
28
  youtubeEndpoint: null, // URL du worker YouTube (à définir par l'utilisateur)
@@ -25,6 +30,16 @@
25
30
  copied: 'Lien copié !'
26
31
  }
27
32
  };
33
+
34
+ // Détecter la configuration YouTube définie avant le chargement
35
+ if (window.bbContents && window.bbContents.config && window.bbContents.config.youtubeEndpoint) {
36
+ config.youtubeEndpoint = window.bbContents.config.youtubeEndpoint;
37
+ }
38
+
39
+ // Détecter la configuration dans l'objet temporaire
40
+ if (window._bbContentsConfig && window._bbContentsConfig.youtubeEndpoint) {
41
+ config.youtubeEndpoint = window._bbContentsConfig.youtubeEndpoint;
42
+ }
28
43
 
29
44
  // Objet principal
30
45
  const bbContents = {
@@ -155,6 +170,24 @@
155
170
  this._initRetryCount = 0;
156
171
  this.init();
157
172
  },
173
+
174
+ // Méthode pour détecter la configuration YouTube définie après le chargement
175
+ checkYouTubeConfig: function() {
176
+ // Vérifier si la configuration a été définie après le chargement
177
+ if (this.config.youtubeEndpoint) {
178
+ console.log('[DEBUG] YouTube endpoint found:', this.config.youtubeEndpoint);
179
+ return true;
180
+ }
181
+
182
+ // Vérifier dans l'objet temporaire
183
+ if (window._bbContentsConfig && window._bbContentsConfig.youtubeEndpoint) {
184
+ this.config.youtubeEndpoint = window._bbContentsConfig.youtubeEndpoint;
185
+ console.log('[DEBUG] YouTube endpoint found in temp config:', this.config.youtubeEndpoint);
186
+ return true;
187
+ }
188
+
189
+ return false;
190
+ },
158
191
 
159
192
  // Observer DOM pour contenu dynamique
160
193
  setupObserver: function() {
@@ -205,32 +238,32 @@
205
238
  bbContents.modules = {
206
239
  // Module Marquee - Version live 1.0.41-beta avec modules parasites supprimés
207
240
  marquee: {
208
- detect: function(scope) {
209
- const s = scope || document;
241
+ detect: function(scope) {
242
+ const s = scope || document;
210
243
  return s.querySelector(bbContents._attrSelector('marquee')) !== null;
211
244
  },
212
245
 
213
246
  // Nouvelle méthode pour vérifier les éléments échoués
214
247
  checkFailed: function(scope) {
215
- const s = scope || document;
248
+ const s = scope || document;
216
249
  const failedElements = s.querySelectorAll('[bb-marquee]:not([data-bb-marquee-processed])');
217
250
  return failedElements.length > 0;
218
- },
219
-
220
- init: function(root) {
221
- const scope = root || document;
222
- if (scope.closest && scope.closest('[data-bb-disable]')) return;
223
- const elements = scope.querySelectorAll(bbContents._attrSelector('marquee'));
251
+ },
252
+
253
+ init: function(root) {
254
+ const scope = root || document;
255
+ if (scope.closest && scope.closest('[data-bb-disable]')) return;
256
+ const elements = scope.querySelectorAll(bbContents._attrSelector('marquee'));
224
257
 
225
- elements.forEach(function(element) {
258
+ elements.forEach(function(element) {
226
259
  // Vérifier si l'élément a déjà été traité par un autre module
227
260
  if (element.bbProcessed || element.hasAttribute('data-bb-youtube-processed')) {
228
261
  // Élément marquee déjà traité par un autre module, ignoré
229
262
  return;
230
263
  }
231
- element.bbProcessed = true;
264
+ element.bbProcessed = true;
232
265
 
233
- // Récupérer les options
266
+ // Récupérer les options
234
267
  const speed = bbContents._getAttr(element, 'bb-marquee-speed') || '100';
235
268
  const direction = bbContents._getAttr(element, 'bb-marquee-direction') || 'left';
236
269
  const pauseOnHover = bbContents._getAttr(element, 'bb-marquee-pause');
@@ -239,67 +272,67 @@
239
272
  const height = bbContents._getAttr(element, 'bb-marquee-height') || '300';
240
273
  const minHeight = bbContents._getAttr(element, 'bb-marquee-min-height');
241
274
 
242
- // Sauvegarder le contenu original
243
- const originalHTML = element.innerHTML;
244
-
245
- // Créer le conteneur principal
246
- const mainContainer = document.createElement('div');
247
- const isVertical = orientation === 'vertical';
275
+ // Sauvegarder le contenu original
276
+ const originalHTML = element.innerHTML;
277
+
278
+ // Créer le conteneur principal
279
+ const mainContainer = document.createElement('div');
280
+ const isVertical = orientation === 'vertical';
248
281
  const useAutoHeight = isVertical && height === 'auto';
249
282
 
250
- mainContainer.style.cssText = `
251
- position: relative;
252
- width: 100%;
283
+ mainContainer.style.cssText = `
284
+ position: relative;
285
+ width: 100%;
253
286
  height: ${isVertical ? (height === 'auto' ? 'auto' : height + 'px') : 'auto'};
254
- overflow: hidden;
255
- min-height: ${isVertical ? '100px' : '50px'};
287
+ overflow: hidden;
288
+ min-height: ${isVertical ? '100px' : '50px'};
256
289
  ${minHeight ? `min-height: ${minHeight};` : ''}
257
- `;
290
+ `;
258
291
 
259
- // Créer le conteneur de défilement
260
- const scrollContainer = document.createElement('div');
261
- scrollContainer.style.cssText = `
292
+ // Créer le conteneur de défilement
293
+ const scrollContainer = document.createElement('div');
294
+ scrollContainer.style.cssText = `
262
295
  ${useAutoHeight ? 'position: relative;' : 'position: absolute;'}
263
- will-change: transform;
296
+ will-change: transform;
264
297
  ${useAutoHeight ? '' : 'height: 100%; top: 0px; left: 0px;'}
265
- display: flex;
266
- ${isVertical ? 'flex-direction: column;' : ''}
267
- align-items: center;
268
- gap: ${gap}px;
269
- ${isVertical ? '' : 'white-space: nowrap;'}
270
- flex-shrink: 0;
298
+ display: flex;
299
+ ${isVertical ? 'flex-direction: column;' : ''}
300
+ align-items: center;
301
+ gap: ${gap}px;
302
+ ${isVertical ? '' : 'white-space: nowrap;'}
303
+ flex-shrink: 0;
271
304
  transition: transform 0.1s ease-out;
272
- `;
305
+ `;
273
306
 
274
- // Créer le bloc de contenu principal
275
- const mainBlock = document.createElement('div');
276
- mainBlock.innerHTML = originalHTML;
277
- mainBlock.style.cssText = `
278
- display: flex;
279
- ${isVertical ? 'flex-direction: column;' : ''}
280
- align-items: center;
281
- gap: ${gap}px;
282
- ${isVertical ? '' : 'white-space: nowrap;'}
283
- flex-shrink: 0;
284
- ${isVertical ? 'min-height: 100px;' : ''}
285
- `;
307
+ // Créer le bloc de contenu principal
308
+ const mainBlock = document.createElement('div');
309
+ mainBlock.innerHTML = originalHTML;
310
+ mainBlock.style.cssText = `
311
+ display: flex;
312
+ ${isVertical ? 'flex-direction: column;' : ''}
313
+ align-items: center;
314
+ gap: ${gap}px;
315
+ ${isVertical ? '' : 'white-space: nowrap;'}
316
+ flex-shrink: 0;
317
+ ${isVertical ? 'min-height: 100px;' : ''}
318
+ `;
319
+
320
+ // Créer plusieurs répétitions pour un défilement continu
321
+ const repeatBlock1 = mainBlock.cloneNode(true);
322
+ const repeatBlock2 = mainBlock.cloneNode(true);
323
+ const repeatBlock3 = mainBlock.cloneNode(true);
324
+
325
+ // Assembler la structure
326
+ scrollContainer.appendChild(mainBlock);
327
+ scrollContainer.appendChild(repeatBlock1);
328
+ scrollContainer.appendChild(repeatBlock2);
329
+ scrollContainer.appendChild(repeatBlock3);
330
+ mainContainer.appendChild(scrollContainer);
331
+
332
+ // Vider et remplacer le contenu original
333
+ element.innerHTML = '';
334
+ element.appendChild(mainContainer);
286
335
 
287
- // Créer plusieurs répétitions pour un défilement continu
288
- const repeatBlock1 = mainBlock.cloneNode(true);
289
- const repeatBlock2 = mainBlock.cloneNode(true);
290
- const repeatBlock3 = mainBlock.cloneNode(true);
291
-
292
- // Assembler la structure
293
- scrollContainer.appendChild(mainBlock);
294
- scrollContainer.appendChild(repeatBlock1);
295
- scrollContainer.appendChild(repeatBlock2);
296
- scrollContainer.appendChild(repeatBlock3);
297
- mainContainer.appendChild(scrollContainer);
298
-
299
- // Vider et remplacer le contenu original
300
- element.innerHTML = '';
301
- element.appendChild(mainContainer);
302
-
303
336
  // Marquer l'élément comme traité par le module marquee
304
337
  element.setAttribute('data-bb-marquee-processed', 'true');
305
338
 
@@ -310,7 +343,7 @@
310
343
  const imagesLoaded = Array.from(images).every(img => img.complete && img.naturalHeight > 0);
311
344
 
312
345
  // Attendre que le contenu soit dans le DOM et que les images soient chargées
313
- requestAnimationFrame(() => {
346
+ requestAnimationFrame(() => {
314
347
  // Calcul plus robuste des dimensions
315
348
  const rect = mainBlock.getBoundingClientRect();
316
349
  const contentWidth = rect.width || mainBlock.offsetWidth;
@@ -342,24 +375,24 @@
342
375
  return;
343
376
  } else {
344
377
  // Échec d'initialisation après plusieurs tentatives
345
- return;
378
+ return;
346
379
  }
347
- }
348
-
349
- if (isVertical) {
350
- // Animation JavaScript pour le vertical
380
+ }
381
+
382
+ if (isVertical) {
383
+ // Animation JavaScript pour le vertical
351
384
  const contentSize = finalHeight;
352
- const totalSize = contentSize * 4 + parseInt(gap) * 3; // 4 copies au lieu de 3
385
+ const totalSize = contentSize * 4 + parseInt(gap) * 3; // 4 copies au lieu de 3
353
386
 
354
387
  // Ajuster la hauteur du scrollContainer seulement si pas en mode auto
355
388
  if (!useAutoHeight) {
356
- scrollContainer.style.height = totalSize + 'px';
389
+ scrollContainer.style.height = totalSize + 'px';
357
390
  }
358
-
359
- let currentPosition = direction === 'bottom' ? -contentSize - parseInt(gap) : 0;
391
+
392
+ let currentPosition = direction === 'bottom' ? -contentSize - parseInt(gap) : 0;
360
393
  const baseStep = (parseFloat(speed) * 2) / 60; // Vitesse de base
361
394
  let currentStep = baseStep;
362
- let isPaused = false;
395
+ let isPaused = false;
363
396
  let animationId = null;
364
397
  let lastTime = 0;
365
398
 
@@ -383,15 +416,15 @@
383
416
 
384
417
  scrollContainer.style.transform = `translate3d(0px, ${currentPosition}px, 0px)`;
385
418
  animationId = requestAnimationFrame(animate);
386
- };
387
-
388
- // Démarrer l'animation
419
+ };
420
+
421
+ // Démarrer l'animation
389
422
  animationId = requestAnimationFrame(animate);
390
-
423
+
391
424
  // Marquee vertical créé avec animation JS
392
-
425
+
393
426
  // Pause au survol avec transition fluide CSS + JS
394
- if (pauseOnHover === 'true') {
427
+ if (pauseOnHover === 'true') {
395
428
  // Transition fluide avec easing naturel
396
429
  const transitionSpeed = (targetSpeed, duration = 300) => {
397
430
  const startSpeed = currentStep;
@@ -422,19 +455,19 @@
422
455
  requestAnimationFrame(animateTransition);
423
456
  };
424
457
 
425
- element.addEventListener('mouseenter', function() {
458
+ element.addEventListener('mouseenter', function() {
426
459
  transitionSpeed(0); // Ralentir jusqu'à 0
427
- });
428
- element.addEventListener('mouseleave', function() {
460
+ });
461
+ element.addEventListener('mouseleave', function() {
429
462
  transitionSpeed(baseStep); // Revenir à la vitesse normale
430
- });
431
- }
432
- } else {
463
+ });
464
+ }
465
+ } else {
433
466
  // Animation JavaScript pour l'horizontal (comme le vertical pour éviter les saccades)
434
467
  const contentSize = finalWidth;
435
468
  const totalSize = contentSize * 4 + parseInt(gap) * 3;
436
- scrollContainer.style.width = totalSize + 'px';
437
-
469
+ scrollContainer.style.width = totalSize + 'px';
470
+
438
471
  let currentPosition = direction === 'right' ? -contentSize - parseInt(gap) : 0;
439
472
  const baseStep = (parseFloat(speed) * 0.5) / 60; // Vitesse de base
440
473
  let currentStep = baseStep;
@@ -448,12 +481,12 @@
448
481
  const deltaTime = currentTime - lastTime;
449
482
  lastTime = currentTime;
450
483
 
451
- if (direction === 'right') {
484
+ if (direction === 'right') {
452
485
  currentPosition += currentStep * (deltaTime / 16.67); // Normaliser à 60fps
453
486
  if (currentPosition >= 0) {
454
487
  currentPosition = -contentSize - parseInt(gap);
455
488
  }
456
- } else {
489
+ } else {
457
490
  currentPosition -= currentStep * (deltaTime / 16.67);
458
491
  if (currentPosition <= -contentSize - parseInt(gap)) {
459
492
  currentPosition = 0;
@@ -470,7 +503,7 @@
470
503
  // Marquee horizontal créé avec animation JS
471
504
 
472
505
  // Pause au survol avec transition fluide CSS + JS
473
- if (pauseOnHover === 'true') {
506
+ if (pauseOnHover === 'true') {
474
507
  // Transition fluide avec easing naturel
475
508
  const transitionSpeed = (targetSpeed, duration = 300) => {
476
509
  const startSpeed = currentStep;
@@ -501,17 +534,17 @@
501
534
  requestAnimationFrame(animateTransition);
502
535
  };
503
536
 
504
- element.addEventListener('mouseenter', function() {
537
+ element.addEventListener('mouseenter', function() {
505
538
  transitionSpeed(0); // Ralentir jusqu'à 0
506
- });
507
- element.addEventListener('mouseleave', function() {
539
+ });
540
+ element.addEventListener('mouseleave', function() {
508
541
  transitionSpeed(baseStep); // Revenir à la vitesse normale
509
- });
510
- }
542
+ });
511
543
  }
512
- });
513
- };
514
-
544
+ }
545
+ });
546
+ };
547
+
515
548
  // Démarrer l'initialisation avec délai adaptatif - Option 1: Attendre que tout soit prêt
516
549
  let initDelay = isVertical ? 500 : 200; // Délais plus longs par défaut
517
550
  if (bbContents._performanceBoostDetected) {
@@ -631,7 +664,7 @@
631
664
  const language = bbContents._getAttr(element, 'bb-youtube-language') || 'fr';
632
665
 
633
666
  // Vérifier la configuration au moment de l'initialisation
634
- const endpoint = bbContents.config.youtubeEndpoint;
667
+ const endpoint = bbContents.checkYouTubeConfig() ? bbContents.config.youtubeEndpoint : null;
635
668
 
636
669
  console.log('[DEBUG] YouTube element config:', {channelId, videoCount, allowShorts, language, endpoint});
637
670
 
@@ -953,6 +986,16 @@
953
986
 
954
987
  // Exposer globalement
955
988
  window.bbContents = bbContents;
989
+
990
+ // Méthode globale pour configurer YouTube après le chargement
991
+ window.configureYouTube = function(endpoint) {
992
+ if (bbContents) {
993
+ bbContents.config.youtubeEndpoint = endpoint;
994
+ console.log('[DEBUG] YouTube endpoint configured globally:', endpoint);
995
+ // Réinitialiser les modules YouTube
996
+ bbContents.reinit();
997
+ }
998
+ };
956
999
 
957
1000
  // Initialisation automatique avec délai pour éviter le blocage
958
1001
  function initBBContents() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bebranded/bb-contents",
3
- "version": "1.0.44-beta",
3
+ "version": "1.0.46-beta",
4
4
  "description": "Contenus additionnels français pour Webflow",
5
5
  "main": "bb-contents.js",
6
6
  "scripts": {