PageSourceSearch

https://tribee.fr/assets/front/js/components/home-charities-2O31Weq.js

js tribee.fr collected 2026-09-24 10:42:58 UTC 6,045 bytes, 200 lines download raw bytes

1import './modal.js';
2import '../../styles/components/home/charities.css'
3import * as youtube from '../utils/youtube.js'
4
5const YOUTUBE_PLAYER_CONTAINER_ID = 'charity-hero-video';
6
7class HomeCharities {
8  #youtubeApiPromise
9  #currentHeroPlayer = null
10
11  start() {
12    document.querySelectorAll('.see-more-button').forEach((button) => {
13      button.addEventListener('click', async (event) => {
14        event.preventDefault();
15        await this.#openCharityDetails(button);
16      });
17    });
18  }
19
20  async #openCharityDetails(button) {
21    const modal = document.querySelector('.charity-details-modal');
22    if (!modal) {
23      return;
24    }
25
26    const heroTitle = modal.querySelector('.charity-details-modal__hero-title');
27    const heroImage = modal.querySelector('.charity-details-modal__hero-image');
28    const heroVideo = modal.querySelector('.charity-details-modal__hero-video');
29    const description = modal.querySelector('.modal__content__body__description');
30    const charityName = button.getAttribute('data-name') ?? '';
31    const videoSrc = button.getAttribute('data-video') ?? '';
32
33    if (!heroTitle || !heroImage || !heroVideo || !description) {
34      return;
35    }
36
37    heroTitle.textContent = charityName;
38    this.#toggleHeroTitle(heroTitle, false);
39    heroImage.src = button.getAttribute('data-image-path') ?? '';
40    heroImage.alt = charityName;
41    description.innerHTML = button.getAttribute('data-description-html') || '';
42
43    await this.#populateHeroMedia(heroVideo, heroImage, videoSrc, charityName, heroTitle);
44    this.#populateTaxReduction(modal, button);
45  }
46
47  async #populateHeroMedia(heroVideo, heroImage, videoSrc, charityName, heroTitle) {
48    this.#resetHeroPlayer();
49    heroVideo.innerHTML = '';
50
51    if (videoSrc === '') {
52      this.#toggleHeroTitle(heroTitle, false);
53      heroVideo.hidden = true;
54      heroImage.hidden = false;
55      return;
56    }
57
58    heroVideo.hidden = false;
59    heroImage.hidden = true;
60
61    if (!youtube.isYoutubeUrl(videoSrc)) {
62      this.#toggleHeroTitle(heroTitle, true);
63      heroVideo.appendChild(this.#createVideoIframe(videoSrc, charityName));
64      return;
65    }
66
67    const videoId = youtube.getYoutubeVideoId(videoSrc);
68    if (videoId === null) {
69      this.#toggleHeroTitle(heroTitle, true);
70      heroVideo.appendChild(this.#createVideoIframe(videoSrc, charityName));
71      return;
72    }
73
74    if (youtube.shouldUseClassicYoutubeIframe()) {
75      this.#toggleHeroTitle(heroTitle, true);
76      heroVideo.appendChild(this.#createVideoIframe(videoSrc, charityName));
77      return;
78    }
79
80    this.#toggleHeroTitle(heroTitle, false);
81    const youtubeContainer = document.createElement('div');
82    youtubeContainer.id = YOUTUBE_PLAYER_CONTAINER_ID;
83    heroVideo.appendChild(youtubeContainer);
84    await this.#attachYoutubeApiPlayer(youtubeContainer, videoId, heroTitle);
85  }
86
87  #populateTaxReduction(modal, button) {
88    const taxReduction = modal.querySelector('.modal__content__body__tax-reduction');
89    const taxReductionEnabled = button.getAttribute('data-tax-enabled');
90
91    if (!taxReduction) {
92      return;
93    }
94
95    if (taxReductionEnabled != 1) {
96      taxReduction.innerHTML = button.getAttribute('data-no-tax-reduction-content') || '';
97      return;
98    }
99
100    taxReduction.innerHTML = button.getAttribute('data-tax-reduction-content') || '';
101    const amount = taxReduction.querySelector('span.amount');
102    if (amount) {
103      amount.innerHTML = button.getAttribute('data-tax-min') || '';
104    }
105  }
106
107  async #attachYoutubeApiPlayer(container, videoId, heroTitle) {
108    const YT = await this.#ensureYoutubeApi();
109    this.#resetHeroPlayer();
110
111    this.#currentHeroPlayer = new YT.Player(container, {
112      videoId,
113      host: 'https://www.youtube.com',
114      playerVars: {
115        playsinline: 1,
116        rel: 0,
117      },
118      events: {
119        onStateChange: (event) => {
120          if (event.data === YT.PlayerState.PLAYING) {
121            this.#toggleHeroTitle(heroTitle, true);
122            return;
123          }
124
125          if (
126            event.data === YT.PlayerState.PAUSED
127            || event.data === YT.PlayerState.ENDED
128            || event.data === YT.PlayerState.CUED
129          ) {
130            this.#toggleHeroTitle(heroTitle, false);
131          }
132        },
133      },
134    });
135  }
136
137  #resetHeroPlayer() {
138    if (this.#currentHeroPlayer?.destroy) {
139      this.#currentHeroPlayer.destroy();
140      this.#currentHeroPlayer = null;
141    }
142  }
143
144  async #ensureYoutubeApi() {
145    if (window.YT && window.YT.Player) {
146      return window.YT;
147    }
148
149    if (this.#youtubeApiPromise) {
150      return this.#youtubeApiPromise;
151    }
152
153    this.#youtubeApiPromise = new Promise((resolve) => {
154      const previousReady = window.onYouTubeIframeAPIReady;
155
156      window.onYouTubeIframeAPIReady = () => {
157        if (typeof previousReady === 'function') {
158          previousReady();
159        }
160
161        resolve(window.YT);
162      };
163
164      const existingScript = document.querySelector('script[src="https://www.youtube.com/iframe_api"]');
165      if (existingScript) {
166        return;
167      }
168
169      const script = document.createElement('script');
170      script.src = 'https://www.youtube.com/iframe_api';
171      script.async = true;
172      document.head.appendChild(script);
173    });
174
175    return this.#youtubeApiPromise;
176  }
177
178  #toggleHeroTitle(heroTitle, shouldHide) {
179    const heroCaption = heroTitle.closest('.charity-details-modal__hero-caption');
180
181    heroTitle.hidden = shouldHide;
182    heroTitle.style.display = shouldHide ? 'none' : '';
183
184    if (heroCaption) {
185      heroCaption.style.display = shouldHide ? 'none' : '';
186    }
187  }
188
189  #createVideoIframe(videoSrc, charityName) {
190    const video = document.createElement('iframe');
191    video.referrerPolicy = 'strict-origin-when-cross-origin';
192    video.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share';
193    video.title = charityName;
194    video.src = youtube.toClassicYoutubeIframeUrl(videoSrc);
195
196    return video;
197  }
198}
199
200new HomeCharities().start();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.