PageSourceSearch

https://menstherapyhub.co.uk/wp-content/plugins/woocommerce/assets/js/frontend/order-attribution.js?ver=11.1.0

js menstherapyhub.co.uk collected 2026-09-29 00:56:14 UTC 7,180 bytes, 228 lines download raw bytes

1( function ( wc_order_attribution ) {
2	'use strict';
3	// Cache params reference for shorter reusability.
4	const params = wc_order_attribution.params;
5
6	// Helper functions.
7	const $ = document.querySelector.bind( document );
8	const propertyAccessor = ( obj, path ) => path.split( '.' ).reduce( ( acc, part ) => acc && acc[ part ], obj );
9	const returnNull = () => null;
10	const stringifyFalsyInputValue = ( value ) => value === null || value === undefined ? '' : value;
11
12	// Hardcode Checkout store key (`wc.wcBlocksData.CHECKOUT_STORE_KEY`), as we no longer have `wc-blocks-checkout` as a dependency.
13	const CHECKOUT_STORE_KEY = 'wc/store/checkout';
14
15	/**
16	 * Get the order attribution data.
17	 *
18	 * Returns object full of `null`s if tracking is disabled or if sourcebuster.js is blocked.
19	 *
20	 * @returns {Object} Schema compatible object.
21	 */
22	wc_order_attribution.getAttributionData = function() {
23		const accessor = params.allowTracking && isSbjsAvailable() ? propertyAccessor : returnNull;
24		const getter  = isSbjsAvailable() ? sbjs.get : {};
25		const entries = Object.entries( wc_order_attribution.fields )
26			.map( ( [ key, property ] ) => [ key, accessor( getter, property ) ] );
27		return Object.fromEntries( entries );
28	}
29
30	/**
31	 * Remove duplicate `<wc-order-attribution-inputs>` elements, leaving only the first one,
32	 * to prevent sending the same data multiple times.
33	 */
34	function removeDuplicateInputGroups() {
35		document.querySelectorAll( 'wc-order-attribution-inputs' ).forEach( ( group, index ) => {
36			if ( index > 0 ) {
37				group.remove();
38			}
39		} );
40	}
41
42	/**
43	 * Update `wc_order_attribution` input elements' values.
44	 *
45	 * @param {Object} values Object containing field values.
46	 */
47	function updateFormValues( values ) {
48		// Remove duplicates before updating to ensure only one set of elements exists.
49		removeDuplicateInputGroups();
50		// Update `<wc-order-attribution-inputs>` elements if any exist.
51		for( const element of document.querySelectorAll( 'wc-order-attribution-inputs' ) ) {
52			element.values = values;
53		}
54
55	};
56
57	/**
58	 * Update Checkout extension data.
59	 *
60	 * @param {Object} values Object containing field values.
61	 */
62	function updateCheckoutBlockData( values ) {
63		// Update Checkout block data if available.
64		if (
65			window.wp &&
66			window.wp.data &&
67			window.wp.data.dispatch &&
68			window.wc &&
69			window.wc.wcBlocksData
70		) {
71			window.wp.data
72				.dispatch( window.wc.wcBlocksData.CHECKOUT_STORE_KEY )
73				.setExtensionData(
74					'woocommerce/order-attribution',
75					values,
76					true
77				);
78		}
79	}
80
81	/**
82	 * Determine whether sourcebuster.js is available.
83	 *
84	 * @returns {boolean} Whether sourcebuster.js is available.
85	 */
86	function isSbjsAvailable() {
87		return typeof sbjs !== 'undefined';
88	}
89
90	/**
91	 * Initialize sourcebuster & set data, or clear cookies & data.
92	 *
93	 * @param {boolean} allow Whether to allow tracking or disable it.
94	 */
95	wc_order_attribution.setOrderTracking = function( allow ) {
96		params.allowTracking = allow;
97		if ( ! allow ) {
98			// Reset cookies, and clear form data.
99			removeTrackingCookies();
100		} else if ( ! isSbjsAvailable() ) {
101			return; // Do nothing, as sourcebuster.js is not loaded.
102		} else {
103			// If not done yet, initialize sourcebuster.js which populates `sbjs.get` object.
104			sbjs.init( {
105				lifetime: Number( params.lifetime ),
106				session_length: Number( params.session ),
107				base64: Boolean( params.base64 ),
108				timezone_offset: '0', // utc
109			} );
110		}
111		const values = wc_order_attribution.getAttributionData();
112		updateFormValues( values );
113		updateCheckoutBlockData( values );
114	}
115
116	/**
117	 * Remove sourcebuster.js cookies.
118	 * To be called whenever tracking is disabled or consent is revoked.
119	 */
120	function removeTrackingCookies() {
121		const domain = window.location.hostname;
122		const sbCookies = [
123			'sbjs_current',
124			'sbjs_current_add',
125			'sbjs_first',
126			'sbjs_first_add',
127			'sbjs_session',
128			'sbjs_udata',
129			'sbjs_migrations',
130			'sbjs_promo'
131		];
132
133		// Remove cookies
134		sbCookies.forEach( ( name ) => {
135			document.cookie = `${name}=; path=/; max-age=-999; domain=.${domain};`;
136		} );
137	}
138
139	// Run init.
140	wc_order_attribution.setOrderTracking( params.allowTracking );
141
142	// Work around the lack of explicit script dependency for the checkout block.
143	// Conditionally, wait for and use 'wp-data' & 'wc-blocks-checkout.
144
145	// Wait for (async) block checkout initialization and set source values once loaded.
146	function eventuallyInitializeCheckoutBlock() {
147		if (
148			window.wp && window.wp.data && typeof window.wp.data.subscribe === 'function'
149		) {
150			// Update checkout block data once more if the checkout store was loaded after this script.
151			const unsubscribe = window.wp.data.subscribe( function () {
152				unsubscribe();
153				updateCheckoutBlockData( wc_order_attribution.getAttributionData() );
154			}, CHECKOUT_STORE_KEY );
155		}
156	};
157	// Wait for DOMContentLoaded to make sure wp.data is in place, if applicable for the page.
158	if (document.readyState === "loading") {
159		document.addEventListener("DOMContentLoaded", eventuallyInitializeCheckoutBlock);
160	} else {
161		eventuallyInitializeCheckoutBlock();
162	}
163
164	/**
165	 * Define an element to contribute order attribute values to the enclosing form.
166	 * To be used with the classic checkout.
167	 */
168	window.customElements.define( 'wc-order-attribution-inputs', class extends HTMLElement {
169		// Our bundler version does not support private class members, so we use a convention of `_` prefix.
170		// #values
171		// #fieldNames
172		constructor(){
173			super();
174			// Cache fieldNames available at the construction time, to avoid malformed behavior if they change in runtime.
175			this._fieldNames = Object.keys( wc_order_attribution.fields );
176			// Allow values to be lazily set before CE upgrade.
177			if ( this.hasOwnProperty( '_values' ) ) {
178				let values = this.values;
179				// Restore the setter.
180				delete this.values;
181				this.values = values || {};
182			}
183		}
184		/**
185		 * Stamp input elements to the element's light DOM.
186		 *
187		 * We could use `.elementInternals.setFromValue` and avoid sprouting `<input>` elements,
188		 * but it's not yet supported in Safari.
189		 */
190		connectedCallback() {
191			this.innerHTML = '';
192			const inputs = new DocumentFragment();
193			for( const fieldName of this._fieldNames ) {
194				const input = document.createElement( 'input' );
195				input.type = 'hidden';
196				input.name = `${params.prefix}${fieldName}`;
197				input.value = stringifyFalsyInputValue( ( this.values && this.values[ fieldName ] ) || '' );
198				inputs.appendChild( input );
199			}
200			this.appendChild( inputs );
201		}
202
203		/**
204		 * Update form values.
205		 */
206		set values( values ) {
207			this._values = values;
208			if( this.isConnected ) {
209				for( const fieldName of this._fieldNames ) {
210					const input = this.querySelector( `input[name="${params.prefix}${fieldName}"]` );
211					if( input ) {
212						input.value = stringifyFalsyInputValue( this.values[ fieldName ] );
213					} else {
214						console.warn(
215							`Field "${fieldName}" not found. ` +
216							`Most likely, the '<wc-order-attribution-inputs>' element was manipulated.`
217						);
218					}
219				}
220			}
221		}
222		get values() {
223			return this._values;
224		}
225	} );
226
227
228}( window.wc_order_attribution ) );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.