1/** 2 * Sets proper language cookie 3 * 4 * Sends ajax request to get browser and IP language. 5 * Sets cookie with current language. 6 * Changes cookie when clicking a link pointed to another language. 7 * 8 */ 9function TRP_IN_Determine_Language(){ 10 var _this = this; 11 var trpCookie = null; 12 var trpHelper = null; 13 14 this.get_lang_from_url = function ( url ) { 15 // Check domain mappings first if Multiple Domains is active 16 if ( trp_language_cookie_data['domain_language_map'] ) { 17 var domainLang = _this.get_lang_from_domain( url ); 18 if ( domainLang ) { 19 return domainLang; 20 } 21 } 22 23 // Fall back to path-based detection 24 // we remove http or https 25 // if the user links to a http link but the abs_home_url is https, we're serving the https one so we don't brake cookies if he doesn't have proper redirects 26 var lang = url.replace( /^(http|https):\/\//g, ''); 27 var abs_home = trp_language_cookie_data[ 'abs_home' ].replace( /^(http|https):\/\//g, ''); 28 29 // we have removed the home path from our URL. We're adding a / in case it's the homepage of one of the languages 30 // removing / from the front so it's easier for understanding explode() 31 lang = trpHelper.ltrim( trpHelper.trailingslashit( lang.replace(abs_home, '') ),'/' ); 32 33 // We now have to see if the first part of the string is actually a language slug 34 var lang_array = lang.split("/"); 35 if( lang_array.length < 2 ){ 36 return trp_language_cookie_data['default_language']; 37 } 38 // The language code is the first non-empty item in this array depending on abs_home slashes 39 for ( var i = 0; i < lang_array.length; i++ ){ 40 if ( lang_array[i] != undefined && lang_array[i] != '' ) { 41 lang = lang_array[i]; 42 break; 43 } 44 } 45 // the lang slug != actual lang. So we need to do array_search so we don't end up with en instead of en_US 46 if( trpHelper.in_array( lang, trp_language_cookie_data['url_slugs']) ){ 47 return trpHelper.array_search(lang, trp_language_cookie_data['url_slugs'] ); 48 } else { 49 return trp_language_cookie_data['default_language']; 50 } 51 52 }; 53 54 /** 55 * Extract language from URL's domain using domain_language_map 56 * Used when Multiple Domains addon is active 57 * 58 * @param {string} url - URL to extract domain from 59 * @return {string|null} Language code or null if not found 60 */ 61 this.get_lang_from_domain = function( url ) { 62 var domainMap = trp_language_cookie_data['domain_language_map']; 63 if ( !domainMap ) { 64 return null; 65 } 66 67 // Extract hostname from URL 68 var hostname; 69 try { 70 var urlObj = new URL( url ); 71 hostname = urlObj.hostname; 72 } catch ( e ) { 73 // Fallback for older browsers or malformed URLs 74 var match = url.match( /^(?:https?:\/\/)?([^\/]+)/i ); 75 hostname = match ? match[1] : null; 76 } 77 78 if ( !hostname ) { 79 return null; 80 } 81 82 // Check if hostname matches any configured domain 83 if ( domainMap[hostname] ) { 84 return domainMap[hostname]; 85 } 86 87 return null; 88 }; 89 90 this.get_current_dom_language = function(){ 91 var html_language_document = document.getElementById("tp-language"); 92 var html_language; 93 if ( html_language_document ){ 94 if ( jQuery('#tp-language').attr('data-tp-language') ){ 95 html_language = jQuery( '#tp-language' ).attr( 'data-tp-language' ); 96 }else if (jQuery('#tp-language').attr('lang') ){ 97 html_language = jQuery( '#tp-language' ).attr( 'lang' ); 98 } 99 } else { 100 html_language = jQuery('html').attr('lang'); 101 html_language = html_language.split("-").join("_"); 102 } 103 104 if ( !trpHelper.in_array( html_language, trp_language_cookie_data['publish_languages'] ) ){ 105 html_language = "error_determining_language"; 106 } 107 108 return html_language; 109 }; 110 111 112 this.ajax_get_needed_language = function() { 113 jQuery.ajax({ 114 url: trp_language_cookie_data['trp_ald_ajax_url'], 115 type: 'post', 116 dataType: 'json', 117 data: { 118 action: 'trp_ald_get_needed_language', 119 detection_method: trp_language_cookie_data['detection_method'], 120 popup_option: trp_language_cookie_data['popup_option'], 121 popup_textarea: trp_language_cookie_data['popup_textarea'], 122 popup_type: trp_language_cookie_data['popup_type'], 123 popup_textarea_change_button: trp_language_cookie_data['popup_textarea_change_button'], 124 popup_textarea_close_button: trp_language_cookie_data['popup_textarea_close_button'], 125 publish_languages: trp_language_cookie_data['publish_languages'], 126 iso_codes: trp_language_cookie_data['iso_codes'], 127 english_name: trp_language_cookie_data['english_name'], 128 default_language: trp_language_cookie_data['default_language'], 129 is_iphone_user_check: trp_language_cookie_data['is_iphone_user_check'] 130 }, 131 success: function( response ) { 132 if ( response ) { 133 _this.redirect_if_needed( response ); 134 }else{ 135 _this.redirect_if_needed( _this.get_current_dom_language() ); 136 } 137 138 }, 139 error: function( errorThrown ){ 140 // make current language the needed language 141 _this.redirect_if_needed( _this.get_current_dom_language() ); 142 } 143 }); 144 }; 145 146 this.activate_popup = function( response, url_to_redirect ){ 147 148 _this.make_ls_clickable(); 149 _this.ls_make_default_language_preselected( response ); 150 151 var popup = document.getElementById("trp_ald_modal_container"); 152 var close = document.getElementById("trp_ald_x_button"); 153 var popup_change_button = document.getElementById("trp_ald_popup_change_language"); 154 var close_popup = document.getElementById("trp_ald_x_button_and_textarea"); 155 var no_text_popup_select_current_language = document.querySelector('[special-selector = "trp_ald_popup_current_language"]'); 156 157 popup.style.display = 'flex'; 158 159 close_popup.onclick = function(e){ 160 popup.style.display = 'none';
161 trpCookie.setCookie( trp_language_cookie_data['cookie_name'], _this.get_current_dom_language(), trp_language_cookie_data['cookie_age'], trp_language_cookie_data['cookie_path'] ); 162 163 // Anchor looks like this <a href="#">. This prevents navigating to # 164 e.preventDefault(); 165 } 166 167 _this.ls_select_language(); 168 169 popup_change_button.onclick = function(){ 170 var selected_language = no_text_popup_select_current_language.getAttribute('data-trp-ald-selected-language'); 171 trpCookie.setCookie( trp_language_cookie_data['cookie_name'], selected_language, trp_language_cookie_data['cookie_age'], trp_language_cookie_data['cookie_path'] ); 172 } 173 } 174 175 176 this.activate_hello_bar = function (response, url_to_redirect){ 177 178 var no_text_popup = document.getElementById("trp_ald_no_text_popup_template"); 179 var clone = no_text_popup.content.cloneNode(true); 180 181 var close_button = clone.getElementById('trp_close'); 182 var mobile_close_button = clone.getElementById('trp_ald_no_text_popup_x_button_and_textarea'); 183 var button_change_language_no_text_popup = clone.getElementById('trp_ald_no_text_popup_change_language'); 184 var no_text_popup_select_current_language = clone.querySelector('[special-selector = "trp_ald_popup_current_language"]'); 185 186 var div = document.createElement('div'); 187 div.appendChild(clone); 188 document.body.insertAdjacentElement('afterbegin', div); 189 190 button_change_language_no_text_popup.onclick = function() { 191 var selected_language = no_text_popup_select_current_language.getAttribute( 'data-trp-ald-selected-language' ); 192 trpCookie.setCookie( trp_language_cookie_data[ 'cookie_name' ], selected_language, trp_language_cookie_data[ 'cookie_age' ], trp_language_cookie_data[ 'cookie_path' ] ); 193 } 194 195 var remove_bar = function () { 196 trpCookie.setCookie( trp_language_cookie_data['cookie_name'], _this.get_current_dom_language(), trp_language_cookie_data['cookie_age'], trp_language_cookie_data['cookie_path'] ); 197 document.body.removeChild(div); 198 }; 199 200 close_button.onclick = remove_bar; 201 mobile_close_button.onclick = remove_bar; 202 203 _this.make_ls_clickable(); 204 _this.ls_select_language(); 205 _this.ls_make_default_language_preselected( response ); 206 } 207 208 209 this.get_ald_language_switcher_transition_duration = function( list ) { 210 if ( !list || window.matchMedia?.( '(prefers-reduced-motion: reduce)' )?.matches ) { 211 return 0; 212 } 213 214 var computed_style = window.getComputedStyle( list ); 215 var parse_time = function( value ) { 216 value = value.trim(); 217 return value.endsWith( 'ms' ) ? parseFloat( value ) : parseFloat( value ) * 1000; 218 }; 219 var durations = computed_style.transitionDuration.split( ',' ).map( parse_time ); 220 var delays = computed_style.transitionDelay.split( ',' ).map( parse_time ); 221 222 return Math.max.apply( null, durations.map( function( duration, index ) { 223 return duration + delays[ index % delays.length ]; 224 }) ); 225 } 226 227 this.finish_ald_language_switcher_transition = function( switcher ) { 228 var $switcher = jQuery( switcher ); 229 var $list = $switcher.find( '.trp-ls-shortcode-language' ); 230 var transition_frame = $switcher.data( 'trpAldTransitionFrame' ); 231 var transition_timeout = $switcher.data( 'trpAldTransitionTimeout' ); 232 233 if ( transition_frame ) { 234 window.cancelAnimationFrame( transition_frame ); 235 $switcher.removeData( 'trpAldTransitionFrame' ); 236 } 237 238 if ( transition_timeout ) { 239 window.clearTimeout( transition_timeout ); 240 $switcher.removeData( 'trpAldTransitionTimeout' ); 241 } 242 243 $list.off( 'transitionend.trpAldSwitcherState' ); 244 $switcher.removeClass( 'is-transitioning' ); 245 246 if ( !$switcher.hasClass( 'is-open' ) ) { 247 $list.attr( 'hidden', '' ).attr( 'inert', '' ); 248 } 249 } 250 251 this.wait_for_ald_language_switcher_transition = function( switcher, transition_duration ) {
252 var $switcher = jQuery( switcher ); 253 var $list = $switcher.find( '.trp-ls-shortcode-language' ); 254 var finish_transition = function() { 255 _this.finish_ald_language_switcher_transition( switcher ); 256 }; 257 258 $list.off( 'transitionend.trpAldSwitcherState' ) 259 .one( 'transitionend.trpAldSwitcherState', function( event ) { 260 if ( event.originalEvent.propertyName === 'max-height' ) { 261 finish_transition(); 262 } 263 }); 264 265 $switcher.data( 'trpAldTransitionTimeout', window.setTimeout( finish_transition, transition_duration + 50 ) ); 266 } 267 268 this.close_ald_language_switchers = function( except_switcher ) { 269 jQuery( '.trp_ald_ls_container .trp-shortcode-overlay' ).each( function() { 270 if ( this !== except_switcher ) { 271 _this.set_ald_language_switcher_open( this, false, false ); 272 } 273 }); 274 } 275 276 this.set_ald_language_switcher_open = function( switcher, open, focus_first_option ) { 277 var $switcher = jQuery( switcher ); 278 279 if ( ! $switcher.length ) { 280 return; 281 } 282 283 var $list = $switcher.find( '.trp-ls-shortcode-language' ); 284 var list = $list.get( 0 ); 285 var transition_duration = _this.get_ald_language_switcher_transition_duration( list ); 286 var has_transition = transition_duration > 0; 287 288 _this.finish_ald_language_switcher_transition( switcher ); 289 290 if ( open ) { 291 _this.close_ald_language_switchers( switcher ); 292 $list.removeAttr( 'hidden inert' ); 293 $switcher.find( '.trp-ls-shortcode-current-language' ) 294 .addClass( 'trp-ls-clicked' ) 295 .attr( 'aria-expanded', 'true' ); 296 $list.addClass( 'trp-ls-clicked' ); 297 298 if ( has_transition ) { 299 $switcher.addClass( 'is-transitioning' ); 300 $switcher.data( 'trpAldTransitionFrame', window.requestAnimationFrame( function() { 301 $switcher.removeData( 'trpAldTransitionFrame' ); 302 $switcher.addClass( 'is-open' ); 303 _this.wait_for_ald_language_switcher_transition( switcher, transition_duration ); 304 }) ); 305 } else { 306 $switcher.addClass( 'is-open' ); 307 } 308 309 if ( focus_first_option ) { 310 setTimeout( function() { 311 $switcher.find( '.trp-ald-popup-select:not(.is-current-language)' ).first().trigger( 'focus' ); 312 }, 0 ); 313 } 314 315 return; 316 } 317 318 var was_open = $switcher.hasClass( 'is-open' ); 319 320 if ( was_open && has_transition ) { 321 $switcher.addClass( 'is-transitioning' ); 322 } 323 324 $switcher.removeClass( 'is-open' ); 325 $switcher.find( '.trp-ls-shortcode-current-language' ) 326 .removeClass( 'trp-ls-clicked' ) 327 .attr( 'aria-expanded', 'false' ); 328 $list.removeClass( 'trp-ls-clicked' ); 329 330 if ( was_open && has_transition ) { 331 _this.wait_for_ald_language_switcher_transition( switcher, transition_duration ); 332 } else { 333 _this.finish_ald_language_switcher_transition( switcher ); 334 } 335 } 336 337 this.make_ls_clickable = function (){ 338 jQuery( '.trp_ald_ls_container .trp-current-language-item__wrapper' ) 339 .off( 'click.trpAldSwitcher' ) 340 .on( 'click.trpAldSwitcher', function ( event ) { 341 event.preventDefault(); 342 event.stopPropagation(); 343 344 var switcher = jQuery( this ).closest( '.trp-language-switcher' ); 345 _this.set_ald_language_switcher_open( switcher, ! switcher.hasClass( 'is-open' ), false ); 346 }); 347 348 jQuery( '.trp_ald_ls_container .trp-language-switcher' ) 349 .off( 'mouseenter.trpAldSwitcher mouseleave.trpAldSwitcher focusout.trpAldSwitcher' ) 350 .on( 'mouseenter.trpAldSwitcher', function() { 351 _this.set_ald_language_switcher_open( this, true, false ); 352 }) 353 .on( 'mouseleave.trpAldSwitcher', function() { 354 if ( ! this.contains( document.activeElement ) ) { 355 _this.set_ald_language_switcher_open( this, false, false ); 356 } 357 }) 358 .on( 'focusout.trpAldSwitcher', function() { 359 var switcher = this; 360 setTimeout( function() { 361 if ( ! switcher.contains( document.activeElement ) ) { 362 _this.set_ald_language_switcher_open( switcher, false, false ); 363 } 364 }, 0 ); 365 }); 366
367 jQuery( '.trp_ald_ls_container .trp-ls-shortcode-current-language' ) 368 .off( 'keydown.trpAldSwitcher' ) 369 .on( 'keydown.trpAldSwitcher', function( event ) { 370 var switcher = jQuery( this ).closest( '.trp-language-switcher' ); 371 372 if ( event.key === 'Enter' || event.key === ' ' ) { 373 event.preventDefault(); 374 _this.set_ald_language_switcher_open( switcher, ! switcher.hasClass( 'is-open' ), false ); 375 return; 376 } 377 378 if ( event.key === 'ArrowDown' ) { 379 event.preventDefault(); 380 _this.set_ald_language_switcher_open( switcher, true, true ); 381 return; 382 } 383 384 if ( event.key === 'Escape' ) { 385 event.preventDefault(); 386 _this.set_ald_language_switcher_open( switcher, false, false ); 387 this.focus(); 388 } 389 }); 390 391 jQuery( '.trp_ald_ls_container .trp-ald-popup-select' ) 392 .off( 'keydown.trpAldSwitcher' ) 393 .on( 'keydown.trpAldSwitcher', function( event ) { 394 var switcher = jQuery( this ).closest( '.trp-language-switcher' ); 395 396 if ( event.key === 'Enter' || event.key === ' ' ) { 397 event.preventDefault(); 398 jQuery( this ).trigger( 'click' ); 399 return; 400 } 401 402 if ( event.key === 'Escape' ) { 403 event.preventDefault(); 404 _this.set_ald_language_switcher_open( switcher, false, false ); 405 switcher.find( '.trp-ls-shortcode-current-language' ).trigger( 'focus' ); 406 } 407 }); 408 409 jQuery('.trp_ald_ls_container .trp-ls-shortcode-language').off( 'click.trpAldSwitcher' ).on( 'click.trpAldSwitcher', function () { 410 _this.close_ald_language_switchers(); 411 }); 412 413 414 jQuery(document).off( 'keyup.trpAldSwitcher' ).on( 'keyup.trpAldSwitcher', function(e) { 415 if (e.key === "Escape") { 416 _this.close_ald_language_switchers(); 417 } 418 }); 419 420 jQuery(document).off( 'click.trpAldSwitcher' ).on("click.trpAldSwitcher", function(event){ 421 if(!jQuery(event.target).closest(".trp_ald_ls_container .trp-language-switcher").length){ 422 _this.close_ald_language_switchers(); 423 } 424 }); 425 } 426 427 this.ls_select_language = function(){ 428 429 var no_text_current_language = document.querySelector('.trp_ald_ls_container .trp-shortcode-overlay .trp-ls-shortcode-current-language'); 430 var no_text_popup_select_current_language = document.querySelector('.trp_ald_ls_container .trp-shortcode-overlay .trp-ls-shortcode-current-language'); 431 var popup_change_button = document.getElementById("trp_ald_popup_change_language"); 432 var button_change_language_no_text_popup = document.getElementById('trp_ald_no_text_popup_change_language'); 433 jQuery('.trp-ald-popup-select').off( 'click.trpAldSwitcher' ).on( 'click.trpAldSwitcher', function ( item ) { 434 no_text_current_language.innerHTML = item.currentTarget.innerHTML; 435 no_text_current_language.setAttribute('data-trp-ald-selected-language', item.currentTarget.getAttribute('data-trp-ald-selected-language')); 436 var selected_language = no_text_popup_select_current_language.getAttribute('data-trp-ald-selected-language'); 437 _this.ls_hide_selected_language_option( selected_language ); 438 _this.set_language_href(selected_language,popup_change_button,button_change_language_no_text_popup); 439 }); 440 } 441 442 this.ls_hide_selected_language_option = function( selected_language ){ 443 var all_languages = document.querySelectorAll('.trp_ald_ls_container .trp-ald-popup-select'); 444 445 for ( var i = 0; i < all_languages.length; i++ ) { 446 if ( all_languages[i].getAttribute('data-trp-ald-selected-language') === selected_language ) { 447 all_languages[i].classList.add('is-current-language'); 448 all_languages[i].setAttribute( 'aria-selected', 'true' ); 449 } else { 450 all_languages[i].classList.remove('is-current-language'); 451 all_languages[i].setAttribute( 'aria-selected', 'false' ); 452 } 453 } 454 } 455 456 this.ls_make_default_language_preselected = function( response ){ 457 458 var no_text_current_language = document.querySelector('[special-selector = "trp_ald_popup_current_language"]'); 459 var all_languages = document.querySelectorAll('.trp_ald_ls_container .trp-ald-popup-select'); 460 var popup_change_button = document.getElementById("trp_ald_popup_change_language"); 461 var button_change_language_no_text_popup = document.getElementById('trp_ald_no_text_popup_change_language'); 462 for ( var i = 0; i< all_languages.length; i++){ 463 if (all_languages[i].id === response){ 464 no_text_current_language.innerHTML = all_languages[i].innerHTML; 465 no_text_current_language.setAttribute('data-trp-ald-selected-language', response); 466 no_text_current_language.setAttribute('id', response); 467 var selected_language = no_text_current_language.getAttribute('data-trp-ald-selected-language'); 468 _this.ls_hide_selected_language_option( selected_language ); 469 _this.set_language_href(selected_language, popup_change_button, button_change_language_no_text_popup); 470 break; 471 } 472 } 473 } 474 475 this.set_language_href = function ( selected_language, popup_change_button, button_change_language_no_text_popup ){ 476 if( popup_change_button !== null ){ 477 popup_change_button.href = _this.get_url_for_lang(selected_language); 478 } 479 if( button_change_language_no_text_popup !== null ){ 480 button_change_language_no_text_popup.href = _this.get_url_for_lang(selected_language); 481 } 482 } 483 484 this.decode_HTML_entities = function(str) { 485 let txt = new DOMParser().parseFromString(str, "text/html"); 486 return txt.documentElement.textContent; 487 } 488 489 this.get_url_for_lang = function( language ){ 490 491 for( i in trp_language_cookie_data['language_urls'] ){ 492 if( i === language ) { 493 let url_for_language = _this.decode_HTML_entities(trp_language_cookie_data['language_urls'][i]); 494 495 return url_for_language; 496 } 497 } 498 return false;
499 }; 500 501 this.is_valid_url = function ( url ) { 502 if ( typeof url === 'undefined' || url === '' ){ 503 return false; 504 } 505 var starting_characters = ['#','?', 'javascript']; 506 for (var i = 0; i < starting_characters.length; i++ ){ 507 if ( url.substring(0, starting_characters[i].length) === starting_characters[i]){ 508 return false; 509 } 510 } 511 return true; 512 }; 513 514 this.replace_underscore_with_dash = function (var_replace){ 515 var_replace = var_replace.toLowerCase(); 516 var_replace = var_replace.split("_").join("-"); 517 518 return var_replace; 519 } 520 521 this.is_same_language_code = function (var1, var2){ 522 var1 = _this.replace_underscore_with_dash(var1); 523 var2 = _this.replace_underscore_with_dash(var2); 524 525 if( var1 == var2 || var1 == "error_determining_language" || var2 == "error_determining_language" ){ 526 return true; 527 } 528 return false; 529 } 530 531 this.is_login_url = function( url ){ 532 if( url.includes( "wp-login.php" )){ 533 return true; 534 } 535 return false; 536 } 537 538 this.add_event_handlers = function(){ 539 jQuery('body').on('click', 'a', function(e) { 540 541 var clicked_url = jQuery(this).attr("href"); 542 if ( _this.is_valid_url( clicked_url ) && !_this.is_login_url( clicked_url )) { 543 var clicked_language = _this.get_lang_from_url(clicked_url); 544 var trp_current_language = trpCookie.getCookie(trp_language_cookie_data['cookie_name']); 545 546 if (!(_this.is_same_language_code(trp_current_language, clicked_language))) { 547 // When Multiple Domains is active, only handle clicks to our configured domains 548 if ( trp_language_cookie_data['domain_language_map'] && !_this.get_lang_from_domain( clicked_url ) ) { 549 return; // External URL â don't change cookie or add trp_lang_switch 550 } 551 552 // Skip cross-domain sync here â the landing page will handle it after detecting trp_lang_switch=1 553 trpCookie.setCookie(trp_language_cookie_data['cookie_name'], clicked_language, trp_language_cookie_data['cookie_age'], trp_language_cookie_data['cookie_path'], true); 554 555 // Add query param to signal deliberate language switch (for cross-domain) 556 if ( trp_language_cookie_data['domain_language_map'] ) { 557 e.preventDefault(); 558 var separator = clicked_url.indexOf('?') !== -1 ? '&' : '?'; 559 window.location.href = clicked_url + separator + 'trp_lang_switch=1'; 560 return false; 561 } 562 } 563 } 564 }); 565 }; 566 567 this.check_if_iphone_user = function (){ 568 569 if( trp_language_cookie_data['is_iphone_user_check'] == false ){ 570 return false; 571 }else{ 572 if( /iPhone/g.test(navigator.userAgent) ){ 573 return true; 574 }else{ 575 return false; 576 } 577 } 578 }; 579 580 this.should_show_popup_on_current_language = function() { 581 if ( ! trp_language_cookie_data['popup_language_condition_enabled'] ) { 582 return true; 583 } 584 585 var popupLanguages = trp_language_cookie_data['popup_languages']; 586 587 if ( !popupLanguages || !popupLanguages.length ) { 588 return trp_language_cookie_data['popup_language_condition_mode'] === 'exclude'; 589 } 590 591 var currentLanguageMatches = trpHelper.in_array( _this.get_current_dom_language(), popupLanguages ); 592 593 return trp_language_cookie_data['popup_language_condition_mode'] === 'exclude' 594 ? !currentLanguageMatches 595 : currentLanguageMatches; 596 }; 597 598 this.redirect_if_needed = function( needed_language ){ 599 // Skip cross-domain sync here â if redirect happens the landing page handles it, if not the cookie is already correct 600 var currentDomLanguage = _this.get_current_dom_language(); 601 602 if ( trp_language_cookie_data['popup_option'] == 'popup' && !_this.should_show_popup_on_current_language() ) {
603 trpCookie.setCookie( trp_language_cookie_data['cookie_name'], currentDomLanguage, trp_language_cookie_data['cookie_age'], trp_language_cookie_data['cookie_path'], true ); 604 _this.add_event_handlers(); 605 return; 606 } 607 608 trpCookie.setCookie( trp_language_cookie_data['cookie_name'], needed_language, trp_language_cookie_data['cookie_age'], trp_language_cookie_data['cookie_path'], true ); 609 _this.add_event_handlers(); 610 611 if (!(_this.is_same_language_code(currentDomLanguage, needed_language)) && _this.check_if_iphone_user() == false ){ 612 url_to_redirect = _this.get_url_for_lang( needed_language ); 613 if(url_to_redirect != 'undefined' && url_to_redirect!= false ) { 614 // redirect to needed language 615 if(trp_language_cookie_data['popup_type'] == 'normal_popup' && trp_language_cookie_data['popup_option'] == 'popup'){ 616 _this.activate_popup( needed_language, url_to_redirect ); 617 }else{ 618 if(trp_language_cookie_data['popup_type'] == 'hello_bar' && trp_language_cookie_data['popup_option'] == 'popup'){ 619 _this.activate_hello_bar(needed_language, url_to_redirect); 620 }else { 621 window.location.replace( url_to_redirect ); 622 } 623 } 624 } 625 } 626 }; 627 628 this.initialize = function (){ 629 trpCookie = new TRP_IN_Cookie(); 630 trpHelper = new TRP_IN_Helper(); 631 if ( ! trpCookie.areCookiesEnabled() ){ 632 _this.add_event_handlers(); 633 return; 634 } 635 636 // Check if this is a deliberate language switch (query param from add_event_handlers) 637 var urlParams = new URLSearchParams( window.location.search ); 638 if ( urlParams.has( 'trp_lang_switch' ) ) { 639 // Remove the query param from URL first 640 urlParams.delete( 'trp_lang_switch' ); 641 var newUrl = window.location.pathname + ( urlParams.toString() ? '?' + urlParams.toString() : '' ) + window.location.hash; 642 history.replaceState( null, '', newUrl ); 643 644 // Deliberate switch - set cookie to current page language, no popup 645 var currentLanguage = _this.get_lang_from_url( window.location.href ); 646 if ( currentLanguage ) { 647 trpCookie.setCookie( trp_language_cookie_data['cookie_name'], currentLanguage, trp_language_cookie_data['cookie_age'], trp_language_cookie_data['cookie_path'] ); 648 _this.add_event_handlers(); 649 return; 650 } 651 // If no domain language found (Multiple Domains not active), continue with normal detection 652 } 653 654 var language_from_cookie = trpCookie.getCookie( trp_language_cookie_data['cookie_name'] ); 655 if ( language_from_cookie && trpHelper.in_array( language_from_cookie, trp_language_cookie_data['publish_languages'] ) ) { 656 // if cookie is set, redirect if needed 657 _this.redirect_if_needed( language_from_cookie ); 658 }else{ 659 // if cookie is not set, send request to find out language and then redirect if needed 660 _this.ajax_get_needed_language(); 661 } 662 }; 663 664 _this.initialize(); 665} 666 667/** 668 * String manipulation functions 669 */ 670function TRP_IN_Helper(){ 671 672 this.trailingslashit = function ( string ){ 673 string = string.replace(/\/+$/,''); 674 string = string + '/'; 675 return string; 676 }; 677 678 this.ltrim = function ( string ) { 679 var trimmed = string.replace(/^\s+/g, ''); 680 return trimmed; 681 }; 682 683 this.in_array = function (needle, haystack) { 684 for(var i in haystack ) { 685 if(haystack[i] == needle) { 686 return true; 687 } 688 } 689 return false; 690 }; 691 692 this.array_search = function(val, array) { 693 if(typeof(array) === 'array' || typeof(array) === 'object') { 694 var rekey; 695 for(var i in array) { 696 if(array[i] == val) { 697 rekey = i; 698 break; 699 } 700 } 701 return rekey; 702 } 703 }; 704 705 /** 706 * Update url with query string. 707 * 708 */ 709 this.update_query_string = function(key, value, url) { 710 if (!url) url = window.location.href; 711 var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"), 712 hash; 713 714 if (re.test(url)) { 715 if (typeof value !== 'undefined' && value !== null) 716 return url.replace(re, '$1' + key + "=" + value + '$2$3'); 717 else { 718 hash = url.split('#'); 719 url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); 720 if (typeof hash[1] !== 'undefined' && hash[1] !== null) 721 url += '#' + hash[1]; 722 return url; 723 } 724 } 725 else { 726 if (typeof value !== 'undefined' && value !== null ) { 727 var separator = url.indexOf('?') !== -1 ? '&' : '?'; 728 hash = url.split('#'); 729 url = hash[0] + separator + key + '=' + value; 730 if (typeof hash[1] !== 'undefined' && hash[1] !== null) 731 url += '#' + hash[1]; 732 return url; 733 } 734 else 735 return url; 736 } 737 }; 738} 739 740/** 741 * Manipulate cookie: set/get/erase 742 * Includes cross-domain sync for Multiple Domains addon 743 */
744function TRP_IN_Cookie() { 745 var _this = this; 746 747 // Track if sync is in progress to prevent duplicate syncs 748 this.syncInProgress = false; 749 750 /** 751 * Set a cookie and trigger cross-domain sync if enabled 752 * 753 * @param {boolean} skipSync - Skip cross-domain sync (e.g. when navigating away immediately) 754 */ 755 this.setCookie = function(cname, cvalue, exdays, cpath, skipSync) { 756 var d = new Date(); 757 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); 758 var expires = "expires=" + d.toUTCString(); 759 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=" + cpath + ";SameSite=Lax"; 760 761 // Trigger cross-domain sync if this is the language cookie 762 if ( cname === trp_language_cookie_data['cookie_name'] && !skipSync ) { 763 _this.syncToOtherDomains( cvalue ); 764 } 765 }; 766 767 this.getCookie = function(cname) { 768 var name = cname + "="; 769 var ca = document.cookie.split(';'); 770 for(var i = 0; i < ca.length; i++) { 771 var c = ca[i]; 772 while (c.charAt(0) == ' ') { 773 c = c.substring(1); 774 } 775 if (c.indexOf(name) == 0) { 776 return c.substring(name.length, c.length); 777 } 778 } 779 return ""; 780 }; 781 782 this.eraseCookie = function(name) { 783 document.cookie = name+'=; Max-Age=-99999999;'; 784 }; 785 786 this.areCookiesEnabled = function(){ 787 if (navigator.cookieEnabled) return true; 788 789 // set and read cookie 790 document.cookie = "cookietest=1"; 791 var ret = document.cookie.indexOf("cookietest=") != -1; 792 793 // delete cookie 794 document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT"; 795 796 return ret; 797 }; 798 799 /** 800 * Sync cookie to all other configured domains (Multiple Domains support) 801 * 802 * @param {string} cookieValue - The language code to sync 803 */ 804 this.syncToOtherDomains = function( cookieValue ) { 805 // Check if sync is enabled and ajax URLs exist 806 if ( !trp_language_cookie_data['sync_enabled'] || 807 !trp_language_cookie_data['sync_ajax_urls'] || 808 _this.syncInProgress ) { 809 return; 810 } 811 812 _this.syncInProgress = true; 813 814 var currentDomain = trp_language_cookie_data['current_domain']; 815 var ajaxUrls = trp_language_cookie_data['sync_ajax_urls']; 816 817 for ( var language in ajaxUrls ) { 818 if ( !ajaxUrls.hasOwnProperty( language ) ) { 819 continue; 820 } 821 822 var ajaxUrl = ajaxUrls[ language ]; 823 824 // Skip if this ajax URL is on the current domain 825 if ( ajaxUrl.indexOf( currentDomain ) === 0 ) { 826 continue; 827 } 828 829 _this.injectSyncIframe( ajaxUrl, cookieValue ); 830 } 831 832 // Reset sync flag after a delay 833 setTimeout( function() { 834 _this.syncInProgress = false; 835 }, 5000 ); 836 }; 837 838 /** 839 * Inject hidden iframe to set cookie on another domain via REST API 840 * 841 * @param {string} restUrl - Target REST API URL 842 * @param {string} cookieValue - Cookie value to set 843 */ 844 this.injectSyncIframe = function( restUrl, cookieValue ) { 845 var iframe = document.createElement( 'iframe' ); 846 iframe.style.display = 'none'; 847 iframe.className = 'trp-ald-sync-iframe'; 848 iframe.src = restUrl + '?trp_ald_cv=' + encodeURIComponent( cookieValue ); 849 850 // Remove iframe after load or timeout 851 iframe.onload = function() { 852 setTimeout( function() { 853 if ( iframe.parentNode ) { 854 iframe.parentNode.removeChild( iframe ); 855 } 856 }, 1000 ); 857 }; 858 859 // Fallback: remove after timeout even if onload doesn't fire 860 setTimeout( function() { 861 if ( iframe.parentNode ) { 862 iframe.parentNode.removeChild( iframe ); 863 } 864 }, 10000 ); 865 866 document.body.appendChild( iframe ); 867 }; 868} 869 870 871jQuery( function() { 872 trpDetermineLanguage = new TRP_IN_Determine_Language(); 873});
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.