first commit

This commit is contained in:
User A0264400
2026-04-01 23:20:16 +03:00
commit a766acdc90
23071 changed files with 4933189 additions and 0 deletions

View File

@@ -0,0 +1,484 @@
( function () {
const permanentlyDisabledServices = [];
const baseUrl =
'https://public-api.wordpress.com/wpcom/v2/woo/address-autocomplete';
const searchUrl = `${ baseUrl }/search`;
const selectUrl = `${ baseUrl }/select`;
const MAX_SERVICE_ERROR_RETRIES = 3;
/**
* Generate a unique session ID using crypto.randomUUID if available, otherwise fallback to Math.random
* @returns {string} A unique session ID
*/
function generateSessionId() {
return crypto && crypto.randomUUID
? crypto.randomUUID()
: Math.random().toString( 36 ).substring( 2 );
}
/**
* Debounce function from lodash, modified to return a promise.
*/
function debounce( func, wait, options ) {
var lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime,
lastInvokeTime = 0,
leading = false,
maxing = false,
trailing = true;
if ( typeof func != 'function' ) {
throw new TypeError( 'Expected a function' );
}
if ( typeof options === 'object' ) {
leading = !! options.leading;
maxing = 'maxWait' in options;
maxWait = maxing ? Math.max( options.maxWait || 0, wait ) : maxWait;
trailing = 'trailing' in options ? !! options.trailing : trailing;
}
function invokeFunc( time ) {
var args = lastArgs,
thisArg = lastThis,
resolve = args._resolve;
lastArgs = lastThis = undefined;
lastInvokeTime = time;
result = func.apply( thisArg, args );
// If there's a resolve function, call it with the result
if ( resolve ) {
resolve( result );
}
return result;
}
function leadingEdge( time ) {
// Reset any `maxWait` timer.
lastInvokeTime = time;
// Start the timer for the trailing edge.
timerId = setTimeout( timerExpired, wait );
// Invoke the leading edge.
return leading
? invokeFunc( time )
: new Promise( ( resolve ) => {
// Store the resolve function to be called when the function executes
lastArgs._resolve = resolve;
} );
}
function remainingWait( time ) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
timeWaiting = wait - timeSinceLastCall;
return maxing
? Math.min( timeWaiting, maxWait - timeSinceLastInvoke )
: timeWaiting;
}
function shouldInvoke( time ) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (
lastCallTime === undefined ||
timeSinceLastCall >= wait ||
timeSinceLastCall < 0 ||
( maxing && timeSinceLastInvoke >= maxWait )
);
}
function timerExpired() {
var time = Date.now();
if ( shouldInvoke( time ) ) {
return trailingEdge( time );
}
// Restart the timer.
timerId = setTimeout( timerExpired, remainingWait( time ) );
}
function trailingEdge( time ) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if ( trailing && lastArgs ) {
return invokeFunc( time );
}
lastArgs = lastThis = undefined;
return result;
}
function cancel() {
if ( timerId !== undefined ) {
clearTimeout( timerId );
}
// Reject any pending promise
if ( lastArgs && lastArgs._resolve ) {
lastArgs._resolve( [] ); // Resolve with empty array for cancelled requests
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge( Date.now() );
}
function debounced() {
var time = Date.now(),
isInvoking = shouldInvoke( time );
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if ( isInvoking ) {
if ( timerId === undefined ) {
return leadingEdge( lastCallTime );
}
if ( maxing ) {
// Handle invocations in a tight loop.
clearTimeout( timerId );
timerId = setTimeout( timerExpired, wait );
return invokeFunc( lastCallTime );
}
}
if ( timerId === undefined ) {
timerId = setTimeout( timerExpired, wait );
}
// Return a promise that will resolve when the function is eventually called
return new Promise( ( resolve ) => {
// Store the resolve function to be called when the function executes
lastArgs._resolve = resolve;
} );
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
Object.entries( a8cAddressAutocompleteServiceKeys ).forEach(
( [ key, value ] ) => {
let sessionId = generateSessionId();
let requestDurations = [];
let serviceErrorRetries = 0;
// LRU Cache for search results - key: `${inputValue}:${country}`, value: data
class LRUCache {
constructor( maxSize = 100 ) {
this.maxSize = maxSize;
this.cache = new Map();
}
get( key ) {
if ( this.cache.has( key ) ) {
// Move to end (most recently used)
const value = this.cache.get( key );
this.cache.delete( key );
this.cache.set( key, value );
return value;
}
return null;
}
set( key, value ) {
if ( this.cache.has( key ) ) {
// Remove existing entry to move to end
this.cache.delete( key );
} else if ( this.cache.size >= this.maxSize ) {
// Remove least recently used (first entry)
const firstKey = this.cache.keys().next().value;
this.cache.delete( firstKey );
}
this.cache.set( key, value );
}
clear() {
this.cache.clear();
}
get size() {
return this.cache.size;
}
}
const searchCache = new LRUCache( 100 );
// Helper function to check cache
const getCachedResult = ( inputValue, country ) => {
const cacheKey = `${ inputValue }:${ country }`;
return searchCache.get( cacheKey );
};
// Helper function to store result in cache
const cacheResult = ( inputValue, country, data ) => {
const cacheKey = `${ inputValue }:${ country }`;
searchCache.set( cacheKey, data );
};
// Shared error handling function
const handleApiError = ( data, response ) => {
if ( ! data.code && ! data.error ) {
return; // No error to handle
}
const errorCode = data.code || data.error;
switch ( errorCode ) {
case 'expired_jwt_token':
case 'malformed_jwt_token':
case 'invalid_jwt_token':
case 'invalid_issuer':
case 'invalid_service':
case 'missing_jwt_token':
permanentlyDisabledServices.push( key );
console.error(
`Automattic Address Suggestion (${ key }) has been disabled due to invalid JWT token`
);
return;
case 'rate_limit_exceeded':
permanentlyDisabledServices.push( key );
setTimeout( () => {
const index =
permanentlyDisabledServices.indexOf( key );
if ( index !== -1 ) {
permanentlyDisabledServices.splice( index, 1 );
}
}, ( Number( response.headers.get( 'RateLimit-Retry-After' ) ) || 60 ) * 1000 );
console.error(
`Automattic Address Suggestion (${ key }) has been disabled due to rate limit exceeded`
);
return;
case 'missing_query':
return;
case 'no_suggestions':
return;
case 'missing_address_id':
console.error(
`Automattic Address Suggestion (${ key }) has been disabled due to missing address ID`
);
return;
case 'no_place':
console.error(
`Automattic Address Suggestion (${ key }) has been disabled due to no place found`
);
return;
case 'missing_session_id':
sessionId = generateSessionId();
return;
case 'woo_address_suggestion_internal_error':
case 'woo_address_suggestion_service_error':
case 'woo_address_suggestion_server_error':
serviceErrorRetries++;
if (
serviceErrorRetries >= MAX_SERVICE_ERROR_RETRIES
) {
permanentlyDisabledServices.push( key );
console.error(
`Automattic Address Suggestion (${ key }) has been disabled due to internal service error`
);
}
return;
default:
return;
}
};
const debouncedSearch = debounce(
async ( inputValue, country ) => {
const params = new URLSearchParams( {
query: inputValue,
country,
lang: document.documentElement.lang || navigator.lang,
session_id: sessionId,
token: value.key,
} );
try {
const startTime = performance.now();
const response = await fetch(
`${ searchUrl }?${ params.toString() }`
);
const endTime = performance.now();
requestDurations.push( endTime - startTime );
let data = await response.json();
// Handle errors using shared function
handleApiError( data, response );
if ( Array.isArray( data ) ) {
data = data.map( ( item ) => ( {
id: item.id,
label: item.label,
matchedSubstrings: item.matched_substrings,
} ) );
// Cache the successful result.
// An empty result is still a valid result and is cached.
cacheResult( inputValue, country, data );
return data;
}
} catch ( e ) {
if ( e.name === 'AbortError' ) {
// Ignore abort errors from cancelled requests
return [];
}
console.error(
`Error fetching address suggestions for ${ key }:`,
e
);
return [];
}
},
300,
{ leading: false, trailing: true }
);
window.wc.addressAutocomplete.registerAddressAutocompleteProvider( {
id: key,
canSearch: () => {
try {
if ( permanentlyDisabledServices.includes( key ) ) {
return false;
}
// Split JWT into parts
const [ , payload ] = value.key.split( '.' );
if ( ! payload ) {
permanentlyDisabledServices.push( key );
return false;
}
// Decode payload
const decodedPayload = JSON.parse( atob( payload ) );
// Check expiration
const currentTime = Math.floor( Date.now() / 1000 );
if (
! decodedPayload.exp ||
decodedPayload.exp < currentTime
) {
permanentlyDisabledServices.push( key );
return false;
}
return true;
} catch ( e ) {
permanentlyDisabledServices.push( key );
return false;
}
},
search: async ( inputValue, country, type ) => {
// We need to return early here because canSearch is not always called from search.
if ( permanentlyDisabledServices.includes( key ) ) {
return [];
}
inputValue = inputValue.trim();
// Check cache first - bypass debounce for cached results
const cachedResult = getCachedResult( inputValue, country );
if ( cachedResult !== null ) {
return cachedResult;
}
return await debouncedSearch( inputValue, country );
},
async select( addressId ) {
const params = new URLSearchParams( {
address_id: addressId,
session_id: sessionId,
lang: document.documentElement.lang,
token: value.key,
} );
const response = await fetch(
`${ selectUrl }?${ params.toString() }`
);
let data = await response.json();
// Reset session ID after successful select
sessionId = generateSessionId();
try {
dispatchEvent(
new CustomEvent(
'wc-address-autocomplete-service-request-durations',
{
detail: {
requestDurations,
provider: key,
},
}
)
);
} catch ( e ) {
console.error( e );
}
requestDurations = [];
// Handle errors using shared function
handleApiError( data, response );
return data;
},
} );
window.addEventListener(
'wc-address-autocomplete-service-request-durations',
( e ) => {
if ( ! value.canTelemetry || e.detail.provider !== key ) {
return;
}
// Send request durations to statsd, to keep track of the average request duration.
new Image().src = createStatsdURL( 'a8c-ac-service', {
name: 'request-durations',
value: e.detail.requestDurations,
type: 'timing',
} );
}
);
}
);
} )();
function createBeacon( section, { name, value, type } ) {
const event = name.replace( '-', '_' );
// A counting event defaults to incrementing by one.
if ( type === 'counting' ) {
value = value === undefined ? 1 : value;
}
value = Array.isArray( value ) ? value : [ value ];
return value.map(
( v ) =>
`a8c.${ section }.${ event }:${ v }|${
type === 'timing' ? 'ms' : 'c'
}`
);
}
function createStatsdURL( sectionName, events ) {
if ( ! Array.isArray( events ) ) {
events = [ events ]; // Only a single event was passed to process.
}
const sanitizedSection = sectionName.replace( /[.:-]/g, '_' );
const json = JSON.stringify( {
beacons: events
.map( ( event ) => createBeacon( sanitizedSection, event ) )
.flat(),
} );
const encodedJson = encodeURIComponent( json );
return `https://pixel.wp.com/boom.gif?json=${ encodedJson }`;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
/* global Cookies */
jQuery( function( $ ) {
// Select all elements with the class [role="alert"] attribute that contain text
var notices = $('[role="alert"]').filter(function() {
return $(this).text().trim().length > 0;
});
if (notices.length > 0) {
/**
* Queuing the focus event at last of the event queue
* to override any other focus events in case of critical error.
* For example, "Skip to content" was being focused just after
* the error, resulting in the voiceover breaking the message
* in between.
*/
setTimeout(function() {
$(notices[0]).attr('tabindex', '-1').focus();
});
}
});

View File

@@ -0,0 +1 @@
jQuery(function(t){var e=t('[role="alert"]').filter(function(){return t(this).text().trim().length>0});e.length>0&&setTimeout(function(){t(e[0]).attr("tabindex","-1").focus()})});

View File

@@ -0,0 +1,44 @@
jQuery( function( $ ) {
// woocommerce_params is required to continue, ensure the object exists
if ( typeof woocommerce_params === 'undefined' ) {
return false;
}
$( '#add_payment_method' )
/* Payment option selection */
.on( 'click init_add_payment_method', '.payment_methods input.input-radio', function() {
if ( $( '.payment_methods input.input-radio' ).length > 1 ) {
var target_payment_box = $( 'div.payment_box.' + $( this ).attr( 'ID' ) );
if ( $( this ).is( ':checked' ) && ! target_payment_box.is( ':visible' ) ) {
$( 'div.payment_box' ).filter( ':visible' ).slideUp( 250 );
if ( $( this ).is( ':checked' ) ) {
$( 'div.payment_box.' + $( this ).attr( 'ID' ) ).slideDown( 250 );
}
}
} else {
$( 'div.payment_box' ).show();
}
})
// Trigger initial click
.find( 'input[name=payment_method]:checked' ).trigger( 'click' );
$( '#add_payment_method' ).on( 'submit', function() {
$( '#add_payment_method' ).block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } });
});
$( document.body ).trigger( 'init_add_payment_method' );
// Prevent firing multiple requests upon double clicking the buttons in payment methods table
$(' .woocommerce .payment-method-actions .button.delete' ).on( 'click' , function( event ) {
if ( $( this ).hasClass( 'disabled' ) ) {
event.preventDefault();
}
$( this ).addClass( 'disabled' );
});
});

View File

@@ -0,0 +1 @@
jQuery(function(e){if("undefined"==typeof woocommerce_params)return!1;e("#add_payment_method").on("click init_add_payment_method",".payment_methods input.input-radio",function(){if(e(".payment_methods input.input-radio").length>1){var t=e("div.payment_box."+e(this).attr("ID"));e(this).is(":checked")&&!t.is(":visible")&&(e("div.payment_box").filter(":visible").slideUp(250),e(this).is(":checked")&&e("div.payment_box."+e(this).attr("ID")).slideDown(250))}else e("div.payment_box").show()}).find("input[name=payment_method]:checked").trigger("click"),e("#add_payment_method").on("submit",function(){e("#add_payment_method").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}),e(document.body).trigger("init_add_payment_method"),e(" .woocommerce .payment-method-actions .button.delete").on("click",function(t){e(this).hasClass("disabled")&&t.preventDefault(),e(this).addClass("disabled")})});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,303 @@
/* global wc_add_to_cart_params */
jQuery( function( $ ) {
if ( typeof wc_add_to_cart_params === 'undefined' ) {
return false;
}
/**
* AddToCartHandler class.
*/
var AddToCartHandler = function() {
this.requests = [];
this.addRequest = this.addRequest.bind( this );
this.run = this.run.bind( this );
this.$liveRegion = this.createLiveRegion();
$( document.body )
.on( 'click', '.add_to_cart_button:not(.wc-interactive)', { addToCartHandler: this }, this.onAddToCart )
// Handle when pressing the Space key on the add to cart anchor with role="button" attribute.
.on( 'keydown', '.add_to_cart_button:not(.wc-interactive)', { addToCartHandler: this },
( e ) => { if ( e.key === ' ' ) { e.preventDefault(); e.target.click(); } }
)
.on( 'click', '.remove_from_cart_button', { addToCartHandler: this }, this.onRemoveFromCart )
.on( 'keydown', '.remove_from_cart_button', this.onKeydownRemoveFromCart )
.on( 'added_to_cart', { addToCartHandler: this }, this.onAddedToCart )
.on( 'removed_from_cart', { addToCartHandler: this }, this.onRemovedFromCart )
.on( 'ajax_request_not_sent.adding_to_cart', this.updateButton );
};
/**
* Add add to cart event.
*/
AddToCartHandler.prototype.addRequest = function( request ) {
this.requests.push( request );
if ( 1 === this.requests.length ) {
this.run();
}
};
/**
* Run add to cart events.
*/
AddToCartHandler.prototype.run = function() {
var requestManager = this,
originalCallback = requestManager.requests[0].complete;
requestManager.requests[0].complete = function() {
if ( typeof originalCallback === 'function' ) {
originalCallback();
}
requestManager.requests.shift();
if ( requestManager.requests.length > 0 ) {
requestManager.run();
}
};
$.ajax( this.requests[0] );
};
/**
* Handle the add to cart event.
*/
AddToCartHandler.prototype.onAddToCart = function( e ) {
var $thisbutton = $( this );
if ( $thisbutton.is( '.ajax_add_to_cart' ) ) {
if ( ! $thisbutton.attr( 'data-product_id' ) ) {
return true;
}
// Clean existing text in mini cart live region and update aria-relevant attribute
// so screen readers can identify the next update if it's the same as the previous one.
e.data.addToCartHandler.$liveRegion
.text( '' )
.removeAttr( 'aria-relevant' );
e.preventDefault();
$thisbutton.removeClass( 'added' );
$thisbutton.addClass( 'loading' );
// Allow 3rd parties to validate and quit early.
if ( false === $( document.body ).triggerHandler( 'should_send_ajax_request.adding_to_cart', [ $thisbutton ] ) ) {
$( document.body ).trigger( 'ajax_request_not_sent.adding_to_cart', [ false, false, $thisbutton ] );
return true;
}
var data = {};
// Fetch changes that are directly added by calling $thisbutton.data( key, value )
$.each( $thisbutton.data(), function( key, value ) {
data[ key ] = value;
});
// Fetch data attributes in $thisbutton. Give preference to data-attributes because they can be directly modified by javascript
// while `.data` are jquery specific memory stores.
$.each( $thisbutton[0].dataset, function( key, value ) {
data[ key ] = value;
});
// Trigger event.
$( document.body ).trigger( 'adding_to_cart', [ $thisbutton, data ] );
e.data.addToCartHandler.addRequest({
type: 'POST',
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ),
data: data,
success: function( response ) {
if ( ! response ) {
return;
}
if ( response.error && response.product_url ) {
window.location = response.product_url;
return;
}
// Redirect to cart option
if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
window.location = wc_add_to_cart_params.cart_url;
return;
}
// Trigger event so themes can refresh other areas.
$( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $thisbutton ] );
},
dataType: 'json'
});
}
};
/**
* Update fragments after remove from cart event in mini-cart.
*/
AddToCartHandler.prototype.onRemoveFromCart = function( e ) {
var $thisbutton = $( this ),
$row = $thisbutton.closest( '.woocommerce-mini-cart-item' );
e.data.addToCartHandler.$liveRegion
.text( '' )
.removeAttr( 'aria-relevant' );
e.preventDefault();
$row.block({
message: null,
overlayCSS: {
opacity: 0.6
}
});
e.data.addToCartHandler.addRequest({
type: 'POST',
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'remove_from_cart' ),
data: {
cart_item_key : $thisbutton.data( 'cart_item_key' )
},
success: function( response ) {
if ( ! response || ! response.fragments ) {
window.location = $thisbutton.attr( 'href' );
return;
}
$( document.body ).trigger( 'removed_from_cart', [ response.fragments, response.cart_hash, $thisbutton ] );
},
error: function() {
window.location = $thisbutton.attr( 'href' );
return;
},
dataType: 'json'
});
};
/**
* Handle when pressing the Space key on the remove item link.
* This is necessary because the link got the role="button" attribute
* and needs to act like a button.
*/
AddToCartHandler.prototype.onKeydownRemoveFromCart = function( event ) {
if ( event.key === ' ' ) {
event.preventDefault();
$( this ).trigger( 'click' );
}
};
/**
* Update cart page elements after add to cart events.
*/
AddToCartHandler.prototype.updateButton = function( e, fragments, cart_hash, $button ) {
// Some themes and plugins manually trigger added_to_cart without passing a button element, which in turn calls this function.
// If there is no button we don't want to crash.
$button = typeof $button === 'undefined' ? false : $button;
if ( $button ) {
$button.removeClass( 'loading' );
if ( fragments ) {
$button.addClass( 'added' );
}
// View cart text.
if ( fragments && ! wc_add_to_cart_params.is_cart && $button.parent().find( '.added_to_cart' ).length === 0 ) {
var anchor = document.createElement( 'a' );
anchor.href = wc_add_to_cart_params.cart_url;
anchor.className = 'added_to_cart wc-forward';
anchor.title = wc_add_to_cart_params.i18n_view_cart;
anchor.textContent = wc_add_to_cart_params.i18n_view_cart;
$button.after( anchor );
}
$( document.body ).trigger( 'wc_cart_button_updated', [ $button ] );
}
};
/**
* Update fragments after add to cart events.
*/
AddToCartHandler.prototype.updateFragments = function( e, fragments ) {
if ( fragments ) {
$.each( fragments, function( key ) {
$( key )
.addClass( 'updating' )
.fadeTo( '400', '0.6' )
.block({
message: null,
overlayCSS: {
opacity: 0.6
}
});
});
$.each( fragments, function( key, value ) {
$( key ).replaceWith( value );
$( key ).stop( true ).css( 'opacity', '1' ).unblock();
});
$( document.body ).trigger( 'wc_fragments_loaded' );
}
};
/**
* Update cart live region message after add/remove cart events.
*/
AddToCartHandler.prototype.alertCartUpdated = function( e, fragments, cart_hash, $button ) {
// Some themes and plugins manually trigger added_to_cart without passing a button element, which in turn calls this function.
// If there is no button we don't want to crash.
$button = typeof $button === 'undefined' ? false : $button;
if ( $button ) {
var message = $button.data( 'success_message' );
if ( !message ) {
return;
}
// If the response after adding/removing an item to/from the cart is really fast,
// screen readers may not have time to identify the changes in the live region element.
// So, we add a delay to ensure an interval between messages.
e.data.addToCartHandler.$liveRegion
.delay(1000)
.text( message )
.attr( 'aria-relevant', 'all' );
}
};
/**
* Add live region into the body element.
*/
AddToCartHandler.prototype.createLiveRegion = function() {
var existingLiveRegion = $( '.widget_shopping_cart_live_region' );
if ( existingLiveRegion.length ) {
return existingLiveRegion;
}
return $( '<div class="widget_shopping_cart_live_region screen-reader-text" role="status"></div>' ).appendTo( 'body' );
};
/**
* Callbacks after added to cart event.
*/
AddToCartHandler.prototype.onAddedToCart = function( e, fragments, cart_hash, $button ) {
e.data.addToCartHandler.updateButton( e, fragments, cart_hash, $button );
e.data.addToCartHandler.updateFragments( e, fragments );
e.data.addToCartHandler.alertCartUpdated( e, fragments, cart_hash, $button );
};
/**
* Callbacks after removed from cart event.
*/
AddToCartHandler.prototype.onRemovedFromCart = function( e, fragments, cart_hash, $button ) {
e.data.addToCartHandler.updateFragments( e, fragments );
e.data.addToCartHandler.alertCartUpdated( e, fragments, cart_hash, $button );
};
/**
* Init AddToCartHandler.
*/
new AddToCartHandler();
});

