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.