PageSourceSearch

https://simplycharlottemason.com/wp-content/plugins/woo-smart-wishlist/assets/js/frontend.js?ver=6.2.0

js simplycharlottemason.com collected 2026-10-02 03:43:57 UTC 65,292 bytes, 1,789 lines download raw bytes

1'use strict';
2
3(function ($) {
4    var $storage = true;
5    var added_ids = [];
6    var key = Cookies.get('woosw_key');
7
8    try {
9        $storage = ('sessionStorage' in window && window.sessionStorage !== null);
10        window.sessionStorage.setItem('woosw', 'test');
11        window.sessionStorage.removeItem('woosw');
12    } catch (err) {
13        $storage = false;
14    }
15
16    $(function () {
17        if (key === null || key === undefined || key === '') {
18            key = woosw_get_key();
19            Cookies.set('woosw_key', key, {expires: 7});
20        }
21
22        // Load data for the first time
23        woosw_load_data();
24
25        if ($('.woosw-custom-menu-item').length || woosw_vars.reload_count === 'yes') {
26            // reload the count
27            woosw_load_count();
28        }
29
30        if ($('.woosw-list-ajax').length) {
31            // reload the list
32            woosw_load_list();
33        }
34
35        if (woosw_vars.added_to_cart === 'yes' && woosw_vars.auto_remove === 'yes') {
36            setTimeout(function () {
37                woosw_load_count();
38                woosw_get_data();
39            }, 300);
40        }
41
42        if (woosw_vars.button_action === 'message') {
43            $.notiny.addTheme('woosw', {
44                notification_class: 'notiny-theme-woosw',
45            });
46        }
47    });
48
49    $(document).on('change', '.woosw-switcher-dropdown', function () {
50        window.location = $(this).val();
51    });
52
53    $(document).on('woosw_refresh_data', function () {
54        woosw_get_data();
55    });
56
57    $(document).on('woosw_refresh_count', function () {
58        woosw_load_count();
59    });
60
61    $(document).on('woosw_wishlist_open', function () {
62        if ($('#woosw_wishlist').hasClass('woosw-loaded')) {
63            woosw_wishlist_show();
64        } else {
65            woosw_wishlist_load();
66        }
67    });
68
69    // woovr
70    $(document).on('woovr_selected', function (e, selected, variations) {
71        if (woosw_vars.variations === 'yes') {
72            var id = selected.attr('data-id');
73            var pid = selected.attr('data-pid');
74
75            if (id > 0) {
76                $('.woosw-btn-' + pid).attr('data-id', id).removeClass('woosw-btn-added woosw-added');
77
78                // refresh button
79                woosw_refresh_button_id(id);
80            } else {
81                $('.woosw-btn-' + pid).attr('data-id', pid).removeClass('woosw-btn-added woosw-added');
82
83                // refresh button
84                woosw_refresh_button_id(pid);
85            }
86        }
87    });
88
89    // found variation
90    $(document).on('found_variation', function (e, t) {
91        if (woosw_vars.variations === 'yes') {
92            var product_id = $(e['target']).attr('data-product_id');
93
94            // change id
95            $('.woosw-btn-' + product_id).attr('data-id', t.variation_id).removeClass('woosw-btn-added woosw-added');
96
97            // refresh button
98            woosw_refresh_button_id(t.variation_id);
99        }
100    });
101
102    // reset data
103    $(document).on('reset_data', function (e) {
104        if (woosw_vars.variations === 'yes') {
105            var product_id = $(e['target']).attr('data-product_id');
106
107            // change id
108            $('.woosw-btn-' + product_id).attr('data-id', product_id).removeClass('woosw-btn-added woosw-added');
109
110            // refresh button
111            woosw_refresh_button_id(product_id);
112        }
113    });
114
115    // auto remove
116    $(document.body).on('added_to_cart', function (e, fragments, cart_hash, $button) {
117        if (woosw_vars.auto_remove === 'yes') {
118            var product_id = parseInt($button.data('product_id'));
119
120            if ((product_id > 0) && $('.woosw-item-' + product_id).length) {
121                $('.woosw-item-' + product_id).remove();
122            }
123
124            woosw_load_count();
125            woosw_get_data();
126        }
127    });
128
129    // quick view
130    $(document).on('click touch', '#woosw_wishlist .woosq-link, #woosw_wishlist .woosq-btn', function (e) {
131        woosw_wishlist_hide();
132        e.preventDefault();
133    });
134
135    // add to wishlist
136    $(document).on('click touch', '.woosw-btn', function (e) {
137        var $this = $(this);
138
139        if ($this.hasClass('woosw-disabled') || $this.is(':disabled') || $this.attr('disabled')) {
140            var notice = $this.attr('title') || woosw_vars.login_message;
141
142            if (notice) {
143                woosw_notice(notice);
144            }
145
146            e.preventDefault();
147            return;
148        }
149
150        var id = $this.attr('data-id');
151        var pid = $this.attr('data-pid');
152        var product_id = $this.attr('data-product_id');
153        var product_name = $this.attr('data-product_name');
154        var product_image = $this.attr('data-product_image');
155
156        if (typeof pid !== typeof undefined && pid !== false) {
157            id = pid;
158        }
159
160        if (typeof product_id !== typeof undefined && product_id !== false) {
161            id = product_id;
162        }
163
164        if ($this.hasClass('woosw-added')) {
165            if (woosw_vars.button_action_added === 'remove') {
166                // remove from  wishlist
167                var data = {
168                    action: 'woosw_remove', product_id: id, key: key, nonce: woosw_vars.nonce,
169                };
170
171                $this.addClass('woosw-adding').find('.woosw-btn-icon').removeClass(woosw_vars.button_normal_icon + ' ' + woosw_vars.button_added_icon).addClass(woosw_vars.button_loading_icon);
172
173                $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_remove'), data, function (response) {
174                    $this.removeClass('woosw-adding').find('.woosw-btn-icon').removeClass(woosw_vars.button_loading_icon);
175
176                    if (response.content != null) {
177                        $('#woosw_wishlist').html(response.content).addClass('woosw-loaded');
178                    }
179
180                    if (response.notice != null) {
181                        woosw_notice(response.notice);
182                    }
183
184                    if (response.count != null) {
185                        woosw_change_count(response.count);
186                    }
187
188                    if (response.data) {
189                        if ($storage) {
190                            sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
191                        }
192
193                        if (response.data.fragments) {
194                            woosw_refresh_fragments(response.data.fragments);
195                        }
196
197                        if (response.data.ids) {
198                            woosw_refresh_buttons(response.data.ids);
199                            woosw_refresh_ids(response.data.ids);
200                        }
201                    }
202
203                    $(document.body).trigger('woosw_remove', [product_id]);
204                });
205            } else if (woosw_vars.button_action_added === 'page') {
206                // open wishlist page
207                window.location.href = woosw_vars.wishlist_url;
208            } else {
209                // open wishlist popup
210                if ($('#woosw_wishlist').hasClass('woosw-loaded')) {
211                    woosw_wishlist_show();
212                } else {
213                    woosw_wishlist_load();
214                }
215            }
216        } else {
217            // add product - check if choose wishlist is enabled
218            if (woosw_vars.choose_wishlist === 'yes' && woosw_vars.enable_multiple === 'yes' && $('#woosw_choose').length) {
219                // fetch wishlists and show choose popup
220                var choose_data = {
221                    action: 'woosw_get_wishlists', nonce: woosw_vars.nonce,
222                };
223
224                $this.addClass('woosw-adding').find('.woosw-btn-icon').removeClass(woosw_vars.button_normal_icon + ' ' + woosw_vars.button_added_icon).addClass(woosw_vars.button_loading_icon);
225
226                $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_get_wishlists'), choose_data, function (response) {
227                    $this.removeClass('woosw-adding').find('.woosw-btn-icon').removeClass(woosw_vars.button_loading_icon);
228
229                    if (response.wishlists && response.wishlists.length > 1) {
230                        // build and show choose popup
231                        woosw_choose_build(response.wishlists, id, product_name, product_image, response.can_add_more);
232                        woosw_choose_show();
233                    } else if (response.can_add_more || (response.wishlists && response.wishlists.length === 1)) {
234                        // 1 wishlist or can add more: show choose popup anyway
235                        woosw_choose_build(response.wishlists || [], id, product_name, product_image, response.can_add_more);
236                        woosw_choose_show();
237                    } else {
238                        // only 1 wishlist, add directly
239                        woosw_add_product($this, id, product_name, product_image);
240                    }
241                });
242            } else {
243                // add directly (original behavior)
244                woosw_add_product($this, id, product_name, product_image);
245            }
246        }
247
248        e.preventDefault();
249    });
250
251    // choose wishlist - select a wishlist item
252    $(document).on('click touch', '.woosw-choose-item', function (e) {
253        e.preventDefault();
254        var $this = $(this);
255        var selected_key = $this.data('key');
256        var product_id = $('#woosw_choose').data('product_id');
257        var product_name = $('#woosw_choose').data('product_name');
258        var product_image = $('#woosw_choose').data('product_image');
259
260        // highlight selected item
261        $('.woosw-choose-item').removeClass('woosw-choose-item-active');
262        $this.addClass('woosw-choose-item-active');
263
264        woosw_popup_loading();
265
266        // set default wishlist first
267        var set_data = {
268            action: 'woosw_set_default', key: selected_key, nonce: woosw_vars.nonce,
269        };
270
271        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_set_default'), set_data, function (response) {
272            // update cookie key
273            key = selected_key;
274            Cookies.set('woosw_key', selected_key, {expires: 7});
275
276            if (response.count != null) {
277                woosw_change_count(response.count);
278            }
279
280            if (response.data) {
281                if ($storage) {
282                    sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
283                }
284
285                if (response.data.fragments) {
286                    woosw_refresh_fragments(response.data.fragments);
287                }
288
289                if (response.data.ids) {
290                    woosw_refresh_buttons(response.data.ids);
291                    woosw_refresh_ids(response.data.ids);
292                }
293            }
294
295            // now add the product
296            var add_data = {
297                action: 'woosw_add', product_id: product_id, nonce: woosw_vars.nonce,
298            };
299
300            $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_add'), add_data, function (add_response) {
301                woosw_choose_hide();
302                woosw_popup_loaded();
303
304                if (woosw_vars.button_action === 'list') {
305                    if (add_response.content != null) {
306                        $('#woosw_wishlist').html(add_response.content).addClass('woosw-loaded');
307                    }
308
309                    if (add_response.notice != null) {
310                        woosw_notice(add_response.notice.replace('{name}', '<strong>' + product_name + '</strong>'));
311                    }
312
313                    woosw_perfect_scrollbar();
314                    woosw_wishlist_show();
315                }
316
317                if (woosw_vars.button_action === 'message') {
318                    $('#woosw_wishlist').removeClass('woosw-loaded');
319
320                    $.notiny({
321                        theme: 'woosw',
322                        position: woosw_vars.message_position,
323                        image: product_image,
324                        text: add_response.notice.replace('{name}', '<strong>' + product_name + '</strong>'),
325                    });
326                }
327
328                if (woosw_vars.button_action === 'no') {
329                    $('#woosw_wishlist').removeClass('woosw-loaded');
330                }
331
332                if (add_response.count != null) {
333                    woosw_change_count(add_response.count);
334                }
335
336                if (add_response.status === 1) {
337                    woosw_refresh_button_id(product_id);
338                }
339
340                if (add_response.data) {
341                    if ($storage) {
342                        sessionStorage.setItem('woosw_data_' + add_response.data.key, JSON.stringify(add_response.data));
343                    }
344
345                    if (add_response.data.fragments) {
346                        woosw_refresh_fragments(add_response.data.fragments);
347                    }
348
349                    if (add_response.data.ids) {
350                        woosw_refresh_buttons(add_response.data.ids);
351                        woosw_refresh_ids(add_response.data.ids);
352                    }
353                }
354
355                $(document.body).trigger('woosw_add', [product_id]);
356            });
357        });
358    });
359
360    // choose wishlist - close popup
361    $(document).on('click touch', '#woosw_choose .woosw-popup-close', function (e) {
362        woosw_choose_hide();
363        e.preventDefault();
364    });
365
366    // choose wishlist - click on overlay area
367    $(document).on('click touch', '#woosw_choose', function (e) {
368        if (!$(e.target).closest('.woosw-popup-content').length) {
369            woosw_choose_hide();
370        }
371    });
372
373    // choose wishlist - save new wishlist
374    function woosw_choose_save_new($row) {
375        var $input = $row.find('.woosw-choose-new-name');
376        var $saveBtn = $row.find('.woosw-choose-new-save');
377        var name = $.trim($input.val());
378
379        if (name === '') {
380            $input.addClass('woosw-rename-error').trigger('focus');
381            return;
382        }
383
384        $input.removeClass('woosw-rename-error');
385        $saveBtn.prop('disabled', true);
386        $row.addClass('woosw-choose-add-new-loading');
387
388        var data = {
389            action: 'woosw_add_wishlist',
390            name: name,
391            nonce: woosw_vars.nonce,
392        };
393
394        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_add_wishlist'), data, function (response) {
395            $saveBtn.prop('disabled', false);
396            $row.removeClass('woosw-choose-add-new-loading');
397
398            // Re-fetch to get the new wishlist key
399            var refetch_data = {
400                action: 'woosw_get_wishlists',
401                nonce: woosw_vars.nonce,
402            };
403
404            $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_get_wishlists'), refetch_data, function (wl_response) {
405                if (!wl_response.wishlists) return;
406
407                // Find newly added wishlist by name
408                var newWl = null;
409                $.each(wl_response.wishlists, function (i, wl) {
410                    if (wl.name === name) {
411                        newWl = wl;
412                    }
413                });
414
415                if (!newWl) {
416                    newWl = wl_response.wishlists[wl_response.wishlists.length - 1];
417                }
418
419                if (newWl) {
420                    // Insert new row into the choose list, above the add-new row
421                    var $list = $('#woosw_choose .woosw-choose-list');
422                    var $newItem = $('<div>', {
423                        'class': 'woosw-choose-item woosw-choose-item-new',
424                        'data-key': newWl.key,
425                    });
426                    $newItem.append($('<span>', { 'class': 'woosw-choose-item-name', text: newWl.name }));
427                    $newItem.append($('<span>', { 'class': 'woosw-choose-item-count', text: '(0)' }));
428                    $list.append($newItem);
429
430                    // Clear input for next entry
431                    $input.val('').trigger('focus');
432
433                    // Hide the add-new row if no more slots remain
434                    if (!wl_response.can_add_more) {
435                        $row.hide();
436                    }
437                }
438            });
439        }).fail(function () {
440            $saveBtn.prop('disabled', false);
441            $row.removeClass('woosw-choose-add-new-loading');
442            $input.addClass('woosw-rename-error').trigger('focus');
443        });
444    }
445
446    $(document).on('click touch', '.woosw-choose-new-save', function (e) {
447        e.preventDefault();
448        e.stopPropagation();
449        woosw_choose_save_new($(this).closest('.woosw-choose-add-new'));
450    });
451
452    $(document).on('keydown', '.woosw-choose-new-name', function (e) {
453        if (e.key === 'Enter') {
454            e.preventDefault();
455            woosw_choose_save_new($(this).closest('.woosw-choose-add-new'));
456        }
457    });
458
459    // add product
460    $(document).on('click touch', '.woosw-item--add span', function (e) {
461        var $this = $(this);
462        var key = $this.closest('.woosw-items').data('key');
463        var $this_item = $this.closest('.woosw-item');
464        var product_id = $this_item.attr('data-id');
465        var product_name = $this_item.attr('data-product_name');
466        var data = {
467            action: 'woosw_add', product_id: product_id, key: key, nonce: woosw_vars.nonce,
468        };
469
470        $this.addClass('woosw-item--adding');
471
472        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_add'), data, function (response) {
473            $this.addClass('woosw-item--adding');
474
475            if (response.content != null) {
476                $('#woosw_wishlist').html(response.content).addClass('woosw-loaded');
477            }
478
479            if (response.notice != null) {
480                woosw_notice(response.notice.replace('{name}', '<strong>' + product_name + '</strong>'));
481            }
482
483            if (response.count != null) {
484                woosw_change_count(response.count);
485            }
486
487            if (response.data) {
488                if ($storage) {
489                    sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
490                }
491
492                if (response.data.fragments) {
493                    woosw_refresh_fragments(response.data.fragments);
494                }
495
496                if (response.data.ids) {
497                    woosw_refresh_buttons(response.data.ids);
498                    woosw_refresh_ids(response.data.ids);
499                }
500            }
501
502            $(document.body).trigger('woosw_add', [product_id]);
503
504            // list shortcode
505            if ($this.closest('.woosw-list').length) {
506                location.reload();
507            }
508        });
509
510        e.preventDefault();
511    });
512
513    // remove product
514    $(document).on('click touch', '.woosw-item--remove span', function (e) {
515        var $this = $(this);
516        var key = $this.closest('.woosw-items').data('key');
517        var $this_item = $this.closest('.woosw-item');
518        var product_id = $this_item.attr('data-id');
519        var data = {
520            action: 'woosw_remove', product_id: product_id, key: key, nonce: woosw_vars.nonce,
521        };
522
523        $this.addClass('woosw-item--removing');
524
525        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_remove'), data, function (response) {
526            $this.removeClass('woosw-item--removing');
527            $this_item.remove();
528
529            // Reset add button in search results if present
530            $('.woosw-search-result-item[data-id="' + product_id + '"] .woosw-search-add-btn')
531                .removeClass('is-added')
532                .prop('disabled', false)
533                .html('<span class="woosw-search-add-icon">+</span> ' + (woosw_vars.add_text || 'Add'));
534
535            if (response.content != null) {
536                $('#woosw_wishlist').html(response.content).addClass('woosw-loaded');
537            }
538
539            if (response.notice != null) {
540                woosw_notice(response.notice);
541            }
542
543            if (response.count != null) {
544                woosw_change_count(response.count);
545            }
546
547            if (response.data) {
548                if ($storage) {
549                    sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
550                }
551
552                if (response.data.fragments) {
553                    woosw_refresh_fragments(response.data.fragments);
554                }
555
556                if (response.data.ids) {
557                    woosw_refresh_buttons(response.data.ids);
558                    woosw_refresh_ids(response.data.ids);
559                }
560            }
561
562            $(document.body).trigger('woosw_remove', [product_id]);
563        });
564
565        e.preventDefault();
566    });
567
568    // empty wishlist
569    $(document).on('click touch', '.woosw-empty', function (e) {
570        var $this = $(this);
571
572        if (confirm(woosw_vars.empty_confirm)) {
573            woosw_popup_loading();
574
575            var key = $this.data('key');
576            var data = {
577                action: 'woosw_empty', key: key, nonce: woosw_vars.nonce,
578            };
579
580            $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_empty'), data, function (response) {
581                if (response.content != null) {
582                    $('#woosw_wishlist').html(response.content).addClass('woosw-loaded');
583                }
584
585                if (response.notice != null) {
586                    woosw_notice(response.notice);
587                }
588
589                if (response.count != null) {
590                    woosw_change_count(response.count);
591                }
592
593                if (response.data) {
594                    if ($storage) {
595                        sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
596                    }
597
598                    if (response.data.fragments) {
599                        woosw_refresh_fragments(response.data.fragments);
600                    }
601
602                    if (response.data.ids) {
603                        woosw_refresh_buttons(response.data.ids);
604                        woosw_refresh_ids(response.data.ids);
605                    }
606                }
607
608                woosw_popup_loaded();
609
610                $(document.body).trigger('woosw_empty', [key]);
611            });
612        }
613
614        e.preventDefault();
615    });
616
617    // click on area
618    $(document).on('click touch', '.woosw-popup', function (e) {
619        var woosw_content = $('.woosw-popup-content');
620
621        if (!$(e.target).closest(woosw_content).length) {
622            woosw_wishlist_hide();
623            woosw_manage_hide();
624        }
625    });
626
627    // continue
628    $(document).on('click touch', '.woosw-continue', function (e) {
629        var url = $(this).attr('data-url');
630        woosw_wishlist_hide();
631
632        if (url !== '') {
633            window.location.href = url;
634        }
635
636        e.preventDefault();
637    });
638
639    // close
640    $(document).on('click touch', '#woosw_wishlist .woosw-popup-close', function (e) {
641        woosw_wishlist_hide();
642        e.preventDefault();
643    });
644
645    // manage close
646    $(document).on('click touch', '#woosw_manage .woosw-popup-close', function (e) {
647        woosw_manage_hide();
648        e.preventDefault();
649    });
650
651    // manage wishlists
652    $(document).on('click touch', '.woosw-manage', function (e) {
653        e.preventDefault();
654        woosw_popup_loading();
655
656        var data = {
657            action: 'woosw_manage_wishlists', nonce: woosw_vars.nonce,
658        };
659
660        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_manage_wishlists'), data, function (response) {
661            woosw_wishlist_hide();
662            $('#woosw_manage').html(response);
663            woosw_manage_show();
664            woosw_popup_loaded();
665        });
666    });
667
668    // add wishlist
669    $(document).on('click touch', '#woosw_add_wishlist', function (e) {
670        e.preventDefault();
671        woosw_popup_loading();
672
673        var name = $('#woosw_wishlist_name').val();
674        var data = {
675            action: 'woosw_add_wishlist', name: name, nonce: woosw_vars.nonce,
676        };
677
678        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_add_wishlist'), data, function (response) {
679            $('#woosw_manage').html(response);
680            $('#woosw_wishlist').removeClass('woosw-loaded');
681            woosw_popup_loaded();
682        });
683    });
684
685    // set default
686    $(document).on('click touch', '.woosw-set-default', function (e) {
687        e.preventDefault();
688        woosw_popup_loading();
689
690        var key = $(this).data('key');
691        var data = {
692            action: 'woosw_set_default', key: key, nonce: woosw_vars.nonce,
693        };
694
695        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_set_default'), data, function (response) {
696            if (response.count != null) {
697                woosw_change_count(response.count);
698            }
699
700            if ((response.products != null) && response.products.length) {
701                response.products.forEach((product_id) => {
702                    woosw_refresh_button_id(product_id);
703                });
704            }
705
706            $('#woosw_manage').html(response.content);
707
708            if (response.data) {
709                if ($storage) {
710                    sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
711                }
712
713                if (response.data.fragments) {
714                    woosw_refresh_fragments(response.data.fragments);
715                }
716
717                if (response.data.ids) {
718                    woosw_refresh_buttons(response.data.ids);
719                    woosw_refresh_ids(response.data.ids);
720                }
721            }
722
723            $('#woosw_wishlist').removeClass('woosw-loaded');
724            woosw_popup_loaded();
725        });
726    });
727
728    // delete wishlist
729    $(document).on('click touch', '.woosw-delete-wishlist', function (e) {
730        e.preventDefault();
731
732        if (confirm(woosw_vars.delete_confirm)) {
733            woosw_popup_loading();
734
735            var key = $(this).data('key');
736            var data = {
737                action: 'woosw_delete_wishlist', key: key, nonce: woosw_vars.nonce,
738            };
739
740            $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_delete_wishlist'), data, function (response) {
741                $('#woosw_manage').html(response);
742                $('#woosw_wishlist').removeClass('woosw-loaded');
743                woosw_popup_loaded();
744            });
745        }
746    });
747
748    // quick rename wishlist
749    $(document).on('click touch', '.woosw-rename-btn', function (e) {
750        e.preventDefault();
751        e.stopPropagation();
752
753        var $btn = $(this);
754        var $wrap = $btn.closest('.woosw-item-name-wrap');
755        var $link = $wrap.find('.woosw-view-wishlist');
756        var $count = $wrap.closest('.woosw-item-inner').find('.woosw-item-count');
757        var key = $btn.data('key');
758        var currentName = $btn.data('name');
759
760        if ($wrap.hasClass('woosw-renaming')) {
761            return;
762        }
763
764        $wrap.addClass('woosw-renaming');
765
766        var $input = $('<input>', {
767            type: 'text',
768            'class': 'woosw-rename-input',
769            val: currentName,
770            maxlength: 200,
771        });
772
773        var $saveBtn = $('<button>', {
774            type: 'button',
775            'class': 'woosw-rename-save',
776            html: '&#10003;',
777            title: woosw_vars.save_text || 'Save',
778        });
779
780        var $cancelBtn = $('<button>', {
781            type: 'button',
782            'class': 'woosw-rename-cancel',
783            html: '&#215;',
784            title: woosw_vars.cancel_text || 'Cancel',
785        });
786
787        $link.hide();
788        $btn.hide();
789        if ($count.length) {
790            $count.hide();
791        }
792        $wrap.append($input).append($saveBtn).append($cancelBtn);
793        $input.trigger('focus').trigger('select');
794
795        function cancelEdit() {
796            $input.remove();
797            $saveBtn.remove();
798            $cancelBtn.remove();
799            $link.show();
800            $btn.show();
801            if ($count.length) {
802                $count.show();
803            }
804            $wrap.removeClass('woosw-renaming');
805        }
806
807        function saveEdit() {
808            var newName = $.trim($input.val());
809
810            if (newName === '') {
811                $input.addClass('woosw-rename-error').trigger('focus');
812                return;
813            }
814
815            if (newName === currentName) {
816                cancelEdit();
817                return;
818            }
819
820            $saveBtn.prop('disabled', true);
821            $cancelBtn.prop('disabled', true);
822            $wrap.addClass('woosw-rename-saving');
823
824            var data = {
825                action: 'woosw_rename_wishlist',
826                key: key,
827                name: newName,
828                nonce: woosw_vars.nonce,
829            };
830
831            $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_rename_wishlist'), data, function (response) {
832                $wrap.removeClass('woosw-rename-saving');
833
834                if (response && response.status === 1) {
835                    var savedName = response.name;
836                    $link.text(savedName);
837                    $btn.data('name', savedName);
838                    currentName = savedName;
839                } else {
840                    $input.addClass('woosw-rename-error').prop('disabled', false).trigger('focus');
841                    $saveBtn.prop('disabled', false);
842                    $cancelBtn.prop('disabled', false);
843                    return;
844                }
845
846                cancelEdit();
847            }).fail(function () {
848                $wrap.removeClass('woosw-rename-saving');
849                $input.addClass('woosw-rename-error').prop('disabled', false).trigger('focus');
850                $saveBtn.prop('disabled', false);
851                $cancelBtn.prop('disabled', false);
852            });
853        }
854
855        $input.on('keydown', function (e) {
856            if (e.key === 'Enter') {
857                e.preventDefault();
858                saveEdit();
859            } else if (e.key === 'Escape') {
860                cancelEdit();
861            }
862        });
863
864        $saveBtn.on('click touch', function (e) {
865            e.preventDefault();
866            saveEdit();
867        });
868
869        $cancelBtn.on('click touch', function (e) {
870            e.preventDefault();
871            cancelEdit();
872        });
873    });
874
875    // quick rename on wishlist detail page
876    $(document).on('click touch', '.woosw-detail-rename-btn', function (e) {
877        e.preventDefault();
878        e.stopPropagation();
879
880        var $btn = $(this);
881        var $nameWrap = $btn.closest('.woosw-detail-name-wrap');
882        var key = $btn.data('key');
883        var currentName = $btn.data('name');
884
885        if ($nameWrap.hasClass('woosw-detail-renaming')) {
886            return;
887        }
888
889        $nameWrap.addClass('woosw-detail-renaming');
890
891        // Hide existing text nodes (keep btn hidden too)
892        $nameWrap.contents().filter(function () {
893            return this.nodeType === 3;
894        }).hide ? null : null;
895
896        // Wrap text in a temporary span to hide it easily
897        var $textSpan = $nameWrap.find('.woosw-detail-name-text');
898        if (!$textSpan.length) {
899            // Replace text node with a span so we can toggle it
900            $nameWrap.contents().filter(function () {
901                return this.nodeType === 3 && $.trim(this.nodeValue) !== '';
902            }).wrap('<span class="woosw-detail-name-text"></span>');
903            $textSpan = $nameWrap.find('.woosw-detail-name-text');
904        }
905        $textSpan.hide();
906        $btn.hide();
907
908        var $input = $('<input>', {
909            type: 'text',
910            'class': 'woosw-detail-rename-input',
911            val: currentName,
912            maxlength: 200,
913        });
914
915        var $saveBtn = $('<button>', {
916            type: 'button',
917            'class': 'woosw-detail-rename-save',
918            html: '&#10003;',
919            title: woosw_vars.save_text || 'Save',
920        });
921
922        var $cancelBtn = $('<button>', {
923            type: 'button',
924            'class': 'woosw-detail-rename-cancel',
925            html: '&#215;',
926            title: woosw_vars.cancel_text || 'Cancel',
927        });
928
929        $nameWrap.append($input).append($saveBtn).append($cancelBtn);
930        $input.trigger('focus').trigger('select');
931
932        function cancelDetailEdit() {
933            $input.remove();
934            $saveBtn.remove();
935            $cancelBtn.remove();
936            $textSpan.show();
937            $btn.show();
938            $nameWrap.removeClass('woosw-detail-renaming');
939        }
940
941        function saveDetailEdit() {
942            var newName = $.trim($input.val());
943
944            if (newName === '') {
945                $input.addClass('woosw-rename-error').trigger('focus');
946                return;
947            }
948
949            if (newName === currentName) {
950                cancelDetailEdit();
951                return;
952            }
953
954            $saveBtn.prop('disabled', true);
955            $cancelBtn.prop('disabled', true);
956            $nameWrap.addClass('woosw-rename-saving');
957
958            var data = {
959                action: 'woosw_rename_wishlist',
960                key: key,
961                name: newName,
962                nonce: woosw_vars.nonce,
963            };
964
965            $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_rename_wishlist'), data, function (response) {
966                $nameWrap.removeClass('woosw-rename-saving');
967
968                if (response && response.status === 1) {
969                    var savedName = response.name;
970                    $textSpan.text(savedName);
971                    $btn.data('name', savedName);
972                    currentName = savedName;
973
974                    // Update switcher dropdown option if present
975                    $('.woosw-switcher-dropdown option[data-key="' + key + '"]').each(function () {
976                        var $opt = $(this);
977                        var optText = $opt.text();
978                        // Replace name part before ' (' count separator
979                        var parenIdx = optText.lastIndexOf(' (');
980                        if (parenIdx > -1) {
981                            $opt.text(savedName + optText.substring(parenIdx));
982                        } else {
983                            $opt.text(savedName);
984                        }
985                    });
986                } else {
987                    $input.addClass('woosw-rename-error').prop('disabled', false).trigger('focus');
988                    $saveBtn.prop('disabled', false);
989                    $cancelBtn.prop('disabled', false);
990                    return;
991                }
992
993                cancelDetailEdit();
994            }).fail(function () {
995                $nameWrap.removeClass('woosw-rename-saving');
996                $input.addClass('woosw-rename-error').prop('disabled', false).trigger('focus');
997                $saveBtn.prop('disabled', false);
998                $cancelBtn.prop('disabled', false);
999            });
1000        }
1001
1002        $input.on('keydown', function (e) {
1003            if (e.key === 'Enter') {
1004                e.preventDefault();
1005                saveDetailEdit();
1006            } else if (e.key === 'Escape') {
1007                cancelDetailEdit();
1008            }
1009        });
1010
1011        $saveBtn.on('click touch', function (e) {
1012            e.preventDefault();
1013            saveDetailEdit();
1014        });
1015
1016        $cancelBtn.on('click touch', function (e) {
1017            e.preventDefault();
1018            cancelDetailEdit();
1019        });
1020    });
1021
1022    // view wishlist
1023    $(document).on('click touch', '.woosw-view-wishlist', function (e) {
1024        e.preventDefault();
1025        woosw_popup_loading();
1026
1027        var key = $(this).data('key');
1028        var data = {
1029            action: 'woosw_view_wishlist', key: key, nonce: woosw_vars.nonce,
1030        };
1031
1032        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_view_wishlist'), data, function (response) {
1033            woosw_manage_hide();
1034            $('#woosw_wishlist').removeClass('woosw-loaded').html(response);
1035            woosw_wishlist_show();
1036            woosw_popup_loaded();
1037        });
1038    });
1039
1040    // menu item
1041    $(document).on('click touch', '.woosw-menu-item a, .woosw-menu a, .woosw-link.woosw-link-auto a', function (e) {
1042        if (woosw_vars.menu_action === 'open_popup') {
1043            e.preventDefault();
1044
1045            if ($('#woosw_wishlist').hasClass('woosw-loaded')) {
1046                woosw_wishlist_show();
1047            } else {
1048                woosw_wishlist_load();
1049            }
1050        }
1051    });
1052
1053    // link popup
1054    $(document).on('click touch', '.woosw-link.woosw-link-popup a', function (e) {
1055        e.preventDefault();
1056
1057        if ($('#woosw_wishlist').hasClass('woosw-loaded')) {
1058            woosw_wishlist_show();
1059        } else {
1060            woosw_wishlist_load();
1061        }
1062    });
1063
1064    // account link
1065    $(document).on('click touch', '.woocommerce-MyAccount-navigation-link--wishlist a', function (e) {
1066        if (woosw_vars.page_myaccount === 'yes_popup') {
1067            e.preventDefault();
1068
1069            if ($('#woosw_wishlist').hasClass('woosw-loaded')) {
1070                woosw_wishlist_show();
1071            } else {
1072                woosw_wishlist_load();
1073            }
1074        }
1075    });
1076
1077    // copy link
1078    $(document).on('click touch', '#woosw_copy_url, #woosw_copy_btn', function (e) {
1079        e.preventDefault();
1080        let $link = $('#woosw_copy_url');
1081        let link = $link.val();
1082
1083        navigator.clipboard.writeText(link).then(function () {
1084            alert(woosw_vars.copied_text + ' ' + link);
1085        }, function () {
1086            alert('Failure to copy!');
1087        });
1088
1089        $link.select();
1090    });
1091
1092    // add note
1093    $(document).on('click touch', '.woosw-item--note', function () {
1094        if ($(this).closest('.woosw-item').find('.woosw-item--note-add').length) {
1095            $(this).closest('.woosw-item').find('.woosw-item--note-add').show();
1096            $(this).hide();
1097        }
1098    });
1099
1100    $(document).on('click touch', '.woosw_add_note', function (e) {
1101        e.preventDefault();
1102        woosw_popup_loading();
1103
1104        var $this = $(this);
1105        var key = $this.closest('.woosw-items').data('key');
1106        var product_id = $this.closest('.woosw-item').attr('data-id');
1107        var note = $this.closest('.woosw-item').find('input[type="text"]').val();
1108        var data = {
1109            action: 'woosw_add_note',
1110            key: key,
1111            product_id: product_id,
1112            note: woosw_html_entities(note),
1113            nonce: woosw_vars.nonce,
1114        };
1115
1116        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_add_note'), data, function (response) {
1117            $this.closest('.woosw-item').find('.woosw-item--note').html(response).show();
1118            $this.closest('.woosw-item').find('.woosw-item--note-add').hide();
1119            woosw_popup_loaded();
1120        });
1121    });
1122
1123    // search/filter products
1124    $(document).on('input', '.woosw-search-input', function () {
1125        var keyword = $(this).val().toLowerCase().trim();
1126        var $items = $(this).closest('.woosw-popup-content').find('.woosw-items:not(.woosw-suggested-items) .woosw-item');
1127
1128        if (keyword === '') {
1129            $items.show();
1130            // show suggested section
1131            $(this).closest('.woosw-popup-content').find('.woosw-suggested, .woosw-suggested-items').show();
1132        } else {
1133            $items.each(function () {
1134                var name = ($(this).attr('data-name') || '').toLowerCase();
1135                var note = ($(this).attr('data-note') || '').toLowerCase();
1136
1137                if (name.indexOf(keyword) > -1 || note.indexOf(keyword) > -1) {
1138                    $(this).show();
1139                } else {
1140                    $(this).hide();
1141                }
1142            });
1143
1144            // hide suggested section when searching
1145            $(this).closest('.woosw-popup-content').find('.woosw-suggested, .woosw-suggested-items').hide();
1146        }
1147    });
1148
1149    // clear search on popup close
1150    $(document).on('click touch', '#woosw_wishlist .woosw-popup-close, .woosw-continue', function () {
1151        $('.woosw-search-input').val('').trigger('input');
1152    });
1153
1154    // resize
1155    $(window).on('resize', function () {
1156        woosw_fix_height();
1157    });
1158
1159    function woosw_wishlist_load() {
1160        var data = {
1161            action: 'woosw_load', nonce: woosw_vars.nonce,
1162        };
1163
1164        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_load'), data, function (response) {
1165            if (response.content != null) {
1166                $('#woosw_wishlist').html(response.content);
1167            }
1168
1169            if (response.count != null) {
1170                if ($('#woosw_wishlist .woosw-items:not(.woosw-suggested-items) .woosw-item').length && ($('#woosw_wishlist .woosw-items:not(.woosw-suggested-items) .woosw-item').length != response.count)) {
1171                    woosw_change_count($('#woosw_wishlist .woosw-items:not(.woosw-suggested-items) .woosw-item').length);
1172                } else {
1173                    woosw_change_count(response.count);
1174                }
1175            }
1176
1177            if (response.notice != null) {
1178                woosw_notice(response.notice);
1179            }
1180
1181            $('#woosw_wishlist').addClass('woosw-loaded');
1182
1183            woosw_perfect_scrollbar();
1184            woosw_wishlist_show();
1185        });
1186    }
1187
1188    function woosw_load_count() {
1189        var data = {
1190            action: 'woosw_load_count', nonce: woosw_vars.nonce,
1191        };
1192
1193        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_load_count'), data, function (response) {
1194            if (response.count != null) {
1195                var count = response.count;
1196
1197                woosw_change_count(count);
1198                $(document.body).trigger('woosw_load_count', [count]);
1199            }
1200        });
1201    }
1202
1203    function woosw_load_list() {
1204        var data = {
1205            action: 'woosw_load_list', nonce: woosw_vars.nonce,
1206        };
1207
1208        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_load_list'), data, function (response) {
1209            if (response.list != null) {
1210                $('.woosw-list-ajax').replaceWith(response.list);
1211            }
1212        });
1213    }
1214
1215    function woosw_wishlist_show() {
1216        $('#woosw_wishlist').addClass('woosw-show');
1217        woosw_fix_height();
1218
1219        $(document.body).trigger('woosw_wishlist_show');
1220    }
1221
1222    function woosw_wishlist_hide() {
1223        $('#woosw_wishlist').removeClass('woosw-show');
1224        $(document.body).trigger('woosw_wishlist_hide');
1225    }
1226
1227    function woosw_manage_show() {
1228        $('#woosw_manage').addClass('woosw-show');
1229        $(document.body).trigger('woosw_manage_show');
1230    }
1231
1232    function woosw_manage_hide() {
1233        $('#woosw_manage').removeClass('woosw-show');
1234        $(document.body).trigger('woosw_manage_hide');
1235    }
1236
1237    function woosw_popup_loading() {
1238        $('.woosw-popup').addClass('woosw-loading');
1239    }
1240
1241    function woosw_popup_loaded() {
1242        $('.woosw-popup').removeClass('woosw-loading');
1243    }
1244
1245    function woosw_change_count(count) {
1246        $('#woosw_wishlist .woosw-count').html(count);
1247        $('.woosw-link .woosw-link-inner').attr('data-count', count);
1248
1249        if (parseInt(count) > 0) {
1250            $('.woosw-empty').show();
1251        } else {
1252            $('.woosw-empty').hide();
1253        }
1254
1255        if ($('.woosw-menu-item .woosw-menu-item-inner').length) {
1256            $('.woosw-menu-item .woosw-menu-item-inner').attr('data-count', count);
1257        } else {
1258            $('.woosw-menu-item a').html('<span class="woosw-menu-item-inner" data-count="' + count + '"><i class="woosw-icon"></i><span>' + woosw_vars.menu_text + '</span></span>');
1259        }
1260
1261        $(document.body).trigger('woosw_change_count', [count]);
1262    }
1263
1264    function woosw_notice(notice) {
1265        $('.woosw-notice').html(notice);
1266        woosw_notice_show();
1267        setTimeout(function () {
1268            woosw_notice_hide();
1269        }, 3000);
1270    }
1271
1272    function woosw_notice_show() {
1273        $('#woosw_wishlist .woosw-notice').addClass('woosw-notice-show');
1274    }
1275
1276    function woosw_notice_hide() {
1277        $('#woosw_wishlist .woosw-notice').removeClass('woosw-notice-show');
1278    }
1279
1280    function woosw_perfect_scrollbar() {
1281        if (woosw_vars.perfect_scrollbar === 'yes') {
1282            jQuery('#woosw_wishlist .woosw-popup-content-mid').perfectScrollbar({theme: 'wpc'});
1283        }
1284    }
1285
1286    function woosw_html_entities(str) {
1287        return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
1288    }
1289
1290    function woosw_get_key() {
1291        var result = [];
1292        var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
1293        var charactersLength = characters.length;
1294
1295        for (var i = 0; i < 6; i++) {
1296            result.push(characters.charAt(Math.floor(Math.random() * charactersLength)));
1297        }
1298
1299        return result.join('');
1300    }
1301
1302    function woosw_fix_height() {
1303        // fix for center only
1304        jQuery('.woosw-popup-center .woosw-popup-content').height(2 * Math.floor(jQuery('.woosw-popup-center .woosw-popup-content').height() / 2) + 2);
1305    }
1306
1307    function woosw_load_data() {
1308        // don't use sessionStorage anymore
1309        woosw_get_data();
1310    }
1311
1312    function woosw_get_data() {
1313        var data = {
1314            action: 'woosw_get_data', nonce: woosw_vars.nonce,
1315        };
1316
1317        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_get_data'), data, function (response) {
1318            if (response) {
1319                if ($storage) {
1320                    sessionStorage.setItem('woosw_data_' + response.key, JSON.stringify(response));
1321                }
1322
1323                if (response.fragments) {
1324                    woosw_refresh_fragments(response.fragments);
1325                }
1326
1327                if (response.ids) {
1328                    woosw_refresh_buttons(response.ids);
1329                    woosw_refresh_ids(response.ids);
1330                }
1331
1332                if (response.key && (key === null || key === undefined || key === '' || key !== response.key)) {
1333                    Cookies.set('woosw_key', response.key, {expires: 7});
1334                }
1335
1336                $(document.body).trigger('woosw_data_refreshed', [response]);
1337            }
1338        });
1339    }
1340
1341    function woosw_refresh_fragments(fragments) {
1342        $.each(fragments, function (key, value) {
1343            $(key).replaceWith(value);
1344        });
1345
1346        $(document.body).trigger('woosw_fragments_refreshed', [fragments]);
1347    }
1348
1349    function woosw_refresh_ids(ids) {
1350        added_ids = ids;
1351    }
1352
1353    function woosw_refresh_buttons(ids) {
1354        $('.woosw-btn').removeClass('woosw-btn-added woosw-added');
1355        $('.woosw-btn:not(.woosw-btn-has-icon)').text(woosw_vars.button_text);
1356        $('.woosw-btn.woosw-btn-has-icon').find('.woosw-btn-icon').removeClass(woosw_vars.button_added_icon).addClass(woosw_vars.button_normal_icon);
1357        $('.woosw-btn.woosw-btn-has-icon').find('.woosw-btn-text').text(woosw_vars.button_text);
1358
1359        $.each(ids, function (key, value) {
1360            $('.woosw-btn-' + key).addClass('woosw-btn-added woosw-added');
1361            $('.woosw-btn-' + key + ':not(.woosw-btn-has-icon)').text(woosw_vars.button_text_added);
1362            $('.woosw-btn-has-icon.woosw-btn-' + key).find('.woosw-btn-icon').removeClass(woosw_vars.button_normal_icon).addClass(woosw_vars.button_added_icon);
1363            $('.woosw-btn-has-icon.woosw-btn-' + key).find('.woosw-btn-text').text(woosw_vars.button_text_added);
1364
1365            if (value.parent !== undefined) {
1366                $('.woosw-btn-' + value.parent).addClass('woosw-btn-added woosw-added');
1367                $('.woosw-btn-' + value.parent + ':not(.woosw-btn-has-icon)').text(woosw_vars.button_text_added);
1368                $('.woosw-btn-has-icon.woosw-btn-' + value.parent).find('.woosw-btn-icon').removeClass(woosw_vars.button_normal_icon).addClass(woosw_vars.button_added_icon);
1369                $('.woosw-btn-has-icon.woosw-btn-' + value.parent).find('.woosw-btn-text').text(woosw_vars.button_text_added);
1370            }
1371        });
1372
1373        $(document.body).trigger('woosw_buttons_refreshed', [ids]);
1374    }
1375
1376    function woosw_refresh_button_id(id) {
1377        $('.woosw-btn[data-id="' + id + '"]').removeClass('woosw-btn-added woosw-added');
1378        $('.woosw-btn[data-id="' + id + '"]:not(.woosw-btn-has-icon)').text(woosw_vars.button_text);
1379        $('.woosw-btn-has-icon.woosw-btn[data-id="' + id + '"]').find('.woosw-btn-icon').removeClass(woosw_vars.button_added_icon).addClass(woosw_vars.button_normal_icon);
1380        $('.woosw-btn-has-icon.woosw-btn[data-id="' + id + '"]').find('.woosw-btn-text').text(woosw_vars.button_text);
1381
1382        $.each(added_ids, function (key) {
1383            if (parseInt(key) === parseInt(id)) {
1384                $('.woosw-btn[data-id="' + id + '"]').addClass('woosw-btn-added woosw-added');
1385                $('.woosw-btn[data-id="' + id + '"]:not(.woosw-btn-has-icon)').text(woosw_vars.button_text_added);
1386                $('.woosw-btn-has-icon.woosw-btn[data-id="' + id + '"]').find('.woosw-btn-icon').removeClass(woosw_vars.button_normal_icon).addClass(woosw_vars.button_added_icon);
1387                $('.woosw-btn-has-icon.woosw-btn[data-id="' + id + '"]').find('.woosw-btn-text').text(woosw_vars.button_text_added);
1388            }
1389        });
1390
1391        $(document.body).trigger('woosw_refresh_button_id', [id, added_ids]);
1392    }
1393
1394    // add product to wishlist (extracted original add logic)
1395    function woosw_add_product($btn, id, product_name, product_image) {
1396        var data = {
1397            action: 'woosw_add', product_id: id, nonce: woosw_vars.nonce,
1398        };
1399
1400        $btn.addClass('woosw-adding').find('.woosw-btn-icon').removeClass(woosw_vars.button_normal_icon + ' ' + woosw_vars.button_added_icon).addClass(woosw_vars.button_loading_icon);
1401
1402        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_add'), data, function (response) {
1403            $btn.removeClass('woosw-adding').find('.woosw-btn-icon').removeClass(woosw_vars.button_loading_icon);
1404
1405            if (woosw_vars.button_action === 'list') {
1406                if (response.content != null) {
1407                    $('#woosw_wishlist').html(response.content).addClass('woosw-loaded');
1408                }
1409
1410                if (response.notice != null) {
1411                    woosw_notice(response.notice.replace('{name}', '<strong>' + product_name + '</strong>'));
1412                }
1413
1414                woosw_perfect_scrollbar();
1415                woosw_wishlist_show();
1416            }
1417
1418            if (woosw_vars.button_action === 'message') {
1419                $('#woosw_wishlist').removeClass('woosw-loaded');
1420
1421                $.notiny({
1422                    theme: 'woosw',
1423                    position: woosw_vars.message_position,
1424                    image: product_image,
1425                    text: response.notice.replace('{name}', '<strong>' + product_name + '</strong>'),
1426                });
1427            }
1428
1429            if (woosw_vars.button_action === 'no') {
1430                $('#woosw_wishlist').removeClass('woosw-loaded');
1431            }
1432
1433            if (response.count != null) {
1434                woosw_change_count(response.count);
1435            }
1436
1437            if (response.status === 1) {
1438                woosw_refresh_button_id(id);
1439            }
1440
1441            if (response.data) {
1442                if ($storage) {
1443                    sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
1444                }
1445
1446                if (response.data.fragments) {
1447                    woosw_refresh_fragments(response.data.fragments);
1448                }
1449
1450                if (response.data.ids) {
1451                    woosw_refresh_buttons(response.data.ids);
1452                    woosw_refresh_ids(response.data.ids);
1453                }
1454            }
1455
1456            $(document.body).trigger('woosw_add', [id]);
1457        });
1458    }
1459
1460    // build choose wishlist popup content
1461    function woosw_choose_build(wishlists, product_id, product_name, product_image, can_add_more) {
1462        var html = '<div class="woosw-popup-inner">';
1463        html += '<div class="woosw-popup-content">';
1464        html += '<div class="woosw-popup-content-top">';
1465        html += '<span class="woosw-name">' + woosw_vars.choose_wishlist_text + '</span>';
1466        html += '<span class="woosw-popup-close"></span>';
1467        html += '</div>';
1468        html += '<div class="woosw-popup-content-mid">';
1469        html += '<div class="woosw-choose-list">';
1470
1471        $.each(wishlists, function (i, wl) {
1472            var active_class = wl.is_default ? ' woosw-choose-item-default' : '';
1473            html += '<div class="woosw-choose-item' + active_class + '" data-key="' + wl.key + '">';
1474            html += '<div class="woosw-choose-item-info">';
1475            var displayName = wl.name;
1476            html += '<span class="woosw-choose-item-name">' + displayName + '</span>';
1477            html += '<span class="woosw-choose-item-count">(' + wl.count + ')</span>';
1478
1479            html += '<div class="woosw-item--badges">';
1480            if (wl.type === 'primary') {
1481                html += '<small class="woosw-badge">' + (woosw_vars.badge_primary_text || 'Primary') + '</small>';
1482            } else if (wl.is_collab) {
1483                html += '<small class="woosw-badge">' + (woosw_vars.badge_followed_text || 'Followed') + '</small>';
1484                html += '<small class="woosw-badge">' + (woosw_vars.badge_collabable_text || 'Collabable') + '</small>';
1485            }
1486            
1487            if (wl.is_default) {
1488                html += '<small class="woosw-badge woosw-badge-default">' + (woosw_vars.badge_default_text || 'Default') + '</small>';
1489            }
1490            html += '</div>';
1491            html += '</div>';
1492            html += '</div>';
1493        });
1494
1495        html += '</div>';
1496
1497        if (can_add_more) {
1498            html += '<div class="woosw-choose-add-new">';
1499            html += '<input type="text" class="woosw-choose-new-name" maxlength="200" placeholder="' + (woosw_vars.placeholder_name || 'New Wishlist') + '" />';
1500            html += '<button type="button" class="woosw-choose-new-save">' + (woosw_vars.add_wishlist_btn_text || 'Add') + '</button>';
1501            html += '</div>';
1502        }
1503
1504        html += '</div>';
1505        html += '</div>';
1506        html += '</div>';
1507
1508        $('#woosw_choose').html(html)
1509            .data('product_id', product_id)
1510            .data('product_name', product_name)
1511            .data('product_image', product_image);
1512    }
1513
1514    // show choose wishlist popup
1515    function woosw_choose_show() {
1516        $('#woosw_choose').addClass('woosw-show');
1517        $(document.body).trigger('woosw_choose_show');
1518    }
1519
1520    // hide choose wishlist popup
1521    function woosw_choose_hide() {
1522        $('#woosw_choose').removeClass('woosw-show');
1523        $(document.body).trigger('woosw_choose_hide');
1524    }
1525
1526    // collabable wishlist toggle
1527    $(document).on('change', '.woosw-collabable-checkbox', function () {
1528        var $this = $(this);
1529        var key = $this.data('key');
1530        var is_checked = $this.is(':checked');
1531        var $searchWrap = $('.woosw-search-product-wrap[data-key="' + key + '"]');
1532        var data = {
1533            action: 'woosw_toggle_collabable',
1534            key: key,
1535            collabable: is_checked ? 'yes' : 'no',
1536            nonce: woosw_vars.nonce,
1537        };
1538
1539        $this.prop('disabled', true);
1540
1541        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_toggle_collabable'), data, function (response) {
1542            $this.prop('disabled', false);
1543
1544            if (response.status === 1) {
1545                if (response.collabable === 1) {
1546                    $searchWrap.removeClass('woosw-hidden');
1547                } else {
1548                    $searchWrap.addClass('woosw-hidden');
1549                    $searchWrap.find('.woosw-search-product-results').empty().removeClass('woosw-active');
1550                    $searchWrap.find('.woosw-search-product-input').val('');
1551                    $searchWrap.removeClass('woosw-has-text woosw-loading');
1552                }
1553            } else {
1554                $this.prop('checked', !is_checked);
1555            }
1556
1557            if (response.notice != null) {
1558                woosw_notice(response.notice);
1559            }
1560        }).fail(function () {
1561            $this.prop('disabled', false);
1562            $this.prop('checked', !is_checked);
1563        });
1564    });
1565
1566    // collabable product search debounce timer
1567    var woosw_collab_search_timer = null;
1568
1569    $(document).on('input', '.woosw-search-product-input', function () {
1570        var $input = $(this);
1571        var $wrap = $input.closest('.woosw-search-product-wrap');
1572        var $results = $wrap.find('.woosw-search-product-results');
1573        var key = $wrap.data('key');
1574        var keyword = $input.val().trim();
1575
1576        clearTimeout(woosw_collab_search_timer);
1577
1578        if (keyword.length === 0) {
1579            $wrap.removeClass('woosw-has-text woosw-loading');
1580            $results.empty().removeClass('woosw-active');
1581            return;
1582        }
1583
1584        $wrap.addClass('woosw-has-text');
1585
1586        if (keyword.length < 2) {
1587            $results.empty().removeClass('woosw-active');
1588            return;
1589        }
1590
1591        $wrap.addClass('woosw-loading');
1592
1593        woosw_collab_search_timer = setTimeout(function () {
1594            var data = {
1595                action: 'woosw_search_products',
1596                keyword: keyword,
1597                key: key,
1598                nonce: woosw_vars.nonce,
1599            };
1600
1601            $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_search_products'), data, function (response) {
1602                $wrap.removeClass('woosw-loading');
1603
1604                if (response.success && response.html) {
1605                    $results.html(response.html).addClass('woosw-active');
1606                } else {
1607                    $results.empty().removeClass('woosw-active');
1608                }
1609            }).fail(function () {
1610                $wrap.removeClass('woosw-loading');
1611            });
1612        }, 300);
1613    });
1614
1615    // clear search input
1616    $(document).on('click touch', '.woosw-search-product-clear', function () {
1617        var $wrap = $(this).closest('.woosw-search-product-wrap');
1618        $wrap.find('.woosw-search-product-input').val('').trigger('input');
1619    });
1620
1621    // close search dropdown on click outside
1622    $(document).on('click touch', function (e) {
1623        if (!$(e.target).closest('.woosw-search-product-wrap').length) {
1624            $('.woosw-search-product-results').removeClass('woosw-active');
1625        }
1626    });
1627
1628    // reopen search dropdown on focus if has results
1629    $(document).on('focus', '.woosw-search-product-input', function () {
1630        var $wrap = $(this).closest('.woosw-search-product-wrap');
1631        var $results = $wrap.find('.woosw-search-product-results');
1632        if ($results.children().length > 0) {
1633            $results.addClass('woosw-active');
1634        }
1635    });
1636
1637    // add product to collabable wishlist from search results
1638    $(document).on('click touch', '.woosw-search-add-btn:not(.is-added)', function (e) {
1639        var $btn = $(this);
1640        var product_id = $btn.data('id');
1641        var key = $btn.data('key');
1642        var $wrap = $btn.closest('.woosw-search-product-wrap');
1643        var data = {
1644            action: 'woosw_add',
1645            product_id: product_id,
1646            key: key,
1647            nonce: woosw_vars.nonce,
1648        };
1649
1650        $btn.addClass('woosw-adding');
1651
1652        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'woosw_add'), data, function (response) {
1653            $btn.removeClass('woosw-adding');
1654
1655            if (response.status === 1) {
1656                $btn.addClass('is-added').prop('disabled', true).html('<span class="woosw-search-add-icon">&#10003;</span> ' + (woosw_vars.added_text || 'Added'));
1657
1658                if (response.notice != null) {
1659                    woosw_notice(response.notice);
1660                }
1661
1662                if (response.count != null) {
1663                    woosw_change_count(response.count);
1664                }
1665
1666                if (response.data) {
1667                    if ($storage) {
1668                        sessionStorage.setItem('woosw_data_' + response.data.key, JSON.stringify(response.data));
1669                    }
1670
1671                    if (response.data.fragments) {
1672                        woosw_refresh_fragments(response.data.fragments);
1673                    }
1674
1675                    if (response.data.ids) {
1676                        woosw_refresh_buttons(response.data.ids);
1677                        woosw_refresh_ids(response.data.ids);
1678                    }
1679                }
1680
1681                // Update items in wishlist table on page
1682                if (response.items != null) {
1683                    var $list = $('.woosw-list[data-key="' + key + '"]');
1684                    if ($list.length) {
1685                        var $existingTable = $list.find('.woosw-items');
1686                        var $emptyMsg = $list.find('.woosw-popup-content-mid-message');
1687
1688                        if ($existingTable.length) {
1689                            $existingTable.replaceWith(response.items);
1690                        } else if ($emptyMsg.length) {
1691                            $emptyMsg.replaceWith(response.items);
1692                        } else {
1693                            $wrap.after(response.items);
1694                        }
1695                    }
1696                }
1697
1698                $(document.body).trigger('woosw_add', [product_id]);
1699            } else if (response.notice != null) {
1700                woosw_notice(response.notice);
1701            }
1702        }).fail(function () {
1703            $btn.removeClass('woosw-adding');
1704        });
1705
1706        e.preventDefault();
1707    });
1708
1709    // show notice next to collaboration button
1710    function woosw_show_collab_notice($btn, message, type) {
1711        if (!message) {
1712            return;
1713        }
1714
1715        // Remove any existing notice next to this button
1716        var $existingNotice = $btn.siblings('.woosw-add-collab-notice');
1717        if ($existingNotice.length) {
1718            var existingTimer = $existingNotice.data('notice-timer');
1719            if (existingTimer) {
1720                clearTimeout(existingTimer);
1721            }
1722            $existingNotice.remove();
1723        }
1724
1725        var noticeClass = (type === 'success') ? 'woosw-notice-success' : 'woosw-notice-error';
1726        var $notice = $('<span class="woosw-add-collab-notice ' + noticeClass + '">' + message + '</span>');
1727
1728        $btn.after($notice);
1729
1730        // Auto fade out and remove notice after 3.5 seconds
1731        var timer = setTimeout(function () {
1732            $notice.addClass('woosw-notice-fadeout');
1733            setTimeout(function () {
1734                $notice.remove();
1735            }, 300);
1736        }, 3500);
1737
1738        $notice.data('notice-timer', timer);
1739    }
1740
1741    // add or remove collaboration wishlist from user's wishlists
1742    $(document).on('click touch', '.woosw-add-collab-btn', function (e) {
1743        e.preventDefault();
1744        var $btn = $(this);
1745        var key = $btn.data('key');
1746
1747        if (!key || $btn.hasClass('woosw-loading')) {
1748            return;
1749        }
1750
1751        $btn.addClass('woosw-loading');
1752
1753        var isAdded = $btn.hasClass('is-added');
1754        var action = isAdded ? 'woosw_remove_collab_wishlist' : 'woosw_add_collab_wishlist';
1755
1756        var data = {
1757            action: action,
1758            key: key,
1759            nonce: woosw_vars.nonce,
1760        };
1761
1762        $.post(woosw_vars.wc_ajax_url.toString().replace('%%endpoint%%', action), data, function (response) {
1763            $btn.removeClass('woosw-loading');
1764
1765            if (response.status === 1) {
1766                if (isAdded) {
1767                    $btn.removeClass('is-added').html('<span class="woosw-add-collab-icon">+</span> ' + (woosw_vars.add_to_my_wishlists_text || 'Follow'));
1768                } else {
1769                    $btn.addClass('is-added').html('<span class="woosw-add-collab-icon">&#215;</span> ' + (woosw_vars.remove_from_my_wishlists_text || 'Unfollow'));
1770                }
1771
1772                if (response.notice != null) {
1773                    woosw_show_collab_notice($btn, response.notice, 'success');
1774                }
1775            } else {
1776                if (response.notice != null) {
1777                    woosw_show_collab_notice($btn, response.notice, 'error');
1778                }
1779            }
1780
1781            if (response.notice != null) {
1782                woosw_notice(response.notice);
1783            }
1784        }).fail(function () {
1785            $btn.removeClass('woosw-loading');
1786            woosw_show_collab_notice($btn, 'An error occurred. Please try again.', 'error');
1787        });
1788    });
1789})(jQuery);

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.