View File

@@ -0,0 +1 @@
jQuery(function(t){if("undefined"==typeof wc_add_to_cart_params)return!1;var a=function(){this.requests=[],this.addRequest=this.addRequest.bind(this),this.run=this.run.bind(this),this.$liveRegion=this.createLiveRegion(),t(document.body).on("click",".add_to_cart_button:not(.wc-interactive)",{addToCartHandler:this},this.onAddToCart).on("keydown",".add_to_cart_button:not(.wc-interactive)",{addToCartHandler:this},t=>{" "===t.key&&(t.preventDefault(),t.target.click())}).on("click",".remove_from_cart_button",{addToCartHandler:this},this.onRemoveFromCart).on("keydown",".remove_from_cart_button",this.onKeydownRemoveFromCart).on("added_to_cart",{addToCartHandler:this},this.onAddedToCart).on("removed_from_cart",{addToCartHandler:this},this.onRemovedFromCart).on("ajax_request_not_sent.adding_to_cart",this.updateButton)};a.prototype.addRequest=function(t){this.requests.push(t),1===this.requests.length&&this.run()},a.prototype.run=function(){var a=this,e=a.requests[0].complete;a.requests[0].complete=function(){"function"==typeof e&&e(),a.requests.shift(),a.requests.length>0&&a.run()},t.ajax(this.requests[0])},a.prototype.onAddToCart=function(a){var e=t(this);if(e.is(".ajax_add_to_cart")){if(!e.attr("data-product_id"))return!0;if(a.data.addToCartHandler.$liveRegion.text("").removeAttr("aria-relevant"),a.preventDefault(),e.removeClass("added"),e.addClass("loading"),!1===t(document.body).triggerHandler("should_send_ajax_request.adding_to_cart",[e]))return t(document.body).trigger("ajax_request_not_sent.adding_to_cart",[!1,!1,e]),!0;var r={};t.each(e.data(),function(t,a){r[t]=a}),t.each(e[0].dataset,function(t,a){r[t]=a}),t(document.body).trigger("adding_to_cart",[e,r]),a.data.addToCartHandler.addRequest({type:"POST",url:wc_add_to_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","add_to_cart"),data:r,success:function(a){a&&(a.error&&a.product_url?window.location=a.product_url:"yes"!==wc_add_to_cart_params.cart_redirect_after_add?t(document.body).trigger("added_to_cart",[a.fragments,a.cart_hash,e]):window.location=wc_add_to_cart_params.cart_url)},dataType:"json"})}},a.prototype.onRemoveFromCart=function(a){var e=t(this),r=e.closest(".woocommerce-mini-cart-item");a.data.addToCartHandler.$liveRegion.text("").removeAttr("aria-relevant"),a.preventDefault(),r.block({message:null,overlayCSS:{opacity:.6}}),a.data.addToCartHandler.addRequest({type:"POST",url:wc_add_to_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_from_cart"),data:{cart_item_key:e.data("cart_item_key")},success:function(a){a&&a.fragments?t(document.body).trigger("removed_from_cart",[a.fragments,a.cart_hash,e]):window.location=e.attr("href")},error:function(){window.location=e.attr("href")},dataType:"json"})},a.prototype.onKeydownRemoveFromCart=function(a){" "===a.key&&(a.preventDefault(),t(this).trigger("click"))},a.prototype.updateButton=function(a,e,r,o){if(o=void 0!==o&&o){if(o.removeClass("loading"),e&&o.addClass("added"),e&&!wc_add_to_cart_params.is_cart&&0===o.parent().find(".added_to_cart").length){var d=document.createElement("a");d.href=wc_add_to_cart_params.cart_url,d.className="added_to_cart wc-forward",d.title=wc_add_to_cart_params.i18n_view_cart,d.textContent=wc_add_to_cart_params.i18n_view_cart,o.after(d)}t(document.body).trigger("wc_cart_button_updated",[o])}},a.prototype.updateFragments=function(a,e){e&&(t.each(e,function(a){t(a).addClass("updating").fadeTo("400","0.6").block({message:null,overlayCSS:{opacity:.6}})}),t.each(e,function(a,e){t(a).replaceWith(e),t(a).stop(!0).css("opacity","1").unblock()}),t(document.body).trigger("wc_fragments_loaded"))},a.prototype.alertCartUpdated=function(t,a,e,r){if(r=void 0!==r&&r){var o=r.data("success_message");if(!o)return;t.data.addToCartHandler.$liveRegion.delay(1e3).text(o).attr("aria-relevant","all")}},a.prototype.createLiveRegion=function(){var a=t(".widget_shopping_cart_live_region");return a.length?a:t('<div class="widget_shopping_cart_live_region screen-reader-text" role="status"></div>').appendTo("body")},a.prototype.onAddedToCart=function(t,a,e,r){t.data.addToCartHandler.updateButton(t,a,e,r),t.data.addToCartHandler.updateFragments(t,a),t.data.addToCartHandler.alertCartUpdated(t,a,e,r)},a.prototype.onRemovedFromCart=function(t,a,e,r){t.data.addToCartHandler.updateFragments(t,a),t.data.addToCartHandler.alertCartUpdated(t,a,e,r)},new a});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,149 @@
/*global wc_address_i18n_params */
jQuery( function( $ ) {
// wc_address_i18n_params is required to continue, ensure the object exists
if ( typeof wc_address_i18n_params === 'undefined' ) {
return false;
}
var locale_json = wc_address_i18n_params.locale.replace( /&quot;/g, '"' ), locale = JSON.parse( locale_json );
function field_is_required( field, is_required ) {
if ( is_required ) {
field.find( 'label .optional' ).remove();
field.addClass( 'validate-required' );
if ( field.find( 'label .required[aria-hidden="true"]' ).length === 0 ) {
field.find( 'label' ).append(
'&nbsp;<span class="required" aria-hidden="true">*</span>'
);
}
} else {
field.find( 'label .required' ).remove();
field.removeClass( 'validate-required woocommerce-invalid woocommerce-invalid-required-field' );
if ( field.find( 'label .optional' ).length === 0 ) {
field.find( 'label' ).append( '&nbsp;<span class="optional">(' + wc_address_i18n_params.i18n_optional_text + ')</span>' );
}
}
}
// Handle locale
$( document.body )
.on( 'country_to_state_changing', function( event, country, wrapper ) {
var thisform = wrapper, thislocale;
if ( typeof locale[ country ] !== 'undefined' ) {
thislocale = locale[ country ];
} else {
thislocale = locale['default'];
}
var $postcodefield = thisform.find( '#billing_postcode_field, #shipping_postcode_field, #calc_shipping_postcode_field' ),
$cityfield = thisform.find( '#billing_city_field, #shipping_city_field, #calc_shipping_city_field' ),
$statefield = thisform.find( '#billing_state_field, #shipping_state_field, #calc_shipping_state_field' );
if ( ! $postcodefield.attr( 'data-o_class' ) ) {
$postcodefield.attr( 'data-o_class', $postcodefield.attr( 'class' ) );
$cityfield.attr( 'data-o_class', $cityfield.attr( 'class' ) );
$statefield.attr( 'data-o_class', $statefield.attr( 'class' ) );
}
var locale_fields = JSON.parse( wc_address_i18n_params.locale_fields );
$.each( locale_fields, function( key, value ) {
var field = thisform.find( value ),
fieldLocale = $.extend( true, {}, locale['default'][ key ], thislocale[ key ] );
// Labels.
if ( typeof fieldLocale.label !== 'undefined' ) {
field.find( 'label' ).html( fieldLocale.label );
}
// Placeholders.
if ( typeof fieldLocale.placeholder !== 'undefined' ) {
field.find( ':input' ).attr( 'placeholder', fieldLocale.placeholder );
field.find( ':input' ).attr( 'data-placeholder', fieldLocale.placeholder );
field.find( '.select2-selection__placeholder' ).text( fieldLocale.placeholder );
}
// Use the i18n label as a placeholder if there is no label element and no i18n placeholder.
if (
typeof fieldLocale.placeholder === 'undefined' &&
typeof fieldLocale.label !== 'undefined' &&
! field.find( 'label:not(.screen-reader-text)' ).length
) {
field.find( ':input' ).attr( 'placeholder', fieldLocale.label );
field.find( ':input' ).attr( 'data-placeholder', fieldLocale.label );
field.find( '.select2-selection__placeholder' ).text( fieldLocale.label );
}
// Required.
if ( typeof fieldLocale.required !== 'undefined' ) {
field_is_required( field, fieldLocale.required );
} else {
field_is_required( field, false );
}
// Priority.
if ( typeof fieldLocale.priority !== 'undefined' ) {
field.data( 'priority', fieldLocale.priority );
}
// Hidden fields.
if ( 'state' !== key ) {
if ( typeof fieldLocale.hidden !== 'undefined' && true === fieldLocale.hidden ) {
field.hide().find( ':input' ).val( '' );
} else {
field.show();
}
}
// Class changes.
if ( Array.isArray( fieldLocale.class ) ) {
field.removeClass( 'form-row-first form-row-last form-row-wide' );
field.addClass( fieldLocale.class.join( ' ' ) );
}
});
var fieldsets = $(
'.woocommerce-billing-fields__field-wrapper,' +
'.woocommerce-shipping-fields__field-wrapper,' +
'.woocommerce-address-fields__field-wrapper,' +
'.woocommerce-additional-fields__field-wrapper .woocommerce-account-fields'
);
fieldsets.each( function( index, fieldset ) {
var rows = $( fieldset ).find( '.form-row' );
var wrapper = rows.first().parent();
// Before sorting, ensure all fields have a priority for bW compatibility.
var last_priority = 0;
rows.each( function() {
if ( ! $( this ).data( 'priority' ) ) {
$( this ).data( 'priority', last_priority + 1 );
}
last_priority = $( this ).data( 'priority' );
} );
// Sort the fields.
rows.sort( function( a, b ) {
var asort = parseInt( $( a ).data( 'priority' ), 10 ),
bsort = parseInt( $( b ).data( 'priority' ), 10 );
if ( asort > bsort ) {
return 1;
}
if ( asort < bsort ) {
return -1;
}
return 0;
});
rows.detach().appendTo( wrapper );
});
})
.trigger( 'wc_address_i18n_ready' );
});

View File

@@ -0,0 +1 @@
jQuery(function(e){if("undefined"==typeof wc_address_i18n_params)return!1;var a=wc_address_i18n_params.locale.replace(/&quot;/g,'"'),i=JSON.parse(a);function d(e,a){a?(e.find("label .optional").remove(),e.addClass("validate-required"),0===e.find('label .required[aria-hidden="true"]').length&&e.find("label").append('&nbsp;<span class="required" aria-hidden="true">*</span>')):(e.find("label .required").remove(),e.removeClass("validate-required woocommerce-invalid woocommerce-invalid-required-field"),0===e.find("label .optional").length&&e.find("label").append('&nbsp;<span class="optional">('+wc_address_i18n_params.i18n_optional_text+")</span>"))}e(document.body).on("country_to_state_changing",function(a,r,t){var l,n=t;l="undefined"!=typeof i[r]?i[r]:i["default"];var o=n.find("#billing_postcode_field, #shipping_postcode_field, #calc_shipping_postcode_field"),s=n.find("#billing_city_field, #shipping_city_field, #calc_shipping_city_field"),p=n.find("#billing_state_field, #shipping_state_field, #calc_shipping_state_field");o.attr("data-o_class")||(o.attr("data-o_class",o.attr("class")),s.attr("data-o_class",s.attr("class")),p.attr("data-o_class",p.attr("class")));var c=JSON.parse(wc_address_i18n_params.locale_fields);e.each(c,function(a,r){var t=n.find(r),o=e.extend(!0,{},i["default"][a],l[a]);"undefined"!=typeof o.label&&t.find("label").html(o.label),"undefined"!=typeof o.placeholder&&(t.find(":input").attr("placeholder",o.placeholder),t.find(":input").attr("data-placeholder",o.placeholder),t.find(".select2-selection__placeholder").text(o.placeholder)),"undefined"!=typeof o.placeholder||"undefined"==typeof o.label||t.find("label:not(.screen-reader-text)").length||(t.find(":input").attr("placeholder",o.label),t.find(":input").attr("data-placeholder",o.label),t.find(".select2-selection__placeholder").text(o.label)),"undefined"!=typeof o.required?d(t,o.required):d(t,!1),"undefined"!=typeof o.priority&&t.data("priority",o.priority),"state"!==a&&("undefined"!=typeof o.hidden&&!0===o.hidden?t.hide().find(":input").val(""):t.show()),Array.isArray(o["class"])&&(t.removeClass("form-row-first form-row-last form-row-wide"),t.addClass(o["class"].join(" ")))}),e(".woocommerce-billing-fields__field-wrapper,.woocommerce-shipping-fields__field-wrapper,.woocommerce-address-fields__field-wrapper,.woocommerce-additional-fields__field-wrapper .woocommerce-account-fields").each(function(a,i){var d=e(i).find(".form-row"),r=d.first().parent(),t=0;d.each(function(){e(this).data("priority")||e(this).data("priority",t+1),t=e(this).data("priority")}),d.sort(function(a,i){var d=parseInt(e(a).data("priority"),10),r=parseInt(e(i).data("priority"),10);return d>r?1:d<r?-1:0}),d.detach().appendTo(r)})}).trigger("wc_address_i18n_ready")});

View File

@@ -0,0 +1,126 @@
;(function ( $, document ) {
/**
* Back in stock form manager.
*
* @param jQuery $form The form element.
*/
var BISFormManager = function( $variationsForm ) {
// Properties.
var self = this;
self.$variationsForm = $variationsForm;
self.product_id = self.$variationsForm.data( 'product_id' );
self.$formContainer = $( '.wc_bis_form[data-bis-product-id="' + self.product_id + '"]' );
self.$form = self.$formContainer.find( 'form' );
self.$formProductInput = self.$formContainer.find( 'input[name="wc_bis_product_id"]' );
// Variation Events.
self.$variationsForm.off( '.wc-bis-form' );
self.$variationsForm.on( 'found_variation.wc-bis-form', { bisForm: self }, self.onFoundVariation );
self.$variationsForm.on( 'show_variation.wc-bis-form', { bisForm: self }, self.onShowVariation );
self.$variationsForm.on( 'reset_data.wc-bis-form', { bisForm: self }, self.onAnnounceReset );
// Form Events.
self.$form.off( '.wc-bis-form' );
self.$form.on( 'submit.wc-bis-form', { bisForm: self }, self.onSendForm );
};
/**
* Handle found variation.
*
* @param {Event} event The event object.
* @param {Object} variation The variation object.
*/
BISFormManager.prototype.onFoundVariation = function( event, variation ) {
var form = event.data.bisForm;
if ( variation.is_in_stock && variation.is_purchasable ) {
return;
}
if ( ! variation.variation_is_active || ! variation.variation_is_visible ) {
return;
}
form.$formProductInput.val( variation.variation_id ).trigger( 'change' );
};
/**
* Handle show variation.
*
* @param {Event} event The event object.
* @param {Object} variation The variation object.
*/
BISFormManager.prototype.onShowVariation = function( event, variation ) {
var form = event.data.bisForm;
if ( variation.is_in_stock && variation.is_purchasable ) {
form.$formContainer.addClass( 'hidden' );
return;
}
if ( ! variation.variation_is_active || ! variation.variation_is_visible ) {
form.$formContainer.addClass( 'hidden' );
return;
}
form.$formContainer.removeClass( 'hidden' );
};
/**
* Handle announce reset.
*
* @param {Event} event The event object.
*/
BISFormManager.prototype.onAnnounceReset = function( event ) {
var form = event.data.bisForm;
form.$formProductInput.val( form.product_id ).trigger( 'change' );
form.$formContainer.addClass( 'hidden' );
};
/**
* Handle send form.
*
* @param {Event} event The event object.
*/
BISFormManager.prototype.onSendForm = function( event ) {
var form = event.data.bisForm;
if ( ! form.$variationsForm.length ) {
return;
}
var $attributes = form.$variationsForm.find( '.variations select' );
if ( $attributes.length ) {
// Build dynamic hidden form fields.
$attributes.each( function( index, el ) {
var $attribute_field = $( el )
var $input = $( '<input/>' );
$input.val( $attribute_field.val() );
$input.prop( 'name', $attribute_field.attr( 'name' ) );
$input.prop( 'type', 'hidden' );
if ( ! form.$form.find( 'input[name="' + $input.prop( 'name' ) + '"]' ).length ) {
form.$form.append( $input );
}
} );
}
};
/**
* Extend jQuery.
*/
$.fn.extend( {
wc_back_in_stock_form: function() {
return this.each( function() {
new BISFormManager( $( this ) );
} );
}
} );
// Initialize the form manager on DOM ready.
$( function() {
$( '.variations_form' ).wc_back_in_stock_form();
});
})( jQuery, document );

