1// Namespace definition 2var toolfactory = toolfactory || {}; 3toolfactory.home = toolfactory.home || {}; 4toolfactory.home.mybookings = toolfactory.home.mybookings || {}; 5 6var oneTapEvent = { 7 finished: false, 8 status: '' 9}; 10var geolocEvent = { 11 finished: false, 12 status: '', 13 airportCode: '', 14 source: -1 15}; 16 17toolfactory.home.mybookings.helpers = 18 (function () { 19 20 var MyBookingsHelpersClass = function() { 21 var self = this; 22 23 this._defaultSettings = { 24 maxNumReloads: 2, 25 reloadsCookieName: 'onetap_reloads' 26 }; 27 28 this.addQueryStringParam = function (queryString, param, value) { 29 var res; 30 31 if (!window.location.search && !queryString) { 32 res = param + '=' + value; 33 } 34 else 35 { 36 res = '&' + param + '=' + value; 37 } 38 39 return res; 40 }; 41 42 this.reloadPage = function () { 43 var reloadAttempts = self.getCookie(self._defaultSettings.reloadsCookieName); 44 if (reloadAttempts && parseInt(reloadAttempts, 10) >= self._defaultSettings.maxNumReloads) { 45 return; 46 } 47 48 var params = ''; 49 50 if (window.location.search.indexOf('onetap') === -1 && oneTapEvent.finished && oneTapEvent.status === 'success') { 51 params += self.addQueryStringParam(params, 'onetap', 'true'); 52 } 53 54 if (geolocEvent.finished && geolocEvent.status === 'success') { 55 if (geolocEvent.source === 500 && window.location.search.indexOf('geoloc_bk') === -1) { 56 params += self.addQueryStringParam(params, 'geoloc_bk', 'true'); 57 } 58 else if (geolocEvent.source === 550 && window.location.search.indexOf('geoloc') === -1) { 59 params += self.addQueryStringParam(params, 'geoloc', 'true'); 60 } 61 } 62 63 if (!reloadAttempts) { 64 self.setCookie(self._defaultSettings.reloadsCookieName, 1, 1/48); 65 } 66 else 67 { 68 self.setCookie(self._defaultSettings.reloadsCookieName, parseInt(reloadAttempts, 10) + 1, 1/48); 69 } 70 71 if (params && params != ' undefined&features=%7B%22feature%22%3A%5B%22DISPLAY_RP_TOS%22%5D%7D') { 72 window.location.search += params; 73 } 74 }; 75 76 this.getCookie = function (cookieName) { 77 var b = document.cookie.match('(^|;)\\s*' + cookieName + '\\s*=\\s*([^;]+)'); 78 return b ? b.pop() : ''; 79 }; 80 81 this.setCookie = function (name, value, daysForExpiration) { 82 83 var host, domain, domainParts; 84 host = location.host; 85 86 var today = new Date(); 87 var expire = new Date(); 88 if (daysForExpiration === null || daysForExpiration === 0) { 89 daysForExpiration = 1; 90 } 91 92 expire.setTime(today.getTime() + 3600000 * 24 * daysForExpiration); 93 94 if (host.split('.').length === 1) { 95 // no "." in a domain - it's localhost or something similar 96 domain = host; 97 if (domain.includes(':')) { 98 domain = domain.split(':').shift(); 99 } 100 101 document.cookie = name + '=' + value + '; domain=' + domain + '; path=/; expires=' + expire.toGMTString(); 102 } else { 103 domainParts = host.split('.'); 104 domainParts.shift(); 105 domain = '.' + domainParts.join('.'); 106 107 document.cookie = name + '=' + value + '; domain=' + domain + '; path=/; expires=' + expire.toGMTString(); 108 109 if (!self.getCookie(name)) { 110 domain = '.' + host; 111 document.cookie = name + '=' + value + '; domain=' + domain + '; path=/; expires=' + expire.toGMTString(); 112 } 113 } 114 }; 115 116 117 this.deleteCookie = function (name) { 118 document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 119 }; 120 121 // Transform a Javascript object to a urlEncoded querystring format 122 this.toUrlEncoded = function toUrlEncoded(obj) { 123 return Object.keys(obj).map(function (k) { 124 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 125 }).join('&'); 126 }; 127 }; 128 129 return new MyBookingsHelpersClass(); 130 131 })(); 132 133toolfactory.home.mybookings.loginOneTap = 134 (function () { 135 'use strict'; 136 137 var LoginOneTapClass = function () { 138 139 var self = this; 140 141 this.mbHelper = toolfactory.home.mybookings.helpers; 142 143 this._defaultSettings = { 144 CookieDisableOneTap: 'ck_disable_onetap' 145 }; 146 147 148 this.checkLogin = function () { 149 150 // If there's no cookie for disabling One Tap UI, check if the user is logged 151 var ckOneTap = self.mbHelper.getCookie(self._defaultSettings.CookieDisableOneTap); 152 var customerDetected = ""; 153 if (toolfactoryDataLayer && toolfactoryDataLayer.Client && toolfactoryDataLayer.Client.Customer != "0" && toolfactoryDataLayer.Client.Customer != "") { 154 customerDetected = toolfactoryDataLayer.Client.Customer; 155 } 156 157 if ((!ckOneTap || ckOneTap == 'false') && customerDetected === "") { 158 159 var checkloginRq = new XMLHttpRequest(); 160 161 checkloginRq.open('GET', window.location.origin +'/myaccount/account/checkloginstatus', true); 162 checkloginRq.timeout = 2000; 163 checkloginRq.withCredentials = true; 164 165 checkloginRq.onreadystatechange = function () { 166 if (checkloginRq.readyState === 4) { 167 if (checkloginRq.status === 200) { 168 169 var response = JSON.parse(checkloginRq.responseText); 170 if (!response.logged && !response.fromBack) { 171 google.accounts.id.prompt(function (notification) { 172 // if google one tap is showing, try to remove the modal for login 173 var element = document.getElementById("loginModal"); 174 if (element != null && element != undefined) 175 element.parentNode.removeChild(element); 176 });
177 } else { 178 oneTapEvent.finished = true; 179 oneTapEvent.status = 'error'; 180 window.dispatchEvent(new CustomEvent('onetap', { 181 detail: { 182 status: 'error' 183 } 184 })); 185 } 186 } 187 else if (checkloginRq.status !== 200) 188 { 189 oneTapEvent.finished = true; 190 oneTapEvent.status = 'error'; 191 window.dispatchEvent(new CustomEvent('onetap', { 192 detail: { 193 status: 'error' 194 } 195 })); 196 } 197 } 198 199 }; 200 201 checkloginRq.send(); 202 } 203 else 204 { 205 // One tap disabled programmatically, or manually by user. 206 // Treat it as error so the page doesn't reload. 207 oneTapEvent.finished = true; 208 oneTapEvent.status = 'error'; 209 window.dispatchEvent(new CustomEvent('onetap', { 210 detail: { 211 status: 'error' 212 } 213 })); 214 } 215 }; 216 217 this.sendToken = function(token) { 218 var encodedTkn = encodeURI(token); 219 220 var loginRq = new XMLHttpRequest(); 221 loginRq.open('POST', window.location.origin + '/myaccount/account/ThirdPartyLogin', true); 222 loginRq.timeout = 3000; // time in milliseconds 223 loginRq.withCredentials = true; 224 loginRq.setRequestHeader('Content-Type', 'application/json'); 225 226 var loginRqData = { 227 provider: "GoogleOneTap", 228 accesstoken: encodedTkn 229 }; 230 231 loginRq.onreadystatechange = function () { 232 if (loginRq.readyState == 4) { 233 if (loginRq.status == 200) { 234 oneTapEvent.finished = true; 235 oneTapEvent.status = 'success'; 236 window.dispatchEvent(new CustomEvent('onetap', { 237 detail: { 238 status: 'success' 239 } 240 })); 241 } 242 else 243 { 244 oneTapEvent.finished = true; 245 oneTapEvent.status = 'error'; 246 window.dispatchEvent(new CustomEvent('onetap', { 247 detail: { 248 status: 'error' 249 } 250 })); 251 } 252 } 253 } 254 255 loginRq.send(JSON.stringify(loginRqData)); 256 }; 257 258 this.loginCustomer = function(CredentialResponse) { 259 if (CredentialResponse != null && CredentialResponse.credential != null && CredentialResponse.credential != "") { 260 self.sendToken(CredentialResponse.credential); 261 } else { 262 self.disableAutoLogin(false); 263 self.mbHelper.setCookie(self._defaultSettings.CookieDisableOneTap, 'true', 1); 264 265 // Show error 266 oneTapEvent.finished = true; 267 oneTapEvent.status = 'error'; 268 window.dispatchEvent(new CustomEvent('onetap', { 269 detail: { 270 status: 'error' 271 } 272 })); 273 } 274 }; 275 276 this.disableAutoLogin = function(forcePageReload) { 277 google.accounts.id.disableAutoSelect().then(function (forcePageReload) { 278 // Do nothing 279 }, function (e) { 280 // Error, write cookie to disable onetap 281 self.mbHelper.setCookie(self._defaultSettings.CookieDisableOneTap, 'true', 1); 282 }).finally(function () { 283 if (forcePageReload) { 284 self.mbHelper.reloadPage(); 285 } 286 }); 287 }; 288 }; 289 290 return new LoginOneTapClass(); 291 })(); 292 293 294toolfactory.home.mybookings.geolocation = 295 (function () { 296 var GeolocationClass = function() { 297 298 var self = this; 299 300 var mbHelper = toolfactory.home.mybookings.helpers; 301 302 // Sets the new position in the user session 303 this.setPosition = function (latitude, longitude, source) { 304 305 var setoriginRq = new XMLHttpRequest(); 306 setoriginRq.open('POST', '/mybookings/origin/setorigingeoloc/', true); 307 setoriginRq.timeout = 5000; // time in milliseconds 308 setoriginRq.withCredentials = true; 309 setoriginRq.setRequestHeader('Content-Type', 'application/json'); 310 311 var setoriginRqData = { 312 Latitude: latitude, 313 Longitude: longitude, 314 Source: source 315 }; 316 317 setoriginRq.onreadystatechange = function () { 318 if (setoriginRq.readyState == 4) { 319 if (setoriginRq.status == 200) { 320 321 var resp = JSON.parse(setoriginRq.responseText); 322 323 if (resp.AirportCode && resp.AirportCode.length === 3) { 324 geolocEvent.finished = true; 325 geolocEvent.status = 'success'; 326 geolocEvent.airportCode = resp.AirportCode; 327 geolocEvent.source = source; 328 window.dispatchEvent(new CustomEvent('geoloc', { 329 detail: { 330 status: 'success' 331 } 332 })); 333 } 334 else { 335 geolocEvent.finished = true; 336 geolocEvent.status = 'error'; 337 geolocEvent.source = source; 338 window.dispatchEvent(new CustomEvent('geoloc', { 339 detail: { 340 status: 'error' 341 } 342 })); 343 } 344 } 345 else { 346 geolocEvent.finished = true; 347 geolocEvent.status = 'error'; 348 geolocEvent.source = source; 349 window.dispatchEvent(new CustomEvent('geoloc', { 350 detail: { 351 status: 'error' 352 } 353 })); 354 } 355 } 356 }; 357 358 setoriginRq.send(JSON.stringify(setoriginRqData)); 359 }; 360 361 362 // Gets position from the location API from the user's browser 363 this.getPositionBrowser = function () { 364 var options = { 365 enableHighAccuracy: true, 366 maximumAge: 0 367 }; 368 369 var geoSuccess = function geoSuccess(position) { 370 self.setPosition(position.coords.latitude, position.coords.longitude, 550); 371 }; 372 373 var geoError = function geoError(error) { 374 self.getPositionBk(500); 375 }; 376 377 navigator.geolocation.getCurrentPosition(geoSuccess, geoError, options); 378 }; 379 380 this.getPositionBk = function(source) { 381 var positionRq = new XMLHttpRequest(); 382 positionRq.open('GET', '/marketing/location/location.ashx', true); 383 positionRq.timeout = 3000; // time in milliseconds 384 positionRq.setRequestHeader('Content-Type', 'application/json'); 385 386 positionRq.onreadystatechange = function () { 387 if (positionRq.readyState === 4) { 388 if (positionRq.status === 200) { 389 var res = JSON.parse(positionRq.responseText); 390 391 if (res && res.Status === "OK") { 392 self.setPosition(res.Data.Latitude, res.Data.Longitude, source); 393 } 394 else 395 { 396 geolocEvent.finished = true; 397 geolocEvent.status = 'error'; 398 geolocEvent.source = source; 399 window.dispatchEvent(new CustomEvent('geolocEvent', { 400 detail: { 401 status: 'error' 402 } 403 })); 404 } 405 } 406 else 407 { 408 geolocEvent.finished = true; 409 geolocEvent.status = 'error'; 410 geolocEvent.source = source; 411 window.dispatchEvent(new CustomEvent('geolocEvent', { 412 detail: { 413 status: 'error' 414 } 415 })); 416 } 417 } 418 } 419 420 positionRq.send(); 421 }; 422 423 // Starts the geolocation process. Ask the user if we can get its position. 424 // If not, dispatch the event as failed and stop. 425 this.getGeoPosition = function () { 426 if (navigator.geolocation) { 427 // Google GeoLocation supported 428 self.getPositionBrowser(); 429 } 430 else 431 { 432 self.getPositionBk(500); 433 } 434 }; 435 }; 436 437 return new GeolocationClass(); 438 })(); 439 440(function () { 441 'use strict'; 442 443 var mbHelper = toolfactory.home.mybookings.helpers; 444 445 // Don't reload the page more than x times. 446 var reloadAttempts = mbHelper.getCookie(mbHelper._defaultSettings.reloadsCookieName); 447 if (reloadAttempts && parseInt(reloadAttempts, 10) >= mbHelper._defaultSettings.maxNumReloads) { 448 return; 449 } 450 451 // Check for browser features. 452 if (!Modernizr.geolocation || !Modernizr.promises || !Modernizr.customevent) { 453 return; 454 } 455 456 var initialAirport; 457 if (toolfactoryDataLayer && toolfactoryDataLayer.Client && toolfactoryDataLayer.Client.OriginAirportCode) { 458 initialAirport = toolfactoryDataLayer.Client.OriginAirportCode; 459 } 460 461 // Event listeners 462 window.addEventListener('onetap', function (e) { 463 if (e.detail.status == 'success') { 464 mbHelper.reloadPage(); 465 } 466 467 if (e.detail.status == 'error' && geolocEvent.finished && geolocEvent.status == 'success') { 468 // Check if the airport is different 469 if (initialAirport && initialAirport != geolocEvent.airportCode) { 470 mbHelper.reloadPage(); 471 } 472 } 473 });
474 475 window.addEventListener('geoloc', function (e) { 476 if (oneTapEvent.finished && e.detail.status == 'success') { 477 // Check if the airport is different 478 if (initialAirport && initialAirport != geolocEvent.airportCode) { 479 mbHelper.reloadPage(); 480 } 481 } 482 }); 483 484 // delete old cookie ck_disableonetap 485 mbHelper.deleteCookie('ck_disableonetap'); 486 487 var is_IE = navigator.userAgent.indexOf("MSIE") > -1; 488 var is_edge = navigator.userAgent.indexOf("Edge") > -1; 489 var isAlreadyLoadedGOT = false; 490 491 if (!is_IE && !is_edge) { 492 // Event OnGoogleLibraryLoad 493 window.onGoogleLibraryLoad = function () { 494 if (!isAlreadyLoadedGOT) { 495 isAlreadyLoadedGOT = true; 496 497 var ot = toolfactory.home.mybookings.loginOneTap; 498 google.accounts.id.initialize({ 499 client_id: "376296607929-daugkjghhd8pvlprg1r08659epqi6sq9.apps.googleusercontent.com", 500 cancel_on_tap_outside: false, 501 callback: ot.loginCustomer, 502 use_fedcm_for_prompt: true 503 }); 504 505 ot.checkLogin(); 506 } 507 }; 508 } 509 510 // Don't ask for geoloc on safari 511 var is_chrome = navigator.userAgent.indexOf('Chrome') > -1; 512 var is_safari = navigator.userAgent.indexOf("Safari") > -1; 513 // The geolocation in facebook browser is not working correctly. 514 var is_facebook_app = navigator.userAgent.indexOf("FBAN") > -1 || navigator.userAgent.indexOf("FBAV") > -1; 515 if ((is_safari && !is_chrome && !is_edge) || is_facebook_app) { 516 return; 517 } 518 519 var ck_airportSrc = mbHelper.getCookie("airport_src"); 520 521 if (!ck_airportSrc || parseInt(ck_airportSrc, 10) < 500) { 522 var geoloc = toolfactory.home.mybookings.geolocation; 523 geoloc.getGeoPosition(); 524 } 525 526 527 528}());
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.