1jQuery(document).ready(function($){ 2 3 4 5 (function(){ 6 7 //initialize datepicker 8 $('.xoo-aff-input-date').each( function( index, dateEl ){ 9 var $dateEl = $(dateEl), 10 dateData = $dateEl.data('date'); 11 $dateEl.datepicker( dateData ); 12 } ); 13 14 }()); 15 16 17 var all_states = xoo_aff_localize.states ? JSON.parse(xoo_aff_localize.states) : {}; 18 var countries_locale = xoo_aff_localize.countries_locale ? JSON.parse(xoo_aff_localize.countries_locale) : {}; 19 20 //-------------------- XXXXXXXXXXXXXXX -------------------- // 21 22 var SelectCountry = function( $select ){ 23 24 var self = this; 25 self.$selectCountry = $select; 26 self.id = self.$selectCountry.attr('name'); 27 self.$form = self.$selectCountry.closest( 'form' ); 28 self.$selectState = self.$form.find('.xoo-aff-states[data-country_field="'+self.id+'"]'); 29 self.$selectPhoneCode = self.$form.find('.xoo-aff-phone_code[data-country_field="'+self.id+'"]'); 30 31 //Methods 32 self.statesHandler = self.$selectState.length ? self.states() : false; 33 34 //Events 35 self.$selectCountry.on( 'change', { country: self }, this.onChange ); 36 self.$selectCountry.trigger('change'); //on load 37 38 } 39 40 SelectCountry.prototype.onChange = function( event ){ 41 var self = event.data.country; 42 if( self.statesHandler ){ 43 self.statesHandler.updateStateField( event ); 44 } 45 46 if( self.$selectPhoneCode.length ){ 47 self.updatePhoneCodeField(); 48 } 49 } 50 51 //PhoneCode field handler 52 SelectCountry.prototype.updatePhoneCodeField = function(){ 53 var country = this, 54 $codeOption = country.$selectPhoneCode.find( 'option[data-country_code="'+country.$selectCountry.val()+'"]' ); 55 56 if( $codeOption ){ 57 $codeOption.prop('selected','selected'); 58 } 59 60 country.$selectPhoneCode.trigger('change'); 61 } 62 63 //State field handler 64 SelectCountry.prototype.states = function(){ 65 66 var country = this, 67 $selectState = country.$selectState, 68 defaultValue = country.$selectState.data( 'default_state' ); 69 70 var Handler = { 71 72 init: function(){ 73 Handler.$statePlaceholder = $selectState.find('option[value="placeholder"]'); 74 Handler.$selectStateCont = $selectState.parent(); 75 Handler.$inputState = Handler.createStateInput(); 76 }, 77 78 getStates: function(){ 79 var states = all_states[ country.$selectCountry.val() ]; 80 return states === undefined || states.length === 0 ? null : states; 81 }, 82 83 createStateInput: function(){ 84 $stateInput = $( '<input type="text" />' ) 85 .prop( 'name', $selectState.attr('name') ) 86 .prop('placeholder', Handler.$statePlaceholder.html() ) 87 .addClass( $selectState.attr('class') ); 88 89 var excludeID = ['select2', 'select2Id' ,'country_field']; 90 91 $.each($selectState.data(), function( id, value ){ 92 if( !excludeID.includes(id) ){ 93 $stateInput.attr('data-'+id, value); 94 } 95 96 }); 97 98 return $stateInput; 99 }, 100 101 updateStateField: function( event ){ 102 103 var country = event.data.country, 104 countryVal = country.$selectCountry.val(); 105 106 //Remove all current states 107 $selectState.find('option').not(Handler.$statePlaceholder).remove(); 108 109 110 var active_states = Handler.getStates(); 111 112 if( !active_states ){ 113 114 Handler.$selectStateCont.find('.select2-container').remove(); 115 Handler.$selectStateCont.append( Handler.$inputState ); 116 117 } 118 else{ 119 Handler.$inputState.remove(); 120 Handler.$selectStateCont.append( $selectState ); 121 $.each( active_states, function( state_key, label ){ 122 $selectState.append( '<option value="'+state_key+'">'+label+'</option>' ); 123 } ) 124 125 if( defaultValue ){ 126 Handler.$selectStateCont.find( 'option[value='+defaultValue+']' ).prop( 'selected', 'selected' ); 127 } 128 129 if( $selectState.attr('select2') === 'yes' ){ 130 $selectState.select2(); 131 } 132 133 } 134 135 136 } 137 138 } 139 140 Handler.init(); 141 142 return Handler; 143 } 144 145 $.each( $('select.xoo-aff-country'), function( index, el ){ 146 new SelectCountry( $(el)); 147 } ); 148 149 150 //-------------------- XXXXXXXXXXXXXXX -------------------- // 151 152 var password_strength_meter = { 153 154 /** 155 * Initialize strength meter actions. 156 */ 157 init: function() { 158 $( document.body ) 159 .on( 160 'keyup change', 161 'input.xoo-aff-password[check_strength="yes"]', 162 this.strengthMeter 163 ); 164 }, 165 166 /** 167 * Strength Meter. 168 */ 169 strengthMeter: function() { 170 var wrapper = $(this).parents('.xoo-aff-group'), 171 form = wrapper.parents('form'); 172 submit = form.length ? $( 'button[type="submit"]', form ) : false, 173 field = $(this), 174 strength = 1, 175 passStrength = $(this).attr('strength_pass').length ? $(this).attr('strength_pass') : xoo_aff_localize.password_strength.min_password_strength, 176 fieldValue = field.val(); 177 178 password_strength_meter.includeMeter( wrapper, field ); 179 180 strength = password_strength_meter.checkPasswordStrength( wrapper, field, passStrength ); 181 182 183 if ( 184 submit && 185 fieldValue.length > 0 && 186 strength < passStrength && 187 -1 !== strength 188 ) { 189 submit.attr( 'disabled', 'disabled' ).addClass( 'disabled' ); 190 } else { 191 submit.removeAttr( 'disabled', 'disabled' ).removeClass( 'disabled' ); 192 } 193 }, 194 195 /** 196 * Include meter HTML. 197 * 198 * @param {Object} wrapper 199 * @param {Object} field 200 */ 201 includeMeter: function( wrapper, field ) { 202 var meter = wrapper.find( '.xoo-aff-password-strength' ); 203 204 if ( '' === field.val() ) { 205 meter.hide(); 206 $( document.body ).trigger( 'xoo-aff-password-strength-hide' ); 207 } else if ( 0 === meter.length ) { 208 wrapper.append( '<div class="xoo-aff-password-strength" aria-l
208ive="polite"></div>' ); 209 $( document.body ).trigger( 'xoo-aff-password-strength-added' ); 210 } else { 211 meter.show(); 212 $( document.body ).trigger( 'xoo-aff-password-strength-show' ); 213 } 214 }, 215 216 /** 217 * Check password strength. 218 * 219 * @param {Object} field 220 * 221 * @return {Int} 222 */ 223 checkPasswordStrength: function( wrapper, field, passStrength ) { 224 var meter = wrapper.find( '.xoo-aff-password-strength' ), 225 hint = wrapper.find( '.xoo-aff-password-hint' ), 226 hint_html = '<small class="xoo-aff-password-hint">' + xoo_aff_localize.password_strength.i18n_password_hint + '</small>', 227 strength = wp.passwordStrength.meter( field.val(), wp.passwordStrength.userInputBlacklist() ), 228 error = ''; 229 230 // Reset. 231 meter.removeClass( 'short bad good strong' ); 232 hint.remove(); 233 234 if ( meter.is( ':hidden' ) ) { 235 return strength; 236 } 237 238 // Error to append 239 if ( strength < passStrength ) { 240 error = ' - ' + xoo_aff_localize.password_strength.i18n_password_error; 241 } 242 243 switch ( strength ) { 244 case 0 : 245 meter.addClass( 'short' ).html( pwsL10n['short'] + error ); 246 meter.after( hint_html ); 247 break; 248 case 1 : 249 meter.addClass( 'bad' ).html( pwsL10n.bad + error ); 250 meter.after( hint_html ); 251 break; 252 case 2 : 253 meter.addClass( 'bad' ).html( pwsL10n.bad + error ); 254 meter.after( hint_html ); 255 break; 256 case 3 : 257 meter.addClass( 'good' ).html( pwsL10n.good + error ); 258 break; 259 case 4 : 260 meter.addClass( 'strong' ).html( pwsL10n.strong + error ); 261 break; 262 case 5 : 263 meter.addClass( 'short' ).html( pwsL10n.mismatch ); 264 break; 265 } 266 267 return strength; 268 } 269 }; 270 271 password_strength_meter.init(); 272 273 if( $.fn.select2 ){ 274 $('select.xoo-aff-select_list[select2="yes"] , select.xoo-aff-country[select2="yes"]').each(function( key, el ){ 275 $(el).select2(); 276 }); 277 } 278 279 280 if( $.fn.select2 ){ 281 282 function formatState (state) { 283 284 if (!state.id) { 285 return state.text; 286 } 287 288 var cc = state.element.getAttribute('data-country_code'); 289 cc = cc ? cc.toLowerCase() : cc; 290 291 var $state = $( '<div class="xoo-aff-flag-cont"><span class="flag ' + cc +'"></span>' + '<span>' + state.text + '</span></div>' ); 292 293 return $state; 294 295 }; 296 297 298 299 $('select.xoo-aff-phone_code[select2="yes"]').each(function( key, el ){ 300 $(el).select2({ templateResult: formatState, templateSelection: formatState, dropdownCssClass: "xoo-aff-select2-dropdown" }); 301 }); 302 } 303 304 305 //Password toggle visiblity 306 $( 'body' ).on( 'click', '.xoo-aff-pw-toggle', function(){ 307 308 var $password = $(this).closest('.xoo-aff-group').find('input.xoo-aff-password'); 309 310 $(this).toggleClass('active'); 311 312 if( $(this).hasClass('active') ){ 313 $password.attr('type','text'); 314 $(this).find('.xoo-aff-pwtog-hide').show(); 315 $(this).find('.xoo-aff-pwtog-show').hide(); 316 } 317 else{ 318 $password.attr('type','password'); 319 $(this).find('.xoo-aff-pwtog-show').show(); 320 $(this).find('.xoo-aff-pwtog-hide').hide(); 321 } 322 323 } ) 324 325 $( 'body' ).on('change', '.xoo-aff-file-profile input[type="file"]', function() { 326 327 var file = this.files[0], 328 $cont = $(this).closest('.xoo-aff-group'); 329 330 if (file) { 331 const reader = new FileReader(); 332 333 reader.onload = function(e) { 334 profileImage.init( $cont, e.target.result); 335 profileImage.onImageLoad(); 336 337 if( $cont.find('.xoo-ff-file-remove') ){ 338 $cont.find('.xoo-ff-files').remove(); 339 } 340 341 }; 342 343 reader.readAsDataURL(file); 344 } 345 else{ 346 profileImage.init( $cont, ''); 347 profileImage.onImageRemove(); 348 349 } 350 }); 351 352 var profileImage = { 353 354 init: function( $cont, imgSrc = '' ){ 355 this.$cont = $cont; 356 this.imgSrc = imgSrc; 357 this.$preview = $cont.find('.xoo-ff-file-preview'); 358 this.$icon = $cont.find('.xoo-aff-input-icon '); 359 this.$checkIcon = $cont.find('.xoo-ff-file-plcheck'); 360 this.$addIcon = $cont.find('.xoo-ff-file-pladd'); 361 }, 362 363 onImageLoad: function(){ 364 this.$preview.attr('src', profileImage.imgSrc).show(); 365 this.$icon.hide(); 366 this.$addIcon.hide(); 367 this.$checkIcon.show(); 368 369 }, 370 371 onImageRemove: function(){ 372 this.$icon.show(); 373 this.$checkIcon.hide(); 374 this.$addIcon.show(); 375 this.$preview.attr('src', '').hide(); 376 } 377 378 } 379 380 381 $('.xoo-aff-file-profile-cont').each(function(index, el){ 382 383 var $el = $(el), 384 $attachedFiled = $el.find('.xoo-ff-file-link'); 385 386 if( $attachedFiled.length ){ 387 profileImage.init( $el, $attachedFiled.attr('href') ); 388 profileImage.onImageLoad(); 389 } 390 }) 391 392 $('body').on( 'click', '.xoo-aff-file-profile-cont .xoo-ff-file-remove', function(){ 393 var $cont = $(this).closest('.xoo-aff-file-profile-cont'); 394 profileImage.init( $cont ); 395 profileImage.onImageRemove(); 396 } ); 397 398 $( 'body' ).on('click', '.xoo-ff-file-remove', function(){ 399 $(this).closest('div').remove(); 400 }); 401 402 403 404 class AutoComplete{ 405 406 constructor( $input ){ 407 this.$input = $input; 408 this.$form = $input.closest('form'); 409 this.hasParts = this.$form.find('[data-autocompad_parent="'+this.$input.attr('name')+'"]').length; 410 this.inputInit = false; 411 412 this.$browserFetch = this.$input.closest('.xoo-aff-group').find('.xoo-aff-auto-fetch-loc'); 413 414 this.events(); 415 } 416 417 418 events(){ 419 this.$input.on('focus', this.init.bind(this) ); 420 if( this.$browserFetch.length ){ 421 this.$browserFetch.on('click', { handler: this }, this.browserGetLocation ); 422 } 423 } 424 425 426 browserGetLocation(event){ 427 428 var handler = event.data.handler; 429 430 if( !navigator.geolocation ){
431 $(this).html('Not supported by browser'); 432 return; 433 } 434 435 var $fetchEl = $(this); 436 437 navigator.geolocation.getCurrentPosition( 438 439 (position) => { 440 handler.googleReverseGeolocate( position.coords.latitude, position.coords.longitude ); 441 }, 442 (error) => { 443 $fetchEl.find('span').text( error.message ); 444 } 445 ); 446 } 447 448 googleReverseGeolocate(lat, long){ 449 450 const geocoder = new google.maps.Geocoder(); 451 452 const latlng = { lat: parseFloat(lat), lng: parseFloat(long) }; 453 454 var autocompleteHandler = this; 455 456 geocoder.geocode({ location: latlng }, function (results, status) { 457 458 if (status === "OK") { 459 460 if (results[0]) { 461 autocompleteHandler.fillAddress( results[0].address_components, results[0].formatted_address ); 462 } 463 else { 464 console.log("No results found"); 465 } 466 } 467 else { 468 autocompleteHandler.$browserFetch.find('span').text( status ); 469 } 470 }); 471 } 472 473 474 475 init(){ 476 477 if( this.inputInit ) return; 478 479 var placesArgs = { 480 fields: ["address_components" ], 481 types: ["address"], 482 } 483 484 if( xoo_aff_localize.geolocate_countries ){ 485 placesArgs.componentRestrictions = {country: xoo_aff_localize.geolocate_countries} 486 } 487 488 this.location = new google.maps.places.Autocomplete(this.$input.get(0), placesArgs); 489 490 if( this.hasParts ){ 491 this.location.addListener('place_changed', this.onAddressChange.bind(this) ); 492 } 493 494 this.inputInit = true; 495 496 } 497 498 onAddressChange(){ 499 this.fillAddress( this.location.getPlace().address_components ); 500 } 501 502 503 fillAddress( components, formatted_address = '' ){ 504 505 var autocompleteHandler = this, 506 $form = this.$form, 507 addressParts = { country: '', postal_code: '', address: '', states: '', city: '', states_longname: '', country_longname: '' }; 508 509 $.each( components, function( index, component ){ 510 511 var componentType = component.types[0]; 512 513 514 switch(componentType) { 515 516 case 'country': 517 addressParts.country = component.short_name; 518 addressParts.country_longname = component.long_name; 519 break; 520 521 522 case "postal_code_suffix": 523 addressParts.postal_code += component.long_name; 524 break; 525 526 case "postal_code": 527 addressParts.postal_code += component.long_name; 528 break; 529 530 case "locality": // Most common 531 case "postal_town": // UK, Ireland, some EU countries 532 case "administrative_area_level_3": // Brazil, Japan, some regions 533 addressParts.city = component.long_name; 534 break; 535 536 case 'administrative_area_level_1': 537 addressParts.states = component.short_name; 538 addressParts.states_longname = component.long_name; 539 break; 540 541 default: 542 addressParts.address += ( component.long_name + ' ' ); 543 break; 544 } 545 546 } ); 547 548 549 //If states are not available for country 550 if( !addressParts.city && addressParts.states && (!countries_locale[ addressParts.country ] || !countries_locale[ addressParts.country ][ 'state' ] || countries_locale[ addressParts.country ][ 'state' ][ 'hidden' ] ) ){ 551 addressParts.city = addressParts.states; 552 addressParts.states = null; 553 } 554 555 var partsNotUsed = {}, 556 partsUsedCounter = 0; 557 558 $.each( addressParts, function( part, value ){ 559 560 var $inputParts = $form.find('[data-autocompad_type="'+part+'"][data-autocompad_parent="'+autocompleteHandler.$input.attr('name')+'"]'); 561 562 if( !$inputParts.length ){ 563 partsNotUsed[part] = value; 564 return true; //do not proceed further as address part element does not exist 565 } 566 567 partsUsedCounter++; 568 569 $inputParts.each( function( index, inputPart ){ 570 571 var $inputPart = $(inputPart); 572 573 if( (part === 'states' || part === 'country') && $inputPart.is('input') ){ // if its an input and not select, we use long name 574 $inputPart.val( addressParts[part+'_longname'] ); 575 } 576 else{ 577 578 //scan through states as the name returned by google does not exactly match the local states data we have 579 if( part === 'states' && !$inputPart.find('option[value="'+value+'"]').length ){ 580 581 var optionFound; 582 583 $inputPart.find('option').each(function( index, option ){
584 var $option = $(option); 585 if( $option.val().includes('-'+value) ){ 586 optionFound = $option; 587 return false; 588 } 589 }) 590 591 592 if( !optionFound ){ 593 optionFound = $inputPart.find("option:contains('" + addressParts.states_longname + "')"); 594 } 595 596 if( optionFound.length ){ 597 $inputPart.val( optionFound.val() ); 598 } 599 600 } 601 else{ 602 $inputPart.val( value ); 603 } 604 605 $inputPart.trigger('change'); 606 607 } 608 609 }); 610 611 } ); 612 613 if( partsUsedCounter > 0 ){ 614 615 var inputAddress = addressParts.address; 616 617 $.each( [ 'city', 'states', 'postal_code', 'country' ], function( index, leftPart ){ 618 if( partsNotUsed[ leftPart ] ){ 619 var partLongName = partsNotUsed[ leftPart + '_longname' ]; 620 partLongName = partLongName ? partLongName : partsNotUsed[ leftPart ]; 621 inputAddress += ( ', ' + partLongName ); 622 } 623 } ); 624 625 this.$input.val(inputAddress); 626 627 628 } 629 else if(formatted_address){ 630 this.$input.val(formatted_address); 631 } 632 633 } 634 635 } 636 637 638 if( xoo_aff_localize.geolocate_apikey ){ 639 640 $('input[data-autocompadd="yes"]').each(function(){ 641 new AutoComplete( $(this) ); 642 }); 643 644 } 645 646 647 648 649 $('.xoo-aff-group').on('focusin', 'input, textarea, select', function () { 650 $(this).closest('.xoo-aff-group').addClass('xoo-aff-isfocused'); 651 }); 652 653 $('.xoo-aff-group').on('focusout', 'input, textarea, select', function () { 654 $(this).closest('.xoo-aff-group').removeClass('xoo-aff-isfocused'); 655 }); 656 657 658 659 660})
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.