View File

@@ -0,0 +1 @@
!function(i,o){var t=function(o){this.$variationsForm=o,this.product_id=this.$variationsForm.data("product_id"),this.$formContainer=i('.wc_bis_form[data-bis-product-id="'+this.product_id+'"]'),this.$form=this.$formContainer.find("form"),this.$formProductInput=this.$formContainer.find('input[name="wc_bis_product_id"]'),this.$variationsForm.off(".wc-bis-form"),this.$variationsForm.on("found_variation.wc-bis-form",{bisForm:this},this.onFoundVariation),this.$variationsForm.on("show_variation.wc-bis-form",{bisForm:this},this.onShowVariation),this.$variationsForm.on("reset_data.wc-bis-form",{bisForm:this},this.onAnnounceReset),this.$form.off(".wc-bis-form"),this.$form.on("submit.wc-bis-form",{bisForm:this},this.onSendForm)};t.prototype.onFoundVariation=function(i,o){var t=i.data.bisForm;o.is_in_stock&&o.is_purchasable||o.variation_is_active&&o.variation_is_visible&&t.$formProductInput.val(o.variation_id).trigger("change")},t.prototype.onShowVariation=function(i,o){var t=i.data.bisForm;o.is_in_stock&&o.is_purchasable?t.$formContainer.addClass("hidden"):o.variation_is_active&&o.variation_is_visible?t.$formContainer.removeClass("hidden"):t.$formContainer.addClass("hidden")},t.prototype.onAnnounceReset=function(i){var o=i.data.bisForm;o.$formProductInput.val(o.product_id).trigger("change"),o.$formContainer.addClass("hidden")},t.prototype.onSendForm=function(o){var t=o.data.bisForm;if(t.$variationsForm.length){var n=t.$variationsForm.find(".variations select");n.length&&n.each(function(o,n){var r=i(n),a=i("<input/>");a.val(r.val()),a.prop("name",r.attr("name")),a.prop("type","hidden"),t.$form.find('input[name="'+a.prop("name")+'"]').length||t.$form.append(a)})}},i.fn.extend({wc_back_in_stock_form:function(){return this.each(function(){new t(i(this))})}}),i(function(){i(".variations_form").wc_back_in_stock_form()})}(jQuery,document);

View File

@@ -0,0 +1,187 @@
/* global wc_cart_fragments_params, Cookies */
jQuery( function( $ ) {
// wc_cart_fragments_params is required to continue, ensure the object exists
if ( typeof wc_cart_fragments_params === 'undefined' ) {
return false;
}
/* Storage Handling */
var $supports_html5_storage = true,
cart_hash_key = wc_cart_fragments_params.cart_hash_key;
try {
$supports_html5_storage = ( 'sessionStorage' in window && window.sessionStorage !== null );
window.sessionStorage.setItem( 'wc', 'test' );
window.sessionStorage.removeItem( 'wc' );
window.localStorage.setItem( 'wc', 'test' );
window.localStorage.removeItem( 'wc' );
} catch( err ) {
$supports_html5_storage = false;
}
/* Cart session creation time to base expiration on */
function set_cart_creation_timestamp() {
if ( $supports_html5_storage ) {
sessionStorage.setItem( 'wc_cart_created', ( new Date() ).getTime() );
}
}
/** Set the cart hash in both session and local storage */
function set_cart_hash( cart_hash ) {
if ( $supports_html5_storage ) {
localStorage.setItem( cart_hash_key, cart_hash );
sessionStorage.setItem( cart_hash_key, cart_hash );
}
}
var $fragment_refresh = {
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_refreshed_fragments' ),
type: 'POST',
data: {
time: new Date().getTime()
},
timeout: wc_cart_fragments_params.request_timeout,
success: function( data ) {
if ( data && data.fragments ) {
$.each( data.fragments, function( key, value ) {
$( key ).replaceWith( value );
});
if ( $supports_html5_storage ) {
sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( data.fragments ) );
set_cart_hash( data.cart_hash );
if ( data.cart_hash ) {
set_cart_creation_timestamp();
}
}
$( document.body ).trigger( 'wc_fragments_refreshed' );
}
},
error: function() {
$( document.body ).trigger( 'wc_fragments_ajax_error' );
}
};
/* Named callback for refreshing cart fragment */
function refresh_cart_fragment() {
$.ajax( $fragment_refresh );
}
/* Cart Handling */
if ( $supports_html5_storage ) {
var cart_timeout = null,
day_in_ms = ( 24 * 60 * 60 * 1000 );
$( document.body ).on( 'wc_fragment_refresh updated_wc_div', function() {
refresh_cart_fragment();
});
$( document.body ).on( 'added_to_cart removed_from_cart', function( event, fragments, cart_hash ) {
var prev_cart_hash = sessionStorage.getItem( cart_hash_key );
if ( prev_cart_hash === null || prev_cart_hash === undefined || prev_cart_hash === '' ) {
set_cart_creation_timestamp();
}
sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( fragments ) );
set_cart_hash( cart_hash );
});
$( document.body ).on( 'wc_fragments_refreshed', function() {
clearTimeout( cart_timeout );
cart_timeout = setTimeout( refresh_cart_fragment, day_in_ms );
} );
// Refresh when storage changes in another tab
$( window ).on( 'storage onstorage', function ( e ) {
if (
cart_hash_key === e.originalEvent.key && localStorage.getItem( cart_hash_key ) !== sessionStorage.getItem( cart_hash_key )
) {
refresh_cart_fragment();
}
});
// Refresh when page is shown after back button (safari)
$( window ).on( 'pageshow' , function( e ) {
if ( e.originalEvent.persisted ) {
$( '.widget_shopping_cart_content' ).empty();
$( document.body ).trigger( 'wc_fragment_refresh' );
}
} );
try {
var wc_fragments = JSON.parse( sessionStorage.getItem( wc_cart_fragments_params.fragment_name ) ),
cart_hash = sessionStorage.getItem( cart_hash_key ),
cookie_hash = Cookies.get( 'woocommerce_cart_hash'),
cart_created = sessionStorage.getItem( 'wc_cart_created' );
if ( cart_hash === null || cart_hash === undefined || cart_hash === '' ) {
cart_hash = '';
}
if ( cookie_hash === null || cookie_hash === undefined || cookie_hash === '' ) {
cookie_hash = '';
}
if ( cart_hash && ( cart_created === null || cart_created === undefined || cart_created === '' ) ) {
throw 'No cart_created';
}
if ( cart_created ) {
var cart_expiration = ( ( 1 * cart_created ) + day_in_ms ),
timestamp_now = ( new Date() ).getTime();
if ( cart_expiration < timestamp_now ) {
throw 'Fragment expired';
}
cart_timeout = setTimeout( refresh_cart_fragment, ( cart_expiration - timestamp_now ) );
}
if ( wc_fragments && wc_fragments['div.widget_shopping_cart_content'] && cart_hash === cookie_hash ) {
$.each( wc_fragments, function( key, value ) {
$( key ).replaceWith(value);
});
$( document.body ).trigger( 'wc_fragments_loaded' );
} else {
throw 'No fragment';
}
} catch( err ) {
refresh_cart_fragment();
}
} else {
refresh_cart_fragment();
}
/* Cart Hiding */
if ( Cookies.get( 'woocommerce_items_in_cart' ) > 0 ) {
$( '.hide_cart_widget_if_empty' ).closest( '.widget_shopping_cart' ).show();
} else {
$( '.hide_cart_widget_if_empty' ).closest( '.widget_shopping_cart' ).hide();
}
$( document.body ).on( 'adding_to_cart', function() {
$( '.hide_cart_widget_if_empty' ).closest( '.widget_shopping_cart' ).show();
});
// Customiser support.
var hasSelectiveRefresh = (
'undefined' !== typeof wp &&
wp.customize &&
wp.customize.selectiveRefresh &&
wp.customize.widgetsPreview &&
wp.customize.widgetsPreview.WidgetPartial
);
if ( hasSelectiveRefresh ) {
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function() {
refresh_cart_fragment();
} );
}
});

View File

