@bebranded/bb-contents 1.0.44-beta → 1.0.45-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 +135 -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.45-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.44-beta',
20
+ version: '1.0.45-beta',
21
21
  debug: true, // Activé temporairement pour debug
22
22
  prefix: 'bb-', // utilisé pour générer les sélecteurs (data-bb-*)
23
23
  youtubeEndpoint: null, // URL du worker YouTube (à définir par l'utilisateur)
@@ -25,6 +25,11 @@
25
25
  copied: 'Lien copié !'
26
26
  }
27
27
  };
28
+
29
+ // Détecter la configuration YouTube définie avant le chargement
30
+ if (window.bbContents && window.bbContents.config && window.bbContents.config.youtubeEndpoint) {
31
+ config.youtubeEndpoint = window.bbContents.config.youtubeEndpoint;
32
+ }
28
33
 
29
34
  // Objet principal
30
35
  const bbContents = {
@@ -155,6 +160,24 @@
155
160
  this._initRetryCount = 0;
156
161
  this.init();
157
162
  },
163
+
164
+ // Méthode pour détecter la configuration YouTube définie après le chargement
165
+ checkYouTubeConfig: function() {
166
+ // Vérifier si la configuration a été définie après le chargement
167
+ if (this.config.youtubeEndpoint) {
168
+ console.log('[DEBUG] YouTube endpoint found:', this.config.youtubeEndpoint);
169
+ return true;
170
+ }
171
+
172
+ // Vérifier dans window.bbContents (au cas où)
173
+ if (window.bbContents && window.bbContents.config && window.bbContents.config.youtubeEndpoint) {
174
+ this.config.youtubeEndpoint = window.bbContents.config.youtubeEndpoint;
175
+ console.log('[DEBUG] YouTube endpoint found in window:', this.config.youtubeEndpoint);
176
+ return true;
177
+ }
178
+
179
+ return false;
180
+ },
158
181
 
159
182
  // Observer DOM pour contenu dynamique
