PageSourceSearch

https://www.sauton.it/wp-content/plugins/gtm-server-side/assets/js/javascript.js?ver=2.2.0

js sauton.it collected 2026-10-09 05:19:29 UTC 11,652 bytes, 515 lines download raw bytes

1/**
2 * Front-end js file.
3 *
4 * @package GTM_Server_Side
5 */
6
7jQuery( document ).ready(
8	function () {
9		jQuery( document ).on(
10			'click',
11			'body.woocommerce-cart [name=update_cart]',
12			function () {
13				pluginGtmServerSide.changeCartQty();
14			}
15		);
16
17		jQuery( document ).on(
18			'keypress',
19			'body.woocommerce-cart .woocommerce-cart-form input[type=number]',
20			function () {
21				pluginGtmServerSide.changeCartQty();
22			}
23		);
24
25		jQuery( document ).on(
26			'click',
27			'.add_to_cart_button:not(.product_type_variable, .product_type_grouped, .single_add_to_cart_button)',
28			function ( e ) {
29				var el = e.target;
30				if ( ! el.dataset ) {
31					return;
32				}
33
34				if ( ! el.dataset.gtm_item_id ) {
35					return;
36				}
37
38				let gtmData    = pluginGtmServerSide.getGtmItemData( el.dataset );
39				let customData = pluginGtmServerSide.getCustomItemData( el.dataset );
40
41				pluginGtmServerSide.pushAddToCart( gtmData );
42				pluginGtmServerSide.pushSelectItem( gtmData, customData );
43			}
44		);
45
46		jQuery( document ).on(
47			'click',
48			'.wc-block-grid__product .add_to_cart_button:not(.product_type_variable, .product_type_grouped, .single_add_to_cart_button)',
49			function ( e ) {
50				var $el = jQuery( this ).closest( '.wc-block-grid__product' );
51				if ( ! $el.length ) {
52					return;
53				}
54
55				if ( ! $el.data( 'gtm_item_id' ) ) {
56					return;
57				}
58
59				let gtmData    = pluginGtmServerSide.getGtmItemData( $el.data() );
60				let customData = pluginGtmServerSide.getCustomItemData( $el.data() );
61
62				pluginGtmServerSide.pushAddToCart( gtmData );
63				pluginGtmServerSide.pushSelectItem( gtmData, customData );
64			}
65		);
66
67		jQuery( document ).on(
68			'click',
69			'.single_add_to_cart_button:not(.disabled)',
70			function ( e ) {
71				var $elForm = jQuery( this ).closest( 'form.cart' );
72				if ( ! $elForm.length ) {
73					return true;
74				}
75
76				if ( $elForm.find( '[name=variation_id]' ).length > 0 ) {
77					pluginGtmServerSide.pushVariationProduct( $elForm );
78					return;
79				}
80
81				if ( $elForm.hasClass( 'grouped_form' ) ) {
82					pluginGtmServerSide.pushGroupProduct( $elForm );
83					return;
84				}
85
86				pluginGtmServerSide.pushSimpleProduct( $elForm );
87			}
88		);
89
90		/**
91		 * Delete from minicart
92		 */
93		jQuery( document ).on(
94			'removed_from_cart',
95			function ( e, fragments, cart_hash, $thisbutton ) {
96				if ( ! $thisbutton.length ) {
97					return;
98				}
99
100				if ( ! $thisbutton.data( 'gtm_item_id' ) ) {
101					return;
102				}
103
104				pluginGtmServerSide.removeFromCart(
105					pluginGtmServerSide.getGtmItemData( $thisbutton.data() )
106				);
107			}
108		);
109
110		/**
111		 * Delete from page: /cart
112		 */
113		jQuery( document ).on(
114			'click',
115			'.woocommerce-cart-form .product-remove > a',
116			function ( e ) {
117				var $el = jQuery( e.currentTarget );
118
119				if ( ! $el.data( 'gtm_item_id' ) ) {
120					return;
121				}
122
123				pluginGtmServerSide.removeFromCart(
124					pluginGtmServerSide.getGtmItemData( $el.data() )
125				);
126			}
127		);
128	}
129);
130
131var pluginGtmServerSide = {
132	pushSimpleProduct: function ( $elForm ) {
133		var item = this.convertInputsToObject(
134			$elForm.find( '[name^=gtm_]' )
135		);
136		item     = this.getGtmItemData( item );
137
138		var $elQty = $elForm.find( '[name=quantity]' );
139		if ( $elQty.length ) {
140			item.quantity = $elQty.val();
141		}
142
143		this.pushAddToCart( item );
144	},
145
146	pushVariationProduct: function ( $elForm ) {
147		var item = this.convertInputsToObject(
148			$elForm.find( '[name^=gtm_]' )
149		);
150		item     = this.getGtmItemData( item );
151
152		var $elQty = $elForm.find( '[name=quantity]' );
153		if ( $elQty.length ) {
154			item.quantity = $elQty.val();
155		}
156
157		var variations = [];
158		$elForm.find( '[name^=attribute_] option:selected' ).each(
159			function () {
160				variations.push( jQuery( this ).text() );
161			}
162		);
163
164		if ( variations.length ) {
165			item.item_variant = variations.join( ',' );
166		}
167
168		this.pushAddToCart( item );
169	},
170
171	pushGroupProduct: function ( $elForm ) {
172		var items = [];
173		$elForm.find( '[name^=quantity\\[]' ).each(
174			function () {
175				if ( ! jQuery( this ).val() ) {
176					return;
177				}
178
179				var $elTd = jQuery( this ).closest( 'td' );
180				if ( ! $elTd.length ) {
181					return;
182				}
183
184				var item = {
185					quantity: jQuery( this ).val(),
186				};
187				$elTd.find( '[name^=gtm_]' ).each(
188					function () {
189						item[ jQuery( this ).data( 'name' ) ] = jQuery( this ).val();
190					}
191				);
192				items.push( item );
193			}
194		);
195		this.pushAddToCart( items );
196	},
197
198	/**
199	 * Remove from cart
200	 *
201	 * @param object item
202	 */
203	removeFromCart: function ( item ) {
204		item.quantity = item.quantity || 1;
205		var eventData = {
206			'event': this.getDataLayerEventName( 'remove_from_cart' ),
207			'ecommerce': {
208				'currency': varGtmServerSide.currency,
209				'items': [
210					item,
211				],
212			},
213		};
214
215		if ( varGtmServerSide.user_data ) {
216			eventData.user_data = {};
217			for ( var key in varGtmServerSide.user_data  ) {
218				eventData.user_data[ key ] = varGtmServerSide.user_data[ key ];
219			}
220		}
221
222		if ( 'yes' === varGtmServerSide.is_custom_event_name ) {
223			this._pushWithStateCartData( eventData );
224
225			return;
226		}
227
228		dataLayer.push( { ecommerce: null } );
229		dataLayer.push( eventData );
230	},
231
232	/**
233	 * Change product quantity in cart
234	 */
235	changeCartQty: function () {
236		var $this = this;
237
238		document.querySelectorAll( '.product-quantity input.qty' ).forEach(
239			function ( el ) {
240				var originalValue = el.defaultValue;
241
242				var currentValue = parseInt( el.value );
243				if ( isNaN( currentValue ) ) {
244					currentValue = originalValue;
245				}
246
247				if ( originalValue != currentValue ) {
248					var elCartItem = el.closest( '.cart_item' );
249					var elDataset  = elCartItem && elCartItem.querySelector( '.remove' );
250					if ( ! elDataset ) {
251						return;
252					}
253
254					if ( originalValue < currentValue ) {
255						var item         = $this.getGtmItemData( elDataset.dataset );
256						item['quantity'] = currentValue - originalValue;
257
258						$this.pushAddToCart( item );
259					}
260				}
261			}
262		);
263	},
264
265	/**
266	 * Return gtm custom data.
267	 *
268	 * @param object items List items.
269	 * @returns object
270	 */
271	getGtmItemData: function ( items ) {
272		return this._getItemData( items, 'gtm_' );
273	},
274
275	/**
276	 * Return gtm custom data.
277	 *
278	 * @param object items List items.
279	 * @returns object
280	 */
281	getCustomItemData: function ( items ) {
282		return this._getItemData( items, 'custom_gtm_' );
283	},
284
285	/**
286	 * Return item data.
287	 *
288	 * @param object items List items.
289	 * @returns object
290	 */
291	_getItemData: function ( items, prefix ) {
292		var result = {};
293		for ( var key in items ) {
294			if ( 0 !== key.indexOf( prefix ) ) {
295				continue;
296			}
297
298			var itemKey       = key.replace( prefix, '' )
299			result[ itemKey ] = items[ key ];
300		}
301		return result;
302	},
303
304	/**
305	 * Convert input elements to object.
306	 *
307	 * @param object $els Elements.
308	 * @returns object
309	 */
310	convertInputsToObject( $els ) {
311		var data = {};
312		if ( ! $els.length ) {
313			return data;
314		}
315
316		$els.each(
317			function () {
318				data[ jQuery( this ).attr( 'name' ) ] = jQuery( this ).val();
319			}
320		);
321		return data;
322	},
323
324	/**
325	 * Filter item price.
326	 *
327	 * @param object item List items.
328	 * @returns object
329	 */
330	filterItemPrice: function ( item ) {
331		if ( typeof item.price == 'string' ) {
332			item.price = parseFloat( item.price );
333			if ( isNaN( item.price ) ) {
334				item.price = 0;
335			}
336		} else if ( typeof item.price != 'number' ) {
337			item.price = 0;
338		}
339		item.price = item.price.toFixed( 2 );
340
341		return item;
342	},
343
344	/**
345	 * Push add_to_cart to dataLayer.
346	 *
347	 * @param mixed item List items.
348	 */
349	pushAddToCart: function ( item ) {
350		this._pushToDataLayer( item, 'add_to_cart', 'product' )
351	},
352
353	/**
354	 * Push add_to_cart to dataLayer.
355	 *
356	 * @param object item List items.
357	 * @param object custom Custom data.
358	 */
359	pushSelectItem: function ( item, custom ) {
360		if ( custom?.pagetype ) { // phpcs:ignore WordPress.WhiteSpace.OperatorSpacing.NoSpaceBefore, WordPress.WhiteSpace.OperatorSpacing.NoSpaceAfter
361			this._pushToDataLayer(
362				item,
363				'select_item',
364				custom.pagetype,
365				{
366					collection_id:  custom?.collection_id,  // phpcs:ignore WordPress.WhiteSpace.OperatorSpacing.NoSpaceBefore, WordPress.WhiteSpace.OperatorSpacing.NoSpaceAfter
367					item_list_name: custom?.item_list_name, // phpcs:ignore WordPress.WhiteSpace.OperatorSpacing.NoSpaceBefore, WordPress.WhiteSpace.OperatorSpacing.NoSpaceAfter
368				}
369			)
370		}
371	},
372
373	/**
374	 * Push to dataLayer.
375	 *
376	 * @param object originalItem List items.
377	 * @param string event Event name.
378	 * @param string pagetype Page type name.
379	 * @param object customEcommerce Ecommerce data.
380	 */
381	_pushToDataLayer: function ( originalItem, event, pagetype, customEcommerce = {} ) {
382		item = Object.assign( {}, originalItem );
383		if ( item.item_id ) {
384			item = [ item ];
385		}
386
387		var items = [];
388		var value = 0;
389		var index = 1;
390		for ( var item_loop of item ) {
391			item_loop.index    = index++;
392			item_loop.quantity = item_loop.quantity ? parseInt( item_loop.quantity, 10 ) : 1;
393			item_loop          = this.filterItemPrice( item_loop );
394			value              = parseFloat( value + ( item_loop.price * item_loop.quantity ) );
395			items.push( item_loop );
396		}
397
398		let eventDataEcommerce = {
399			'currency': varGtmServerSide.currency,
400			'value': value.toFixed( 2 ),
401			'items': items,
402		}
403
404		var eventData = {
405			'event':          this.getDataLayerEventName( event ),
406			'ecomm_pagetype': pagetype,
407			'ecommerce': Object.assign( {}, eventDataEcommerce, customEcommerce ),
408		};
409		if ( varGtmServerSide.user_data ) {
410			eventData.user_data = {};
411			for ( var key in varGtmServerSide.user_data  ) {
412				eventData.user_data[ key ] = varGtmServerSide.user_data[ key ];
413			}
414		}
415
416		if ( 'add_to_cart' === event && 'yes' === varGtmServerSide.is_custom_event_name ) {
417			this._pushWithStateCartData( eventData );
418
419			return;
420		}
421
422		dataLayer.push( { ecommerce: null } );
423		dataLayer.push( eventData );
424	},
425
426	/**
427	 * Return data layer event name.
428	 *
429	 * @param  string $event_name Event name.
430	 * @return string
431	 */
432	getDataLayerEventName: function( event_name ) {
433		if ( 'yes' === varGtmServerSide.is_custom_event_name ) {
434			return event_name + varGtmServerSide.DATA_LAYER_CUSTOM_EVENT_NAME;
435		}
436		return event_name;
437	},
438
439	/**
440	 * Internal helper: actually performs the AJAX request and pushes to the dataLayer.
441	 *
442	 * @param {object} eventData eventData object.
443	 * @return {void}
444	 */
445	_sendStateCartDataAjax: function( eventData ) {
446		jQuery.post(
447			varGtmServerSide.ajax,
448			{
449				action: 'gtm_server_side_state_cart_data',
450				security: varGtmServerSide.security,
451			},
452			function ( response ) {
453				if ( ! response || ! response.success ) {
454					dataLayer.push( { ecommerce: null } );
455					dataLayer.push( eventData );
456
457					return false;
458				}
459
460				eventData['cart_state'] = response.data;
461
462				dataLayer.push( { ecommerce: null } );
463				dataLayer.push( eventData );
464			}
465		);
466	},
467
468	/**
469	 * Push dataLayer with state cart data
470	 *
471	 * @param {object} eventData Event data object.
472	 * @return {void}
473	 */
474	_pushWithStateCartData: function( eventData ) {
475		let self  = this;
476		let fired = false;
477
478		var handler = function( event, xhr, settings ) {
479			if ( fired ) {
480				return;
481			}
482
483			if ( ! settings || ! settings.url ) {
484				return;
485			}
486
487			let url = settings.url;
488
489			if (
490				url.indexOf( 'wc-ajax=add_to_cart' ) !== -1 ||
491				url.indexOf( 'wc-ajax=remove_from_cart' ) !== -1
492			) {
493				fired = true;
494
495				jQuery( document ).off( 'ajaxComplete', handler );
496
497				self._sendStateCartDataAjax( eventData );
498			}
499		};
500
501		jQuery( document ).on( 'ajaxComplete', handler );
502
503		setTimeout(
504			function() {
505				if ( fired ) {
506					return;
507				}
508
509				jQuery( document ).off( 'ajaxComplete', handler );
510				self._sendStateCartDataAjax( eventData );
511			},
512			1500
513		);
514	}
515};

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.