@@ -0,0 +1 @@
jQuery(function(e){if("undefined"==typeof wc_cart_fragments_params)return!1;var t=!0,r=wc_cart_fragments_params.cart_hash_key;try{t="sessionStorage"in window&&null!==window.sessionStorage,window.sessionStorage.setItem("wc","test"),window.sessionStorage.removeItem("wc"),window.localStorage.setItem("wc","test"),window.localStorage.removeItem("wc")}catch(f){t=!1}function n(){t&&sessionStorage.setItem("wc_cart_created",(new Date).getTime())}function o(e){t&&(localStorage.setItem(r,e),sessionStorage.setItem(r,e))}var a={url:wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%","get_refreshed_fragments"),type:"POST",data:{time:(new Date).getTime()},timeout:wc_cart_fragments_params.request_timeout,success:function(r){r&&r.fragments&&(e.each(r.fragments,function(t,r){e(t).replaceWith(r)}),t&&(sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(r.fragments)),o(r.cart_hash),r.cart_hash&&n()),e(document.body).trigger("wc_fragments_refreshed"))},error:function(){e(document.body).trigger("wc_fragments_ajax_error")}};function s(){e.ajax(a)}if(t){var i=null;e(document.body).on("wc_fragment_refresh updated_wc_div",function(){s()}),e(document.body).on("added_to_cart removed_from_cart",function(e,t,a){var s=sessionStorage.getItem(r);null!==s&&s!==undefined&&""!==s||n(),sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(t)),o(a)}),e(document.body).on("wc_fragments_refreshed",function(){clearTimeout(i),i=setTimeout(s,864e5)}),e(window).on("storage onstorage",function(e){r===e.originalEvent.key&&localStorage.getItem(r)!==sessionStorage.getItem(r)&&s()}),e(window).on("pageshow",function(t){t.originalEvent.persisted&&(e(".widget_shopping_cart_content").empty(),e(document.body).trigger("wc_fragment_refresh"))});try{var c=JSON.parse(sessionStorage.getItem(wc_cart_fragments_params.fragment_name)),_=sessionStorage.getItem(r),g=Cookies.get("woocommerce_cart_hash"),m=sessionStorage.getItem("wc_cart_created");if(null!==_&&_!==undefined&&""!==_||(_=""),null!==g&&g!==undefined&&""!==g||(g=""),_&&(null===m||m===undefined||""===m))throw"No cart_created";if(m){var d=1*m+864e5,w=(new Date).getTime();if(d<w)throw"Fragment expired";i=setTimeout(s,d-w)}if(!c||!c["div.widget_shopping_cart_content"]||_!==g)throw"No fragment";e.each(c,function(t,r){e(t).replaceWith(r)}),e(document.body).trigger("wc_fragments_loaded")}catch(f){s()}}else s();Cookies.get("woocommerce_items_in_cart")>0?e(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show():e(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").hide(),e(document.body).on("adding_to_cart",function(){e(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show()}),"undefined"!=typeof wp&&wp.customize&&wp.customize.selectiveRefresh&&wp.customize.widgetsPreview&&wp.customize.widgetsPreview.WidgetPartial&&wp.customize.selectiveRefresh.bind("partial-content-rendered",function(){s()})});

View File

@@ -0,0 +1,822 @@
/* global wc_cart_params */
jQuery( function ( $ ) {
// wc_cart_params is required to continue, ensure the object exists
if ( typeof wc_cart_params === 'undefined' ) {
return false;
}
// Utility functions for the file.
/**
* Gets a url for a given AJAX endpoint.
*
* @param {String} endpoint The AJAX Endpoint
* @return {String} The URL to use for the request
*/
var get_url = function ( endpoint ) {
return wc_cart_params.wc_ajax_url
.toString()
.replace( '%%endpoint%%', endpoint );
};
/**
* Check if a node is blocked for processing.
*
* @param {JQuery Object} $node
* @return {bool} True if the DOM Element is UI Blocked, false if not.
*/
var is_blocked = function ( $node ) {
return (
$node.is( '.processing' ) || $node.parents( '.processing' ).length
);
};
/**
* Block a node visually for processing.
*
* @param {JQuery Object} $node
*/
var block = function ( $node ) {
if ( ! is_blocked( $node ) ) {
$node.addClass( 'processing' ).block( {
message: null,
overlayCSS: {
background: '#fff',
opacity: 0.6,
},
} );
}
};
/**
* Unblock a node after processing is complete.
*
* @param {JQuery Object} $node
*/
var unblock = function ( $node ) {
$node.removeClass( 'processing' ).unblock();
};
/**
* Removes duplicate notices.
*
* @param {JQuery Object} $notices
*/
var remove_duplicate_notices = function ( $notices ) {
var seen = new Set();
var deduplicated_notices = [];
$notices.each( function () {
const text = $( this ).text();
if ( ! seen.has( text ) ) {
seen.add( text );
deduplicated_notices.push( this );
}
} );
return $( deduplicated_notices );
};
/**
* Update the .woocommerce div with a string of html.
*
* @param {String} html_str The HTML string with which to replace the div.
* @param {bool} preserve_notices Should notices be kept? False by default.
*/
var update_wc_div = function ( html_str, preserve_notices ) {
var $html = $.parseHTML( html_str );
var $new_form = $( '.woocommerce-cart-form', $html );
var $new_totals = $( '.cart_totals', $html );
var $notices = remove_duplicate_notices(
$(
'.woocommerce-error, .woocommerce-message, .woocommerce-info, .is-error, .is-info, .is-success',
$html
)
);
// No form, cannot do this.
if ( $( '.woocommerce-cart-form' ).length === 0 ) {
window.location.reload();
return;
}
// Remove errors
if ( ! preserve_notices ) {
$(
'.woocommerce-error, .woocommerce-message, .woocommerce-info, .is-error, .is-info, .is-success, .coupon-error-notice'
).remove();
}
if ( $new_form.length === 0 ) {
// If the checkout is also displayed on this page, trigger reload instead.
if ( $( '.woocommerce-checkout' ).length ) {
window.location.reload();
return;
}
// No items to display now! Replace all cart content.
var $cart_html = $( '.wc-empty-cart-message', $html ).closest(
'.woocommerce'
);
$( '.woocommerce-cart-form__contents' )
.closest( '.woocommerce' )
.replaceWith( $cart_html );
// Display errors
if ( $notices.length > 0 ) {
show_notice( $notices );
}
// Notify plugins that the cart was emptied.
$( document.body ).trigger( 'wc_cart_emptied' );
} else {
// If the checkout is also displayed on this page, trigger update event.
if ( $( '.woocommerce-checkout' ).length ) {
$( document.body ).trigger( 'update_checkout' );
}
// Store the old coupon error message and value before the
// .woocommerce-cart-form is replaced with the new form.
var $old_coupon_field_val = $( '#coupon_code' ).val();
var $old_coupon_error_msg = $( '#coupon_code' )
.closest( '.coupon' )
.find( '.coupon-error-notice' );
$( '.woocommerce-cart-form' ).replaceWith( $new_form );
$( '.woocommerce-cart-form' )
.find( ':input[name="update_cart"]' )
.prop( 'disabled', true );
if ( preserve_notices && $old_coupon_error_msg.length > 0 ) {
var $new_coupon_field = $( '.woocommerce-cart-form' ).find( '#coupon_code' );
var $new_coupon_field_wrapper = $new_coupon_field.closest( '.coupon' );
$new_coupon_field.val( $old_coupon_field_val );
// The coupon input with error needs to be focused before adding the live region
// with the error message, otherwise the screen reader won't read it.
$new_coupon_field.focus();
show_coupon_error( $old_coupon_error_msg, $new_coupon_field_wrapper, true );
}
if ( $notices.length > 0 ) {
show_notice( $notices );
}
update_cart_totals_div( $new_totals );
}
$( document.body ).trigger( 'updated_wc_div' );
};
/**
* Update the .cart_totals div with a string of html.
*
* @param {String} html_str The HTML string with which to replace the div.
*/
var update_cart_totals_div = function ( html_str ) {
$( '.cart_totals' ).replaceWith( html_str );
$( document.body ).trigger( 'updated_cart_totals' );
};
/**
* Shows new notices on the page.
*
* @param {Object} The Notice HTML Element in string or object form.
*/
var show_notice = function ( html_element, $target ) {
if ( ! $target ) {
$target =
$( '.woocommerce-notices-wrapper:first' ) ||
$( '.wc-empty-cart-message' ).closest( '.woocommerce' ) ||
$( '.woocommerce-cart-form' );
}
$target.prepend( html_element );
};
/**
* Shows coupon form errors.
*
* @param {string|object} html_element The HTML string response after applying an invalid coupon or a jQuery element.
* @param {Object} $target Coupon field wrapper jQuery element.
* @param {boolean} is_live_region Whether role="alert" should be added or not.
*/
var show_coupon_error = function ( html_element, $target, is_live_region ) {
if ( $target.length === 0 ) {
return;
}
var $coupon_error_el = html_element;
if ( typeof html_element === 'string' ) {
var msg = $( $.parseHTML( html_element ) ).text().trim();
if ( msg === '' ) {
return;
}
$coupon_error_el = $('<p>', {
class: 'coupon-error-notice',
id: 'coupon-error-notice',
text: msg
});
}
if ( is_live_region ) {
$coupon_error_el.attr( 'role', 'alert' );
}
$target.find( '#coupon_code' )
.addClass( 'has-error' )
.attr( 'aria-invalid', 'true' )
.attr( 'aria-describedby', 'coupon-error-notice' );
$target.append( $coupon_error_el );
};
/**
* Object to handle AJAX calls for cart shipping changes.
*/
var cart_shipping = {
/**
* Initialize event handlers and UI state.
*/
init: function ( cart ) {
this.cart = cart;
this.toggle_shipping = this.toggle_shipping.bind( this );
this.shipping_method_selected =
this.shipping_method_selected.bind( this );
this.shipping_calculator_submit =
this.shipping_calculator_submit.bind( this );
$( document ).on(
'click',
'.shipping-calculator-button',
this.toggle_shipping
);
$( document ).on(
'change',
'select.shipping_method, :input[name^=shipping_method]',
this.shipping_method_selected
);
$( document ).on(
'submit',
'form.woocommerce-shipping-calculator',
this.shipping_calculator_submit
);
$( '.shipping-calculator-form' ).hide();
},
/**
* Toggle Shipping Calculator panel
*/
toggle_shipping: function ( event ) {
var $target = $( event.currentTarget );
$( '.shipping-calculator-form' ).slideToggle( 'slow', function () {
var self = this;
setTimeout( function () {
var $form = $( self );
$target.attr( 'aria-expanded', $form.is( ':visible' ) ? 'true' : 'false' );
}, 0 );
} );
$( 'select.country_to_state, input.country_to_state' ).trigger(
'change'
);
$( document.body ).trigger( 'country_to_state_changed' ); // Trigger select2 to load.
return false;
},
/**
* Handles when a shipping method is selected.
*/
shipping_method_selected: function ( event ) {
var shipping_methods = {};
// eslint-disable-next-line max-len
$(
'select.shipping_method, :input[name^=shipping_method][type=radio]:checked, :input[name^=shipping_method][type=hidden]'
).each( function () {
shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val();
} );
block( $( 'div.cart_totals' ) );
var data = {
security: wc_cart_params.update_shipping_method_nonce,
shipping_method: shipping_methods,
};
$.ajax( {
type: 'post',
url: get_url( 'update_shipping_method' ),
data: data,
dataType: 'html',
success: function ( response ) {
update_cart_totals_div( response );
var newCurrentTarget = document.getElementById( event.currentTarget.id );
if ( newCurrentTarget ) {
newCurrentTarget.focus();
}
},
complete: function () {
unblock( $( 'div.cart_totals' ) );
$( document.body ).trigger( 'updated_shipping_method' );
},
} );
},
/**
* Handles a shipping calculator form submit.
*
* @param {Object} evt The JQuery event.
*/
shipping_calculator_submit: function ( evt ) {
evt.preventDefault();
var $form = $( evt.currentTarget );
block( $( 'div.cart_totals' ) );
block( $form );
// Provide the submit button value because wc-form-handler expects it.
$( '<input />' )
.attr( 'type', 'hidden' )
.attr( 'name', 'calc_shipping' )
.attr( 'value', 'x' )
.appendTo( $form );
// Make call to actual form post URL.
$.ajax( {
type: $form.attr( 'method' ),
url: $form.attr( 'action' ),
data: $form.serialize(),
dataType: 'html',
success: function ( response ) {
update_wc_div( response );
},
complete: function () {
unblock( $form );
unblock( $( 'div.cart_totals' ) );
},
} );
},
};
/**
* Object to handle cart UI.
*/
var cart = {
/**
* Initialize cart UI events.
*/
init: function () {
this.update_cart_totals = this.update_cart_totals.bind( this );
this.input_keypress = this.input_keypress.bind( this );
this.cart_submit = this.cart_submit.bind( this );
this.submit_click = this.submit_click.bind( this );
this.apply_coupon = this.apply_coupon.bind( this );
this.remove_coupon_clicked =
this.remove_coupon_clicked.bind( this );
this.remove_coupon_error = this.remove_coupon_error.bind( this );
this.quantity_update = this.quantity_update.bind( this );
this.item_remove_clicked = this.item_remove_clicked.bind( this );
this.item_restore_clicked = this.item_restore_clicked.bind( this );
this.update_cart = this.update_cart.bind( this );
$( document ).on( 'wc_update_cart added_to_cart', function () {
cart.update_cart.apply( cart, [].slice.call( arguments, 1 ) );
} );
$( document ).on(
'click',
'.woocommerce-cart-form :input[type=submit]',
this.submit_click
);
$( document ).on(
'keypress',
'.woocommerce-cart-form :input[type=number]',
this.input_keypress
);
$( document ).on(
'submit',
'.woocommerce-cart-form',
this.cart_submit
);
$( document ).on(
'click',
'a.woocommerce-remove-coupon',
this.remove_coupon_clicked
);
$( document ).on(
'keydown',
'a.woocommerce-remove-coupon',
this.on_keydown_remove_coupon
);
$( document ).on(
'click',
'.woocommerce-cart-form .product-remove > a',
this.item_remove_clicked
);
$( document ).on(
'keydown',
'.woocommerce-cart-form .product-remove > a',
this.on_keydown_remove_item
);
$( document ).on(
'click',
'.woocommerce-cart .restore-item',
this.item_restore_clicked
);
$( document ).on(
'change input',
'.woocommerce-cart-form .cart_item :input',
this.input_changed
);
$( document ).on(
'change input',
'#coupon_code',
this.remove_coupon_error
);
$( '.woocommerce-cart-form :input[name="update_cart"]' ).prop(
'disabled',
true
);
},
/**
* After an input is changed, enable the update cart button.
*/
input_changed: function () {
$( '.woocommerce-cart-form :input[name="update_cart"]' ).prop(
'disabled',
false
);
},
/**
* Update entire cart via ajax.
*/
update_cart: function ( preserve_notices ) {
var $form = $( '.woocommerce-cart-form' );
block( $form );
block( $( 'div.cart_totals' ) );
// Make call to actual form post URL.
$.ajax( {
type: $form.attr( 'method' ),
url: $form.attr( 'action' ),
data: $form.serialize(),
dataType: 'html',
success: function ( response ) {
update_wc_div( response, preserve_notices );
},
complete: function () {
unblock( $form );
unblock( $( 'div.cart_totals' ) );
$.scroll_to_notices( $( '[role="alert"]' ) );
},
} );
},
/**
* Update the cart after something has changed.
*/
update_cart_totals: function () {
block( $( 'div.cart_totals' ) );
$.ajax( {
url: get_url( 'get_cart_totals' ),
dataType: 'html',
success: function ( response ) {
update_cart_totals_div( response );
},
complete: function () {
unblock( $( 'div.cart_totals' ) );
},
} );
},
/**
* Handle the <ENTER> key for quantity fields.
*
* @param {Object} evt The JQuery event
*
* For IE, if you hit enter on a quantity field, it makes the
* document.activeElement the first submit button it finds.
* For us, that is the Apply Coupon button. This is required
* to catch the event before that happens.
*/
input_keypress: function ( evt ) {
// Catch the enter key and don't let it submit the form.
if ( 13 === evt.keyCode ) {
var $form = $( evt.currentTarget ).parents( 'form' );
try {
// If there are no validation errors, handle the submit.
if ( $form[ 0 ].checkValidity() ) {
evt.preventDefault();
this.cart_submit( evt );
}
} catch ( err ) {
evt.preventDefault();
this.cart_submit( evt );
}
}
},
/**
* Handle cart form submit and route to correct logic.
*
* @param {Object} evt The JQuery event
*/
cart_submit: function ( evt ) {
var $submit = $( document.activeElement ),
$clicked = $( ':input[type=submit][clicked=true]' ),
$form = $( evt.currentTarget );
// For submit events, currentTarget is form.
// For keypress events, currentTarget is input.
if ( ! $form.is( 'form' ) ) {
$form = $( evt.currentTarget ).parents( 'form' );
}
if (
0 === $form.find( '.woocommerce-cart-form__contents' ).length
) {
return;
}
if ( is_blocked( $form ) ) {
return false;
}
if (
$clicked.is( ':input[name="update_cart"]' ) ||
$submit.is( 'input.qty' )
) {
evt.preventDefault();
this.quantity_update( $form );
} else if (
$clicked.is( ':input[name="apply_coupon"]' ) ||
$submit.is( '#coupon_code' )
) {
evt.preventDefault();
this.apply_coupon( $form );
}
},
/**
* Special handling to identify which submit button was clicked.
*
* @param {Object} evt The JQuery event
*/
submit_click: function ( evt ) {
$(
':input[type=submit]',
$( evt.target ).parents( 'form' )
).removeAttr( 'clicked' );
$( evt.target ).attr( 'clicked', 'true' );
},
/**
* Apply Coupon code
*
* @param {JQuery Object} $form The cart form.
*/
apply_coupon: function ( $form ) {
block( $form );
var cart = this;
var $text_field = $( '#coupon_code' );
var coupon_code = $text_field.val();
var data = {
security: wc_cart_params.apply_coupon_nonce,
coupon_code: coupon_code,
};
$.ajax( {
type: 'POST',
url: get_url( 'apply_coupon' ),
data: data,
dataType: 'html',
success: function ( response ) {
$(
'.woocommerce-error, .woocommerce-message, .woocommerce-info, ' +
'.is-error, .is-info, .is-success, .coupon-error-notice'
).remove();
// We only want to show coupon notices if they are not errors.
// Coupon errors are shown under the input.
if ( response.indexOf( 'woocommerce-error' ) === -1 && response.indexOf( 'is-error' ) === -1 ) {
show_notice( response );
} else {
var $coupon_wrapper = $text_field.closest( '.coupon' );
if ( $coupon_wrapper.length > 0 ) {
show_coupon_error( response, $coupon_wrapper, false );
}
}
$( document.body ).trigger( 'applied_coupon', [
coupon_code,
] );
},
complete: function () {
unblock( $form );
cart.update_cart( true );
},
} );
},
/**
* Handle when a remove coupon link is clicked.
*
* @param {Object} evt The JQuery event
*/
remove_coupon_clicked: function ( evt ) {
evt.preventDefault();
var cart = this;
var $wrapper = $( evt.currentTarget ).closest( '.cart_totals' );
var coupon = $( evt.currentTarget ).attr( 'data-coupon' );
block( $wrapper );
var data = {
security: wc_cart_params.remove_coupon_nonce,
coupon: coupon,
};
$.ajax( {
type: 'POST',
url: get_url( 'remove_coupon' ),
data: data,
dataType: 'html',
success: function ( response ) {
$(
'.woocommerce-error, .woocommerce-message, .woocommerce-info, .is-error, .is-info, .is-success'
).remove();
show_notice( response );
$( document.body ).trigger( 'removed_coupon', [ coupon ] );
$( '#coupon_code' )
.val('')
.removeClass('has-error')
.removeAttr('aria-invalid')
.removeAttr('aria-describedby')
.closest('.coupon')
.find('.coupon-error-notice')
.remove();
unblock( $wrapper );
},
complete: function () {
cart.update_cart( true );
},
} );
},
/**
* Handle when pressing the Space key on the remove coupon link.
* This is necessary because the link got the role="button" attribute
* and needs to act like a button.
*
* @param {Object} evt The JQuery event
*/
on_keydown_remove_coupon: function ( evt ) {
if ( evt.key === ' ' ) {
evt.preventDefault();
$( evt.currentTarget ).trigger( 'click' );
}
},
/**
* Handle when the coupon input loses focus.
*
* @param {Object} evt The JQuery event
*/
remove_coupon_error: function ( evt ) {
$( evt.currentTarget )
.removeClass( 'has-error' )
.removeAttr( 'aria-invalid' )
.removeAttr( 'aria-describedby' )
.closest( '.coupon' )
.find( '.coupon-error-notice' )
.remove();
},
/**
* Handle a cart Quantity Update
*
* @param {JQuery Object} $form The cart form.
*/
quantity_update: function ( $form ) {
block( $form );
block( $( 'div.cart_totals' ) );
// Provide the submit button value because wc-form-handler expects it.
$( '<input />' )
.attr( 'type', 'hidden' )
.attr( 'name', 'update_cart' )
.attr( 'value', 'Update Cart' )
.appendTo( $form );
// Make call to actual form post URL.
$.ajax( {
type: $form.attr( 'method' ),
url: $form.attr( 'action' ),
data: $form.serialize(),
dataType: 'html',
success: function ( response ) {
update_wc_div( response );
},
complete: function () {
unblock( $form );
unblock( $( 'div.cart_totals' ) );
$.scroll_to_notices( $( '[role="alert"]' ) );
},
} );
},
/**
* Handle when a remove item link is clicked.
*
* @param {Object} evt The JQuery event
*/
item_remove_clicked: function ( evt ) {
evt.preventDefault();
var $a = $( evt.currentTarget );
var $form = $a.parents( 'form' );
block( $form );
block( $( 'div.cart_totals' ) );
$.ajax( {
type: 'GET',
url: $a.attr( 'href' ),
dataType: 'html',
success: function ( response ) {
update_wc_div( response );
},
complete: function () {
unblock( $form );
unblock( $( 'div.cart_totals' ) );
$.scroll_to_notices( $( '[role="alert"]' ) );
$( document.body ).trigger( 'item_removed_from_classic_cart');
},
} );
},
/**
* Handle when pressing the Space key on the remove item link.
* This is necessary because the link got the role="button" attribute
* and needs to act like a button.
*
* @param {Object} evt The JQuery event
*/
on_keydown_remove_item: function ( event ) {
if ( event.key === ' ' ) {
event.preventDefault();
$( event.currentTarget ).trigger( 'click' );
}
},
/**
* Handle when a restore item link is clicked.
*
* @param {Object} evt The JQuery event
*/
item_restore_clicked: function ( evt ) {
evt.preventDefault();
var $a = $( evt.currentTarget );
var $form = $( 'form.woocommerce-cart-form' );
block( $form );
block( $( 'div.cart_totals' ) );
$.ajax( {
type: 'GET',
url: $a.attr( 'href' ),
dataType: 'html',
success: function ( response ) {
update_wc_div( response );
},
complete: function () {
unblock( $form );
unblock( $( 'div.cart_totals' ) );
},
} );
},
};
cart_shipping.init( cart );
cart.init();
} );

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,185 @@
/*global wc_country_select_params */
jQuery( function( $ ) {
// wc_country_select_params is required to continue, ensure the object exists
if ( typeof wc_country_select_params === 'undefined' ) {
return false;
}
// Select2 Enhancement if it exists
if ( $().selectWoo ) {
var getEnhancedSelectFormatString = function() {
return {
'language': {
errorLoading: function() {
// Workaround for https://github.com/select2/select2/issues/4355 instead of i18n_ajax_error.
return wc_country_select_params.i18n_searching;
},
inputTooLong: function( args ) {
var overChars = args.input.length - args.maximum;
if ( 1 === overChars ) {
return wc_country_select_params.i18n_input_too_long_1;
}
return wc_country_select_params.i18n_input_too_long_n.replace( '%qty%', overChars );
},
inputTooShort: function( args ) {
var remainingChars = args.minimum - args.input.length;
if ( 1 === remainingChars ) {
return wc_country_select_params.i18n_input_too_short_1;
}
return wc_country_select_params.i18n_input_too_short_n.replace( '%qty%', remainingChars );
},
loadingMore: function() {
return wc_country_select_params.i18n_load_more;
},
maximumSelected: function( args ) {
if ( args.maximum === 1 ) {
return wc_country_select_params.i18n_selection_too_long_1;
}
return wc_country_select_params.i18n_selection_too_long_n.replace( '%qty%', args.maximum );
},
noResults: function() {
return wc_country_select_params.i18n_no_matches;
},
searching: function() {
return wc_country_select_params.i18n_searching;
}
}
};
};
var wc_country_select_select2 = function() {
$( 'select.country_select:visible, select.state_select:visible' ).each( function() {
var $this = $( this );
var select2_args = $.extend({
placeholder: $this.attr( 'data-placeholder' ) || $this.attr( 'placeholder' ) || '',
label: $this.attr( 'data-label' ) || null,
required: $this.attr( 'aria-required' ) === 'true' || null,
width: '100%'
}, getEnhancedSelectFormatString() );
$( this )
.on( 'select2:select', function() {
$( this ).trigger( 'focus' ); // Maintain focus after select https://github.com/select2/select2/issues/4384
} )
.selectWoo( select2_args );
});
};
wc_country_select_select2();
$( document.body ).on( 'country_to_state_changed', function() {
wc_country_select_select2();
});
}
/* State/Country select boxes */
var states_json = wc_country_select_params.countries.replace( /&quot;/g, '"' ),
states = JSON.parse( states_json ),
wrapper_selectors = '.woocommerce-billing-fields,' +
'.woocommerce-shipping-fields,' +
'.woocommerce-address-fields,' +
'.woocommerce-shipping-calculator';
$( document.body ).on( 'change refresh', 'select.country_to_state, input.country_to_state', function() {
// Grab wrapping element to target only stateboxes in same 'group'
var $wrapper = $( this ).closest( wrapper_selectors );
if ( ! $wrapper.length ) {
$wrapper = $( this ).closest('.form-row').parent();
}
var country = $( this ).val(),
$statebox = $wrapper.find( '#billing_state, #shipping_state, #calc_shipping_state' ),
$parent = $statebox.closest( '.form-row' ),
input_name = $statebox.attr( 'name' ),
input_id = $statebox.attr('id'),
input_classes = $statebox.attr('data-input-classes'),
value = $statebox.val(),
placeholder = $statebox.attr( 'placeholder' ) || $statebox.attr( 'data-placeholder' ) || '',
$newstate;
if ( placeholder === wc_country_select_params.i18n_select_state_text ) {
placeholder = '';
}
if ( states[ country ] ) {
if ( $.isEmptyObject( states[ country ] ) ) {
$newstate = $( '<input type="hidden" />' )
.prop( 'id', input_id )
.prop( 'name', input_name )
.attr( 'data-input-classes', input_classes )
.addClass( 'hidden ' + input_classes );
$parent.hide().find( '.select2-container' ).remove();
$statebox.replaceWith( $newstate );
$( document.body ).trigger( 'country_to_state_changed', [ country, $wrapper ] );
} else {
var state = states[ country ],
$defaultOption = $( '<option value=""></option>' ).text( wc_country_select_params.i18n_select_state_text );
if ( ! placeholder ) {
placeholder = wc_country_select_params.i18n_select_state_text;
}
$parent.show();
if ( $statebox.is( 'input' ) ) {
$newstate = $( '<select></select>' )
.prop( 'id', input_id )
.prop( 'name', input_name )
.data( 'placeholder', placeholder )
.attr( 'data-input-classes', input_classes )
.addClass( 'state_select ' + input_classes );
$statebox.replaceWith( $newstate );
$statebox = $wrapper.find( '#billing_state, #shipping_state, #calc_shipping_state' );
}
$statebox.empty().append( $defaultOption );
$.each( state, function( index ) {
var $option = $( '<option></option>' )
.prop( 'value', index )
.text( state[ index ] );
$statebox.append( $option );
} );
$statebox.val( value ).trigger( 'change' );
$( document.body ).trigger( 'country_to_state_changed', [country, $wrapper ] );
}
} else {
if ( $statebox.is( 'select, input[type="hidden"]' ) ) {
$newstate = $( '<input type="text" />' )
.prop( 'id', input_id )
.prop( 'name', input_name )
.prop( 'placeholder', placeholder )
.attr( 'data-input-classes', input_classes )
.addClass( 'input-text ' + input_classes );
$parent.show().find( '.select2-container' ).remove();
$statebox.replaceWith( $newstate );
$( document.body ).trigger( 'country_to_state_changed', [country, $wrapper ] );
}
}
$( document.body ).trigger( 'country_to_state_changing', [country, $wrapper ] );
});
$( document.body ).on( 'wc_address_i18n_ready', function() {
// Init country selects with their default value once the page loads.
$( wrapper_selectors ).each( function() {
var $country_input = $( this ).find( '#billing_country, #shipping_country, #calc_shipping_country' );
if ( 0 === $country_input.length || 0 === $country_input.val().length ) {
return;
}
$country_input.trigger( 'refresh' );
});
});
});

View File

@@ -0,0 +1 @@
jQuery(function(t){if("undefined"==typeof wc_country_select_params)return!1;if(t().selectWoo){var e=function(){t("select.country_select:visible, select.state_select:visible").each(function(){var e=t(this),n=t.extend({placeholder:e.attr("data-placeholder")||e.attr("placeholder")||"",label:e.attr("data-label")||null,required:"true"===e.attr("aria-required")||null,width:"100%"},{language:{errorLoading:function(){return wc_country_select_params.i18n_searching},inputTooLong:function(t){var e=t.input.length-t.maximum;return 1===e?wc_country_select_params.i18n_input_too_long_1:wc_country_select_params.i18n_input_too_long_n.replace("%qty%",e)},inputTooShort:function(t){var e=t.minimum-t.input.length;return 1===e?wc_country_select_params.i18n_input_too_short_1:wc_country_select_params.i18n_input_too_short_n.replace("%qty%",e)},loadingMore:function(){return wc_country_select_params.i18n_load_more},maximumSelected:function(t){return 1===t.maximum?wc_country_select_params.i18n_selection_too_long_1:wc_country_select_params.i18n_selection_too_long_n.replace("%qty%",t.maximum)},noResults:function(){return wc_country_select_params.i18n_no_matches},searching:function(){return wc_country_select_params.i18n_searching}}});t(this).on("select2:select",function(){t(this).trigger("focus")}).selectWoo(n)})};e(),t(document.body).on("country_to_state_changed",function(){e()})}var n=wc_country_select_params.countries.replace(/&quot;/g,'"'),a=JSON.parse(n),o=".woocommerce-billing-fields,.woocommerce-shipping-fields,.woocommerce-address-fields,.woocommerce-shipping-calculator";t(document.body).on("change refresh","select.country_to_state, input.country_to_state",function(){var e=t(this).closest(o);e.length||(e=t(this).closest(".form-row").parent());var n,c=t(this).val(),r=e.find("#billing_state, #shipping_state, #calc_shipping_state"),i=r.closest(".form-row"),s=r.attr("name"),_=r.attr("id"),l=r.attr("data-input-classes"),p=r.val(),u=r.attr("placeholder")||r.attr("data-placeholder")||"";if(u===wc_country_select_params.i18n_select_state_text&&(u=""),a[c])if(t.isEmptyObject(a[c]))n=t('<input type="hidden" />').prop("id",_).prop("name",s).attr("data-input-classes",l).addClass("hidden "+l),i.hide().find(".select2-container").remove(),r.replaceWith(n),t(document.body).trigger("country_to_state_changed",[c,e]);else{var d=a[c],m=t('<option value=""></option>').text(wc_country_select_params.i18n_select_state_text);u||(u=wc_country_select_params.i18n_select_state_text),i.show(),r.is("input")&&(n=t("<select></select>").prop("id",_).prop("name",s).data("placeholder",u).attr("data-input-classes",l).addClass("state_select "+l),r.replaceWith(n),r=e.find("#billing_state, #shipping_state, #calc_shipping_state")),r.empty().append(m),t.each(d,function(e){var n=t("<option></option>").prop("value",e).text(d[e]);r.append(n)}),r.val(p).trigger("change"),t(document.body).trigger("country_to_state_changed",[c,e])}else r.is('select, input[type="hidden"]')&&(n=t('<input type="text" />').prop("id",_).prop("name",s).prop("placeholder",u).attr("data-input-classes",l).addClass("input-text "+l),i.show().find(".select2-container").remove(),r.replaceWith(n),t(document.body).trigger("country_to_state_changed",[c,e]));t(document.body).trigger("country_to_state_changing",[c,e])}),t(document.body).on("wc_address_i18n_ready",function(){t(o).each(function(){var e=t(this).find("#billing_country, #shipping_country, #calc_shipping_country");0!==e.length&&0!==e.val().length&&e.trigger("refresh")})})});

View File

@@ -0,0 +1,13 @@
jQuery( function( $ ) {
$( '.wc-credit-card-form-card-number' ).payment( 'formatCardNumber' );
$( '.wc-credit-card-form-card-expiry' ).payment( 'formatCardExpiry' );
$( '.wc-credit-card-form-card-cvc' ).payment( 'formatCardCVC' );
$( document.body )
.on( 'updated_checkout wc-credit-card-form-init', function() {
$( '.wc-credit-card-form-card-number' ).payment( 'formatCardNumber' );
$( '.wc-credit-card-form-card-expiry' ).payment( 'formatCardExpiry' );
$( '.wc-credit-card-form-card-cvc' ).payment( 'formatCardCVC' );
})
.trigger( 'wc-credit-card-form-init' );
} );

View File

@@ -0,0 +1 @@
jQuery(function(r){r(".wc-credit-card-form-card-number").payment("formatCardNumber"),r(".wc-credit-card-form-card-expiry").payment("formatCardExpiry"),r(".wc-credit-card-form-card-cvc").payment("formatCardCVC"),r(document.body).on("updated_checkout wc-credit-card-form-init",function(){r(".wc-credit-card-form-card-number").payment("formatCardNumber"),r(".wc-credit-card-form-card-expiry").payment("formatCardExpiry"),r(".wc-credit-card-form-card-cvc").payment("formatCardCVC")}).trigger("wc-credit-card-form-init")});

View File

@@ -0,0 +1,142 @@
/*global wc_geolocation_params */
jQuery( function( $ ) {
/**
* Contains the current geo hash (or false if the hash
* is not set/cannot be determined).
*
* @type {boolean|string}
*/
var geo_hash = false;
/**
* Obtains the current geo hash from the `woocommerce_geo_hash` cookie, if set.
*
* @returns {boolean}
*/
function get_geo_hash() {
var geo_hash_cookie = Cookies.get( 'woocommerce_geo_hash' );
if ( 'string' === typeof geo_hash_cookie && geo_hash_cookie.length ) {
geo_hash = geo_hash_cookie;
return true;
}
return false;
}
/**
* If we have an active geo hash value but it does not match the `?v=` query var in
* current page URL, that indicates that we need to refresh the page.
*
* @returns {boolean}
*/
function needs_refresh() {
return geo_hash && ( new URLSearchParams( window.location.search ) ).get( 'v' ) !== geo_hash;
}
/**
* Appends (or replaces) the geo hash used for links on the current page.
*/
var $append_hashes = function() {
if ( ! geo_hash ) {
return;
}
$( 'a[href^="' + wc_geolocation_params.home_url + '"]:not(a[href*="v="]), a[href^="/"]:not(a[href*="v="])' ).each( function() {
var $this = $( this ),
href = $this.attr( 'href' ),
href_parts = href.split( '#' );
href = href_parts[0];
if ( href.indexOf( '?' ) > 0 ) {
href = href + '&v=' + geo_hash;
} else {
href = href + '?v=' + geo_hash;
}
if ( typeof href_parts[1] !== 'undefined' && href_parts[1] !== null ) {
href = href + '#' + href_parts[1];
}
$this.attr( 'href', href );
});
};
var $geolocate_customer = {
url: wc_geolocation_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_customer_location' ),
type: 'GET',
success: function( response ) {
if ( response.success && response.data.hash && response.data.hash !== geo_hash ) {
$geolocation_redirect( response.data.hash );
}
}
};
/**
* Once we have a new hash, we redirect so a new version of the current page
* (with correct pricing for the current region, etc) is displayed.
*
* @param {string} hash
*/
var $geolocation_redirect = function( hash ) {
// Updates our (cookie-based) cache of the hash value. Expires in 1 hour.
Cookies.set( 'woocommerce_geo_hash', hash, { expires: 1 / 24 } );
const urlQuery = new URL( window.location ).searchParams;
const existingHash = urlQuery.get( 'v' );
// If the current URL does not contain the expected hash, redirect.
if ( existingHash !== hash ) {
urlQuery.set( 'v', hash );
window.location.search = '?' + urlQuery.toString();
}
};
/**
* Updates any forms on the page so they use the current geo hash.
*/
function update_forms() {
if ( ! geo_hash ) {
return;
}
$( 'form' ).each( function () {
var $this = $( this );
var method = $this.attr( 'method' );
var hasField = $this.find( 'input[name="v"]' ).length > 0;
if ( method && 'get' === method.toLowerCase() && ! hasField ) {
$this.append( '<input type="hidden" name="v" value="' + geo_hash + '" />' );
} else {
var href = $this.attr( 'action' );
if ( href ) {
if ( href.indexOf( '?' ) > 0 ) {
$this.attr( 'action', href + '&v=' + geo_hash );
} else {
$this.attr( 'action', href + '?v=' + geo_hash );
}
}
}
});
}
// Get the current geo hash. If it doesn't exist, or if it doesn't match the current
// page URL, perform a geolocation request.
if ( ! get_geo_hash() || needs_refresh() ) {
$.ajax( $geolocate_customer );
}
// Page updates.
update_forms();
$append_hashes();
$( document.body ).on( 'added_to_cart', function() {
$append_hashes();
});
// Enable user to trigger manual append hashes on AJAX operations
$( document.body ).on( 'woocommerce_append_geo_hashes', function() {
$append_hashes();
});
});

View File

@@ -0,0 +1 @@
jQuery(function(e){var t=!1;var o,a=function(){t&&e('a[href^="'+wc_geolocation_params.home_url+'"]:not(a[href*="v="]), a[href^="/"]:not(a[href*="v="])').each(function(){var o=e(this),a=o.attr("href"),n=a.split("#");a=(a=n[0]).indexOf("?")>0?a+"&v="+t:a+"?v="+t,"undefined"!=typeof n[1]&&null!==n[1]&&(a=a+"#"+n[1]),o.attr("href",a)})},n={url:wc_geolocation_params.wc_ajax_url.toString().replace("%%endpoint%%","get_customer_location"),type:"GET",success:function(e){e.success&&e.data.hash&&e.data.hash!==t&&c(e.data.hash)}},c=function(e){Cookies.set("woocommerce_geo_hash",e,{expires:1/24});const t=new URL(window.location).searchParams;t.get("v")!==e&&(t.set("v",e),window.location.search="?"+t.toString())};("string"!=typeof(o=Cookies.get("woocommerce_geo_hash"))||!o.length||(t=o,0)||t&&new URLSearchParams(window.location.search).get("v")!==t)&&e.ajax(n),t&&e("form").each(function(){var o=e(this),a=o.attr("method"),n=o.find('input[name="v"]').length>0;if(a&&"get"===a.toLowerCase()&&!n)o.append('<input type="hidden" name="v" value="'+t+'" />');else{var c=o.attr("action");c&&(c.indexOf("?")>0?o.attr("action",c+"&v="+t):o.attr("action",c+"?v="+t))}}),a(),e(document.body).on("added_to_cart",function(){a()}),e(document.body).on("woocommerce_append_geo_hashes",function(){a()})});

View File

@@ -0,0 +1,5 @@
jQuery( function( $ ) {
$( '.lost_reset_password' ).on( 'submit', function () {
$( 'button[type="submit"]', this ).attr( 'disabled', 'disabled' );
});
});

View File

@@ -0,0 +1 @@
jQuery(function(t){t(".lost_reset_password").on("submit",function(){t('button[type="submit"]',this).attr("disabled","disabled")})});

View File

@@ -0,0 +1,228 @@
( function ( wc_order_attribution ) {
'use strict';
// Cache params reference for shorter reusability.
const params = wc_order_attribution.params;
// Helper functions.
const $ = document.querySelector.bind( document );
const propertyAccessor = ( obj, path ) => path.split( '.' ).reduce( ( acc, part ) => acc && acc[ part ], obj );
const returnNull = () => null;
const stringifyFalsyInputValue = ( value ) => value === null || value === undefined ? '' : value;
// Hardcode Checkout store key (`wc.wcBlocksData.CHECKOUT_STORE_KEY`), as we no longer have `wc-blocks-checkout` as a dependency.
const CHECKOUT_STORE_KEY = 'wc/store/checkout';
/**
* Get the order attribution data.
*
* Returns object full of `null`s if tracking is disabled or if sourcebuster.js is blocked.
*
* @returns {Object} Schema compatible object.
*/
wc_order_attribution.getAttributionData = function() {
const accessor = params.allowTracking && isSbjsAvailable() ? propertyAccessor : returnNull;
const getter = isSbjsAvailable() ? sbjs.get : {};
const entries = Object.entries( wc_order_attribution.fields )
.map( ( [ key, property ] ) => [ key, accessor( getter, property ) ] );
return Object.fromEntries( entries );
}
/**
* Remove duplicate `<wc-order-attribution-inputs>` elements, leaving only the first one,
* to prevent sending the same data multiple times.
*/
function removeDuplicateInputGroups() {
document.querySelectorAll( 'wc-order-attribution-inputs' ).forEach( ( group, index ) => {
if ( index > 0 ) {
group.remove();
}
} );
}
/**
* Update `wc_order_attribution` input elements' values.
*
* @param {Object} values Object containing field values.
*/
function updateFormValues( values ) {
// Remove duplicates before updating to ensure only one set of elements exists.
removeDuplicateInputGroups();
// Update `<wc-order-attribution-inputs>` elements if any exist.
for( const element of document.querySelectorAll( 'wc-order-attribution-inputs' ) ) {
element.values = values;
}
};
/**
* Update Checkout extension data.
*
* @param {Object} values Object containing field values.
*/
function updateCheckoutBlockData( values ) {
// Update Checkout block data if available.
if (
window.wp &&
window.wp.data &&
window.wp.data.dispatch &&
window.wc &&
window.wc.wcBlocksData
) {
window.wp.data
.dispatch( window.wc.wcBlocksData.CHECKOUT_STORE_KEY )
.setExtensionData(
'woocommerce/order-attribution',
values,
true
);
}
}
/**
* Determine whether sourcebuster.js is available.
*
* @returns {boolean} Whether sourcebuster.js is available.
*/
function isSbjsAvailable() {
return typeof sbjs !== 'undefined';
}
/**
* Initialize sourcebuster & set data, or clear cookies & data.
*
* @param {boolean} allow Whether to allow tracking or disable it.
*/
wc_order_attribution.setOrderTracking = function( allow ) {
params.allowTracking = allow;
if ( ! allow ) {
// Reset cookies, and clear form data.
removeTrackingCookies();
} else if ( ! isSbjsAvailable() ) {
return; // Do nothing, as sourcebuster.js is not loaded.
} else {
// If not done yet, initialize sourcebuster.js which populates `sbjs.get` object.
sbjs.init( {
lifetime: Number( params.lifetime ),
session_length: Number( params.session ),
base64: Boolean( params.base64 ),
timezone_offset: '0', // utc
} );
}
const values = wc_order_attribution.getAttributionData();
updateFormValues( values );
updateCheckoutBlockData( values );
}
/**
* Remove sourcebuster.js cookies.
* To be called whenever tracking is disabled or consent is revoked.
*/
function removeTrackingCookies() {
const domain = window.location.hostname;
const sbCookies = [
'sbjs_current',
'sbjs_current_add',
'sbjs_first',
'sbjs_first_add',
'sbjs_session',
'sbjs_udata',
'sbjs_migrations',
'sbjs_promo'
];
// Remove cookies
sbCookies.forEach( ( name ) => {
document.cookie = `${name}=; path=/; max-age=-999; domain=.${domain};`;
} );
}
// Run init.
wc_order_attribution.setOrderTracking( params.allowTracking );
// Work around the lack of explicit script dependency for the checkout block.
// Conditionally, wait for and use 'wp-data' & 'wc-blocks-checkout.
// Wait for (async) block checkout initialization and set source values once loaded.
function eventuallyInitializeCheckoutBlock() {
if (
window.wp && window.wp.data && typeof window.wp.data.subscribe === 'function'
) {
// Update checkout block data once more if the checkout store was loaded after this script.
const unsubscribe = window.wp.data.subscribe( function () {
unsubscribe();
updateCheckoutBlockData( wc_order_attribution.getAttributionData() );
}, CHECKOUT_STORE_KEY );
}
};
// Wait for DOMContentLoaded to make sure wp.data is in place, if applicable for the page.
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", eventuallyInitializeCheckoutBlock);
} else {
eventuallyInitializeCheckoutBlock();
}
/**
* Define an element to contribute order attribute values to the enclosing form.
* To be used with the classic checkout.
*/
window.customElements.define( 'wc-order-attribution-inputs', class extends HTMLElement {
// Our bundler version does not support private class members, so we use a convention of `_` prefix.
// #values
// #fieldNames
constructor(){
super();
// Cache fieldNames available at the construction time, to avoid malformed behavior if they change in runtime.
this._fieldNames = Object.keys( wc_order_attribution.fields );
// Allow values to be lazily set before CE upgrade.
if ( this.hasOwnProperty( '_values' ) ) {
let values = this.values;
// Restore the setter.
delete this.values;
this.values = values || {};
}
}
/**
* Stamp input elements to the element's light DOM.
*
* We could use `.elementInternals.setFromValue` and avoid sprouting `<input>` elements,
* but it's not yet supported in Safari.
*/
connectedCallback() {
this.innerHTML = '';
const inputs = new DocumentFragment();
for( const fieldName of this._fieldNames ) {
const input = document.createElement( 'input' );
input.type = 'hidden';
input.name = `${params.prefix}${fieldName}`;
input.value = stringifyFalsyInputValue( ( this.values && this.values[ fieldName ] ) || '' );
inputs.appendChild( input );
}
this.appendChild( inputs );
}
/**
* Update form values.
*/
set values( values ) {
this._values = values;
if( this.isConnected ) {
for( const fieldName of this._fieldNames ) {
const input = this.querySelector( `input[name="${params.prefix}${fieldName}"]` );
if( input ) {
input.value = stringifyFalsyInputValue( this.values[ fieldName ] );
} else {
console.warn(
`Field "${fieldName}" not found. ` +
`Most likely, the '<wc-order-attribution-inputs>' element was manipulated.`
);
}
}
}
}
get values() {
return this._values;
}
} );
}( window.wc_order_attribution ) );

