PageSourceSearch

https://www.metacenterchicago.com/wp-content/plugins/yith-woocomme…/unminified/jquery.yith-wcwl.js?ver=4.18.1

js metacenterchicago.com collected 2026-09-28 10:11:28 UTC 48,133 bytes, 1,845 lines download raw bytes

1/**
2 * Main YITH WooCommerce Wishlist JS
3 *
4 * @author YITH <[email protected]>
5 * @package YITH WooCommerce Wishlist
6 * @version 3.0.0
7 */
8
9/* globals yith_wcwl_l10n, wc_add_to_cart_params, yith_wccl_general */
10
11jQuery( function ( $ ) {
12
13	/* === MAIN INIT === */
14
15	$( document ).on( 'yith_wcwl_init', function () {
16		var t = $( this ),
17			cart_redirect_after_add = (typeof (wc_add_to_cart_params) !== 'undefined' && wc_add_to_cart_params !== null) ? wc_add_to_cart_params.cart_redirect_after_add : '';
18
19		t.on( 'click', '.add_to_wishlist', function ( ev ) {
20			var t = $( this ),
21				product_id = t.attr( 'data-product-id' ),
22				el_wrap = $( '.add-to-wishlist-' + product_id ),
23				filtered_data = null,
24				data = {
25					action: yith_wcwl_l10n.actions.add_to_wishlist_action,
26					nonce: yith_wcwl_l10n.nonce.add_to_wishlist_nonce,
27					context: 'frontend',
28					add_to_wishlist: product_id,
29					product_type: t.data( 'product-type' ),
30					wishlist_id: t.data( 'wishlist-id' ),
31					fragments: retrieve_fragments( product_id )
32				};
33
34			// allow third party code to filter data
35			if ( filtered_data = $( document ).triggerHandler( 'yith_wcwl_add_to_wishlist_data', [ t, data ] ) ) {
36				data = filtered_data;
37			}
38
39			ev.preventDefault();
40
41			jQuery( document.body ).trigger( 'adding_to_wishlist' );
42
43			if ( yith_wcwl_l10n.multi_wishlist && yith_wcwl_l10n.modal_enable ) {
44				var wishlist_popup_container = t.parents( '.yith-wcwl-popup-footer' ).prev( '.yith-wcwl-popup-content' ),
45					wishlist_popup_select = wishlist_popup_container.find( '.wishlist-select' ),
46					wishlist_popup_name = wishlist_popup_container.find( '.wishlist-name' ),
47					wishlist_popup_visibility = wishlist_popup_container.find( '.wishlist-visibility' ).filter( ':checked' );
48
49				data.wishlist_id = wishlist_popup_select.is( ':visible' ) ? wishlist_popup_select.val() : 'new';
50				data.wishlist_name = wishlist_popup_name.val();
51				data.wishlist_visibility = wishlist_popup_visibility.val();
52
53				if ( 'new' === data.wishlist_id && ! data.wishlist_name ) {
54					wishlist_popup_name.closest( 'p' ).addClass( 'woocommerce-invalid' );
55					return false;
56				} else {
57					wishlist_popup_name.closest( 'p' ).removeClass( 'woocommerce-invalid' );
58				}
59			}
60
61			if ( ! is_cookie_enabled() ) {
62				window.alert( yith_wcwl_l10n.labels.cookie_disabled );
63				return;
64			}
65
66			$.ajax( {
67				type: 'POST',
68				url: yith_wcwl_l10n.ajax_url,
69				data: data,
70				dataType: 'json',
71				beforeSend: function () {
72					block( t );
73				},
74				complete: function () {
75					unblock( t );
76				},
77				success: function ( response ) {
78					var response_result = response.result,
79						response_message = response.message;
80
81					if ( yith_wcwl_l10n.multi_wishlist && yith_wcwl_l10n.modal_enable ) {
82						// close PrettyPhoto popup
83						close_pretty_photo( response_message, response_result );
84
85						// update options for all wishlist selects
86						if ( typeof (response.user_wishlists) !== 'undefined' ) {
87							update_wishlists( response.user_wishlists );
88						}
89					} else {
90						print_message( response_message );
91					}
92
93					if ( response_result === 'true' || response_result === 'exists' ) {
94						if ( typeof response.fragments !== 'undefined' ) {
95							replace_fragments( response.fragments );
96						}
97
98						if ( ! yith_wcwl_l10n.multi_wishlist || yith_wcwl_l10n.hide_add_button ) {
99							el_wrap.find( '.yith-wcwl-add-button' ).remove();
100						}
101
102						el_wrap.addClass( 'exists' );
103					}
104
105					init_handling_after_ajax();
106
107					$( 'body' ).trigger( 'added_to_wishlist', [ t, el_wrap ] );
108				}
109
110			} );
111
112			return false;
113		} );
114
115		t.on( 'click', '.wishlist_table .remove_from_wishlist', function ( ev ) {
116			var t = $( this );
117
118			ev.preventDefault();
119
120			remove_item_from_wishlist( t );
121
122			return false;
123		} );
124
125		t.on( 'adding_to_cart', 'body', function ( ev, button, data ) {
126			if ( typeof button !== 'undefined' && typeof data !== 'undefined' && button.closest( '.wishlist_table' ).length ) {
127				data.remove_from_wishlist_after_add_to_cart = button.closest( '[data-row-id]' ).data( 'row-id' );
128				data.wishlist_id = button.closest( '.wishlist_table' ).data( 'id' );
129				typeof wc_add_to_cart_params !== 'undefined' && (wc_add_to_cart_params.cart_redirect_after_add = yith_wcwl_l10n.redirect_to_cart);
130				typeof yith_wccl_general !== 'undefined' && (yith_wccl_general.cart_redirect = isTrue( yith_wcwl_l10n.redirect_to_cart ));
131			}
132		} );
133
134		t.on( 'added_to_cart', 'body', function ( ev, fragments, carthash, button ) {
135			if ( typeof button !== 'undefined' && button.closest( '.wishlist_table' ).length ) {
136				typeof wc_add_to_cart_params !== 'undefined' && (wc_add_to_cart_params.cart_redirect_after_add = cart_redirect_after_add);
137				typeof yith_wccl_general !== 'undefined' && (yith_wccl_general.cart_redirect = isTrue( cart_redirect_after_add ));
138
139				var tr = button.closest( '[data-row-id]' ),
140					table = tr.closest( '.wishlist-fragment' ),
141					options = table.data( 'fragment-options' );
142
143				button.removeClass( 'added' );
144				tr.find( '.added_to_cart' ).remove();
145
146				if ( yith_wcwl_l10n.remove_from_wishlist_after_add_to_cart && options.is_user_owner ) {
147					tr.remove();
148				}
149			}
150		} );
151
152		t.on( 'added_to_cart', 'body', function () {
153			var messages = $( '.woocommerce-message' );
154
155			if ( messages.length === 0 ) {
156				$( '#yith-wcwl-form' ).prepend( yith_wcwl_l10n.labels.added_to_cart_message );
157			} else {
158				messages.fadeOut( 300, function () {
159					$( this ).replaceWith( yith_wcwl_l10n.labels.added_to_cart_message ).fadeIn();
160				} );
161			}
162		} );
163
164		t.on( 'cart_page_refreshed', 'body', init_handling_after_ajax );
165
166		t.on( 'click', '.show-title-form', show_title_form );
167
168		t.on( 'click', '.wishlist-title-with-form h2', show_title_form );
169
170		t.on( 'click', '.remove_from_all_wishlists', function ( ev ) {
171			var t = $( this ),
172				prod_id = t.attr( 'data-product-id' ),
173				wishlist_id = t.data( 'wishlist-id' ),
174				content = t.closest( '.content' ),
175				data = {
176					action: yith_wcwl_l10n.actions.remove_from_all_wishlists,
177					nonce: yith_wcwl_l10n.nonce.remove_from_all_wishlists_nonce,
178					context: 'frontend',
179					prod_id: prod_id,
180					wishlist_id: wishlist_id,
181					fragments: retrieve_fragments( prod_id )
182				};
183
184			ev.preventDefault();
185
186			$.ajax( {
187				beforeSend: function () {
188					block( content );
189				},
190				complete: function () {
191					unblock( content );
192				},
193				data: data,
194				dataType: 'json',
195				method: 'post',
196				success: function ( data ) {
197					if ( typeof data.fragments !== 'undefined' ) {
198						replace_fragments( data.fragments );
199					}
200
201					init_handling_after_ajax();
202				},
203				url: yith_wcwl_l10n.ajax_url
204			} );
205		} );
206
207		t.on( 'click', '.hide-title-form', hide_title_form );
208
209		t.on( 'click', '.save-title-form', submit_title_form );
210
211		t.on( 'change', '.wishlist_manage_table .wishlist-visibility', save_privacy );
212
213		t.on( 'change', '.change-wishlist', function () {
214			var t = $( this ),
215				table = t.parents( '.cart.wishlist_table' ),
216				wishlist_token = table.data( 'token' ),
217				item_id = t.parents( '[data-row-id]' ).data( 'row-id' ),
218				to_token = t.val();
219
220			call_ajax_move_item_to_another_wishlist(
221				{
222					wishlist_token: wishlist_token,
223					destination_wishlist_token: to_token,
224					item_id: item_id,
225					fragments: retrieve_fragments()
226				},
227				function () {
228					block( table );
229				},
230				function ( data ) {
231					if ( typeof data.fragments !== 'undefined' ) {
232						replace_fragments( data.fragments );
233					}
234
235					unblock( table );
236				}
237			);
238		} );
239
240		t.on( 'click', '.yith-wcwl-popup-footer .move_to_wishlist', function () {
241			var t = $( this ),
242				product_id = t.attr( 'data-product-id' ),
243				wishlist_token = t.data( 'origin-wishlist-id' ),
244				form = t.closest( 'form' ),
245				to_token = form.find( '.wishlist-select' ).val(),
246				wishlist_name_field = form.find( '.wishlist-name' ),
247				wishlist_name = wishlist_name_field.val(),
248				wishlist_visibility = form.find( '.wishlist-visibility' ).filter( ':checked' ).val();
249
250			if ( 'new' === to_token && ! wishlist_name ) {
251				wishlist_name_field.closest( 'p' ).addClass( 'woocommerce-invalid' );
252				return false;
253			} else {
254				wishlist_name_field.closest( 'p' ).removeClass( 'woocommerce-invalid' );
255			}
256
257			call_ajax_move_item_to_another_wishlist(
258				{
259					wishlist_token: wishlist_token,
260					destination_wishlist_token: to_token,
261					item_id: product_id,
262					wishlist_name: wishlist_name,
263					wishlist_visibility: wishlist_visibility,
264					fragments: retrieve_fragments( product_id )
265				},
266				function () {
267					block( t );
268				},
269				function ( response ) {
270					var response_message = response.message;
271
272					if ( yith_wcwl_l10n.multi_wishlist ) {
273						close_pretty_photo( response_message );
274
275						if ( typeof (response.user_wishlists) !== 'undefined' ) {
276							update_wishlists( response.user_wishlists );
277						}
278					} else {
279						print_message( response_message );
280					}
281
282					if ( typeof response.fragments !== 'undefined' ) {
283						replace_fragments( response.fragments );
284					}
285
286					init_handling_after_ajax();
287
288					unblock( t );
289				}
290			);
291		} );
292
293		t.on( 'click', '.delete_item', function () {
294			var t = $( this ),
295				product_id = t.attr( 'data-product-id' ),
296				item_id = t.data( 'item-id' ),
297				el_wrap = $( '.add-to-wishlist-' + product_id ),
298				data = {
299					action: yith_wcwl_l10n.actions.delete_item_action,
300					nonce: yith_wcwl_l10n.nonce.delete_item_nonce,
301					context: 'frontend',
302					item_id: item_id,
303					fragments: retrieve_fragments( product_id )
304				};
305
306			$.ajax( {
307				url: yith_wcwl_l10n.ajax_url,
308				data: data,
309				dataType: 'json',
310				beforeSend: function () {
311					block( t );
312				},
313				complete: function () {
314					unblock( t );
315				},
316				method: 'post',
317				success: function ( response ) {
318					var fragments = response.fragments,
319						response_message = response.message;
320
321					if ( yith_wcwl_l10n.multi_wishlist ) {
322						close_pretty_photo( response_message );
323					}
324
325					if ( ! t.closest( '.yith-wcwl-remove-button' ).length ) {
326						print_message( response_message );
327					}
328
329					if ( typeof fragments !== 'undefined' ) {
330						replace_fragments( fragments );
331					}
332
333					init_handling_after_ajax();
334
335					$( 'body' ).trigger( 'removed_from_wishlist', [ t, el_wrap ] );
336				}
337			} );
338
339			return false;
340		} );
341
342		t.on( 'change', '.yith-wcwl-popup-content .wishlist-select', function () {
343			var t = $( this );
344
345			if ( t.val() === 'new' ) {
346				t.parents( '.yith-wcwl-first-row' ).next( '.yith-wcwl-second-row' ).show();
347			} else {
348				t.parents( '.yith-wcwl-first-row' ).next( '.yith-wcwl-second-row' ).hide();
349			}
350		} );
351
352		t.on( 'change', '#bulk_add_to_cart', function () {
353			var t = $( this ),
354				checkboxes = t.closest( '.wishlist_table' ).find( '[data-row-id]' ).find( 'input[type="checkbox"]:not(:disabled)' );
355
356			if ( t.is( ':checked' ) ) {
357				checkboxes.prop( 'checked', 'checked' ).change();
358			} else {
359				checkboxes.prop( 'checked', false ).change();
360			}
361		} );
362
363		t.on( 'submit', '.wishlist-ask-an-estimate-popup', function () {
364			var t = $( this ),
365				form = t.closest( 'form' ),
366				pp_content = t.closest( '.pp_content' ),
367				data = form.serializeArray().reduce( ( data, field ) => {
368					data[ field.name ] = field.value;
369					return data;
370				}, {} );
371
372			data.action = yith_wcwl_l10n.actions.ask_an_estimate;
373			data.nonce = yith_wcwl_l10n.nonce.ask_an_estimate_nonce;
374			data.context = 'frontend';
375
376			$.ajax( {
377				beforeSend: function () {
378					block( form );
379				},
380				complete: function () {
381					unblock( form );
382				},
383				data: data,
384				dataType: 'json',
385				method: 'post',
386				success: function ( data ) {
387					if ( typeof data.result !== 'undefined' && data.result ) {
388						var template = data.template;
389
390						if ( typeof template !== 'undefined' ) {
391							form.replaceWith( template );
392							pp_content.css( 'height', 'auto' );
393
394							setTimeout( close_pretty_photo, yith_wcwl_l10n.time_to_close_prettyphoto );
395						}
396					} else if ( typeof data.message !== 'undefined' ) {
397						form.find( '.woocommerce-error' ).remove();
398						form.find( '.popup-description' ).after( $( '<div>', {
399							'text': data.message,
400							'class': 'woocommerce-error'
401						} ) );
402					}
403				},
404				url: yith_wcwl_l10n.ajax_url
405			} );
406
407			return false;
408		} );
409
410		t.on( 'click', '.yith-wfbt-add-wishlist', function ( e ) {
411			e.preventDefault();
412			var t = $( this ),
413				form = $( '#yith-wcwl-form' );
414
415			$( 'html, body' ).animate( {
416				scrollTop: (form.offset().top)
417			}, 500 );
418
419			// ajax call
420			reload_wishlist_and_adding_elem( t, form );
421		} );
422
423		t.on( 'submit', '.yith-wcwl-popup-form', function () {
424			return false;
425		} );
426
427		t.on( 'yith_infs_added_elem', function () {
428			init_wishlist_pretty_photo();
429		} );
430
431		t.on( 'found_variation', function ( ev, variation ) {
432			var t = $( ev.target ),
433				product_id = t.data( 'product_id' ),
434				variation_id = variation.variation_id,
435				target1 = $( '.yith-wcwl-add-to-wishlist' )
436					.find( '[data-product-id="' + product_id + '"]' ),
437				target2 = $( '.yith-wcwl-add-to-wishlist' )
438					.find( '[data-original-product-id="' + product_id + '"]' ),
439				targets = target1.add( target2 ),
440				fragments = targets.closest( '.wishlist-fragment' ).filter( ':visible' );
441
442			if ( ! product_id || ! variation_id || ! targets.length ) {
443				return;
444			}
445
446			targets.each( function () {
447				var t = $( this ),
448					container = t.closest( '.yith-wcwl-add-to-wishlist' ),
449					options;
450
451				t.attr( 'data-original-product-id', product_id );
452				t.attr( 'data-product-id', variation_id );
453
454				if ( container.length ) {
455					options = container.data( 'fragment-options' );
456
457					if ( typeof options !== 'undefined' ) {
458						options.product_id = variation_id;
459						container.data( 'fragment-options', options );
460					}
461
462					container
463						.removeClass( function ( i, classes ) {
464							return classes.match( /add-to-wishlist-\S+/g ).join( ' ' );
465						} )
466						.addClass( 'add-to-wishlist-' + variation_id )
467						.attr( 'data-fragment-ref', variation_id );
468				}
469			} );
470
471			if ( ! yith_wcwl_l10n.reload_on_found_variation ) {
472				return;
473			}
474
475			block( fragments );
476
477			load_fragments( {
478				fragments: fragments,
479				firstLoad: false
480			} );
481		} );
482
483		t.on( 'reset_data', function ( ev ) {
484			var t = $( ev.target ),
485				product_id = t.data( 'product_id' ),
486				targets = $( '[data-original-product-id="' + product_id + '"]' ),
487				fragments = targets.closest( '.wishlist-fragment' ).filter( ':visible' );
488
489			if ( ! product_id || ! targets.length ) {
490				return;
491			}
492
493			targets.each( function () {
494				var t = $( this ),
495					container = t.closest( '.yith-wcwl-add-to-wishlist' ),
496					variation_id = t.attr( 'data-product-id' ),
497					options;
498
499				t.attr( 'data-product-id', product_id );
500				t.attr( 'data-original-product-id', '' );
501
502				if ( container.length ) {
503					options = container.data( 'fragment-options' );
504
505					if ( typeof options !== 'undefined' ) {
506						options.product_id = product_id;
507						container.data( 'fragment-options', options );
508					}
509
510					container
511						.removeClass( 'add-to-wishlist-' + variation_id )
512						.addClass( 'add-to-wishlist-' + product_id )
513						.attr( 'data-fragment-ref', product_id );
514				}
515			} );
516
517			if ( ! yith_wcwl_l10n.reload_on_found_variation ) {
518				return;
519			}
520
521			block( fragments );
522
523			load_fragments( {
524				fragments: fragments,
525				firstLoad: false
526			} );
527
528		} );
529
530		t.on( 'yith_wcwl_reload_fragments', ( event, data ) => load_fragments( data ) );
531
532		t.on( 'yith_wcwl_reload_after_ajax', init_handling_after_ajax );
533
534		t.on( 'yith_infs_added_elem', function ( ev, elem ) {
535			load_fragments( {
536				container: elem,
537				firstLoad: false
538			} );
539		} );
540
541		t.on( 'yith_wcwl_fragments_loaded', function ( ev, original, update, firstLoad ) {
542			if ( ! firstLoad ) {
543				return;
544			}
545
546			$( '.variations_form' ).find( '.variations select' ).last().change();
547		} );
548
549		t.on( 'click', '.yith-wcwl-popup-feedback .close-popup', function ( ev ) {
550			ev.preventDefault();
551
552			close_pretty_photo();
553		} );
554
555		init_wishlist_popup();
556
557		init_wishlist_tooltip();
558
559		init_wishlist_dropdown();
560
561		init_wishlist_drag_n_drop();
562
563		init_quantity();
564
565		init_wishlist_details_popup();
566
567		init_wishlist_popup_tabs();
568
569		init_select_box();
570
571		init_checkbox_handling();
572
573		init_wishlist_pretty_photo();
574
575		init_add_to_cart_icon();
576
577		init_wishlist_responsive();
578
579		init_copy_wishlist_link();
580
581		if ( yith_wcwl_l10n.enable_ajax_loading ) {
582			load_fragments();
583		}
584
585	} ).trigger( 'yith_wcwl_init' );
586
587	// Avoid pressing the enter key in the qty input.
588	$( 'form#yith-wcwl-form .wishlist_table .product-quantity input' ).on( 'keypress', function ( e ) {
589		if ( e.keyCode == '13' ) {
590			e.preventDefault();
591			return false;
592		}
593	} );
594
595	// Move the Add to Wishlist button under the gallery
596	$( document ).ready( function () {
597		if ( yith_wcwl_l10n.yith_wcwl_button_position === 'thumbnails' ) {
598			$( '.woocommerce-product-gallery + div.yith-wcwl-add-to-wishlist' ).appendTo( '.woocommerce-product-gallery' );
599		}
600	} );
601
602	$( document ).on( 'keydown', '#yith-wcwl-form input[name="wishlist_name"]', function ( event ) {
603		const key = event.key;
604		if ( [ 'Enter', 'Escape' ].includes( key ) ) {
605			const $container = $( this ).closest( '.wishlist-title-container' );
606			if ( 'Enter' === key ) {
607				$container.find( 'a.save-title-form' ).trigger( 'click' );
608			} else {
609				$container.find( 'a.hide-title-form' ).trigger( 'click' );
610			}
611
612			event.preventDefault();
613		}
614	} )
615
616
617	/* === INIT FUNCTIONS === */
618
619	/**
620	 * Adds selectbox where needed
621	 *
622	 * @return void
623	 * @since 3.0.0
624	 */
625	function init_select_box() {
626		if ( typeof $.fn.selectBox !== 'undefined' ) {
627			$( 'select.selectBox' ).filter( ':visible' ).not( '.enhanced' ).selectBox().addClass( 'enhanced' );
628		}
629	}
630
631	/**
632	 * Init PrettyPhoto for all links withi the plugin that open a popup
633	 *
634	 * @return void
635	 * @since 2.0.16
636	 */
637	function init_wishlist_pretty_photo() {
638		if ( typeof $.prettyPhoto === 'undefined' ) {
639			return;
640		}
641
642		var ppParams = {
643			hook: 'data-rel',
644			social_tools: false,
645			theme: 'pp_woocommerce yith-wcwl-pp-modal',
646			horizontal_padding: 20,
647			opacity: 0.8,
648			deeplinking: false,
649			overlay_gallery: false,
650			keyboard_shortcuts: false,
651			default_width: 500,
652			changepicturecallback: function () {
653				init_select_box();
654
655				$( '.wishlist-select' ).filter( ':visible' ).change();
656				$( document ).trigger( 'yith_wcwl_popup_opened', [ this ] );
657			},
658			markup: '<div class="pp_pic_holder">' +
659				'<div class="pp_content_container">' +
660				'<div class="pp_content">' +
661				'<div class="pp_loaderIcon"></div>' +
662				'<div class="pp_fade">' +
663				'<a href="#" class="pp_expand" title="Expand the image">Expand</a>' +
664				'<div class="pp_hoverContainer">' +
665				'<a class="pp_next" href="#">next</a>' +
666				'<a class="pp_previous" href="#">previous</a>' +
667				'</div>' +
668				'<div id="pp_full_res"></div>' +
669				'<div class="pp_details">' +
670				'<a class="pp_close" href="#">Close</a>' +
671				'</div>' +
672				'</div>' +
673				'</div>' +
674				'</div>' +
675				'</div>' +
676				'<div class="pp_overlay yith-wcwl-overlay"></div>'
677		};
678
679		$( 'a[data-rel^="prettyPhoto[add_to_wishlist_"]' )
680			.add( 'a[data-rel="prettyPhoto[ask_an_estimate]"]' )
681			.add( 'a[data-rel="prettyPhoto[create_wishlist]"]' )
682			.off( 'click' )
683			.prettyPhoto( ppParams );
684
685		$( 'a[data-rel="prettyPhoto[move_to_another_wishlist]"]' ).on( 'click', function () {
686			var t = $( this ),
687				popup = $( '#move_to_another_wishlist' ),
688				form = popup.find( 'form' ),
689				row_id = form.find( '.row-id' ),
690				id = t.closest( '[data-row-id]' ).data( 'row-id' );
691
692			if ( row_id.length ) {
693				row_id.remove();
694			}
695
696			var input = $( '<input>', {
697				type: 'hidden',
698				name: 'row_id',
699				class: 'row-id'
700			} ).val( id );
701			form.append( input );
702		} ).prettyPhoto( ppParams );
703
704		// add & remove class to body when popup is opened
705		var callback = function ( node, op ) {
706				if ( typeof node.classList !== 'undefined' && node.classList.contains( 'yith-wcwl-overlay' ) ) {
707					var method = 'remove' === op ? 'removeClass' : 'addClass';
708
709					$( 'body' )[ method ]( 'yith-wcwl-with-pretty-photo' );
710				}
711			},
712			callbackAdd = function ( node ) {
713				callback( node, 'add' );
714			},
715			callbackRemove = function ( node ) {
716				callback( node, 'remove' );
717			},
718			observer = new MutationObserver( function ( mutationsList ) {
719				for ( var i in mutationsList ) {
720					var mutation = mutationsList[ i ];
721					if ( mutation.type === 'childList' ) {
722						typeof mutation.addedNodes !== 'undefined' && typeof mutation.addedNodes.forEach === 'function' && mutation.addedNodes.forEach( callbackAdd );
723						typeof mutation.removedNodes !== 'undefined' && typeof mutation.addedNodes.forEach === 'function' && mutation.removedNodes.forEach( callbackRemove );
724					}
725				}
726			} );
727
728		observer.observe( document.body, {
729			childList: true
730		} );
731	}
732
733	/**
734	 * Init checkbox handling
735	 *
736	 * @return void
737	 * @since 3.0.0
738	 */
739	function init_checkbox_handling() {
740		var checkboxes = $( '.wishlist_table' ).find( '.product-checkbox input[type="checkbox"]' );
741
742		checkboxes.off( 'change' ).on( 'change', function () {
743			var t = $( this ),
744				p = t.parent();
745
746			p
747				.removeClass( 'checked' )
748				.removeClass( 'unchecked' )
749				.addClass( t.is( ':checked' ) ? 'checked' : 'unchecked' );
750		} ).trigger( 'change' );
751	}
752
753	/**
754	 * Show icon on Add to Cart button
755	 *
756	 * @return void
757	 */
758	function init_add_to_cart_icon() {
759		$( '.add_to_cart' ).filter( '[data-icon]' ).not( '.icon-added' ).each( function () {
760			var t = $( this ),
761				data = t.data( 'icon' ),
762				icon;
763
764			if ( data.match( /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi ) ) {
765				icon = $( '<img/>', { 'src': data } );
766			} else {
767				icon = $( '<i/>', { 'class': 'fa ' + data } );
768			}
769
770			t.prepend( icon ).addClass( 'icon-added' );
771		} );
772	}
773
774	/**
775	 * Init js handling on wishlist table items after ajax update
776	 *
777	 * @return void
778	 * @since 2.0.7
779	 */
780	function init_handling_after_ajax() {
781		init_select_box();
782		init_wishlist_pretty_photo();
783		init_checkbox_handling();
784		init_add_to_cart_icon();
785		init_wishlist_dropdown();
786		init_wishlist_tooltip();
787		init_wishlist_details_popup();
788		init_wishlist_drag_n_drop();
789		init_quantity();
790		init_copy_wishlist_link();
791
792		$( document ).trigger( 'yith_wcwl_init_after_ajax' );
793	}
794
795	/**
796	 * Add tooltip to Add to Wishlist buttons
797	 *
798	 * @return void
799	 * @since 3.0.0
800	 */
801	function init_wishlist_tooltip() {
802		if ( ! yith_wcwl_l10n.enable_tooltip ) {
803			return;
804		}
805
806		$( '.yith-wcwl-add-to-wishlist' ).find( '[data-title]' ).each( function () {
807			var t = $( this );
808
809			if ( t.hasClass( 'tooltip-added' ) ) {
810				return;
811			}
812
813			t
814				.on( 'mouseenter', function () {
815					var t = $( this );
816
817					var tooltip = $( '<span>', { 'class': 'yith-wcwl-tooltip', 'text': t.data( 'title' ) } );
818
819					t.append( tooltip );
820
821					var width = tooltip.outerWidth() + 6;
822					tooltip.outerWidth( width );
823
824					tooltip.fadeIn( 200 );
825
826					t.addClass( 'with-tooltip' );
827				} )
828				.on( 'mouseleave', function () {
829					var t = $( this );
830
831					t.find( '.yith-wcwl-tooltip' ).fadeOut( 200, function () {
832						t.removeClass( 'with-tooltip' ).find( '.yith-wcwl-tooltip' ).remove();
833					} );
834				} );
835
836			t.addClass( 'tooltip-added' );
837		} );
838	}
839
840	/**
841	 * Add wishlist popup message
842	 *
843	 * @return void
844	 * @since 2.0.0
845	 */
846	function init_wishlist_popup() {
847		if ( typeof yith_wcwl_l10n.enable_notices !== 'undefined' && ! yith_wcwl_l10n.enable_notices ) {
848			return;
849		}
850
851		if ( $( '.yith-wcwl-add-to-wishlist' ).length && ! $( '#yith-wcwl-popup-message' ).length ) {
852			var message_div = $( '<div>' )
853					.attr( 'id', 'yith-wcwl-message' ),
854				popup_div = $( '<div>' )
855					.attr( 'id', 'yith-wcwl-popup-message' )
856					.html( message_div )
857					.hide();
858
859			$( 'body' ).prepend( popup_div );
860		}
861	}
862
863	/**
864	 * Add Dropdown to Add to Wishlist when modal is disabled and Multi Wishlist enabled
865	 *
866	 * @return void
867	 * @since 3.0.0
868	 */
869	function init_wishlist_dropdown() {
870		$( '.yith-wcwl-add-button' ).filter( '.with-dropdown' )
871			.on( 'mouseleave', function () {
872				var t = $( this ),
873					dropdown = t.find( '.yith-wcwl-dropdown' );
874
875				if ( dropdown.length ) {
876					dropdown.fadeOut( 200 );
877				}
878			} )
879			.children( 'a' )
880			.on( 'mouseenter', function () {
881				var t = $( this ),
882					el_wrap = t.closest( '.with-dropdown' ),
883					dropdown = el_wrap.find( '.yith-wcwl-dropdown' );
884
885				if ( dropdown.length && dropdown.children().length ) {
886					el_wrap.find( '.yith-wcwl-dropdown' ).fadeIn( 200 );
887				}
888			} );
889	}
890
891	/**
892	 * Handle Drag & Drop of wishlist items for sorting
893	 *
894	 * @return void
895	 * @since 3.0.0
896	 */
897	function init_wishlist_drag_n_drop() {
898		if ( typeof yith_wcwl_l10n.enable_drag_n_drop === 'undefined' || ! yith_wcwl_l10n.enable_drag_n_drop ) {
899			return;
900		}
901
902		$( '.wishlist_table' ).filter( '.sortable' ).not( '.no-interactions' ).each( function () {
903			var t = $( this ),
904				jqxhr = false;
905
906			t.sortable( {
907				items: '[data-row-id]',
908				scroll: true,
909				helper: function ( e, ui ) {
910					ui.children().each( function () {
911						$( this ).width( $( this ).width() );
912					} );
913					return ui;
914				},
915				update: function () {
916					var row = t.find( '[data-row-id]' ),
917						positions = [],
918						i = 0;
919
920					if ( ! row.length ) {
921						return;
922					}
923
924					if ( jqxhr ) {
925						jqxhr.abort();
926					}
927
928					row.each( function () {
929						var t = $( this );
930
931						t.find( 'input[name*="[position]"]' ).val( i++ );
932
933						positions.push( t.data( 'row-id' ) );
934					} );
935
936					jqxhr = $.ajax( {
937						data: {
938							action: yith_wcwl_l10n.actions.sort_wishlist_items,
939							nonce: yith_wcwl_l10n.nonce.sort_wishlist_items_nonce,
940							context: 'frontend',
941							positions: positions,
942							wishlist_token: t.data( 'token' ),
943							page: t.data( 'page' ),
944							per_page: t.data( 'per-page' )
945						},
946						method: 'POST',
947						url: yith_wcwl_l10n.ajax_url
948					} );
949				}
950			} );
951		} );
952	}
953
954	/**
955	 * Handle quantity input change for each wishlist item
956	 *
957	 * @return void
958	 * @since 3.0.0
959	 */
960	function init_quantity() {
961		var jqxhr,
962			timeout;
963
964		$( '.wishlist_table' ).on( 'change', '.product-quantity :input', function () {
965			var t = $( this ),
966				row = t.closest( '[data-row-id]' ),
967				product_id = row.data( 'row-id' ),
968				table = t.closest( '.wishlist_table' ),
969				token = table.data( 'token' );
970
971			clearTimeout( timeout );
972
973			// set add to cart link to add specific qty to cart
974			row.find( '.add_to_cart' ).attr( 'data-quantity', t.val() );
975
976			timeout = setTimeout( function () {
977				if ( jqxhr ) {
978					jqxhr.abort();
979				}
980
981				jqxhr = $.ajax( {
982					beforeSend: function () {
983						block( table );
984					},
985					complete: function () {
986						unblock( table );
987					},
988					data: {
989						action: yith_wcwl_l10n.actions.update_item_quantity,
990						nonce: yith_wcwl_l10n.nonce.update_item_quantity_nonce,
991						context: 'frontend',
992						product_id: product_id,
993						wishlist_token: token,
994						quantity: t.val()
995					},
996					method: 'POST',
997					url: yith_wcwl_l10n.ajax_url
998				} );
999			}, 1000 );
1000		} );
1001	}
1002
1003	/**
1004	 * Init handling for copy button
1005	 *
1006	 * @return void
1007	 * @since 2.2.11
1008	 */
1009	function init_copy_wishlist_link() {
1010		$( '.copy-trigger' ).on( 'click', function () {
1011
1012			var obj_to_copy = $( '.copy-target' );
1013
1014			if ( obj_to_copy.length > 0 ) {
1015				if ( obj_to_copy.is( 'input' ) ) {
1016
1017					if ( isOS() ) {
1018
1019						obj_to_copy[ 0 ].setSelectionRange( 0, 9999 );
1020					} else {
1021						obj_to_copy.select();
1022					}
1023					document.execCommand( 'copy' );
1024				} else {
1025
1026					var hidden = $( '<input/>', {
1027						val: obj_to_copy.text(),
1028						type: 'text'
1029					} );
1030
1031					$( 'body' ).append( hidden );
1032
1033					if ( isOS() ) {
1034						hidden[ 0 ].setSelectionRange( 0, 9999 );
1035					} else {
1036						hidden.select();
1037					}
1038					document.execCommand( 'copy' );
1039
1040					hidden.remove();
1041				}
1042			}
1043		} );
1044	}
1045
1046	/**
1047	 * Handle popup for images grid layout
1048	 *
1049	 * @return void
1050	 * @since 3.0.0
1051	 */
1052	function init_wishlist_details_popup() {
1053
1054		$( '.wishlist_table' ).filter( '.images_grid' ).not( '.enhanced' )
1055			.on( 'click', '[data-row-id] .product-thumbnail a', function ( ev ) {
1056				if ( ! yith_wcwl_l10n.disable_popup_grid_view ) {
1057					var t = $( this ),
1058						item = t.closest( '[data-row-id]' ),
1059						items = item.siblings( '[data-row-id]' ),
1060						popup = item.find( '.item-details' );
1061
1062					ev.preventDefault();
1063
1064					if ( popup.length ) {
1065						items.removeClass( 'show' );
1066						item.toggleClass( 'show' );
1067					}
1068				}
1069			} )
1070			.on( 'click', '[data-row-id] a.close', function ( ev ) {
1071				var t = $( this ),
1072					item = t.closest( '[data-row-id]' ),
1073					popup = item.find( '.item-details' );
1074
1075				ev.preventDefault();
1076
1077				if ( popup.length ) {
1078					item.removeClass( 'show' );
1079				}
1080			} )
1081			.on( 'click', '[data-row-id] a.remove_from_wishlist', function ( ev ) {
1082				var t = $( this );
1083
1084				ev.stopPropagation();
1085
1086				remove_item_from_wishlist( t );
1087
1088				return false;
1089			} )
1090			.addClass( 'enhanced' );
1091
1092
1093		$( document )
1094			.on( 'click', function ( ev ) {
1095				if ( ! $( ev.target ).closest( '[data-row-id]' ).length ) {
1096					$( '.wishlist_table' ).filter( '.images_grid' ).find( '.show' ).removeClass( 'show' );
1097				}
1098			} )
1099			.on( 'added_to_cart', function () {
1100				$( '.wishlist_table' ).filter( '.images_grid' ).find( '.show' ).removeClass( 'show' );
1101			} );
1102	}
1103
1104	/**
1105	 * Handle tabs inside wishlist popups
1106	 *
1107	 * @return void
1108	 * @since 3.0.0
1109	 */
1110	function init_wishlist_popup_tabs() {
1111		$( document ).on( 'click', '.show-tab', function ( ev ) {
1112			var t = $( this ),
1113				container = t.closest( '.yith-wcwl-popup-content' ),
1114				tab = t.data( 'tab' ),
1115				target = container.find( '.tab' ).filter( '.' + tab );
1116
1117			ev.preventDefault();
1118
1119			if ( ! target.length ) {
1120				return false;
1121			}
1122
1123			t.addClass( 'active' ).siblings( '.show-tab' ).removeClass( 'active' );
1124
1125			target.show().siblings( '.tab' ).hide();
1126
1127			if ( 'create' === tab ) {
1128				container.prepend( '<input type="hidden" id="new_wishlist_selector" class="wishlist-select" value="new">' );
1129			} else {
1130				container.find( '#new_wishlist_selector' ).remove();
1131			}
1132
1133			$( document ).trigger( 'yith_wcwl_tab_selected', [ tab, target ] );
1134		} );
1135
1136		$( document ).on( 'change', '.wishlist-select', function () {
1137			var t = $( this ),
1138				container = t.closest( '.yith-wcwl-popup-content' ),
1139				tab = t.closest( '.tab' ),
1140				createTab = container.find( '.tab.create' ),
1141				showTab = container.find( '.show-tab' ),
1142				createShowTab = showTab.filter( '[data-tab="create"]' ),
1143				val = t.val();
1144
1145			if ( val === 'new' && createTab.length ) {
1146				tab.hide();
1147				createTab.show();
1148
1149				showTab.removeClass( 'active' );
1150				createShowTab.addClass( 'active' );
1151				t.find( 'option:selected' ).prop( 'selected', false );
1152				t.change();
1153			}
1154		} );
1155	}
1156
1157	/**
1158	 * Init responsive behaviour of the wishlist
1159	 *
1160	 * @return void
1161	 * @since 3.0.0
1162	 */
1163	function init_wishlist_responsive() {
1164		var jqxhr = false;
1165
1166		if ( ! yith_wcwl_l10n.is_wishlist_responsive ) {
1167			return;
1168		}
1169
1170		$( window ).on( 'resize', function () {
1171			var table = $( '.wishlist_table.responsive' ),
1172				mobile = table.is( '.mobile' ),
1173				media = window.matchMedia( '(max-width: ' + yith_wcwl_l10n.mobile_media_query + 'px)' ),
1174				form = table.closest( 'form' ),
1175				id = form.attr( 'class' ),
1176				options = form.data( 'fragment-options' ),
1177				fragments = {},
1178				load = false;
1179
1180			if ( ! table.length ) {
1181				return;
1182			}
1183
1184			if ( media.matches && table && ! mobile ) {
1185				options.is_mobile = 'yes';
1186				load = true;
1187			} else if ( ! media.matches && table && mobile ) {
1188				options.is_mobile = 'no';
1189				load = true;
1190			}
1191
1192			if ( load ) {
1193				if ( jqxhr ) {
1194					jqxhr.abort();
1195				}
1196
1197				fragments[ id.split( ' ' ).join( yith_wcwl_l10n.fragments_index_glue ) ] = options;
1198
1199				jqxhr = $.ajax( {
1200					beforeSend: function () {
1201						block( table );
1202					},
1203					complete: function () {
1204						unblock( table );
1205					},
1206					data: {
1207						action: yith_wcwl_l10n.actions.load_mobile_action,
1208						nonce: yith_wcwl_l10n.nonce.load_mobile_nonce,
1209						context: 'frontend',
1210						fragments: fragments
1211					},
1212					method: 'post',
1213					success: function ( data ) {
1214						if ( typeof data.fragments !== 'undefined' ) {
1215							replace_fragments( data.fragments );
1216
1217							init_handling_after_ajax();
1218
1219							$( document ).trigger( 'yith_wcwl_responsive_template', [ mobile, data.fragments ] );
1220						}
1221					},
1222					url: yith_wcwl_l10n.ajax_url
1223				} );
1224			}
1225		} );
1226	}
1227
1228	/* === EVENT HANDLING === */
1229
1230	/**
1231	 * Move item to another wishlist
1232	 *
1233	 * @return void
1234	 * @since 3.0.0
1235	 */
1236	function call_ajax_move_item_to_another_wishlist( data, beforeSend, complete ) {
1237		data.action = yith_wcwl_l10n.actions.move_to_another_wishlist_action;
1238		data.nonce = yith_wcwl_l10n.nonce.move_to_another_wishlist_nonce;
1239		data.context = 'frontend';
1240
1241		if ( data.wishlist_token === '' || data.destination_wishlist_token === '' || data.item_id === '' ) {
1242			return;
1243		}
1244
1245		$.ajax( {
1246			beforeSend: beforeSend,
1247			url: yith_wcwl_l10n.ajax_url,
1248			data: data,
1249			dataType: 'json',
1250			method: 'post',
1251			success: function ( response ) {
1252				complete( response );
1253
1254				init_handling_after_ajax();
1255
1256				$( 'body' ).trigger( 'moved_to_another_wishlist', [ $( this ), data.item_id ] );
1257			}
1258		} );
1259	}
1260
1261	/**
1262	 * Remove a product from the wishlist.
1263	 *
1264	 * @param el
1265	 * @return void
1266	 * @since 1.0.0
1267	 */
1268	function remove_item_from_wishlist( el ) {
1269		var table = el.parents( '.cart.wishlist_table' ),
1270			row = el.parents( '[data-row-id]' ),
1271			data_row_id = row.data( 'row-id' ),
1272			wishlist_id = table.data( 'id' ),
1273			wishlist_token = table.data( 'token' ),
1274			data = {
1275				action: yith_wcwl_l10n.actions.remove_from_wishlist_action,
1276				nonce: yith_wcwl_l10n.nonce.remove_from_wishlist_nonce,
1277				context: 'frontend',
1278				remove_from_wishlist: data_row_id,
1279				wishlist_id: wishlist_id,
1280				wishlist_token: wishlist_token,
1281				fragments: retrieve_fragments( data_row_id )
1282			};
1283
1284		$.ajax( {
1285			beforeSend: function () {
1286				block( table );
1287			},
1288			complete: function () {
1289				unblock( table );
1290			},
1291			data: data,
1292			method: 'post',
1293			success: function ( data ) {
1294				if ( typeof data.fragments !== 'undefined' ) {
1295					replace_fragments( data.fragments );
1296				}
1297
1298				init_handling_after_ajax();
1299
1300				$( 'body' ).trigger( 'removed_from_wishlist', [ el, row ] );
1301			},
1302			url: yith_wcwl_l10n.ajax_url
1303		} );
1304	}
1305
1306	/**
1307	 * Remove a product from the wishlist.
1308	 *
1309	 * @param el
1310	 * @param form
1311	 * @return void
1312	 * @since 1.0.0
1313	 */
1314	function reload_wishlist_and_adding_elem( el, form ) {
1315
1316		var product_id = el.attr( 'data-product-id' ),
1317			table = $( document ).find( '.cart.wishlist_table' ),
1318			pagination = table.data( 'pagination' ),
1319			per_page = table.data( 'per-page' ),
1320			wishlist_id = table.data( 'id' ),
1321			wishlist_token = table.data( 'token' ),
1322			data = {
1323				action: yith_wcwl_l10n.actions.reload_wishlist_and_adding_elem_action,
1324				nonce: yith_wcwl_l10n.nonce.reload_wishlist_and_adding_elem_nonce,
1325				context: 'frontend',
1326				pagination: pagination,
1327				per_page: per_page,
1328				wishlist_id: wishlist_id,
1329				wishlist_token: wishlist_token,
1330				add_to_wishlist: product_id,
1331				product_type: el.data( 'product-type' )
1332			};
1333
1334		if ( ! is_cookie_enabled() ) {
1335			window.alert( yith_wcwl_l10n.labels.cookie_disabled );
1336			return;
1337		}
1338
1339		$.ajax( {
1340			type: 'POST',
1341			url: yith_wcwl_l10n.ajax_url,
1342			data: data,
1343			dataType: 'html',
1344			beforeSend: function () {
1345				block( table );
1346			},
1347			complete: function () {
1348				unblock( table );
1349			},
1350			success: function ( res ) {
1351				var obj = $( res ),
1352					new_form = obj.find( '#yith-wcwl-form' ), // get new form
1353					shortcode = obj.find( '.yith-wfbt-slider-wrapper' ); // get new form
1354
1355				form.replaceWith( new_form );
1356				$( '.yith-wfbt-slider-wrapper' ).replaceWith( shortcode );
1357				init_handling_after_ajax();
1358
1359				$( document ).trigger( 'yith_wcwl_reload_wishlist_from_frequently' );
1360			}
1361		} );
1362	}
1363
1364	/**
1365	 * Show form to edit wishlist title
1366	 *
1367	 * @param ev event
1368	 * @return void
1369	 * @since 2.0.0
1370	 */
1371	function show_title_form( ev ) {
1372		var t = $( this ),
1373			table = t.closest( '.wishlist_table' ),
1374			title = null;
1375		ev.preventDefault();
1376
1377		// if button is in table
1378		if ( table.length ) {
1379			title = t.closest( '[data-wishlist-id]' ).find( '.wishlist-title' );
1380		} else {
1381			title = t.parents( '.wishlist-title' );
1382		}
1383
1384		title.next().css( 'display', 'inline-block' ).find( 'input[type="text"]' ).focus();
1385		title.hide();
1386	}
1387
1388	/**
1389	 * Hide form to edit wishlist title
1390	 *
1391	 * @param ev event
1392	 * @return void
1393	 * @since 2.0.0
1394	 */
1395	function hide_title_form( ev ) {
1396		var t = $( this );
1397		ev.preventDefault();
1398
1399		t.parents( '.hidden-title-form' ).hide();
1400		t.parents( '.hidden-title-form' ).prev().show();
1401	}
1402
1403	/**
1404	 * Submit form to save a new wishlist title
1405	 *
1406	 * @param ev event
1407	 * @return void
1408	 * @since 2.0.7
1409	 */
1410	function submit_title_form( ev ) {
1411		var t = $( this ),
1412			form = t.closest( '.hidden-title-form' ),
1413			row = t.closest( '[data-wishlist-id]' ),
1414			wishlist_id = row.data( 'wishlist-id' ),
1415			title_input = form.find( 'input[type="text"]' ),
1416			new_title = title_input.val(),
1417			data = {};
1418
1419		ev.preventDefault();
1420
1421		if ( ! new_title ) {
1422			form.addClass( 'woocommerce-invalid' );
1423			title_input.focus();
1424			return;
1425		}
1426
1427		if ( ! wishlist_id ) {
1428			wishlist_id = $( '#wishlist_id' ).val();
1429		}
1430
1431		data = {
1432			action: yith_wcwl_l10n.actions.save_title_action,
1433			nonce: yith_wcwl_l10n.nonce.save_title_nonce,
1434			context: 'frontend',
1435			wishlist_id: wishlist_id,
1436			title: new_title,
1437			fragments: retrieve_fragments()
1438		};
1439
1440		$.ajax( {
1441			type: 'POST',
1442			url: yith_wcwl_l10n.ajax_url,
1443			data: data,
1444			dataType: 'json',
1445			beforeSend: function () {
1446				block( form );
1447			},
1448			complete: function () {
1449				unblock( form );
1450			},
1451			success: function ( response ) {
1452				var fragments = response.fragments,
1453					status = response.result;
1454
1455				if ( status ) {
1456					form.hide();
1457					form.prev().find( '.wishlist-anchor, h1, h2' ).text( new_title ).end().show();
1458				} else {
1459					form.addClass( 'woocommerce-invalid' );
1460					title_input.focus();
1461				}
1462
1463				if ( typeof fragments !== 'undefined' ) {
1464					replace_fragments( fragments );
1465				}
1466
1467				init_handling_after_ajax();
1468			}
1469		} );
1470	}
1471
1472	/**
1473	 * Submit form to save a new wishlist privacy
1474	 *
1475	 * @return void
1476	 * @since 2.0.7
1477	 */
1478	function save_privacy() {
1479		var t = $( this ),
1480			new_privacy = t.val(),
1481			row = t.closest( '[data-wishlist-id]' ),
1482			wishlist_id = row.data( 'wishlist-id' ),
1483			data = {
1484				action: yith_wcwl_l10n.actions.save_privacy_action,
1485				nonce: yith_wcwl_l10n.nonce.save_privacy_nonce,
1486				context: 'frontend',
1487				wishlist_id: wishlist_id,
1488				privacy: new_privacy,
1489				fragments: retrieve_fragments()
1490			};
1491
1492		$.ajax( {
1493			type: 'POST',
1494			url: yith_wcwl_l10n.ajax_url,
1495			data: data,
1496			dataType: 'json',
1497			success: function ( response ) {
1498				var fragments = response.fragments;
1499
1500				if ( typeof fragments !== 'undefined' ) {
1501					replace_fragments( fragments );
1502				}
1503			}
1504		} );
1505	}
1506
1507	/* === UTILS === */
1508
1509	/**
1510	 * Closes pretty photo popup, if any
1511	 *
1512	 * @return void
1513	 * @since 3.0.0
1514	 */
1515	function close_pretty_photo( message, status ) {
1516		if ( typeof $.prettyPhoto !== 'undefined' && typeof $.prettyPhoto.close !== 'undefined' ) {
1517			if ( typeof message !== 'undefined' ) {
1518				var container = $( '.pp_content_container' ),
1519					content = container.find( '.pp_content' ),
1520					form = container.find( '.yith-wcwl-popup-form' ),
1521					popup = form.closest( '.pp_pic_holder' );
1522
1523				if ( form.length ) {
1524					var new_content = $( '<div/>', {
1525						'class': 'yith-wcwl-popup-feedback'
1526					} );
1527
1528					new_content.append( $( '<i/>', { 'class': 'fa heading-icon ' + ('error' === status ? 'fa-exclamation-triangle' : 'fa-check') } ) );
1529					new_content.append( $( '<p/>', { 'class': 'feedback', 'html': message } ) );
1530					new_content.css( 'display', 'none' );
1531
1532					content.css( 'height', 'auto' );
1533
1534					form.after( new_content );
1535					form.fadeOut( 200, function () {
1536						new_content.fadeIn();
1537					} );
1538
1539					popup.addClass( 'feedback' );
1540					popup.css( 'left', (($( window ).innerWidth() / 2) - (popup.outerWidth() / 2)) + 'px' );
1541
1542					if ( typeof yith_wcwl_l10n.auto_close_popup === 'undefined' || yith_wcwl_l10n.auto_close_popup ) {
1543						setTimeout( close_pretty_photo, yith_wcwl_l10n.popup_timeout );
1544					}
1545				}
1546			} else {
1547				try {
1548					$.prettyPhoto.close();
1549
1550					if ( yith_wcwl_l10n.redirect_after_ask_estimate ) {
1551						window.location.replace( yith_wcwl_l10n.ask_estimate_redirect_url );
1552					}
1553				} catch ( e ) { /* do nothing, no popup to close */
1554				}
1555			}
1556		}
1557	}
1558
1559	/**
1560	 * Print wishlist message for the user
1561	 *
1562	 * @var response_message string Message to print
1563	 * @return void
1564	 * @since 3.0.0
1565	 */
1566	function print_message( response_message ) {
1567		var msgPopup = $( '#yith-wcwl-popup-message' ),
1568			msg = $( '#yith-wcwl-message' ),
1569			timeout = typeof yith_wcwl_l10n.popup_timeout !== 'undefined' ? yith_wcwl_l10n.popup_timeout : 3000;
1570
1571		if ( typeof yith_wcwl_l10n.enable_notices !== 'undefined' && ! yith_wcwl_l10n.enable_notices ) {
1572			return;
1573		}
1574
1575		msg.html( response_message );
1576		msgPopup.css( 'margin-left', '-' + $( msgPopup ).width() + 'px' ).fadeIn();
1577		window.setTimeout( function () {
1578			msgPopup.fadeOut();
1579		}, timeout );
1580	}
1581
1582	/**
1583	 * Update lists after a new list is added
1584	 *
1585	 * @param wishlists array Array of wishlists
1586	 * @return void
1587	 * @since 3.0.0
1588	 */
1589	function update_wishlists( wishlists ) {
1590		var wishlist_select = $( 'select.wishlist-select' ),
1591			wishilst_dropdown = $( 'ul.yith-wcwl-dropdown' );
1592
1593		// update options for all wishlist selects
1594		wishlist_select.each( function () {
1595			var t = $( this ),
1596				wishlist_options = t.find( 'option' ),
1597				new_option = wishlist_options.filter( '[value="new"]' );
1598
1599			wishlist_options.not( new_option ).remove();
1600
1601			$.each( wishlists, function ( i, v ) {
1602				$( '<option>', { value: v.id, html: v.wishlist_name } ).appendTo( t );
1603			} );
1604
1605			t.append( new_option );
1606		} );
1607
1608		// update options for all wishlist dropdown
1609		wishilst_dropdown.each( function () {
1610			var t = $( this ),
1611				wishlist_options = t.find( 'li' ),
1612				container = t.closest( '.yith-wcwl-add-button' ),
1613				default_button = container.children( 'a.add_to_wishlist' ),
1614				product_id = default_button.attr( 'data-product-id' ),
1615				product_type = default_button.attr( 'data-product-type' );
1616
1617			wishlist_options.remove();
1618			$.each( wishlists, function ( i, v ) {
1619				if ( v[ 'default' ] ) {
1620					return;
1621				}
1622
1623				$( '<li>' ).append( $( '<a>', {
1624					'rel': 'nofollow',
1625					'html': v.wishlist_name,
1626					'class': 'add_to_wishlist',
1627					'href': v.add_to_this_wishlist_url,
1628					'data-product-id': product_id,
1629					'data-product-type': product_type,
1630					'data-wishlist-id': v.id
1631				} ) ).appendTo( t );
1632			} );
1633		} );
1634	}
1635
1636	/**
1637	 * Block item if possible
1638	 *
1639	 * @param item jQuery object
1640	 * @return void
1641	 * @since 3.0.0
1642	 */
1643	function block( item ) {
1644		if ( typeof $.fn.block !== 'undefined' ) {
1645			item.fadeTo( '400', '0.6' ).block( {
1646				message: null,
1647				overlayCSS: {
1648					background: 'transparent url(' + yith_wcwl_l10n.ajax_loader_url + ') no-repeat center',
1649					backgroundSize: '40px 40px',
1650					opacity: 1
1651				}
1652			} );
1653		}
1654	}
1655
1656	/**
1657	 * Unblock item if possible
1658	 *
1659	 * @param item jQuery object
1660	 * @return void
1661	 * @since 3.0.0
1662	 */
1663	function unblock( item ) {
1664		if ( typeof $.fn.unblock !== 'undefined' ) {
1665			item.stop( true ).css( 'opacity', '1' ).unblock();
1666		}
1667	}
1668
1669	/**
1670	 * Check if cookies are enabled
1671	 *
1672	 * @return bool
1673	 * @since 2.0.0
1674	 */
1675	function is_cookie_enabled() {
1676		if ( navigator.cookieEnabled ) {
1677			return true;
1678		}
1679
1680		// set and read cookie
1681		document.cookie = 'cookietest=1';
1682		var ret = document.cookie.indexOf( 'cookietest=' ) !== -1;
1683
1684		// delete cookie
1685		document.cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT';
1686
1687		return ret;
1688	}
1689
1690	/**
1691	 * Retrieve fragments that need to be refreshed in the page
1692	 *
1693	 * @param search string Ref to search among all fragments in the page
1694	 * @return object Object containing a property for each fragments that matches search
1695	 * @since 3.0.0
1696	 */
1697	function retrieve_fragments( search ) {
1698		var options = {},
1699			fragments = null;
1700
1701		if ( search ) {
1702			if ( typeof search === 'object' ) {
1703				search = $.extend( {
1704					fragments: null,
1705					s: '',
1706					container: $( document ),
1707					firstLoad: false
1708				}, search );
1709
1710				if ( ! search.fragments ) {
1711					fragments = search.container.find( '.wishlist-fragment' );
1712				} else {
1713					fragments = search.fragments;
1714				}
1715
1716				if ( search.s ) {
1717					fragments = fragments.not( '[data-fragment-ref]' ).add( fragments.filter( '[data-fragment-ref="' + search.s + '"]' ) );
1718				}
1719
1720				if ( search.firstLoad ) {
1721					fragments = fragments.filter( '.on-first-load' );
1722				}
1723			} else {
1724				fragments = $( '.wishlist-fragment' );
1725
1726				if ( typeof search === 'string' || typeof search === 'number' ) {
1727					fragments = fragments.not( '[data-fragment-ref]' ).add( fragments.filter( '[data-fragment-ref="' + search + '"]' ) );
1728				}
1729			}
1730		} else {
1731			fragments = $( '.wishlist-fragment' );
1732		}
1733
1734		if ( fragments.length ) {
1735			fragments.each( function () {
1736				var t = $( this ),
1737					id = t.attr( 'class' ).split( ' ' ).filter( ( val ) => {
1738						return val.length && val !== 'exists';
1739					} ).join( yith_wcwl_l10n.fragments_index_glue );
1740
1741				options[ id ] = t.data( 'fragment-options' );
1742			} );
1743		} else {
1744			return null;
1745		}
1746
1747		return options;
1748	}
1749
1750	/**
1751	 * Load fragments on page loading
1752	 *
1753	 * @param search string Ref to search among all fragments in the page
1754	 * @since 3.0.0
1755	 */
1756	function load_fragments( search ) {
1757		search = $.extend( {
1758			firstLoad: true
1759		}, search );
1760
1761		var fragments = retrieve_fragments( search );
1762
1763		if ( ! fragments ) {
1764			return;
1765		}
1766
1767		$.ajax( {
1768			data: {
1769				action: yith_wcwl_l10n.actions.load_fragments,
1770				nonce: yith_wcwl_l10n.nonce.load_fragments_nonce,
1771				context: 'frontend',
1772				fragments: fragments
1773			},
1774			method: 'post',
1775			success: function ( data ) {
1776				if ( typeof data.fragments !== 'undefined' ) {
1777					replace_fragments( data.fragments, search );
1778
1779					init_handling_after_ajax();
1780
1781					$( document ).trigger( 'yith_wcwl_fragments_loaded', [ fragments, data.fragments, search.firstLoad ] );
1782
1783				}
1784			},
1785			url: yith_wcwl_l10n.ajax_url
1786		} );
1787	}
1788
1789	/**
1790	 * Replace fragments with template received
1791	 *
1792	 * @param fragments array Array of fragments to replace
1793	 * @param data additional data passed to the trigger
1794	 * @since 3.0.0
1795	 */
1796	function replace_fragments( fragments, data = {} ) {
1797		$.each( fragments, function ( i, v ) {
1798			var itemSelector = '.' + i.split( yith_wcwl_l10n.fragments_index_glue ).filter( ( val ) => {
1799					return val.length && val !== 'exists' && val !== 'with-count';
1800				} ).join( '.' ),
1801				toReplace = $( itemSelector );
1802
1803			// find replace template
1804			var replaceWith = $( v ).filter( itemSelector );
1805
1806			if ( ! replaceWith.length ) {
1807				replaceWith = $( v ).find( itemSelector );
1808			}
1809
1810			if ( toReplace.length && replaceWith.length ) {
1811				toReplace.replaceWith( replaceWith );
1812			}
1813		} );
1814
1815		$( document.body ).trigger( 'yith_wcwl_fragments_replaced', { fragments, data } );
1816	}
1817
1818	(() => {
1819		var applyBulkButton = $( 'input[name="apply_bulk_actions"]' );
1820
1821		function maybeDisableApplyBulkButton() {
1822			var buttons = $( '.product-checkbox input:checked' );
1823			applyBulkButton.prop( 'disabled', ! buttons.length );
1824		};
1825
1826		$( document ).on( 'change', '.product-checkbox input', maybeDisableApplyBulkButton );
1827		maybeDisableApplyBulkButton();
1828	})();
1829
1830	/**
1831	 * Check if device is an IOS device
1832	 * @since 2.2.11
1833	 */
1834	function isOS() {
1835		return navigator.userAgent.match( /ipad|iphone/i );
1836	}
1837
1838	/**
1839	 * Check if passed value could be considered true
1840	 * @since 3.0.14
1841	 */
1842	function isTrue( value ) {
1843		return true === value || 'yes' === value || '1' === value || 1 === value;
1844	}
1845} );

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.