PageSourceSearch

https://www.idomyou.fr/js/performance.js?v=20260916-1

js idomyou.fr collected 2026-09-24 14:21:42 UTC 11,201 bytes, 377 lines download raw bytes

1(function () {
2  "use strict";
3
4  var GA4_ID = "G-EDD07P75CL";
5  var GTM_ID = "GTM-KZH5Z9GR";
6  var INTERCOM_APP_ID = "p7ulgbr9";
7  // Meta pixel of the ad sets (the previous value was the ad ACCOUNT id, not
8  // a pixel: every browser event went nowhere).
9  var META_PIXEL_ID = "1589487805675731";
10  // ChatGPT / OpenAI Ads pixel. Single place to change it for www.
11  var OPENAI_ADS_PIXEL_ID = "2M76RfpzYwf3YUmc5kK3EX";
12  var OPENAI_ADS_SDK_URL = "https://bzrcdn.openai.com/sdk/oaiq.min.js";
13  var OPENAI_ADS_PRODUCTION_HOSTS = ["app.idomyou.fr", "www.idomyou.fr", "idomyou.fr"];
14  var CROSS_DOMAIN_LINKER = {
15    domains: [
16      "www.idomyou.fr",
17      "app.idomyou.fr",
18      "idomyou.fr",
19      "www.idomyou.com",
20      "app.idomyou.com",
21      "idomyou.com"
22    ]
23  };
24
25  function onIdle(callback) {
26    if ("requestIdleCallback" in window) {
27      window.requestIdleCallback(callback, { timeout: 2500 });
28      return;
29    }
30
31    window.setTimeout(callback, 1200);
32  }
33
34  function onReady(callback) {
35    if (document.readyState === "loading") {
36      document.addEventListener("DOMContentLoaded", callback, { once: true });
37      return;
38    }
39
40    callback();
41  }
42
43  function configureGtagLinker() {
44    window.dataLayer = window.dataLayer || [];
45    window.gtag = window.gtag || function () {
46      window.dataLayer.push(arguments);
47    };
48
49    window.gtag("js", new Date());
50    window.gtag("config", GA4_ID, {
51      linker: CROSS_DOMAIN_LINKER
52    });
53  }
54
55  function loadGoogleTag() {
56    if (document.getElementById("idomyou-google-tag-script")) return;
57
58    var script = document.createElement("script");
59    script.id = "idomyou-google-tag-script";
60    script.async = true;
61    script.src = "https://www.googletagmanager.com/gtag/js?id=" + GA4_ID;
62    document.head.appendChild(script);
63  }
64
65  function loadGtm() {
66    if (document.getElementById("idomyou-gtm-script")) return;
67
68    window.dataLayer = window.dataLayer || [];
69    window.dataLayer.push({
70      "gtm.start": new Date().getTime(),
71      event: "gtm.js"
72    });
73
74    var script = document.createElement("script");
75    script.id = "idomyou-gtm-script";
76    script.async = true;
77    script.src = "https://www.googletagmanager.com/gtm.js?id=" + GTM_ID;
78    document.head.appendChild(script);
79  }
80
81  function loadMetaPixel() {
82    if (window.fbq || document.getElementById("idomyou-meta-pixel-script")) return;
83
84    var fbq = window.fbq = function () {
85      fbq.callMethod ? fbq.callMethod.apply(fbq, arguments) : fbq.queue.push(arguments);
86    };
87
88    if (!window._fbq) window._fbq = fbq;
89    fbq.push = fbq;
90    fbq.loaded = true;
91    fbq.version = "2.0";
92    fbq.queue = [];
93
94    var script = document.createElement("script");
95    script.id = "idomyou-meta-pixel-script";
96    script.async = true;
97    script.src = "https://connect.facebook.net/en_US/fbevents.js";
98    document.head.appendChild(script);
99
100    fbq("init", META_PIXEL_ID);
101    fbq("track", "PageView");
102  }
103
104  // OpenAI Ads (oaiq) — loaded once, async, only after marketing consent.
105  function loadOpenAiAdsPixel() {
106    if (window.oaiq || document.getElementById("idomyou-openai-ads-script")) return;
107
108    var oaiq = window.oaiq = function () {
109      oaiq.q.push(arguments);
110    };
111    oaiq.q = [];
112
113    var script = document.createElement("script");
114    script.id = "idomyou-openai-ads-script";
115    script.async = true;
116    script.src = OPENAI_ADS_SDK_URL;
117    document.head.appendChild(script);
118
119    oaiq("init", {
120      pixelId: OPENAI_ADS_PIXEL_ID,
121      debug: OPENAI_ADS_PRODUCTION_HOSTS.indexOf(window.location.hostname) === -1
122    });
123  }
124
125  function primeIntercomStub() {
126    var settings = window.intercomSettings || {
127      api_base: "https://api-iam.intercom.io",
128      app_id: INTERCOM_APP_ID
129    };
130    var intercom = window.Intercom;
131
132    window.intercomSettings = settings;
133
134    if (typeof intercom === "function") return intercom;
135
136    var stub = function () {
137      stub.c(arguments);
138    };
139    stub.q = [];
140    stub.c = function (args) {
141      stub.q.push(args);
142    };
143    window.Intercom = typeof intercom === "function" ? intercom : stub;
144
145    return window.Intercom;
146  }
147
148  function loadIntercom() {
149    var intercom = primeIntercomStub();
150
151    if (typeof intercom === "function" && intercom.booted) {
152      intercom("reattach_activator");
153      intercom("update", window.intercomSettings);
154      return;
155    }
156
157    if (document.getElementById("idomyou-intercom-script")) return;
158
159    var script = document.createElement("script");
160    script.id = "idomyou-intercom-script";
161    script.async = true;
162    script.src = "https://widget.intercom.io/widget/" + INTERCOM_APP_ID;
163    document.head.appendChild(script);
164  }
165
166  function lazyLoadMapFrames() {
167    var frames = Array.prototype.slice.call(
168      document.querySelectorAll("iframe[data-src][data-lazy-map]")
169    );
170
171    if (!frames.length) return;
172
173    function loadFrame(frame) {
174      if (frame.src || !frame.dataset.src) return;
175      frame.src = frame.dataset.src;
176    }
177
178    if (!("IntersectionObserver" in window)) {
179      frames.forEach(loadFrame);
180      return;
181    }
182
183    var observer = new IntersectionObserver(function (entries) {
184      entries.forEach(function (entry) {
185        if (!entry.isIntersecting) return;
186        loadFrame(entry.target);
187        observer.unobserve(entry.target);
188      });
189    }, { rootMargin: "200px" });
190
191    frames.forEach(function (frame) {
192      frame.addEventListener("click", function () {
193        loadFrame(frame);
194      }, { once: true });
195      observer.observe(frame);
196    });
197  }
198
199  function lazyLoadReviewsScript() {
200    var reviewRoots = document.querySelectorAll("[data-google-review-marquee]");
201    if (!reviewRoots.length || document.getElementById("idomyou-google-reviews-script")) {
202      return;
203    }
204
205    function loadReviewsScript() {
206      if (document.getElementById("idomyou-google-reviews-script")) return;
207
208      var script = document.createElement("script");
209      script.id = "idomyou-google-reviews-script";
210      script.src = "js/google-reviews-marquee.js?v=20260504-1";
211      script.defer = true;
212      document.body.appendChild(script);
213    }
214
215    if (!("IntersectionObserver" in window)) {
216      loadReviewsScript();
217      return;
218    }
219
220    var observer = new IntersectionObserver(function (entries) {
221      if (!entries.some(function (entry) { return entry.isIntersecting; })) return;
222      loadReviewsScript();
223      observer.disconnect();
224    }, { rootMargin: "300px" });
225
226    Array.prototype.forEach.call(reviewRoots, function (root) {
227      observer.observe(root);
228    });
229  }
230
231  // Cross-domain continuity www -> app: forward the marketing query string on
232  // every link to app.idomyou.fr at click time. The idy_attr cookie
233  // (.idomyou.fr) is the primary carrier; the URL is belt and braces. Done in
234  // a capture-phase click listener so CMS-rendered cards, i18n-rewritten
235  // buttons and target="_blank" links are all covered without a load-time scan.
236  var APP_LINK_PATTERN = /^https?:\/\/app\.idomyou\.(fr|com)(\/|\?|#|$)/i;
237  // `idy_ref` = host of the external referrer recorded on www (the app's own
238  // document.referrer is always www once the visitor clicks through). Same
239  // treatment as a forwarded gclid: read from the attribution record the
240  // consent manager exposes, no storage of its own.
241  var FORWARDED_PARAM_KEYS = [
242    "gclid", "gbraid", "wbraid", "fbclid", "msclkid",
243    "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content",
244    "idy_ref"
245  ];
246
247  function collectForwardedParams() {
248    var params = {};
249
250    try {
251      var current = new URLSearchParams(window.location.search || "");
252
253      FORWARDED_PARAM_KEYS.forEach(function (key) {
254        var value = current.get(key);
255
256        if (value) params[key] = value;
257      });
258    } catch (_error) {
259      // ignore malformed query strings
260    }
261
262    var attribution =
263      window.idomyouConsent && typeof window.idomyouConsent.getAttribution === "function"
264        ? window.idomyouConsent.getAttribution()
265        : null;
266
267    if (attribution) {
268      FORWARDED_PARAM_KEYS.forEach(function (key) {
269        if (!params[key] && attribution[key]) params[key] = attribution[key];
270      });
271    }
272
273    if (
274      !params.idy_ref &&
275      window.idomyouConsent &&
276      typeof window.idomyouConsent.getExternalReferrerHost === "function"
277    ) {
278      var referrerHost = window.idomyouConsent.getExternalReferrerHost();
279
280      if (referrerHost) params.idy_ref = referrerHost;
281    }
282
283    return params;
284  }
285
286  function decorateAppLink(anchor) {
287    var href = anchor.getAttribute("href") || "";
288
289    if (!APP_LINK_PATTERN.test(href)) return;
290
291    var url;
292
293    try {
294      url = new URL(href);
295    } catch (_error) {
296      return;
297    }
298
299    if (url.protocol === "http:") url.protocol = "https:";
300
301    var params = collectForwardedParams();
302
303    Object.keys(params).forEach(function (key) {
304      if (!url.searchParams.has(key)) url.searchParams.set(key, params[key]);
305    });
306
307    anchor.setAttribute("href", url.toString());
308  }
309
310  function forwardAttributionToAppLinks() {
311    if (typeof URL !== "function" || typeof URLSearchParams !== "function") return;
312
313    function onLinkActivation(event) {
314      var target = event.target;
315      var anchor = target && typeof target.closest === "function"
316        ? target.closest("a[href]")
317        : null;
318
319      if (anchor) decorateAppLink(anchor);
320    }
321
322    // Capture phase, several activation paths: pointerdown/touchstart run
323    // before the navigation of a tap that never emits "click" in some mobile
324    // browsers, focusin covers keyboard users, contextmenu covers "copy link"
325    // / "open in new tab". decorateAppLink is idempotent (searchParams.has).
326    ["pointerdown", "touchstart", "mousedown", "click", "auxclick", "contextmenu", "focu
326sin"]
327      .forEach(function (eventName) {
328        document.addEventListener(eventName, onLinkActivation, true);
329      });
330
331    // One pass over the links already in the DOM (CMS-rendered cards and the
332    // i18n rewrites come later; the listeners above cover those at click).
333    Array.prototype.forEach.call(document.querySelectorAll("a[href]"), decorateAppLink);
334  }
335
336  function getConsentPreferences() {
337    if (!window.idomyouConsent || typeof window.idomyouConsent.getPreferences !== "function") {
338      return null;
339    }
340
341    return window.idomyouConsent.getPreferences();
342  }
343
344  function loadConsentDependentScripts(preferences) {
345    if (!preferences) return;
346
347    if (preferences.analytics === true) {
348      configureGtagLinker();
349      loadGoogleTag();
350    }
351
352    if (preferences.marketing === true) {
353      loadGtm();
354      loadMetaPixel();
355      loadOpenAiAdsPixel();
356    }
357
358    if (preferences.support === true) {
359      primeIntercomStub();
360      window.setTimeout(function () {
361        onIdle(loadIntercom);
362      }, 15000);
363    }
364  }
365
366  onReady(function () {
367    forwardAttributionToAppLinks();
368    lazyLoadMapFrames();
369    lazyLoadReviewsScript();
370
371    loadConsentDependentScripts(getConsentPreferences());
372
373    if (window.idomyouConsent && typeof window.idomyouConsent.onChange === "function") {
374      window.idomyouConsent.onChange(loadConsentDependentScripts);
375    }
376  });
377}());

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.