View File

@@ -0,0 +1 @@
!function(t){"use strict";const e=t.params,n=(document.querySelector.bind(document),(t,e)=>e.split(".").reduce((t,e)=>t&&t[e],t)),i=()=>null,s=t=>null===t||t===undefined?"":t,o="wc/store/checkout";function a(t){document.querySelectorAll("wc-order-attribution-inputs").forEach((t,e)=>{e>0&&t.remove()});for(const e of document.querySelectorAll("wc-order-attribution-inputs"))e.values=t}function r(t){window.wp&&window.wp.data&&window.wp.data.dispatch&&window.wc&&window.wc.wcBlocksData&&window.wp.data.dispatch(window.wc.wcBlocksData.CHECKOUT_STORE_KEY).setExtensionData("woocommerce/order-attribution",t,!0)}function c(){return"undefined"!=typeof sbjs}function d(){if(window.wp&&window.wp.data&&"function"==typeof window.wp.data.subscribe){const e=window.wp.data.subscribe(function(){e(),r(t.getAttributionData())},o)}}t.getAttributionData=function(){const s=e.allowTracking&&c()?n:i,o=c()?sbjs.get:{},a=Object.entries(t.fields).map(([t,e])=>[t,s(o,e)]);return Object.fromEntries(a)},t.setOrderTracking=function(n){if(e.allowTracking=n,n){if(!c())return;sbjs.init({lifetime:Number(e.lifetime),session_length:Number(e.session),base64:Boolean(e.base64),timezone_offset:"0"})}else!function(){const t=window.location.hostname;["sbjs_current","sbjs_current_add","sbjs_first","sbjs_first_add","sbjs_session","sbjs_udata","sbjs_migrations","sbjs_promo"].forEach(e=>{document.cookie=`${e}=; path=/; max-age=-999; domain=.${t};`})}();const i=t.getAttributionData();a(i),r(i)},t.setOrderTracking(e.allowTracking),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",d):d(),window.customElements.define("wc-order-attribution-inputs",class extends HTMLElement{constructor(){if(super(),this._fieldNames=Object.keys(t.fields),this.hasOwnProperty("_values")){let t=this.values;delete this.values,this.values=t||{}}}connectedCallback(){this.innerHTML="";const t=new DocumentFragment;for(const n of this._fieldNames){const i=document.createElement("input");i.type="hidden",i.name=`${e.prefix}${n}`,i.value=s(this.values&&this.values[n]||""),t.appendChild(i)}this.appendChild(t)}set values(t){if(this._values=t,this.isConnected)for(const t of this._fieldNames){const n=this.querySelector(`input[name="${e.prefix}${t}"]`);n?n.value=s(this.values[t]):console.warn(`Field "${t}" not found. `+"Most likely, the '<wc-order-attribution-inputs>' element was manipulated.")}}get values(){return this._values}})}(window.wc_order_attribution);

View File

@@ -0,0 +1,162 @@
/* global wp, pwsL10n, wc_password_strength_meter_params */
jQuery( function ( $ ) {
'use strict';
/**
* Password Strength Meter class.
*/
var wc_password_strength_meter = {
/**
* Initialize strength meter actions.
*/
init: function () {
$( document.body ).on(
'keyup change',
'form.register #reg_password, form.checkout #account_password, ' +
'form.edit-account #password_1, form.lost_reset_password #password_1',
this.strengthMeter
);
$( 'form.checkout #createaccount' ).trigger( 'change' );
},
/**
* Strength Meter.
*/
strengthMeter: function () {
var wrapper = $(
'form.register, form.checkout, form.edit-account, form.lost_reset_password'
),
submit = $( 'button[type="submit"]', wrapper ),
field = $(
'#reg_password, #account_password, #password_1',
wrapper
),
strength = 1,
fieldValue = field.val(),
stop_checkout = ! wrapper.is( 'form.checkout' ); // By default is disabled on checkout.
wc_password_strength_meter.includeMeter( wrapper, field );
strength = wc_password_strength_meter.checkPasswordStrength(
wrapper,
field
);
// Allow password strength meter stop checkout.
if ( wc_password_strength_meter_params.stop_checkout ) {
stop_checkout = true;
}
if (
fieldValue.length > 0 &&
strength <
wc_password_strength_meter_params.min_password_strength &&
-1 !== strength &&
stop_checkout
) {
submit.attr( 'disabled', 'disabled' ).addClass( 'disabled' );
} else {
submit.prop( 'disabled', false ).removeClass( 'disabled' );
}
},
/**
* Include meter HTML.
*
* @param {Object} wrapper
* @param {Object} field
*/
includeMeter: function ( wrapper, field ) {
var meter = wrapper.find( '.woocommerce-password-strength' );
if ( '' === field.val() ) {
meter.hide();
$( document.body ).trigger( 'wc-password-strength-hide' );
field.removeAttr( 'aria-describedby' );
} else if ( 0 === meter.length ) {
var meter =
'<div id="password_strength" class="woocommerce-password-strength" role="alert"></div>';
var wrapper = field.parent();
// If the field is inside a password-input, inject the meter after the password-input.
if ( wrapper.is( '.password-input' ) ) {
wrapper.after( meter );
} else {
field.after( meter );
}
field.attr( 'aria-describedby', 'password_strength' );
$( document.body ).trigger( 'wc-password-strength-added' );
} else {
meter.show();
$( document.body ).trigger( 'wc-password-strength-show' );
}
},
/**
* Check password strength.
*
* @param {Object} field
*
* @return {Int}
*/
checkPasswordStrength: function ( wrapper, field ) {
var meter = wrapper.find( '.woocommerce-password-strength' ),
hint = wrapper.find( '.woocommerce-password-hint' ),
hint_html =
'<small class="woocommerce-password-hint">' +
wc_password_strength_meter_params.i18n_password_hint +
'</small>',
strength = wp.passwordStrength.meter(
field.val(),
wp.passwordStrength.userInputDisallowedList()
),
error = '';
// Reset.
meter.removeClass( 'short bad good strong' );
hint.remove();
if ( meter.is( ':hidden' ) ) {
return strength;
}
// Error to append
if (
strength <
wc_password_strength_meter_params.min_password_strength
) {
error =
' - ' +
wc_password_strength_meter_params.i18n_password_error;
}
switch ( strength ) {
case 0:
meter
.addClass( 'short' )
.html( pwsL10n[ 'short' ] + error );
meter.after( hint_html );
break;
case 1:
meter.addClass( 'bad' ).html( pwsL10n.bad + error );
meter.after( hint_html );
break;
case 2:
meter.addClass( 'bad' ).html( pwsL10n.bad + error );
meter.after( hint_html );
break;
case 3:
meter.addClass( 'good' ).html( pwsL10n.good + error );
break;
case 4:
meter.addClass( 'strong' ).html( pwsL10n.strong + error );
break;
case 5:
meter.addClass( 'short' ).html( pwsL10n.mismatch );
break;
}
return strength;
},
};
wc_password_strength_meter.init();
} );

View File

@@ -0,0 +1 @@
jQuery(function(s){"use strict";var r={init:function(){s(document.body).on("keyup change","form.register #reg_password, form.checkout #account_password, form.edit-account #password_1, form.lost_reset_password #password_1",this.strengthMeter),s("form.checkout #createaccount").trigger("change")},strengthMeter:function(){var e,t=s("form.register, form.checkout, form.edit-account, form.lost_reset_password"),a=s('button[type="submit"]',t),o=s("#reg_password, #account_password, #password_1",t),d=o.val(),n=!t.is("form.checkout");r.includeMeter(t,o),e=r.checkPasswordStrength(t,o),wc_password_strength_meter_params.stop_checkout&&(n=!0),d.length>0&&e<wc_password_strength_meter_params.min_password_strength&&-1!==e&&n?a.attr("disabled","disabled").addClass("disabled"):a.prop("disabled",!1).removeClass("disabled")},includeMeter:function(r,e){var t=r.find(".woocommerce-password-strength");if(""===e.val())t.hide(),s(document.body).trigger("wc-password-strength-hide"),e.removeAttr("aria-describedby");else if(0===t.length){t='<div id="password_strength" class="woocommerce-password-strength" role="alert"></div>';(r=e.parent()).is(".password-input")?r.after(t):e.after(t),e.attr("aria-describedby","password_strength"),s(document.body).trigger("wc-password-strength-added")}else t.show(),s(document.body).trigger("wc-password-strength-show")},checkPasswordStrength:function(s,r){var e=s.find(".woocommerce-password-strength"),t=s.find(".woocommerce-password-hint"),a='<small class="woocommerce-password-hint">'+wc_password_strength_meter_params.i18n_password_hint+"</small>",o=wp.passwordStrength.meter(r.val(),wp.passwordStrength.userInputDisallowedList()),d="";if(e.removeClass("short bad good strong"),t.remove(),e.is(":hidden"))return o;switch(o<wc_password_strength_meter_params.min_password_strength&&(d=" - "+wc_password_strength_meter_params.i18n_password_error),o){case 0:e.addClass("short").html(pwsL10n.short+d),e.after(a);break;case 1:case 2:e.addClass("bad").html(pwsL10n.bad+d),e.after(a);break;case 3:e.addClass("good").html(pwsL10n.good+d);break;case 4:e.addClass("strong").html(pwsL10n.strong+d);break;case 5:e.addClass("short").html(pwsL10n.mismatch)}return o}};r.init()});

View File

@@ -0,0 +1,83 @@
/* global woocommerce_price_slider_params, accounting */
jQuery( function( $ ) {
// woocommerce_price_slider_params is required to continue, ensure the object exists
if ( typeof woocommerce_price_slider_params === 'undefined' ) {
return false;
}
$( document.body ).on( 'price_slider_create price_slider_slide', function( event, min, max ) {
$( '.price_slider_amount span.from' ).html( accounting.formatMoney( min, {
symbol: woocommerce_price_slider_params.currency_format_symbol,
decimal: woocommerce_price_slider_params.currency_format_decimal_sep,
thousand: woocommerce_price_slider_params.currency_format_thousand_sep,
precision: woocommerce_price_slider_params.currency_format_num_decimals,
format: woocommerce_price_slider_params.currency_format
} ) );
$( '.price_slider_amount span.to' ).html( accounting.formatMoney( max, {
symbol: woocommerce_price_slider_params.currency_format_symbol,
decimal: woocommerce_price_slider_params.currency_format_decimal_sep,
thousand: woocommerce_price_slider_params.currency_format_thousand_sep,
precision: woocommerce_price_slider_params.currency_format_num_decimals,
format: woocommerce_price_slider_params.currency_format
} ) );
$( document.body ).trigger( 'price_slider_updated', [ min, max ] );
});
function init_price_filter() {
$( 'input#min_price, input#max_price' ).hide();
$( '.price_slider, .price_label' ).show();
var min_price = $( '.price_slider_amount #min_price' ).data( 'min' ),
max_price = $( '.price_slider_amount #max_price' ).data( 'max' ),
step = $( '.price_slider_amount' ).data( 'step' ) || 1,
current_min_price = $( '.price_slider_amount #min_price' ).val(),
current_max_price = $( '.price_slider_amount #max_price' ).val();
$( '.price_slider:not(.ui-slider)' ).slider({
range: true,
animate: true,
min: min_price,
max: max_price,
step: step,
values: [ current_min_price, current_max_price ],
create: function() {
$( '.price_slider_amount #min_price' ).val( current_min_price );
$( '.price_slider_amount #max_price' ).val( current_max_price );
$( document.body ).trigger( 'price_slider_create', [ current_min_price, current_max_price ] );
},
slide: function( event, ui ) {
$( 'input#min_price' ).val( ui.values[0] );
$( 'input#max_price' ).val( ui.values[1] );
$( document.body ).trigger( 'price_slider_slide', [ ui.values[0], ui.values[1] ] );
},
change: function( event, ui ) {
$( document.body ).trigger( 'price_slider_change', [ ui.values[0], ui.values[1] ] );
}
});
}
init_price_filter();
$( document.body ).on( 'init_price_filter', init_price_filter );
var hasSelectiveRefresh = (
'undefined' !== typeof wp &&
wp.customize &&
wp.customize.selectiveRefresh &&
wp.customize.widgetsPreview &&
wp.customize.widgetsPreview.WidgetPartial
);
if ( hasSelectiveRefresh ) {
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function() {
init_price_filter();
} );
}
});