160
183
  setupObserver: function() {
@@ -205,32 +228,32 @@
205
228
  bbContents.modules = {
206
229
  // Module Marquee - Version live 1.0.41-beta avec modules parasites supprimés
207
230
  marquee: {
208
- detect: function(scope) {
209
- const s = scope || document;
231
+ detect: function(scope) {
232
+ const s = scope || document;
210
233
  return s.querySelector(bbContents._attrSelector('marquee')) !== null;
211
234
  },
212
235
 
213
236
  // Nouvelle méthode pour vérifier les éléments échoués
214
237
  checkFailed: function(scope) {
215
- const s = scope || document;
238
+ const s = scope || document;
216
239
  const failedElements = s.querySelectorAll('[bb-marquee]:not([data-bb-marquee-processed])');
217
240
  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'));
241
+ },
242
+
243
+ init: function(root) {
244
+ const scope = root || document;
245
+ if (scope.closest && scope.closest('[data-bb-disable]')) return;
246
+ const elements = scope.querySelectorAll(bbContents._attrSelector('marquee'));
224
247
 
225
- elements.forEach(function(element) {
248
+ elements.forEach(function(element) {
226
249
  // Vérifier si l'élément a déjà été traité par un autre module
227
250
  if (element.bbProcessed || element.hasAttribute('data-bb-youtube-processed')) {
228
251
  // Élément marquee déjà traité par un autre module, ignoré
229
252
  return;
230
253
  }
231
- element.bbProcessed = true;
254
+ element.bbProcessed = true;
232
255
 
233
- // Récupérer les options
256
+ // Récupérer les options
234
257
  const speed = bbContents._getAttr(element, 'bb-marquee-speed') || '100';
235
258
  const direction = bbContents._getAttr(element, 'bb-marquee-direction') || 'left';
236
259
  const pauseOnHover = bbContents._getAttr(element, 'bb-marquee-pause');
@@ -239,67 +262,67 @@
239
262
  const height = bbContents._getAttr(element, 'bb-marquee-height') || '300';
240
263
  const minHeight = bbContents._getAttr(element, 'bb-marquee-min-height');
241
264
 
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';
265
+ // Sauvegarder le contenu original
266
+ const originalHTML = element.innerHTML;
267
+
268
+ // Créer le conteneur principal
269
+ const mainContainer = document.createElement('div');
270
+ const isVertical = orientation === 'vertical';
248
271
  const useAutoHeight = isVertical && height === 'auto';
249
272
 
250
- mainContainer.style.cssText = `
251
- position: relative;
252
- width: 100%;
273
+ mainContainer.style.cssText = `
274
+ position: relative;
275
+ width: 100%;
253
276
  height: ${isVertical ? (height === 'auto' ? 'auto' : height + 'px') : 'auto'};
254
- overflow: hidden;
255
- min-height: ${isVertical ? '100px' : '50px'};
277
+ overflow: hidden;
278
+ min-height: ${isVertical ? '100px' : '50px'};
256
279
  ${minHeight ? `min-height: ${minHeight};` : ''}
257
- `;
280
+ `;
258
281
 
259
- // Créer le conteneur de défilement
260
- const scrollContainer = document.createElement('div');
261
- scrollContainer.style.cssText = `
282
+ // Créer le conteneur de défilement
283
+ const scrollContainer = document.createElement('div');
284
+ scrollContainer.style.cssText = `
262
285
  ${useAutoHeight ? 'position: relative;' : 'position: absolute;'}
263
- will-change: transform;
286
+ will-change: transform;
264
287
  ${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;
288
+ display: flex;
289
+ ${isVertical ? 'flex-direction: column;' : ''}
290
+ align-items: center;
291
+ gap: ${gap}px;
292
+ ${isVertical ? '' : 'white-space: nowrap;'}
293
+ flex-shrink: 0;
271
294
  transition: transform 0.1s ease-out;
272
- `;
295
+ `;
273
296
 
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
- `;
297
+ // Créer le bloc de contenu principal
298
+ const mainBlock = document.createElement('div');
299
+ mainBlock.innerHTML = originalHTML;
300
+ mainBlock.style.cssText = `
301
+ display: flex;
302
+ ${isVertical ? 'flex-direction: column;' : ''}
303
+ align-items: center;
304
+ gap: ${gap}px;
305
+ ${isVertical ? '' : 'white-space: nowrap;'}
306
+ flex-shrink: 0;
307
+ ${isVertical ? 'min-height: 100px;' : ''}
308
+ `;
309
+
310
+ // Créer plusieurs répétitions pour un défilement continu
311
+ const repeatBlock1 = mainBlock.cloneNode(true);
312
+ const repeatBlock2 = mainBlock.cloneNode(true);
313
+ const repeatBlock3 = mainBlock.cloneNode(true);
314
+
315
+ // Assembler la structure
316
+ scrollContainer.appendChild(mainBlock);
317
+ scrollContainer.appendChild(repeatBlock1);
318
+ scrollContainer.appendChild(repeatBlock2);
319
+ scrollContainer.appendChild(repeatBlock3);
320
+ mainContainer.appendChild(scrollContainer);
321
+
322
+ // Vider et remplacer le contenu original
323
+ element.innerHTML = '';
324
+ element.appendChild(mainContainer);
286
325
 
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
326
  // Marquer l'élément comme traité par le module marquee
304
327
  element.setAttribute('data-bb-marquee-processed', 'true');
305
328
 
@@ -310,7 +333,7 @@
310
333
  const imagesLoaded = Array.from(images).every(img => img.complete && img.naturalHeight > 0);
311
334
 
312
335
  // Attendre que le contenu soit dans le DOM et que les images soient chargées
313
- requestAnimationFrame(() => {
336
+ requestAnimationFrame(() => {
314
337
  // Calcul plus robuste des dimensions
315
338
  const rect = mainBlock.getBoundingClientRect();
316
339
  const contentWidth = rect.width || mainBlock.offsetWidth;
@@ -342,24 +365,24 @@
342
365
  return;
343
366
  } else {
344
367
  // Échec d'initialisation après plusieurs tentatives
345
- return;
368
+ return;
346
369
  }
347
- }
348
-
349
- if (isVertical) {
350
- // Animation JavaScript pour le vertical
370
+ }
371
+
372
+ if (isVertical) {
373
+ // Animation JavaScript pour le vertical
351
374
  const contentSize = finalHeight;
352
- const totalSize = contentSize * 4 + parseInt(gap) * 3; // 4 copies au lieu de 3
375
+ const totalSize = contentSize * 4 + parseInt(gap) * 3; // 4 copies au lieu de 3
353
376
 
354
377
  // Ajuster la hauteur du scrollContainer seulement si pas en mode auto
355
378
  if (!useAutoHeight) {
356
- scrollContainer.style.height = totalSize + 'px';
379
+ scrollContainer.style.height = totalSize + 'px';
357
380
  }
358
-
359
- let currentPosition = direction === 'bottom' ? -contentSize - parseInt(gap) : 0;
381
+
382
+ let currentPosition = direction === 'bottom' ? -contentSize - parseInt(gap) : 0;
360
383
  const baseStep = (parseFloat(speed) * 2) / 60; // Vitesse de base
361
384
  let currentStep = baseStep;
362
- let isPaused = false;
385
+ let isPaused = false;
363
386
  let animationId = null;
364
387
  let lastTime = 0;
365
388
 
@@ -383,15 +406,15 @@
383
406
 
384
407
  scrollContainer.style.transform = `translate3d(0px, ${currentPosition}px, 0px)`;
385
408
  animationId = requestAnimationFrame(animate);
386
- };
387
-
388
- // Démarrer l'animation
409
+ };
410
+
411
+ // Démarrer l'animation
389
412
  animationId = requestAnimationFrame(animate);
390
-
413
+
391
414
  // Marquee vertical créé avec animation JS
392
-
415
+
393
416
  // Pause au survol avec transition fluide CSS + JS
394
- if (pauseOnHover === 'true') {
417
+ if (pauseOnHover === 'true') {
395
418
  // Transition fluide avec easing naturel
396
419
  const transitionSpeed = (targetSpeed, duration = 300) => {
397
420
  const startSpeed = currentStep;
@@ -422,19 +445,19 @@
422
445
  requestAnimationFrame(animateTransition);
423
446
  };
424
447
 
425
- element.addEventListener('mouseenter', function() {
448
+ element.addEventListener('mouseenter', function() {
426
449
  transitionSpeed(0); // Ralentir jusqu'à 0
427
- });
428
- element.addEventListener('mouseleave', function() {
450
+ });
451
+ element.addEventListener('mouseleave', function() {
429
452
  transitionSpeed(baseStep); // Revenir à la vitesse normale
430
- });
431
- }
432
- } else {
453
+ });
454
+ }
455
+ } else {
433
456
  // Animation JavaScript pour l'horizontal (comme le vertical pour éviter les saccades)
434
457
  const contentSize = finalWidth;
435
458
  const totalSize = contentSize * 4 + parseInt(gap) * 3;
436
- scrollContainer.style.width = totalSize + 'px';
437
-
459
+ scrollContainer.style.width = totalSize + 'px';
460
+
438
461
  let currentPosition = direction === 'right' ? -contentSize - parseInt(gap) : 0;
439
462
  const baseStep = (parseFloat(speed) * 0.5) / 60; // Vitesse de base
440
463
  let currentStep = baseStep;
@@ -448,12 +471,12 @@
448
471
  const deltaTime = currentTime - lastTime;
449
472
  lastTime = currentTime;
450
473
 
451
- if (direction === 'right') {
474
+ if (direction === 'right') {
452
475
  currentPosition += currentStep * (deltaTime / 16.67); // Normaliser à 60fps
453
476
  if (currentPosition >= 0) {
454
477
  currentPosition = -contentSize - parseInt(gap);
455
478
  }
456
- } else {
479
+ } else {
457
480
  currentPosition -= currentStep * (deltaTime / 16.67);
458
481
  if (currentPosition <= -contentSize - parseInt(gap)) {
459
482
  currentPosition = 0;
@@ -470,7 +493,7 @@
470
493
  // Marquee horizontal créé avec animation JS
471
494
 
472
495
  // Pause au survol avec transition fluide CSS + JS
473
- if (pauseOnHover === 'true') {
496
+ if (pauseOnHover === 'true') {
474
497
  // Transition fluide avec easing naturel
475
498
  const transitionSpeed = (targetSpeed, duration = 300) => {
476
499
  const startSpeed = currentStep;
@@ -501,17 +524,17 @@
501
524
  requestAnimationFrame(animateTransition);
502
525
  };
503
526
 
504
- element.addEventListener('mouseenter', function() {
527
+ element.addEventListener('mouseenter', function() {
505
528
  transitionSpeed(0); // Ralentir jusqu'à 0
506
- });
507
- element.addEventListener('mouseleave', function() {
529
+ });
530
+ element.addEventListener('mouseleave', function() {
508
531
  transitionSpeed(baseStep); // Revenir à la vitesse normale
509
- });
510
- }
532
+ });
511
533
  }
512
- });
513
- };
514
-
534
+ }
535
+ });
536
+ };
537
+
515
538
  // Démarrer l'initialisation avec délai adaptatif - Option 1: Attendre que tout soit prêt
516
539
  let initDelay = isVertical ? 500 : 200; // Délais plus longs par défaut
517
540
  if (bbContents._performanceBoostDetected) {
@@ -631,7 +654,7 @@
631
654
  const language = bbContents._getAttr(element, 'bb-youtube-language') || 'fr';
632
655
 
633
656
  // Vérifier la configuration au moment de l'initialisation
634
- const endpoint = bbContents.config.youtubeEndpoint;
657
+ const endpoint = bbContents.checkYouTubeConfig() ? bbContents.config.youtubeEndpoint : null;
635
658
 
636
659
  console.log('[DEBUG] YouTube element config:', {channelId, videoCount, allowShorts, language, endpoint});
637
660
 
@@ -953,6 +976,16 @@
953
976
 
954
977
  // Exposer globalement
955
978
  window.bbContents = bbContents;
979
+
980
+ // Méthode globale pour configurer YouTube après le chargement
981
+ window.configureYouTube = function(endpoint) {
982
+ if (bbContents) {
983
+ bbContents.config.youtubeEndpoint = endpoint;
984
+ console.log('[DEBUG] YouTube endpoint configured globally:', endpoint);
985
+ // Réinitialiser les modules YouTube
986
+ bbContents.reinit();
987
+ }
988
+ };
956
989
 
957
990
  // Initialisation automatique avec délai pour éviter le blocage
958
991
  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.45-beta",
4
4
  "description": "Contenus additionnels français pour Webflow",
5
5
  "main": "bb-contents.js",
6
6
  "scripts": {