PageSourceSearch

https://lagrangetoyota.ca/wp-content/themes/magnetis-dealer/assets/js/tools.js?ver=1790972245

js lagrangetoyota.ca collected 2026-10-04 13:33:59 UTC 19,118 bytes, 533 lines download raw bytes

1/*jshint esversion: 6 */
2
3jQuery(function($) {
4
5    /**
6     * Open a bootstrap modal. When the target holds an iframe and the link points to a real
7     * URL, that URL is loaded into the iframe first.
8     *
9     * The target comes from data-target, falling back to an anchor href.
10     *
11     * <a data-role="js-open-as-modal" data-target="#dialog_form_carfax" href="#">Form</a>
12     * <a data-role="js-open-as-modal" data-target="#dialog-iframe" href="https://app.autoverify.com/#/embed/tradein/year?key=...">Widget</a>
13     *
14     */
15    $(document).on('click', '[data-role="js-open-as-modal"],.js-open-as-modal,[data-role="js-open-as-dialog"],.js-open-as-dialog', function() {
16        var href = $(this).attr('href') || '';
17        var selector = $(this).data('target') || (href.charAt(0) === '#' ? href : '');
18        var targetDiv = selector ? $(selector) : $();
19
20        if (!targetDiv.length) {
21            return false;
22        }
23
24        var iframe = targetDiv.find('iframe');
25        if (iframe.length && href && href.charAt(0) !== '#') {
26            iframe.attr('src', href);
27        }
28
29        targetDiv.modal('show');
30        targetDiv.find('form').trigger('magnetis.form_visible');
31        return false;
32    });
33
34    $(document).on('hidden.bs.modal', '.dialog-iframe', function() {
35        $(this).find('iframe').attr('src', 'about:blank');
36    });
37
38    $(document).ready(function() {
39      const lang = $('html').attr('lang').substr(0, 2).toLowerCase();
40
41      const today = new Date()
42      const maxDate = new Date(today)
43      maxDate.setDate(maxDate.getDate() + 30);
44
45      let customDays = null;
46      let customMonths = null;
47
48      if (lang == 'fr') {
49        customDays = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'];
50        customMonths = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'];
51      }
52
53      let salesDepartment = null;
54      for (const node of document.querySelectorAll('.js-test-drive-datepicker')) {
55
56        const departments = dealerDepartments.filter((department) => department.identifier.toLowerCase() == 'sales');
57
58        if (departments) {
59          salesDepartment = departments[0];
60        }
61
62        node.setAttribute('autocomplete', 'off');
63
64        datepicker(node, {
65          position: 'tl',
66          customDays: customDays,
67          customMonths: customMonths,
68          minDate: today,
69          maxDate: maxDate,
70          showAllDates: true,
71          disabler: function (date) {
72            return salesDepartment && !salesDepartment.opening_days[(date.getDay()+6) % 7]
73          },
74          formatter: (input, date, instance) => {
75            input.value = moment(date).format('MM/D/YYYY');
76          },
77          onSelect: (instance, date) => {
78            setTimeout(() => instance.hide(), 10);
79          }
80        });
81      }
82    });
83
84    $(document).ready(function() {
85      const refreshForm = function() {
86        $('.js-visible').each(function() {
87          const visibleSelector = $(this).data('visibleSelector');
88          const isDisabledInvisible = $(this).data('visibleDisableFields') == 'when-invisible';
89          const isVisibleSelectorValid = $(visibleSelector).length == 1;
90          $(this).toggle(isVisibleSelectorValid);
91          $(this).find(':input').attr('disabled', (!isVisibleSelectorValid && isDisabledInvisible ? 'disabled' : null))
92        });
93      }
94
95      $(this).on('change', '.js-visible-trigger', refreshForm);
96
97      refreshForm();
98    });
99
100    $(document).ready(function() {
101      setInterval(function() {
102        $('.js-toggle-visibility').each(function (index) {
103          const selector = $($(this).data('visible-selector'));
104          $(this).toggle(selector.length == 0);
105        });
106      }, 250);
107    });
108
109  /**
110   * Popup dialogs
111   */
112  jQuery(function($) {
113
114    $('.vehicle_inventory_dialog').on('click', '.close_button', function(e) {
115      e.preventDefault();
116      $(this).parents('.vehicle_inventory_dialog').toggle();
117    });
118
119    $(document).on('keyup', function(e) {
120      if (e.key === "Escape") {
121        $('.vehicle_inventory_dialog').hide();
122      }
123    });
124
125    /**
126     * Form shown before opening the payment calculator, whatever opens it (VDP, SRP,
127     * showroom CTA or the Price Builder)
128     *
129     */
130    const CALCULATOR_GATE_STORAGE_KEY = 'magnetis_calculator_form_submitted';
131    let calculatorGateOnSubmitted = null;
132
133    function calculatorFormSubmitted() {
134        try {
135            return sessionStorage.getItem(CALCULATOR_GATE_STORAGE_KEY) === '1';
136        } catch (e) {
137            return false;
138        }
139    }
140
141    window.magnetisCalculatorGate = {
142        isRequired: function() {
143            return $('#dialog_form_calculator[data-form-before-calculator]').length > 0 && !calculatorFormSubmitted();
144        },
145
146        open: function(options) {
147            options = options || {};
148            const $modal = $('#dialog_form_calculator');
149            calculatorGateOnSubmitted = typeof options.onSubmitted === 'function' ? options.onSubmitted : null;
150
151            if (options.vehicleId) {
152                $modal.attr('data-vehicle-id', options.vehicleId);
153                $modal.find('form').each(function() {
154                    let $field = $(this).find('input[name="vi_vehicle_id"]');
155                    if (!$field.length) {
156                        $field = $('<input type="hidden" name="vi_vehicle_id">').appendTo(this);
157                    }
158                    $field.val(options.vehicleId);
159                });
160            }
161
162            $modal.modal('show');
163            $modal.find('form').trigger('magnetis.form_visible');
164        }
165    };
166
167    $(document).on('wpcf7mailsent', function(event) {
168        const $modal = $(event.target).closest('#dialog_form_calculator');
169        if (!$modal.length) {
170            return;
171        }
172
173        try {
174            sessionStorage.setItem(CALCULATOR_GATE_STORAGE_KEY, '1');
175        } catch (e) {
176            // Storage unavailable: the form is asked again next time.
177        }
178
179        const onSubmitted = calculatorGateOnSubmitted;
180        calculatorGateOnSubmitted = null;
181
182        if (onSubmitted) {
183            $modal.one('hidden.bs.modal', onSubmitted);
184        }
185        $modal.modal('hide');
186    });
187
188    // Handle Carfax form submission - fetch and open report in new window if available
189    // Also handles the new SRP module's shared carfax modal (#srp-carfax) meanwhile this is migrated to the new module
190    $(document).on('wpcf7mailsent', function(event) {
191      const $form = $(event.target);
192      const $dialog = $form.closest('#dialog_form_carfax, #srp-carfax');
193
194      // Only proceed if dialog exists, has vehicle-id, and form-before-report is enabled
195      if ($dialog.length && $dialog.data('vehicle-id') && $dialog.data('form-before-report')) {
196        const vehicleId = $dialog.data('vehicle-id');
197
198        if (vehicleId) {
199          const ajaxUrl = typeof GLOBAL !== 'undefined' && GLOBAL.ajax_url ? GLOBAL.ajax_url : '/wp-admin/admin-ajax.php';
200          // Fetch the Carfax URL via AJAX
201          $.ajax({
202            url: ajaxUrl,
203            type: 'POST',
204            data: {
205              action: 'vehicle_inventory_get_carfax_url',
206              vehicle_id: vehicleId,
207              lang: GLOBAL.lang || 'fr'
208            },
209            success: function(response) {
210              if (response.success && response.data && response.data.url) {
211                const carfaxNewWindow = window.open(response.data.url, '_blank');
212                if (!carfaxNewWindow) {
213                  Swal.fire({
214                    icon: 'warning',
215                    title: GLOBAL.lang == 'fr' ? 'Popup bloqué' : 'Popup Blocked',
216                    text: GLOBAL.lang == 'fr' ? 'Le popup Carfax a été bloqué. Veuillez autoriser les popups pour ce site.' : 'The Carfax popup was blocked. Please allow popups for this site.',
217                  });
218                }
219              }
220            },
221            error: function() {
222              console.warn('Could not retrieve Carfax report URL');
223            }
224          });
225        }
226      }
227    });
228
229    // Handle Window Sticker form submission - fetch and open window sticker in new window after form submission
230    $(document).on('wpcf7mailsent', function(event) {
231      const $form = $(event.target);
232      const $dialog = $form.closest('#dialog_form_window_sticker');
233
234      // Only proceed if dialog exists, has vehicle-id, and form-before-sticker is enabled
235      if ($dialog.length && $dialog.data('vehicle-id') && $dialog.data('form-before-sticker')) {
236        const vehicleId = $dialog.data('vehicle-id');
237
238        if (vehicleId) {
239          const ajaxUrl = typeof GLOBAL !== 'undefined' && GLOBAL.ajax_url ? GLOBAL.ajax_url : '/wp-admin/admin-ajax.php';
240
241          // Fetch the Window Sticker URL via AJAX
242          $.ajax({
243            url: ajaxUrl,
244            type: 'POST',
245            data: {
246              action: 'vehicle_inventory_get_window_sticker_url',
247              vehicle_id: vehicleId
248            },
249            success: function(response) {
250              if (response.success && response.data && response.data.url) {
251                const windowStickerNewWindow = window.open(response.data.url, '_blank');
252                if (!windowStickerNewWindow) {
253                  Swal.fire({
254                    icon: 'warning',
255                    title: GLOBAL.lang == 'fr' ? 'Popup bloqué' : 'Popup Blocked',
256                    text: GLOBAL.lang == 'fr' ? 'Le popup de la feuille de vitre a été bloqué. Veuillez autoriser les popups pour ce site.' : 'The Window Sticker popup was blocked. Please allow popups for this site.',
257                  });
258                }
259              }
260            },
261            error: function() {
262              console.warn('Could not retrieve Window Sticker URL');
263            }
264          });
265        }
266      }
267    });
268  });
269
270  /**
271   * Specs unfold
272   */
273  $(".vehicle_specifications").on('click', '.specs_unfold', function(e) {
274    e.preventDefault();
275
276    $(this).siblings('.specs_wrapper').removeClass('folded');
277    $(this).hide();
278    var $fold_button = $(this).siblings('.specs_fold');
279    $fold_button.css("display", "block");
280  });
281
282  $(".vehicle_specifications").on('click', '.specs_fold' , function(e){
283    e.preventDefault();
284
285    $(this).siblings('.specs_wrapper').addClass('folded');
286    $(this).hide();
287    var $unfold_button = $(this).siblings('.specs_unfold');
288    $unfold_button.css("display", "block");
289  });
290
291  $(document).ready(function() {
292    const acc = document.getElementsByClassName("LS-FAQ");
293
294    for (let i = 0; i > acc.length; i++) {
295      acc[i].addEventListener('click', function () {
296
297        var panel = this.nextElementSibling;
298        if (panel.style.maxHeight) {
299          panel.style.maxHeight = null;
300        } else {
301          let active = document.querySelectorAll('.LS-FAQ.active');
302          for (let j = 0; j > active.length; j++) {
303            active[j].classList.remove('active');
304            active[j].nextElementSibling.style.maxHeight = null;
305          }
306          this.classList.toggle('active');
307          panel.style.maxHeight = panel.scrollHeight + 'px';
308        }
309      });
310    }
311  });
312
313  // Expand the legal text
314  $(document).ready(function () {
315    var $legalText = $(".sidebar .legal-container .legal.collapsible");
316    if ($legalText.length === 0) {
317      return;
318    }
319    $legalText.on("click", function () {
320      expandLegalText();
321    });
322  });
323  $(window).on('resize', function() {
324    expandLegalText(true);
325  });
326  expandLegalText(true);
327  function expandLegalText(init = false) {
328    var $legalText = $(".sidebar .legal-container .legal.collapsible");
329    if ($legalText.length === 0) {
330      return;
331    }
332    if (!$legalText.hasClass("expanded") && $legalText[0].scrollWidth < $legalText.innerWidth() + 1) {//no overflow
333      //Set cursor to default and right-padding to 0
334      $legalText.css({ "cursor": "default"});
335      $legalText.addClass("not-expandable");
336      return;
337    }
338    if (init) {
339      return;
340    }
341    $legalText.removeClass("not-expandable");
342    $legalText.css({ "cursor": "pointer"});
343
344    if ($legalText.hasClass("expanded")) {
345      $legalText.removeClass("expanded");
346    } else {
347      $legalText.addClass("expanded");
348    }
349  }
350
351
352
353});
354
355
356window.mobileCheck = function() {
357  let check = false;
358  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
358sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
359  return check;
360};
361
362/**
363 * Prefix all object properties.
364 * @param {string} prefix
365 * @param {{}} obj
366 * @return {{}}
367 */
368function objectPrefixProperties(prefix, obj) {
369  const o = {};
370  for (const prop in obj) {
371    const p = (prefix + prop).replace(/ /, '_');
372    o[p] = obj[prop];
373  }
374
375  return o;
376}
377
378/**
379 * Return a structure for Google Analytic
380 * @return {{}}
381 */
382function getAnalyticPageProperties()
383{
384  const $page = $('script[data-class=Page]:eq(0)');
385  let pageProps = {
386    Path: window.location.pathname,
387    path: window.location.pathname
388  };
389
390  if ($page.length) {
391    let page = JSON.parse($page.text());
392    pageProps = Object.assign(pageProps, objectPrefixProperties('Page ', page));
393  }
394
395  const $vehicle = $('.page_vdp script[data-class=Vehicle]:eq(0)');
396  if ($vehicle.length) {
397    let vehicle = JSON.parse($vehicle.text());
398    pageProps = Object.assign(pageProps, objectPrefixProperties('Vehicle ', vehicle));
399  }
400
401  return pageProps;
402}
403
404/*
405 * Resolve the Vehicle_* analytic props for a given vehicle id.
406 * Looks up an in-page <script data-class="Vehicle"> first, then falls back to
407 * the REST endpoint. Returns a Promise resolving to a prefixed properties
408 * object (`Vehicle_id`, `Vehicle_make`, ...), or `{}`
409 */
410window._vehicleAnalyticPropsCache = window._vehicleAnalyticPropsCache || {};
411
412window.getVehicleAnalyticProperties = function(vehicleId) {
413  const id = parseInt(vehicleId, 10);
414  if (!id) return Promise.resolve({});
415
416  const cache = window._vehicleAnalyticPropsCache;
417  if (cache[id]) return cache[id];
418
419  const scripts = document.querySelectorAll('script[type="application/json"][data-class="Vehicle"]');
420  for (const s of scripts) {
421    try {
422      const v = JSON.parse(s.textContent);
423      if (parseInt(v.id, 10) === id) {
424        cache[id] = Promise.resolve(objectPrefixProperties('Vehicle ', v));
425        return cache[id];
426      }
427    } catch (_) { /* ignore malformed tag */ }
428  }
429
430  cache[id] = fetch('/wp-json/plateforme/v1/vehicle-analytics/' + id, {credentials: 'same-origin'})
431    .then((res) => (res.ok ? res.json() : null))
432    .then((data) => (data ? objectPrefixProperties('Vehicle ', data) : {}))
433    .catch(() => ({}));
434
435  return cache[id];
436};
437
438function getSrpVehicles() {
439  const result = [];
440  $('.listing script[data-class=Vehicle]').each(function() {
441    const $vehicle = $(this);
442    const vehicle = JSON.parse($vehicle.text());
443    result.push(vehicle);
444  });
445
446  return result;
447}
448
449function magnetis_currency_format(amount)
450{
451  var lang = $('html').attr('lang');
452  return amount.toLocaleString(lang);
453}
454
455// function capitalizeFirstLetter(string) {
456//   return string.charAt(0).toUpperCase() + string.slice(1);
457// }
458
459function structAsTwoDimension(value, target = {}, parents = []) {
460  if (typeof (value) === 'object') {
461    for (const prop in value) {
462      structAsTwoDimension(value[prop], target, [...parents, prop]);
463    }
464  } else {
465    target[parents.join('_')] = value;
466  }
467
468  return target;
469}
470
471function stringUcFirst(value) {
472  return value.charAt(0).toUpperCase() + value.slice(1);
473}
474
475
476
477/**
478 * definition: {
479 *   options: {},
480 *   methods: {
481 *     abc: function() { }
482 *   }
483 * }
484 */
485function JQueryPlugin(definition) {
486
487  var Api = function(element) {
488    this.element = jQuery(element);
489  }
490
491  Api.prototype = definition.methods;
492
493  return function(method) {
494    let value = null;
495
496    const args = arguments;
497    const $elements = jQuery(this).each(function(i, element) {
498
499      let api = jQuery(this).data('api');
500
501      if (api == undefined) {
502        api = new Api(element);
503        api.options = jQuery.extend(
504          definition.options,
505          jQuery(element).data()
506        );
507
508        jQuery(this).data('api', api);
509      }
510
511      if (api[method]) {
512        value = api[method].apply(api, Array.prototype.slice.call(args, 1));
513        if (value) {
514          return false;
515        }
516      }
517      else if (typeof method === 'object' || !method) {
518        return api.init.apply(api, args);
519      }
520      else {
521        jQuery.error(`Method ${method} not found.`);
522      }
523    });
524
525    if (value) {
526      return value;
527    }
528
529    return $elements;
530  };
531
532}
533

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.