View File

@@ -0,0 +1 @@
jQuery(function(e){if("undefined"==typeof woocommerce_price_slider_params)return!1;function r(){e("input#min_price, input#max_price").hide(),e(".price_slider, .price_label").show();var r=e(".price_slider_amount #min_price").data("min"),i=e(".price_slider_amount #max_price").data("max"),c=e(".price_slider_amount").data("step")||1,o=e(".price_slider_amount #min_price").val(),_=e(".price_slider_amount #max_price").val();e(".price_slider:not(.ui-slider)").slider({range:!0,animate:!0,min:r,max:i,step:c,values:[o,_],create:function(){e(".price_slider_amount #min_price").val(o),e(".price_slider_amount #max_price").val(_),e(document.body).trigger("price_slider_create",[o,_])},slide:function(r,i){e("input#min_price").val(i.values[0]),e("input#max_price").val(i.values[1]),e(document.body).trigger("price_slider_slide",[i.values[0],i.values[1]])},change:function(r,i){e(document.body).trigger("price_slider_change",[i.values[0],i.values[1]])}})}e(document.body).on("price_slider_create price_slider_slide",function(r,i,c){e(".price_slider_amount span.from").html(accounting.formatMoney(i,{symbol:woocommerce_price_slider_params.currency_format_symbol,decimal:woocommerce_price_slider_params.currency_format_decimal_sep,thousand:woocommerce_price_slider_params.currency_format_thousand_sep,precision:woocommerce_price_slider_params.currency_format_num_decimals,format:woocommerce_price_slider_params.currency_format})),e(".price_slider_amount span.to").html(accounting.formatMoney(c,{symbol:woocommerce_price_slider_params.currency_format_symbol,decimal:woocommerce_price_slider_params.currency_format_decimal_sep,thousand:woocommerce_price_slider_params.currency_format_thousand_sep,precision:woocommerce_price_slider_params.currency_format_num_decimals,format:woocommerce_price_slider_params.currency_format})),e(document.body).trigger("price_slider_updated",[i,c])}),r(),e(document.body).on("init_price_filter",r),"undefined"!=typeof wp&&wp.customize&&wp.customize.selectiveRefresh&&wp.customize.widgetsPreview&&wp.customize.widgetsPreview.WidgetPartial&&wp.customize.selectiveRefresh.bind("partial-content-rendered",function(){r()})});

View File

