woocommerce/plugins/woocommerce-blocks/assets/js/base/utils/legacy-events.js

86 lines
2.7 KiB
JavaScript

const Event = window.Event || null;
/** @typedef {import('window').HTMLNode} HTMLNode */
/**
* Wrapper function to dispatch an event so it's compatible with IE11.
*
* @param {string} name Name of the event to dispatch.
* @param {Object} [options] Some additional options to modify
* the event.
* @param {boolean} [options.bubbles] Whether the event bubbles.
* @param {boolean} [options.cancelable] Whether the event is cancelable.
* @param {HTMLNode} [options.element] Element that dispatches the event. By
* default, the body.
*/
export const dispatchEvent = (
name,
{ bubbles = false, cancelable = false, element }
) => {
if ( ! element ) {
element = document.body;
}
// In IE, Event is an object and can't be instantiated with `new Event()`.
if ( typeof Event === 'function' ) {
const event = new Event( name, {
bubbles,
cancelable,
} );
element.dispatchEvent( event );
} else {
const event = document.createEvent( 'Event' );
event.initEvent( name, bubbles, cancelable );
element.dispatchEvent( event );
}
};
let fragmentRequestTimeoutId;
// This is a hack to trigger cart updates till we migrate to block based cart
// that relies on the store, see
// https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/1247
export const triggerFragmentRefresh = () => {
if ( fragmentRequestTimeoutId ) {
clearTimeout( fragmentRequestTimeoutId );
}
fragmentRequestTimeoutId = setTimeout( () => {
dispatchEvent( 'wc_fragment_refresh', {
bubbles: true,
cancelable: true,
} );
}, 50 );
};
/**
* Function that listens to a jQuery event and dispatches a native JS event.
* Useful to convert WC Core events into events that can be read by blocks.
*
* @param {string} jQueryEventName Name of the jQuery event to listen to.
* @param {string} nativeEventName Name of the native event to dispatch.
* @param {boolean} bubbles Whether the event bubbles.
* @param {boolean} cancelable Whether the event is cancelable.
*
* @return {Function} Function to remove the jQuery event handler. Ideally it
* should be used when the component is unmounted.
*/
export const translateJQueryEventToNative = (
jQueryEventName,
nativeEventName,
bubbles = false,
cancelable = false
) => {
// @ts-ignore -- jQuery is window global
if ( typeof jQuery !== 'function' ) {
return () => void null;
}
const eventDispatcher = () => {
dispatchEvent( nativeEventName, { bubbles, cancelable } );
};
// @ts-ignore -- jQuery is window global
jQuery( document ).on( jQueryEventName, eventDispatcher );
// @ts-ignore -- jQuery is window global
return () => jQuery( document ).off( jQueryEventName, eventDispatcher );
};