PageSourceSearch

https://www.maartenonline.nl/app/plugins/duracelltomi-google-tag-manager/js/gtm4wp-woocommerce.js?ver=1.22.5

js maartenonline.nl collected 2026-10-02 11:50:12 UTC 23,918 bytes, 707 lines download raw bytes

1let gtm4wp_last_selected_product_variation;
2window.gtm4wp_view_item_fired_during_pageload = false;
3
4window.gtm4wp_checkout_step_fired = []; // step 1 will be the billing section which is reported during pageload, no need to handle here
5
6window.gtm4wp_first_container_id = "";
7
8function gtm4wp_woocommerce_console_log( message ) {
9	if ( typeof console !== 'undefined' && console.log ) {
10		if ( typeof message === 'object' ) {
11			message = JSON.stringify( message );
12		}
13
14		const d = new Date();
15		const time = d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + '.' + d.getMilliseconds();
16		message = time + ' - ' + message;
17		
18		console.log( '[GTM4WP debug]: ' + message );
19	}
20}
21
22function gtm4wp_woocommerce_handle_cart_qty_change() {
23	document.querySelectorAll( '.product-quantity input.qty' ).forEach(function( qty_el ) {
24		const original_value = qty_el.defaultValue;
25
26		let current_value  = parseInt( qty_el.value );
27		if ( isNaN( current_value ) ) {
28			current_value = original_value;
29		}
30
31		// is quantity changed changed?
32		if ( original_value != current_value ) {
33			const cart_item_temp = qty_el.closest( '.cart_item' );
34			const productdata_el = cart_item_temp && cart_item_temp.querySelector( '.remove' );
35			if ( !productdata_el ) {
36				return;
37			}
38
39			const productdata = gtm4wp_read_json_from_node( productdata_el, "gtm4wp_product_data");
40			if ( !productdata ) {
41				return true;
42			}
43
44			// does the quantity increase?
45			if ( original_value < current_value ) {
46				// yes => handle add to cart event
47				productdata.quantity = current_value - original_value;
48				productdata.price    = productdata.price;
49
50				gtm4wp_push_ecommerce( 'add_to_cart', [ productdata ], {
51					'currency': gtm4wp_currency, // ga4 version
52					'value': productdata.price * productdata.quantity
53				});
54			} else {
55				// no => handle remove from cart event
56				productdata.quantity = original_value - current_value;
57				productdata.price    = productdata.price;
58
59				gtm4wp_push_ecommerce( 'remove_from_cart', [ productdata ], {
60					'currency': gtm4wp_currency,
61					'value': productdata.price * productdata.quantity
62				});
63			}
64		} // end if qty changed
65	}); // end each qty field
66} // end gtm4wp_woocommerce_handle_cart_qty_change()
67
68function gtm4wp_woocommerce_handle_payment_method_change() {
69	// do not report checkout step if already reported
70	if ( gtm4wp_checkout_step_fired.indexOf( 'payment_method' ) > -1 ) {
71		return;
72	}
73
74	// do not fire event during page load
75	if ( 'complete' != document.readyState ) {
76		return;
77	}
78
79	let payment_type = '(payment type not found)';
80	let payment_el = document.querySelector( '.payment_methods input:checked' );
81	if ( !payment_el ) {
82		payment_el = document.querySelector( 'input[name^=payment_method]' ); // select the first input element
83	}
84	if ( payment_el ) {
85		payment_type = payment_el.value;
86	}
87
88	gtm4wp_push_ecommerce( 'add_payment_info', window.gtm4wp_checkout_products, {
89		'currency': gtm4wp_currency,
90		'payment_type': payment_type,
91		'value': window.gtm4wp_checkout_value
92	});
93
94	gtm4wp_checkout_step_fired.push( 'payment_method' );
95} // end gtm4wp_woocommerce_handle_payment_method_change()
96
97function gtm4wp_woocommerce_handle_shipping_method_change() {
98	// do not report checkout step if already reported
99	if ( gtm4wp_checkout_step_fired.indexOf( 'shipping_method' ) > -1 ) {
100		return;
101	}
102
103	// do not fire event during page load
104	if ( 'complete' != document.readyState ) {
105		return;
106	}
107
108	let shipping_tier = '(shipping tier not found)';
109	let shipping_el = document.querySelector( 'input[name^=shipping_method]:checked' );
110	if ( !shipping_el ) {
111		shipping_el = document.querySelector( 'input[name^=shipping_method]' ); // select the first input element
112	}
113	if ( shipping_el ) {
114		shipping_tier = shipping_el.value;
115	}
116
117	gtm4wp_push_ecommerce( 'add_shipping_info', window.gtm4wp_checkout_products, {
118		'currency': gtm4wp_currency,
119		'shipping_tier': shipping_tier,
120		'value': window.gtm4wp_checkout_value
121	});
122
123	gtm4wp_checkout_step_fired.push( 'shipping_method' );
124}
125
126function gtm4wp_woocommerce_process_pages() {
127	// loop through WC blocks to set proper listname and position parameters
128	const gtm4wp_product_block_names = {
129		'wp-block-handpicked-products': {
130			'displayname': 'Handpicked Products',
131			'counter': 1
132		},
133		'wp-block-product-best-sellers': {
134			'displayname': 'Best Selling Products',
135			'counter': 1
136		},
137		'wp-block-product-category': {
138			'displayname': 'Product Category List',
139			'counter': 1
140		},
141		'wp-block-product-new': {
142			'displayname': 'New Products',
143			'counter': 1
144		},
145		'wp-block-product-on-sale': {
146			'displayname': 'Sale Products',
147			'counter': 1
148		},
149		'wp-block-products-by-attribute': {
150			'displayname': 'Products By Attribute',
151			'counter': 1
152		},
153		'wp-block-product-tag': {
154			'displayname': 'Products By Tag',
155			'counter': 1
156		},
157		'wp-block-product-top-rated': {
158			'displayname': 'Top Rated Products',
159			'counter': 1
160		},
161	}
162
163	document.querySelectorAll( '.wc-block-grid .wc-block-grid__product' ).forEach( function( product_grid_item ) {
164
165		const product_grid_container = product_grid_item.closest( '.wc-block-grid' );
166		const product_data_el = product_grid_item.querySelector( '.gtm4wp_productdata' );
167
168		if ( product_grid_container && product_data_el ) {
169
170			const product_grid_container_classes = product_grid_container.classList;
171
172			if ( product_grid_container_classes ) {
173
174				for(let i in gtm4wp_product_block_names) {
175					if ( product_grid_container_classes.contains( i ) ) {
176						gtm4wp_update_json_in_node( product_data_el, 'gtm4wp_product_data', 'item_list_name', gtm4wp_product_block_names[i].displayname );
177						gtm4wp_update_json_in_node( product_data_el, 'gtm4wp_product_data', 'index', gtm4wp_product_block_names[i].counter );
178
179						gtm4wp_product_block_names[i].counter++;
180					}
181				}
182			}
183		}
184
185	});
186
187	// track impressions of products in product lists
188	if ( document.querySelectorAll( '.gtm4wp_productdata,.widget-product-item' ).length > 0 ) {
189		let products = [];
190
191		document.querySelectorAll( '.gtm4wp_productdata,.widget-product-item' ).forEach( function( productdata_el ) {
192			const productdata = gtm4wp_read_json_from_node( productdata_el, "gtm4wp_product_data");
193			if ( !productdata ) {
194				return true;
195			}
196
197			products.push(productdata);
198		});
199
200		if ( gtm4wp_product_per_impression > 0 ) {
201			// Need to split the product submissions up into chunks in order to avoid the GA 16kb hit size limit
202			let chunk;
203
204			while ( products.length ) {
205				chunk = products.splice( 0, gtm4wp_product_per_impression );
206
207				gtm4wp_push_ecommerce( 'view_item_list', chunk, {
208					'currency': gtm4wp_currency
209				});
210			}
211		} else {
212			// push everything in one event and let's hope the best :-)
213			gtm4wp_push_ecommerce( 'view_item_list', products, {
214				'currency': gtm4wp_currency
215			});
216		}
217	}
218
219	// manage events related to user clicks
220	document.addEventListener( 'click', function( e ) {
221		let event_target_element = e.target;
222
223		if ( !event_target_element ) {
224			// for some reason event target is not specificed
225			return true;
226		}
227
228		// track add to cart events for simple products in product lists
229		if ( event_target_element.closest( '.add_to_cart_button:not(.product_type_variable, .product_type_grouped, .product_type_bundle_input_required, .single_add_to_cart_button)' ) ) {
230			const product_el = event_target_element.closest( '.product,.wc-block-grid__product' );
231
232			const productdata_el = product_el && product_el.querySelector( '.gtm4wp_productdata' );
233			if ( !productdata_el ) {
234				return true;
235			}
236
237			const productdata  = gtm4wp_read_json_from_node( productdata_el, "gtm4wp_product_data" );
238			if ( !productdata ) {
239				return true;
240			}
241
242			if ( "variable" === productdata.product_type || "grouped" === productdata.product_type ) {
243				return true;
244			}
245
246			if ( productdata.productlink ) {
247				delete productdata.productlink;
248			}
249			delete productdata.product_type;
250			productdata.quantity = 1;
251
252			gtm4wp_push_ecommerce( 'add_to_cart', [ productdata ], {
253				'currency': gtm4wp_currency,
254				'value': productdata.price
255			});
256		}
257
258		// track add to cart events for products on product detail pages
259		const add_to_cart_button = event_target_element.closest( '.single_add_to_cart_button' );
260		if ( add_to_cart_button ) {
261			if (add_to_cart_button.classList.contains( 'disabled' ) || add_to_cart_button.disabled) {
262				// do not track clicks on disabled buttons
263				return true;
264			}
265
266			const product_form = event_target_element.closest( 'form.cart' );
267			if ( !product_form ) {
268				return true;
269			}
270
271			let product_variant_id = product_form.querySelectorAll( '[name=variation_id]' );
272			let product_is_grouped = product_form.classList && product_form.classList.contains( 'grouped_form' );
273
274			if ( product_variant_id.length > 0 ) {
275				if ( gtm4wp_last_selected_product_variation ) {
276					const qty_el = product_form.querySelector( '[name=quantity]' );
277					gtm4wp_last_selected_product_variation.quantity = (qty_el && qty_el.value) || 1;
278
279					gtm4wp_push_ecommerce( 'add_to_cart', [ gtm4wp_last_selected_product_variation ], {
280						'currency': gtm4wp_currency,
281						'value': (gtm4wp_last_selected_product_variation.price * gtm4wp_last_selected_product_variation.quantity).toFixed(2)
282					});
283				}
284			} else if ( product_is_grouped ) {
285				const products_in_group = document.querySelectorAll( '.grouped_form .gtm4wp_productdata' );
286				let products = [];
287				let sum_value = 0;
288
289				products_in_group.forEach( function( product_data_el ) {
290					const productdata = gtm4wp_read_json_from_node(product_data_el, 'gtm4wp_product_data', ['productlink']);
291					if ( !productdata ) {
292						return true;
293					}
294
295					let product_qty = 0;
296					const product_qty_input = document.querySelectorAll( 'input[name=quantity\\[' + productdata.internal_id + '\\]]' );
297					if ( product_qty_input.length > 0 ) {
298						product_qty = (product_qty_input[0] && product_qty_input[0].value) || 1;
299					} else {
300						return true;
301					}
302
303					if ( 0 == product_qty ) {
304						return true;
305					}
306					productdata.quantity = product_qty;
307
308					delete productdata.internal_id;
309
310					products.push( productdata );
311					sum_value += productdata.price * productdata.quantity;
312				});
313
314				if ( 0 == products.length ) {
315					return true;
316				}
317
318				gtm4wp_push_ecommerce( 'add_to_cart', products, {
319					'currency': gtm4wp_currency,
320					'value': sum_value.toFixed(2)
321				});
322			} else {
323				const product_data_el = product_form.querySelector( '[name=gtm4wp_product_data]' );
324				if ( !product_data_el ) {
325					return true;
326				}
327
328				let productdata = gtm4wp_read_from_json( product_data_el.value );
329				productdata.quantity = product_form.querySelector( '[name=quantity]' ) && product_form.querySelector( '[name=quantity]' ).value;
330				if ( isNaN( productdata.quantity ) ) {
331					productdata.quantity = 1;
332				}
333
334				gtm4wp_push_ecommerce( 'add_to_cart', [ productdata ], {
335					'currency': gtm4wp_currency,
336					'value': productdata.price * productdata.quantity
337				});
338			}
339		}
340
341		// track remove links in mini cart widget and on cart page
342		if ( event_target_element.closest( '.mini_cart_item a.remove,.product-remove a.remove' ) ) {
343			const click_el = event_target_element;
344
345			const productdata_el = click_el && click_el.closest( '.mini_cart_item a.remove,.product-remove a.remove' );
346			if ( !productdata_el ) {
347				return true;
348			}
349
350			const productdata = gtm4wp_read_json_from_node( productdata_el, "gtm4wp_product_data");
351			if ( !productdata ) {
352				return true;
353			}
354
355			let qty = 0;
356			const cart_item_el = productdata_el.closest( '.cart_item' );
357			let qty_element = cart_item_el && cart_item_el.querySelectorAll( '.product-quantity input.qty' );
358			if ( !qty_element || ( 0 === qty_element.length ) ) {
359				const mini_cart_item_el = productdata_el.closest( '.mini_cart_item' );
360				qty_element = mini_cart_item_el && mini_cart_item_el.querySelectorAll( '.quantity' );
361				if ( qty_element && ( qty_element.length > 0 ) ) {
362					qty = parseInt( qty_element[0].textContent );
363
364					if ( Number.isNaN( qty ) ) {
365						qty = 0;
366					}
367				}
368			} else {
369				qty = qty_element[0].value;
370			}
371
372			if ( 0 === qty ) {
373				return true;
374			}
375
376			productdata.quantity = qty;
377
378			gtm4wp_push_ecommerce( 'remove_from_cart', [ productdata ], {
379				'currency': gtm4wp_currency,
380				'value': productdata.price * productdata.quantity
381			});
382		}
383
384		// track clicks in product lists
385		const matching_link_element = event_target_element.closest(
386			'.products li:not(.product-category) a:not(.add_to_cart_button):not(.quick-view-button),'
387			+'.wc-block-grid__products li:not(.product-category) a:not(.add_to_cart_button):not(.quick-view-button),'
388			+'.products>div:not(.product-category) a:not(.add_to_cart_button):not(.quick-view-button),'
389			+'.widget-product-item,'
390			+'.woocommerce-grouped-product-list-item__label a'
391		);
392		if ( matching_link_element) {
393			// Do nothing if GTM is blocked for some reason.
394			// At this point, we only know that Google Tag has been loaded.
395			// If only a Google Tag is loaded, it also populates the google_tag_manager object.
396			if ( 'undefined' == typeof google_tag_manager ) {
397				return true;
398			}
399
400			const event_target_element = e.target;
401
402			// try to find product data as it is in different places depending on the clicked element.
403			let temp_selector = event_target_element.closest( '.product,.wc-block-grid__product' );
404			let productdata_el;
405
406			if ( temp_selector ) {
407				productdata_el = temp_selector.querySelector( '.gtm4wp_productdata' );
408
409			} else {
410				temp_selector = event_target_element.closest( '.products li' );
411
412				if ( temp_selector ) {
413					productdata_el = temp_selector.querySelector( '.gtm4wp_productdata' );
414
415				} else {
416					temp_selector = event_target_element.closest( '.products>div' );
417
418					if ( temp_selector ) {
419						productdata_el = temp_selector.querySelector( '.gtm4wp_productdata' );
420
421					} else {
422						temp_selector = event_target_element.closest( '.woocommerce-grouped-product-list-item__label' );
423
424						if ( temp_selector ) {
425							productdata_el = temp_selector.querySelector( '.gtm4wp_productdata' );
426						} else {
427							productdata_el = event_target_element;
428						}
429					}
430				}
431			}
432
433			// Extract product data from the found DOM node.
434			const productdata = gtm4wp_read_json_from_node( productdata_el, 'gtm4wp_product_data', ['internal_id'] );
435			if ( !productdata ) {
436				return true;
437			}
438
439			// Only act on links pointing to the product detail page
440			if ( productdata.productlink != matching_link_element.getAttribute( 'href' ) ) {
441				return true;
442			}
443
444			// Look at first GTM container ID in case there are multiple GTM containers live on the page
445			// since eventCallback is called on every container and we only need this executed once in this case.
446			for (let i in window.google_tag_manager) {
447				if (i.substring(0,4).toLowerCase() == "gtm-") {
448					window.gtm4wp_first_container_id = i;
449					break;
450				}
451			}
452
453			// Do not do anything if GTM was not loaded.
454			// The google_tag_manager object is still available if only Google Tag is loaded.
455			if ( "" === window.gtm4wp_first_container_id ) {
456				return true;
457			}
458
459			let datalayer_timeout = 2000;
460			if (typeof window.gtm4wp_datalayer_max_timeout !== 'undefined') {
461				datalayer_timeout = window.gtm4wp_datalayer_max_timeout;
462			}
463
464			if (datalayer_timeout > 0) {
465				const ctrl_key_pressed = e.ctrlKey || e.metaKey;
466				const target_new_tab = ( '_blank' === matching_link_element.target );
467
468				// save this info to prevent redirection if another plugin already prevented to event for some reason
469				let event_already_prevented = e.defaultPrevented;
470				if ( !event_already_prevented ) {
471					e.preventDefault();
472				}
473
474				if ( ctrl_key_pressed || target_new_tab ) {
475					// we need to open the new tab/page here so that popup blocker of the browser doesn't block our code
476					window.productpage_window = window.open( 'about:blank', '_blank' );
477				}
478
479				const productlink_to_redirect = productdata.productlink;
480				delete productdata.productlink;
481				// fire ga4 version
482				gtm4wp_push_ecommerce( 'select_item', [ productdata ], {
483					'currency': gtm4wp_currency
484				}, function( container_id ) {
485					if ( "undefined" !== typeof container_id && window.gtm4wp_first_container_id != container_id) {
486						// only call this for the first loaded container
487						return true;
488					}
489
490					if ( !event_already_prevented ) {
491						if ( ( target_new_tab || ctrl_key_pressed ) && productpage_window ) {
492							productpage_window.location.href = productlink_to_redirect;
493						} else {
494							document.location.href = productlink_to_redirect;
495						}
496					}
497				},
498				datalayer_timeout);
499			} else {
500				delete productdata.productlink;
501				gtm4wp_push_ecommerce( 'select_item', [ productdata ], {
502					'currency': gtm4wp_currency
503				});
504			}
505		}
506	}, { capture: true } );
507
508	// track variable products on their detail pages
509	// currently, we need to use jQuery here since WooCommerce is firing this event using jQuery
510	// that can not be catched using vanilla JS
511	jQuery( document ).on( 'found_variation', function( event, product_variation ) {
512		if ( "undefined" == typeof product_variation ) {
513			// some ither plugins trigger this event without variation data
514			return;
515		}
516
517		if ( (document.readyState === "interactive") && gtm4wp_view_item_fired_during_pageload ) {
518			// some custom attribute rendering plugins fire this event multiple times during page load
519			return;
520		}
521
522		// event target is the <form> element of the add to cart button.
523		const product_form    = event.target;
524		if ( !product_form ) {
525			return true;
526		}
527
528		const product_data_el = product_form.querySelector( '[name=gtm4wp_product_data]' );
529		if ( !product_data_el ) {
530			return true;
531		}
532
533		let current_product_detail_data;
534		try {
535			current_product_detail_data = JSON.parse( product_data_el.value );
536		} catch(e) {
537			console && console.error && console.error( e.message );
538			return true;
539		}
540
541		current_product_detail_data.price = gtm4wp_make_sure_is_float( current_product_detail_data.price );
542
543		current_product_detail_data.item_group_id = current_product_detail_data.id;
544		current_product_detail_data.id = product_variation.variation_id;
545		current_product_detail_data.item_id = product_variation.variation_id;
546		current_product_detail_data.sku = product_variation.sku;
547		if ( gtm4wp_use_sku_instead && product_variation.sku && ('' !== product_variation.sku) ) {
548			current_product_detail_data.id = product_variation.sku;
549			current_product_detail_data.item_id = product_variation.sku;
550		}
551		current_product_detail_data.price = gtm4wp_make_sure_is_float( product_variation.display_price );
552
553		let product_variation_attribute_values = [];
554		for( let attrib_key in product_variation.attributes ) {
555			product_variation_attribute_values.push( product_variation.attributes[ attrib_key ] );
556		}
557		current_product_detail_data.item_variant = product_variation_attribute_values.join(',');
558		gtm4wp_last_selected_product_variation = current_product_detail_data;
559
560		delete current_product_detail_data.internal_id;
561
562		// fire ga4 version
563		gtm4wp_push_ecommerce( 'view_item', [ current_product_detail_data ], {
564			'currency': gtm4wp_currency,
565			'value': current_product_detail_data.price
566		});
567
568		if ( document.readyState === "interactive" ) {
569			gtm4wp_view_item_fired_during_pageload = true;
570		}
571	});
572	jQuery( '.variations select' ).trigger( 'change' );
573
574	// initiate codes in WooCommere Quick View
575	// currently, we need to use jQuery here since WooCommerce Quick View is showing the popup using
576	// jQuery AJAX calls that can not be catched using vanilla JS
577	jQuery( document ).ajaxSuccess( function( event, xhr, settings ) {
578		if(typeof settings !== 'undefined') {
579			if (settings.url.indexOf( 'wc-api=WC_Quick_View' ) > -1 ) {
580				setTimeout( function() {
581
582					const dl_data = document.querySelector('#gtm4wp_quickview_data');
583					if ( dl_data && dl_data.dataset && dl_data.dataset.gtm4wp_datalayer ) {
584						try {
585							const dl_data_obj = JSON.parse( dl_data.dataset.gtm4wp_datalayer );
586							if ( dl_data_obj && window.dataLayer ) {
587								window.dataLayer.push(dl_data_obj);
588							}
589						} catch(e) {
590							console && console.error && console.error( e.message );
591						}
592					}
593
594				}, 500);
595			}
596		}
597	});
598
599	let gtm4wp_is_cart     = false;
600	let gtm4wp_is_checkout = false;
601
602	const doc_body = document.querySelector( 'body' );
603	if ( doc_body ) {
604		gtm4wp_is_cart     = doc_body.classList && doc_body.classList.contains( 'woocommerce-cart' );
605		gtm4wp_is_checkout = doc_body.classList && doc_body.classList.contains( 'woocommerce-checkout' );
606	}
607
608	// codes for ecommerce events on cart page
609	if ( gtm4wp_is_cart ) {
610		document.addEventListener( 'click', function( e ) {
611			let event_target_element = e.target;
612
613			if ( !event_target_element ) {
614				// for some reason event target is not specificed
615				return true;
616			}
617
618			if ( !event_target_element.closest( '[name=update_cart]' ) ) {
619				return true;
620			}
621
622			gtm4wp_woocommerce_handle_cart_qty_change();
623		});
624
625		document.addEventListener( 'keypress', function( e ) {
626			let event_target_element = e.target;
627
628			if ( !event_target_element ) {
629				// for some reason event target is not specificed
630				return true;
631			}
632
633			if ( !event_target_element.closest( '.woocommerce-cart-form input[type=number]' ) ) {
634				return true;
635			}
636
637			gtm4wp_woocommerce_handle_cart_qty_change();
638		});
639	}
640
641	// codes for ecommerce events on checkout page
642	if ( gtm4wp_is_checkout ) {
643		window.gtm4wp_checkout_value        = window.gtm4wp_checkout_value || 0;
644		window.gtm4wp_checkout_products     = window.gtm4wp_checkout_products || [];
645		window.gtm4wp_checkout_products_ga4 = window.gtm4wp_checkout_products_ga4 || [];
646
647		document.addEventListener( 'change', function( e ) {
648			let event_target_element = e.target;
649
650			if ( !event_target_element ) {
651				// for some reason event target is not specificed
652				return true;
653			}
654
655			if ( !event_target_element.closest( 'input[name^=shipping_method]' ) ) {
656				return true;
657			}
658
659			gtm4wp_woocommerce_handle_shipping_method_change();
660		});
661
662		document.addEventListener( 'change', function( e ) {
663			let event_target_element = e.target;
664
665			if ( !event_target_element ) {
666				// for some reason event target is not specificed
667				return true;
668			}
669
670			if ( !event_target_element.closest( 'input[name=payment_method]' ) ) {
671				return true;
672			}
673
674			gtm4wp_woocommerce_handle_payment_method_change();
675		});
676
677		// We need to use jQuery where since the checkout_place_order event is only triggered using jQuery
678		const checkout_form = jQuery('form.checkout');
679		checkout_form.on('checkout_place_order', function () {
680			if ( gtm4wp_checkout_step_fired.indexOf( 'shipping_method' ) == -1 ) {
681				// shipping methods are not visible if only one is available
682				// and if the user has already a pre-selected method, no click event will fire to report the checkout step
683				gtm4wp_woocommerce_handle_shipping_method_change();
684			}
685
686			if ( gtm4wp_checkout_step_fired.indexOf( 'payment_method' ) == -1 ) {
687				// if the user has already a pre-selected method, no click event will fire to report the checkout step
688				gtm4wp_woocommerce_handle_payment_method_change();
689			}
690		});
691	}
692}
693
694function gtm4wp_woocommerce_page_loading_completed() {
695	document.removeEventListener( "DOMContentLoaded", gtm4wp_woocommerce_page_loading_completed );
696	window.removeEventListener( "load", gtm4wp_woocommerce_page_loading_completed );
697	gtm4wp_woocommerce_process_pages();
698}
699
700// code and idea borrowed from jQuery:
701// https://github.com/jquery/jquery/blob/main/src/core/ready.js
702if ( document.readyState !== "loading" ) {
703	window.setTimeout( gtm4wp_woocommerce_process_pages );
704} else {
705	document.addEventListener( "DOMContentLoaded", gtm4wp_woocommerce_page_loading_completed );
706	window.addEventListener( "load", gtm4wp_woocommerce_page_loading_completed );
707}

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.