@@ -0,0 +1,551 @@
/*global wc_single_product_params, PhotoSwipe, PhotoSwipeUI_Default */
jQuery( function( $ ) {
// wc_single_product_params is required to continue.
if ( typeof wc_single_product_params === 'undefined' ) {
return false;
}
$( 'body' )
// Tabs
.on( 'init', '.wc-tabs-wrapper, .woocommerce-tabs', function() {
$( this ).find( '.wc-tab, .woocommerce-tabs .panel:not(.panel .panel)' ).hide();
var hash = window.location.hash;
var url = window.location.href;
var $tabs = $( this ).find( '.wc-tabs, ul.tabs' ).first();
if ( hash.toLowerCase().indexOf( 'comment-' ) >= 0 || hash === '#reviews' || hash === '#tab-reviews' ) {
$tabs.find( 'li.reviews_tab a' ).trigger( 'click' );
} else if ( url.indexOf( 'comment-page-' ) > 0 || url.indexOf( 'cpage=' ) > 0 ) {
$tabs.find( 'li.reviews_tab a' ).trigger( 'click' );
} else if ( hash === '#tab-additional_information' ) {
$tabs.find( 'li.additional_information_tab a' ).trigger( 'click' );
} else {
$tabs.find( 'li:first a' ).trigger( 'click' );
}
} )
.on( 'click', '.wc-tabs li a, ul.tabs li a', function( e ) {
e.preventDefault();
var $tab = $( this );
var $tabs_wrapper = $tab.closest( '.wc-tabs-wrapper, .woocommerce-tabs' );
var $tabs = $tabs_wrapper.find( '.wc-tabs, ul.tabs' );
$tabs.find( 'li' ).removeClass( 'active' );
$tabs
.find( 'a[role="tab"]' )
.attr( 'aria-selected', 'false' )
.attr( 'tabindex', '-1' );
$tabs_wrapper.find( '.wc-tab, .panel:not(.panel .panel)' ).hide();
$tab.closest( 'li' ).addClass( 'active' );
$tab
.attr( 'aria-selected', 'true' )
.attr( 'tabindex', '0' );
$tabs_wrapper.find( '#' + $tab.attr( 'href' ).split( '#' )[1] ).show();
} )
.on( 'keydown', '.wc-tabs li a, ul.tabs li a', function( e ) {
var isRTL = document.documentElement.dir === 'rtl';
var direction = e.key;
var next = isRTL ? 'ArrowLeft' : 'ArrowRight';
var prev = isRTL ? 'ArrowRight' : 'ArrowLeft';
var down = 'ArrowDown';
var up = 'ArrowUp';
var home = 'Home';
var end = 'End';
if ( ! [ next, prev, down, up, end, home ].includes( direction ) ) {
return;
}
var $tab = $( this );
var $tabs_wrapper = $tab.closest( '.wc-tabs-wrapper, .woocommerce-tabs' );
var $tabsList = $tabs_wrapper.find( '.wc-tabs, ul.tabs' );
var $tabs = $tabsList.find( 'a[role="tab"]' );
var endIndex = $tabs.length - 1;
var tabIndex = $tabs.index( $tab );
var targetIndex = direction === prev || direction === up ? tabIndex - 1 : tabIndex + 1;
var orientation = 'horizontal';
/**
* We don't know if the tabs are going to be vertical or horizontal,
* so let's try to detect the orientation depending on the position of the tabs.
*/
if ( $tabs.length >= 2 ) {
var firstTab = $tabs[0].getBoundingClientRect();
var secondTab = $tabs[1].getBoundingClientRect();
var orientation = Math.abs( secondTab.top - firstTab.top ) > Math.abs( secondTab.left - firstTab.left )
? 'vertical'
: 'horizontal';
}
/**
* If the tabs are vertical, we don't need to detect left/right keys
* If the tabs are horizontal, we don't need to detect up/down keys
*/
if (
( orientation === 'vertical' && ( direction === prev || direction === next ) ) ||
( orientation === 'horizontal' && ( direction === up || direction === down ) )
) {
return;
}
e.preventDefault();
if (
( direction === prev && tabIndex === 0 && orientation === 'horizontal' ) ||
( direction === up && tabIndex === 0 && orientation === 'vertical' ) ||
direction === end
) {
targetIndex = endIndex;
} else if (
( next === direction && tabIndex === endIndex && orientation === 'horizontal' ) ||
( down === direction && tabIndex === endIndex && orientation === 'vertical' ) ||
direction === home
) {
targetIndex = 0;
}
$tabs.eq( targetIndex ).focus();
} )
// Review link
.on( 'click', 'a.woocommerce-review-link', function() {
$( '.reviews_tab a' ).trigger( 'click' );
return true;
} )
// Star ratings for comments
.on( 'init', '#rating', function() {
$( this )
.hide()
.before(
'<p class="stars">\
<span role="group" aria-labelledby="comment-form-rating-label">\
<a role="radio" tabindex="0" aria-checked="false" class="star-1" href="#">' +
wc_single_product_params.i18n_rating_options[0] +
'</a>\
<a role="radio" tabindex="-1" aria-checked="false" class="star-2" href="#">' +
wc_single_product_params.i18n_rating_options[1] +
'</a>\
<a role="radio" tabindex="-1" aria-checked="false" class="star-3" href="#">' +
wc_single_product_params.i18n_rating_options[2] +
'</a>\
<a role="radio" tabindex="-1" aria-checked="false" class="star-4" href="#">' +
wc_single_product_params.i18n_rating_options[3] +
'</a>\
<a role="radio" tabindex="-1" aria-checked="false" class="star-5" href="#">' +
wc_single_product_params.i18n_rating_options[4] +
'</a>\
</span>\
</p>'
);
} )
.on( 'click', '#respond p.stars a', function() {
var $star = $( this ),
starPos = $star.closest( 'p.stars' ).find( 'a' ).index( $star ) + 1,
$rating = $( this ).closest( '#respond' ).find( '#rating' ),
$container = $( this ).closest( '.stars' );
$rating.val( starPos );
$star.siblings( 'a' )
.removeClass( 'active' )
.attr( 'aria-checked', 'false' )
.attr( 'tabindex', '-1' );
$star
.addClass( 'active' )
.attr( 'aria-checked', 'true' )
.attr( 'tabindex', '0' );
$container.addClass( 'selected' );
return false;
} )
.on( 'click', '#respond #submit', function() {
var $rating = $( this ).closest( '#respond' ).find( '#rating' ),
rating = $rating.val();
if ( $rating.length > 0 && ! rating && wc_single_product_params.review_rating_required === 'yes' ) {
window.alert( wc_single_product_params.i18n_required_rating_text );
return false;
}
} )
/**
* Handle keyup events for tabs, tabs li a, and respond p.stars a.
* The stopPropagation is used to prevent the keyup event from being triggered on the flexslider.
*/
.on( 'keyup', '.wc-tabs li a, ul.tabs li a, #respond p.stars a', function( e ) {
var direction = e.key;
var next = [ 'ArrowRight', 'ArrowDown' ];
var prev = [ 'ArrowLeft', 'ArrowUp' ];
var allDirections = next.concat( prev );
if ( ! allDirections.includes( direction ) ) {
return;
}
e.preventDefault();
e.stopPropagation();
if ( next.includes( direction ) ) {
$( this ).next().focus().click();
return;
}
$( this ).prev().focus().click();
} );
// Init Tabs and Star Ratings
$( '.wc-tabs-wrapper, .woocommerce-tabs, #rating' ).trigger( 'init' );
var productGalleryElement;
/**
* Product gallery class.
*/
var ProductGallery = function( $target, args ) {
this.$target = $target;
this.$images = $( '.woocommerce-product-gallery__image', $target );
// No images? Abort.
if ( 0 === this.$images.length ) {
this.$target.css( 'opacity', 1 );
return;
}
// Make this object available.
$target.data( 'product_gallery', this );
// Pick functionality to initialize...
this.flexslider_enabled = 'function' === typeof $.fn.flexslider && wc_single_product_params.flexslider_enabled;
this.zoom_enabled = 'function' === typeof $.fn.zoom && wc_single_product_params.zoom_enabled;
this.photoswipe_enabled = typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled;
// ...also taking args into account.
if ( args ) {
this.flexslider_enabled = false === args.flexslider_enabled ? false : this.flexslider_enabled;
this.zoom_enabled = false === args.zoom_enabled ? false : this.zoom_enabled;
this.photoswipe_enabled = false === args.photoswipe_enabled ? false : this.photoswipe_enabled;
}
// ...and what is in the gallery.
if ( 1 === this.$images.length ) {
this.flexslider_enabled = false;
}
// Bind functions to this.
this.initFlexslider = this.initFlexslider.bind( this );
this.initZoom = this.initZoom.bind( this );
this.initZoomForTarget = this.initZoomForTarget.bind( this );
this.initPhotoswipe = this.initPhotoswipe.bind( this );
this.onResetSlidePosition = this.onResetSlidePosition.bind( this );
this.getGalleryItems = this.getGalleryItems.bind( this );
this.openPhotoswipe = this.openPhotoswipe.bind( this );
this.trapFocusPhotoswipe = this.trapFocusPhotoswipe.bind( this );
this.handlePswpTrapFocus = this.handlePswpTrapFocus.bind( this );
if ( this.flexslider_enabled ) {
this.initFlexslider( args.flexslider );
$target.on( 'woocommerce_gallery_reset_slide_position', this.onResetSlidePosition );
} else {
this.$target.css( 'opacity', 1 );
}
if ( this.zoom_enabled ) {
this.initZoom();
$target.on( 'woocommerce_gallery_init_zoom', this.initZoom );
}
if ( this.photoswipe_enabled ) {
this.initPhotoswipe();
}
};
/**
* Initialize flexSlider.
*/
ProductGallery.prototype.initFlexslider = function( args ) {
var $target = this.$target,
gallery = this;
var options = $.extend( {
selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image',
start: function() {
$target.css( 'opacity', 1 );
},
after: function( slider ) {
gallery.initZoomForTarget( gallery.$images.eq( slider.currentSlide ) );
}
}, args );
$target.flexslider( options );
// Trigger resize after main image loads to ensure correct gallery size.
$( '.woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image:eq(0) .wp-post-image' ).one( 'load', function() {
var $image = $( this );
if ( $image ) {
setTimeout( function() {
var setHeight = $image.closest( '.woocommerce-product-gallery__image' ).height();
var $viewport = $image.closest( '.flex-viewport' );
if ( setHeight && $viewport ) {
$viewport.height( setHeight );
}
}, 100 );
}
} ).each( function() {
if ( this.complete ) {
$( this ).trigger( 'load' );
}
} );
};
/**
* Init zoom.
*/
ProductGallery.prototype.initZoom = function() {
if (document.readyState === 'complete') {
this.initZoomForTarget(this.$images.first());
} else {
$(window).on('load', () => {
this.initZoomForTarget(this.$images.first());
});
}
};
/**
* Init zoom.
*/
ProductGallery.prototype.initZoomForTarget = function( zoomTarget ) {
if ( ! this.zoom_enabled ) {
return false;
}
var galleryWidth = this.$target.width(),
zoomEnabled = false;
$( zoomTarget ).each( function( index, target ) {
var image = $( target ).find( 'img' );
if ( image.data( 'large_image_width' ) > galleryWidth ) {
zoomEnabled = true;
return false;
}
} );
// But only zoom if the img is larger than its container.
if ( zoomEnabled ) {
var zoom_options = $.extend( {
touch: false,
callback: function() {
var zoomImg = this;
setTimeout( function() {
zoomImg.removeAttribute( 'role' );
zoomImg.setAttribute( 'alt', '' );
zoomImg.setAttribute( 'aria-hidden', 'true' );
}, 100 );
}
}, wc_single_product_params.zoom_options );
if ( 'ontouchstart' in document.documentElement ) {
zoom_options.on = 'click';
}
zoomTarget.trigger( 'zoom.destroy' );
zoomTarget.zoom( zoom_options );
setTimeout( function() {
if ( zoomTarget.find(':hover').length ) {
zoomTarget.trigger( 'mouseover' );
}
}, 100 );
}
};
/**
* Init PhotoSwipe.
*/
ProductGallery.prototype.initPhotoswipe = function() {
if ( this.zoom_enabled && this.$images.length > 0 ) {
this.$target.prepend(
'<a href="#" role="button" class="woocommerce-product-gallery__trigger" aria-haspopup="dialog" ' +
'aria-controls="photoswipe-fullscreen-dialog" aria-label="' +
wc_single_product_params.i18n_product_gallery_trigger_text + '">' +
'<span aria-hidden="true">🔍</span>' +
'</a>'
);
this.$target.on( 'click', '.woocommerce-product-gallery__trigger', this.openPhotoswipe );
this.$target.on( 'keydown', '.woocommerce-product-gallery__trigger', ( e ) => {
if ( e.key === ' ' ) {
this.openPhotoswipe( e );
}
} );
this.$target.on( 'click', '.woocommerce-product-gallery__image a', function( e ) {
e.preventDefault();
});
// If flexslider is disabled, gallery images also need to trigger photoswipe on click.
if ( ! this.flexslider_enabled ) {
this.$target.on( 'click', '.woocommerce-product-gallery__image a', this.openPhotoswipe );
}
} else {
this.$target.on( 'click', '.woocommerce-product-gallery__image a', this.openPhotoswipe );
}
};
/**
* Reset slide position to 0.
*/
ProductGallery.prototype.onResetSlidePosition = function() {
this.$target.flexslider( 0 );
};
/**
* Get product gallery image items.
*/
ProductGallery.prototype.getGalleryItems = function() {
var $slides = this.$images,
items = [];
if ( $slides.length > 0 ) {
$slides.each( function( i, el ) {
var img = $( el ).find( 'img' );
if ( img.length ) {
var large_image_src = img.attr( 'data-large_image' ),
large_image_w = img.attr( 'data-large_image_width' ),
large_image_h = img.attr( 'data-large_image_height' ),
alt = img.attr( 'alt' ),
item = {
alt : alt,
src : large_image_src,
w : large_image_w,
h : large_image_h,
title: img.attr( 'data-caption' ) ? img.attr( 'data-caption' ) : img.attr( 'title' )
};
items.push( item );
}
} );
}
return items;
};
/**
* Open photoswipe modal.
*/
ProductGallery.prototype.openPhotoswipe = function( e ) {
e.preventDefault();
var pswpElement = $( '.pswp' )[0],
items = this.getGalleryItems(),
eventTarget = $( e.target ),
currentTarget = e.currentTarget,
self = this,
clicked;
if ( 0 < eventTarget.closest( '.woocommerce-product-gallery__trigger' ).length ) {
clicked = this.$target.find( '.flex-active-slide' );
} else {
clicked = eventTarget.closest( '.woocommerce-product-gallery__image' );
}
var options = $.extend( {
index: $( clicked ).index(),
addCaptionHTMLFn: function( item, captionEl ) {
if ( ! item.title ) {
captionEl.children[0].textContent = '';
return false;
}
captionEl.children[0].textContent = item.title;
return true;
},
timeToIdle: 0, // Ensure the gallery controls are always visible to avoid keyboard navigation issues.
}, wc_single_product_params.photoswipe_options );
// Initializes and opens PhotoSwipe.
var photoswipe = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options );
photoswipe.listen( 'afterInit', function() {
self.trapFocusPhotoswipe( true );
});
photoswipe.listen( 'close', function() {
self.trapFocusPhotoswipe( false );
currentTarget.focus();
});
photoswipe.init();
};
/**
* Control focus in photoswipe modal.
*
* @param {boolean} trapFocus - Whether to trap focus or not.
*/
ProductGallery.prototype.trapFocusPhotoswipe = function( trapFocus ) {
var pswp = document.querySelector( '.pswp' );
if ( ! pswp ) {
return;
}
if ( trapFocus ) {
pswp.addEventListener( 'keydown', this.handlePswpTrapFocus );
} else {
pswp.removeEventListener( 'keydown', this.handlePswpTrapFocus );
}
};
/**
* Handle keydown event in photoswipe modal.
*/
ProductGallery.prototype.handlePswpTrapFocus = function( e ) {
var allFocusablesEls = e.currentTarget.querySelectorAll( 'button:not([disabled])' );
var filteredFocusablesEls = Array.from( allFocusablesEls ).filter( function( btn ) {
return btn.style.display !== 'none' && window.getComputedStyle( btn ).display !== 'none';
} );
if ( 1 >= filteredFocusablesEls.length ) {
return;
}
var firstTabStop = filteredFocusablesEls[0];
var lastTabStop = filteredFocusablesEls[filteredFocusablesEls.length - 1];
if ( e.key === 'Tab' ) {
if ( e.shiftKey ) {
if ( document.activeElement === firstTabStop ) {
e.preventDefault();
lastTabStop.focus();
}
} else if ( document.activeElement === lastTabStop ) {
e.preventDefault();
firstTabStop.focus();
}
}
};
/**
* Function to call wc_product_gallery on jquery selector.
*/
$.fn.wc_product_gallery = function( args ) {
new ProductGallery( this, args || wc_single_product_params );
return this;
};
/*
* Initialize all galleries on page.
*/
$( '.woocommerce-product-gallery' ).each( function() {
$( this ).trigger( 'wc-product-gallery-before-init', [ this, wc_single_product_params ] );
productGalleryElement = $( this ).wc_product_gallery( wc_single_product_params );
$( this ).trigger( 'wc-product-gallery-after-init', [ this, wc_single_product_params ] );
} );
} );

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,117 @@
/*global wc_tokenization_form_params */
jQuery( function( $ ) {
/**
* WCTokenizationForm class.
*/
var TokenizationForm = function( $target ) {
this.$target = $target;
this.$formWrap = $target.closest( '.payment_box' );
// Params.
this.params = $.extend( {}, {
'is_registration_required': false,
'is_logged_in' : false
}, wc_tokenization_form_params );
// Bind functions to this.
this.onDisplay = this.onDisplay.bind( this );
this.hideForm = this.hideForm.bind( this );
this.showForm = this.showForm.bind( this );
this.showSaveNewCheckbox = this.showSaveNewCheckbox.bind( this );
this.hideSaveNewCheckbox = this.hideSaveNewCheckbox.bind( this );
// When a radio button is changed, make sure to show/hide our new CC info area.
this.$target.on(
'click change',
':input.woocommerce-SavedPaymentMethods-tokenInput',
{ tokenizationForm: this },
this.onTokenChange
);
// OR if create account is checked.
$( 'input#createaccount' ).on( 'change', { tokenizationForm: this }, this.onCreateAccountChange );
// First display.
this.onDisplay();
};
TokenizationForm.prototype.onDisplay = function() {
// Make sure a radio button is selected if there is no is_default for this payment method..
if ( 0 === $( ':input.woocommerce-SavedPaymentMethods-tokenInput:checked', this.$target ).length ) {
$( ':input.woocommerce-SavedPaymentMethods-tokenInput:last', this.$target ).prop( 'checked', true );
}
// Don't show the "use new" radio button if we only have one method..
if ( 0 === this.$target.data( 'count' ) ) {
$( '.woocommerce-SavedPaymentMethods-new', this.$target ).remove();
}
// Hide "save card" if "Create Account" is not checked and registration is not forced.
var hasCreateAccountCheckbox = 0 < $( 'input#createaccount' ).length,
createAccount = hasCreateAccountCheckbox && $( 'input#createaccount' ).is( ':checked' );
if ( createAccount || this.params.is_logged_in || this.params.is_registration_required ) {
this.showSaveNewCheckbox();
} else {
this.hideSaveNewCheckbox();
}
// Trigger change event
$( ':input.woocommerce-SavedPaymentMethods-tokenInput:checked', this.$target ).trigger( 'change' );
};
TokenizationForm.prototype.onTokenChange = function( event ) {
if ( 'new' === $( this ).val() ) {
event.data.tokenizationForm.showForm();
event.data.tokenizationForm.showSaveNewCheckbox();
} else {
event.data.tokenizationForm.hideForm();
event.data.tokenizationForm.hideSaveNewCheckbox();
}
};
TokenizationForm.prototype.onCreateAccountChange = function( event ) {
if ( $( this ).is( ':checked' ) ) {
event.data.tokenizationForm.showSaveNewCheckbox();
} else {
event.data.tokenizationForm.hideSaveNewCheckbox();
}
};
TokenizationForm.prototype.hideForm = function() {
$( '.wc-payment-form', this.$formWrap ).hide();
};
TokenizationForm.prototype.showForm = function() {
$( '.wc-payment-form', this.$formWrap ).show();
};
TokenizationForm.prototype.showSaveNewCheckbox = function() {
$( '.woocommerce-SavedPaymentMethods-saveNew', this.$formWrap ).show();
};
TokenizationForm.prototype.hideSaveNewCheckbox = function() {
$( '.woocommerce-SavedPaymentMethods-saveNew', this.$formWrap ).hide();
};
/**
* Function to call wc_product_gallery on jquery selector.
*/
$.fn.wc_tokenization_form = function( args ) {
new TokenizationForm( this, args );
return this;
};
/**
* Initialize.
*/
$( document.body ).on( 'updated_checkout wc-credit-card-form-init', function() {
// Loop over gateways with saved payment methods
var $saved_payment_methods = $( 'ul.woocommerce-SavedPaymentMethods' );
$saved_payment_methods.each( function() {
$( this ).wc_tokenization_form();
} );
} );
} );

View File

@@ -0,0 +1 @@
jQuery(function(e){var t=function(t){this.$target=t,this.$formWrap=t.closest(".payment_box"),this.params=e.extend({},{is_registration_required:!1,is_logged_in:!1},wc_tokenization_form_params),this.onDisplay=this.onDisplay.bind(this),this.hideForm=this.hideForm.bind(this),this.showForm=this.showForm.bind(this),this.showSaveNewCheckbox=this.showSaveNewCheckbox.bind(this),this.hideSaveNewCheckbox=this.hideSaveNewCheckbox.bind(this),this.$target.on("click change",":input.woocommerce-SavedPaymentMethods-tokenInput",{tokenizationForm:this},this.onTokenChange),e("input#createaccount").on("change",{tokenizationForm:this},this.onCreateAccountChange),this.onDisplay()};t.prototype.onDisplay=function(){0===e(":input.woocommerce-SavedPaymentMethods-tokenInput:checked",this.$target).length&&e(":input.woocommerce-SavedPaymentMethods-tokenInput:last",this.$target).prop("checked",!0),0===this.$target.data("count")&&e(".woocommerce-SavedPaymentMethods-new",this.$target).remove(),0<e("input#createaccount").length&&e("input#createaccount").is(":checked")||this.params.is_logged_in||this.params.is_registration_required?this.showSaveNewCheckbox():this.hideSaveNewCheckbox(),e(":input.woocommerce-SavedPaymentMethods-tokenInput:checked",this.$target).trigger("change")},t.prototype.onTokenChange=function(t){"new"===e(this).val()?(t.data.tokenizationForm.showForm(),t.data.tokenizationForm.showSaveNewCheckbox()):(t.data.tokenizationForm.hideForm(),t.data.tokenizationForm.hideSaveNewCheckbox())},t.prototype.onCreateAccountChange=function(t){e(this).is(":checked")?t.data.tokenizationForm.showSaveNewCheckbox():t.data.tokenizationForm.hideSaveNewCheckbox()},t.prototype.hideForm=function(){e(".wc-payment-form",this.$formWrap).hide()},t.prototype.showForm=function(){e(".wc-payment-form",this.$formWrap).show()},t.prototype.showSaveNewCheckbox=function(){e(".woocommerce-SavedPaymentMethods-saveNew",this.$formWrap).show()},t.prototype.hideSaveNewCheckbox=function(){e(".woocommerce-SavedPaymentMethods-saveNew",this.$formWrap).hide()},e.fn.wc_tokenization_form=function(e){return new t(this,e),this},e(document.body).on("updated_checkout wc-credit-card-form-init",function(){e("ul.woocommerce-SavedPaymentMethods").each(function(){e(this).wc_tokenization_form()})})});

View File

@@ -0,0 +1,203 @@
/**
* Common address autocomplete functionality shared between shortcode and blocks implementations.
* This module provides the core registration and provider management logic.
*/
( function () {
// Initialize the global wc.addressAutocomplete namespace
window.wc = window.wc || {};
window.wc.addressAutocomplete = window.wc.addressAutocomplete || {
providers: {},
activeProvider: { billing: null, shipping: null },
serverProviders: [], // Store parsed server providers
};
// Parse server providers configuration
// Try multiple possible param locations for compatibility
let serverProviders = [];
try {
let params = null;
// Check for common module params first
if ( window && window.wc_address_autocomplete_common_params ) {
params = window.wc_address_autocomplete_common_params;
}
// Fallback to regular params if common params not found
else if ( window && window.wc_address_autocomplete_params ) {
params = window.wc_address_autocomplete_params;
}
if ( params && params.address_providers ) {
const raw = params.address_providers;
if ( typeof raw === 'string' ) {
const parsed = JSON.parse( raw );
serverProviders = Array.isArray( parsed ) ? parsed : [];
} else if ( Array.isArray( raw ) ) {
serverProviders = raw;
}
}
} catch ( e ) {
console.error( 'Invalid address providers JSON:', e );
}
// Store server providers in the global namespace for external access
window.wc.addressAutocomplete.serverProviders = serverProviders;
/**
* Register an address autocomplete provider. This will be used by both shortcode and blocks implementations.
* @param {Object} provider The provider object
* @return {boolean} Whether the registration was successful
*/
function registerAddressAutocompleteProvider( provider ) {
try {
// Check required properties
if ( ! provider || typeof provider !== 'object' ) {
throw new Error( 'Address provider must be a valid object' );
}
if ( ! provider.id || typeof provider.id !== 'string' ) {
throw new Error( 'Address provider must have a valid ID' );
}
if ( typeof provider.canSearch !== 'function' ) {
throw new Error(
'Address provider must have a canSearch function'
);
}
if ( typeof provider.search !== 'function' ) {
throw new Error(
'Address provider must have a search function'
);
}
if ( typeof provider.select !== 'function' ) {
throw new Error(
'Address provider must have a select function'
);
}
const serverProviders =
window.wc.addressAutocomplete.serverProviders;
if ( ! Array.isArray( serverProviders ) ) {
throw new Error( 'Server providers configuration is invalid' );
}
var isRegistered = serverProviders.some( function (
serverProvider
) {
return (
serverProvider &&
typeof serverProvider === 'object' &&
typeof serverProvider.id === 'string' &&
serverProvider.id === provider.id
);
} );
if ( ! isRegistered ) {
throw new Error(
'Provider ' + provider.id + ' not registered on server'
);
}
// Check if a provider with the same ID already exists
if ( window.wc.addressAutocomplete.providers[ provider.id ] ) {
console.warn(
'Address provider with ID "' +
provider.id +
'" is already registered.'
);
return false;
}
// Freeze and add provider to registry.
Object.freeze( provider );
window.wc.addressAutocomplete.providers[ provider.id ] = provider;
// Check if window.wp.data and the checkout store is available, if so we're likely in a block context
if (
window.wp &&
window.wp.data &&
window.wp.data.dispatch &&
window.wc &&
window.wc.wcBlocksData &&
window.wc.wcBlocksData.checkoutStore
) {
// Dispatch an action to notify that a new provider has been registered
window.wp.data
.dispatch( window.wc.wcBlocksData.checkoutStore )
.addAddressAutocompleteProvider( provider.id );
}
return true;
} catch ( error ) {
console.error(
'Error registering address provider:',
error.message
);
return false;
}
}
// Export the registration function and server providers to the global namespace
window.wc.addressAutocomplete.registerAddressAutocompleteProvider =
registerAddressAutocompleteProvider;
/**
* Get server provider configuration by ID
* @param {string} providerId The provider ID
* @return {Object|null} The server provider configuration or null if not found
*/
window.wc.addressAutocomplete.getServerProvider = function ( providerId ) {
const serverProviders = window.wc.addressAutocomplete.serverProviders;
if ( ! Array.isArray( serverProviders ) ) {
return null;
}
return (
serverProviders.find( function ( provider ) {
return provider && provider.id === providerId;
} ) || null
);
};
/**
* Get all registered providers
* @return {Object} All registered providers
*/
window.wc.addressAutocomplete.getProviders = function () {
return window.wc.addressAutocomplete.providers;
};
/**
* Get active provider for a specific type
* @param {string} type The address type ('billing' or 'shipping')
* @return {Object|null} The active provider or null
*/
window.wc.addressAutocomplete.getActiveProvider = function ( type ) {
return window.wc.addressAutocomplete.activeProvider[ type ] || null;
};
/**
* Set active provider for a specific type
* @param {string} type The address type ('billing' or 'shipping')
* @param {Object|null} provider The provider to set as active, or null to clear
*/
window.wc.addressAutocomplete.setActiveProvider = function (
type,
provider
) {
window.wc.addressAutocomplete.activeProvider[ type ] = provider;
};
/**
* Check if address autocomplete is available for blocks
* @return {boolean} Whether blocks checkout is available
*/
window.wc.addressAutocomplete.isBlocksContext = function () {
return !! (
window.wc &&
window.wc.wcSettings &&
window.wc.wcSettings.allSettings &&
window.wc.wcSettings.allSettings.isCheckoutBlock
);
};
} )();

View File

@@ -0,0 +1 @@
!function(){window.wc=window.wc||{},window.wc.addressAutocomplete=window.wc.addressAutocomplete||{providers:{},activeProvider:{billing:null,shipping:null},serverProviders:[]};let e=[];try{let o=null;if(window&&window.wc_address_autocomplete_common_params?o=window.wc_address_autocomplete_common_params:window&&window.wc_address_autocomplete_params&&(o=window.wc_address_autocomplete_params),o&&o.address_providers){const r=o.address_providers;if("string"==typeof r){const o=JSON.parse(r);e=Array.isArray(o)?o:[]}else Array.isArray(r)&&(e=r)}}catch(r){console.error("Invalid address providers JSON:",r)}window.wc.addressAutocomplete.serverProviders=e,window.wc.addressAutocomplete.registerAddressAutocompleteProvider=function(e){try{if(!e||"object"!=typeof e)throw new Error("Address provider must be a valid object");if(!e.id||"string"!=typeof e.id)throw new Error("Address provider must have a valid ID");if("function"!=typeof e.canSearch)throw new Error("Address provider must have a canSearch function");if("function"!=typeof e.search)throw new Error("Address provider must have a search function");if("function"!=typeof e.select)throw new Error("Address provider must have a select function");const o=window.wc.addressAutocomplete.serverProviders;if(!Array.isArray(o))throw new Error("Server providers configuration is invalid");if(!o.some(function(r){return r&&"object"==typeof r&&"string"==typeof r.id&&r.id===e.id}))throw new Error("Provider "+e.id+" not registered on server");return window.wc.addressAutocomplete.providers[e.id]?(console.warn('Address provider with ID "'+e.id+'" is already registered.'),!1):(Object.freeze(e),window.wc.addressAutocomplete.providers[e.id]=e,window.wp&&window.wp.data&&window.wp.data.dispatch&&window.wc&&window.wc.wcBlocksData&&window.wc.wcBlocksData.checkoutStore&&window.wp.data.dispatch(window.wc.wcBlocksData.checkoutStore).addAddressAutocompleteProvider(e.id),!0)}catch(r){return console.error("Error registering address provider:",r.message),!1}},window.wc.addressAutocomplete.getServerProvider=function(e){const r=window.wc.addressAutocomplete.serverProviders;return Array.isArray(r)&&r.find(function(r){return r&&r.id===e})||null},window.wc.addressAutocomplete.getProviders=function(){return window.wc.addressAutocomplete.providers},window.wc.addressAutocomplete.getActiveProvider=function(e){return window.wc.addressAutocomplete.activeProvider[e]||null},window.wc.addressAutocomplete.setActiveProvider=function(e,r){window.wc.addressAutocomplete.activeProvider[e]=r},window.wc.addressAutocomplete.isBlocksContext=function(){return!!(window.wc&&window.wc.wcSettings&&window.wc.wcSettings.allSettings&&window.wc.wcSettings.allSettings.isCheckoutBlock)}}();

View File

@@ -0,0 +1,267 @@
/* global Cookies */
jQuery( function ( $ ) {
// Orderby
$( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function () {
$( this ).closest( 'form' ).trigger( 'submit' );
} );
// Target quantity inputs on product pages
$( 'input.qty:not(.product-quantity input.qty)' ).each( function () {
var min = parseFloat( $( this ).attr( 'min' ) );
if ( min >= 0 && parseFloat( $( this ).val() ) < min ) {
$( this ).val( min );
}
} );
var noticeID = $( '.woocommerce-store-notice' ).data( 'noticeId' ) || '',
cookieName = 'store_notice' + noticeID;
// Check the value of that cookie and show/hide the notice accordingly
if ( 'hidden' === Cookies.get( cookieName ) ) {
$( '.woocommerce-store-notice' ).hide();
} else {
$( '.woocommerce-store-notice' ).show();
/**
* After adding the role="button" attribute to the
* .woocommerce-store-notice__dismiss-link element,
* we need to add the keydown event listener to it.
*/
function store_notice_keydown_handler( event ) {
if ( ['Enter', ' '].includes( event.key ) ) {
event.preventDefault();
$( '.woocommerce-store-notice__dismiss-link' ).click();
}
}
// Set a cookie and hide the store notice when the dismiss button is clicked
function store_notice_click_handler( event ) {
Cookies.set( cookieName, 'hidden', { path: '/' } );
$( '.woocommerce-store-notice' ).hide();
event.preventDefault();
$( '.woocommerce-store-notice__dismiss-link' )
.off( 'click', store_notice_click_handler )
.off( 'keydown', store_notice_keydown_handler );
}
$( '.woocommerce-store-notice__dismiss-link' )
.on( 'click', store_notice_click_handler )
.on( 'keydown', store_notice_keydown_handler );
}
// Make form field descriptions toggle on focus.
if ( $( '.woocommerce-input-wrapper span.description' ).length ) {
$( document.body ).on( 'click', function () {
$( '.woocommerce-input-wrapper span.description:visible' )
.prop( 'aria-hidden', true )
.slideUp( 250 );
} );
}
$( '.woocommerce-input-wrapper' ).on( 'click', function ( event ) {
event.stopPropagation();
} );
$( '.woocommerce-input-wrapper :input' )
.on( 'keydown', function ( event ) {
var input = $( this ),
parent = input.parent(),
description = parent.find( 'span.description' );
if (
27 === event.which &&
description.length &&
description.is( ':visible' )
) {
description.prop( 'aria-hidden', true ).slideUp( 250 );
event.preventDefault();
return false;
}
} )
.on( 'click focus', function () {
var input = $( this ),
parent = input.parent(),
description = parent.find( 'span.description' );
parent.addClass( 'currentTarget' );
$(
'.woocommerce-input-wrapper:not(.currentTarget) span.description:visible'
)
.prop( 'aria-hidden', true )
.slideUp( 250 );
if ( description.length && description.is( ':hidden' ) ) {
description.prop( 'aria-hidden', false ).slideDown( 250 );
}
parent.removeClass( 'currentTarget' );
} );
// Common scroll to element code.
$.scroll_to_notices = function ( scrollElement ) {
if ( scrollElement.length ) {
$( 'html, body' ).animate(
{
scrollTop: scrollElement.offset().top - 100,
},
1000
);
}
};
// Show password visibility hover icon on woocommerce forms
$( '.woocommerce form .woocommerce-Input[type="password"]' ).wrap(
'<span class="password-input"></span>'
);
// Add 'password-input' class to the password wrapper in checkout page.
$( '.woocommerce form input' )
.filter( ':password' )
.parent( 'span' )
.addClass( 'password-input' );
$( '.password-input' ).each( function () {
const describedBy = $( this ).find( 'input' ).attr( 'id' );
$( this ).append(
'<button type="button" class="show-password-input" aria-label="' +
woocommerce_params.i18n_password_show +
'" aria-describedBy="' +
describedBy +
'"></button>'
);
} );
$( '.show-password-input' ).on( 'click', function ( event ) {
event.preventDefault();
if ( $( this ).hasClass( 'display-password' ) ) {
$( this ).removeClass( 'display-password' );
$( this ).attr(
'aria-label',
woocommerce_params.i18n_password_show
);
} else {
$( this ).addClass( 'display-password' );
$( this ).attr(
'aria-label',
woocommerce_params.i18n_password_hide
);
}
if ( $( this ).hasClass( 'display-password' ) ) {
$( this )
.siblings( [ 'input[type="password"]' ] )
.prop( 'type', 'text' );
} else {
$( this )
.siblings( 'input[type="text"]' )
.prop( 'type', 'password' );
}
$( this ).siblings( 'input' ).focus();
} );
$( 'a.coming-soon-footer-banner-dismiss' ).on( 'click', function ( e ) {
var target = $( e.target );
$.ajax( {
type: 'post',
url: target.data( 'rest-url' ),
data: {
woocommerce_meta: {
coming_soon_banner_dismissed: 'yes',
},
},
beforeSend: function ( xhr ) {
xhr.setRequestHeader(
'X-WP-Nonce',
target.data( 'rest-nonce' )
);
},
complete: function () {
$( '#coming-soon-footer-banner' ).hide();
},
} );
} );
// If the "Enable AJAX add to cart buttons on archives" setting is disabled
// the add-to-cart.js file won't be loaded, so we need to add the event listener here.
if ( typeof wc_add_to_cart_params === 'undefined') {
$( document.body ).on( 'keydown', '.remove_from_cart_button', on_keydown_remove_from_cart );
}
$( document.body ).on( 'item_removed_from_classic_cart updated_wc_div', focus_populate_live_region );
} );
/**
* Handle when pressing the Space key on the remove item link.
* This is necessary because the link has the role="button" attribute
* and needs to act like a button.
*/
function on_keydown_remove_from_cart( event ) {
if ( event.key === ' ' ) {
event.preventDefault();
event.currentTarget.click();
}
}
/**
* Focus on the first notice element on the page.
*
* Populated live regions don't always are announced by screen readers.
* This function focus on the first notice message with the role="alert"
* attribute to make sure it's announced.
*/
function focus_populate_live_region() {
var noticeClasses = [
'woocommerce-message',
'woocommerce-error',
'wc-block-components-notice-banner',
];
var noticeSelectors = noticeClasses
.map( function ( className ) {
return '.' + className + '[role="alert"]';
} )
.join( ', ' );
var noticeElements = document.querySelectorAll( noticeSelectors );
if ( noticeElements.length === 0 ) {
return;
}
var firstNotice = noticeElements[ 0 ];
firstNotice.setAttribute( 'tabindex', '-1' );
// Wait for the element to get the tabindex attribute so it can be focused.
var delayFocusNoticeId = setTimeout( function () {
firstNotice.focus();
clearTimeout( delayFocusNoticeId );
}, 500 );
}
/**
* Refresh the sorted by live region.
*/
function refresh_sorted_by_live_region() {
var sorted_by_live_region = document.querySelector(
'.woocommerce-result-count'
);
if ( sorted_by_live_region ) {
var text = sorted_by_live_region.innerHTML;
sorted_by_live_region.setAttribute('aria-hidden', 'true');
var sorted_by_live_region_id = setTimeout( function () {
sorted_by_live_region.setAttribute('aria-hidden', 'false');
sorted_by_live_region.innerHTML = '';
sorted_by_live_region.innerHTML = text;
clearTimeout( sorted_by_live_region_id );
}, 2000 );
}
}
function on_document_ready() {
focus_populate_live_region();
refresh_sorted_by_live_region();
}
document.addEventListener( 'DOMContentLoaded', on_document_ready );

View File

@@ -0,0 +1 @@
function on_keydown_remove_from_cart(e){" "===e.key&&(e.preventDefault(),e.currentTarget.click())}function focus_populate_live_region(){var e=["woocommerce-message","woocommerce-error","wc-block-components-notice-banner"].map(function(e){return"."+e+'[role="alert"]'}).join(", "),o=document.querySelectorAll(e);if(0!==o.length){var t=o[0];t.setAttribute("tabindex","-1");var n=setTimeout(function(){t.focus(),clearTimeout(n)},500)}}function refresh_sorted_by_live_region(){var e=document.querySelector(".woocommerce-result-count");if(e){var o=e.innerHTML;e.setAttribute("aria-hidden","true");var t=setTimeout(function(){e.setAttribute("aria-hidden","false"),e.innerHTML="",e.innerHTML=o,clearTimeout(t)},2e3)}}function on_document_ready(){focus_populate_live_region(),refresh_sorted_by_live_region()}jQuery(function(e){e(".woocommerce-ordering").on("change","select.orderby",function(){e(this).closest("form").trigger("submit")}),e("input.qty:not(.product-quantity input.qty)").each(function(){var o=parseFloat(e(this).attr("min"));o>=0&&parseFloat(e(this).val())<o&&e(this).val(o)});var o="store_notice"+(e(".woocommerce-store-notice").data("noticeId")||"");if("hidden"===Cookies.get(o))e(".woocommerce-store-notice").hide();else{function t(o){["Enter"," "].includes(o.key)&&(o.preventDefault(),e(".woocommerce-store-notice__dismiss-link").click())}e(".woocommerce-store-notice").show(),e(".woocommerce-store-notice__dismiss-link").on("click",function n(r){Cookies.set(o,"hidden",{path:"/"}),e(".woocommerce-store-notice").hide(),r.preventDefault(),e(".woocommerce-store-notice__dismiss-link").off("click",n).off("keydown",t)}).on("keydown",t)}e(".woocommerce-input-wrapper span.description").length&&e(document.body).on("click",function(){e(".woocommerce-input-wrapper span.description:visible").prop("aria-hidden",!0).slideUp(250)}),e(".woocommerce-input-wrapper").on("click",function(e){e.stopPropagation()}),e(".woocommerce-input-wrapper :input").on("keydown",function(o){var t=e(this).parent().find("span.description");if(27===o.which&&t.length&&t.is(":visible"))return t.prop("aria-hidden",!0).slideUp(250),o.preventDefault(),!1}).on("click focus",function(){var o=e(this).parent(),t=o.find("span.description");o.addClass("currentTarget"),e(".woocommerce-input-wrapper:not(.currentTarget) span.description:visible").prop("aria-hidden",!0).slideUp(250),t.length&&t.is(":hidden")&&t.prop("aria-hidden",!1).slideDown(250),o.removeClass("currentTarget")}),e.scroll_to_notices=function(o){o.length&&e("html, body").animate({scrollTop:o.offset().top-100},1e3)},e('.woocommerce form .woocommerce-Input[type="password"]').wrap('<span class="password-input"></span>'),e(".woocommerce form input").filter(":password").parent("span").addClass("password-input"),e(".password-input").each(function(){const o=e(this).find("input").attr("id");e(this).append('<button type="button" class="show-password-input" aria-label="'+woocommerce_params.i18n_password_show+'" aria-describedBy="'+o+'"></button>')}),e(".show-password-input").on("click",function(o){o.preventDefault(),e(this).hasClass("display-password")?(e(this).removeClass("display-password"),e(this).attr("aria-label",woocommerce_params.i18n_password_show)):(e(this).addClass("display-password"),e(this).attr("aria-label",woocommerce_params.i18n_password_hide)),e(this).hasClass("display-password")?e(this).siblings(['input[type="password"]']).prop("type","text"):e(this).siblings('input[type="text"]').prop("type","password"),e(this).siblings("input").focus()}),e("a.coming-soon-footer-banner-dismiss").on("click",function(o){var t=e(o.target);e.ajax({type:"post",url:t.data("rest-url"),data:{woocommerce_meta:{coming_soon_banner_dismissed:"yes"}},beforeSend:function(e){e.setRequestHeader("X-WP-Nonce",t.data("rest-nonce"))},complete:function(){e("#coming-soon-footer-banner").hide()}})}),"undefined"==typeof wc_add_to_cart_params&&e(document.body).on("keydown",".remove_from_cart_button",on_keydown_remove_from_cart),e(document.body).on("item_removed_from_classic_cart updated_wc_div",focus_populate_live_region)}),document.addEventListener("DOMContentLoaded",on_document_ready);

View File

@@ -0,0 +1,19 @@
( function () {
'use strict';
// Set order attribution on consent change.
document.addEventListener( 'wp_listen_for_consent_change', ( e ) => {
const changedConsentCategory = e.detail;
for ( const key in changedConsentCategory ) {
if ( changedConsentCategory.hasOwnProperty( key ) && key === window.wc_order_attribution.params.consentCategory ) {
window.wc_order_attribution.setOrderTracking( changedConsentCategory[ key ] === 'allow' );
}
}
} );
// Set order attribution as soon as consent type is defined.
document.addEventListener( 'wp_consent_type_defined', () => {
window.wc_order_attribution.setOrderTracking( wp_has_consent( window.wc_order_attribution.params.consentCategory ) );
} );
}() );

View File

@@ -0,0 +1 @@
!function(){"use strict";document.addEventListener("wp_listen_for_consent_change",t=>{const n=t.detail;for(const t in n)n.hasOwnProperty(t)&&t===window.wc_order_attribution.params.consentCategory&&window.wc_order_attribution.setOrderTracking("allow"===n[t])}),document.addEventListener("wp_consent_type_defined",()=>{window.wc_order_attribution.setOrderTracking(wp_has_consent(window.wc_order_attribution.params.consentCategory))})}();