1(function($){ 2 function showToast(message, type){ 3 var $c = $('#sh-toast-container'); 4 if(!$c.length){ $c = $('<div id="sh-toast-container"/>').appendTo('body'); } 5 var $t = $('<div class="sh-toast"/>').addClass(type==='success'?'is-success':'is-error').text(message).appendTo($c); 6 setTimeout(function(){ $t.fadeOut(200, function(){ $(this).remove(); }); }, 2400); 7 } 8 9 function setHeartState($btn, active){ 10 $btn.toggleClass('is-active', !!active); 11 var $path = $btn.find('.sh-heart-path'); 12 if(active){ 13 $path.attr('fill', (window.SHFavorites && SHFavorites.brand && SHFavorites.brand.red) || '#E63946'); 14 $path.attr('stroke', (window.SHFavorites && SHFavorites.brand && SHFavorites.brand.red) || '#E63946'); 15 } else { 16 $path.attr('fill', 'none'); 17 $path.attr('stroke', 'currentColor'); 18 } 19 // Sync CTA text if present in wrapper 20 try { 21 // Support multiple wrapper contexts (activity/company/results) 22 var $wrap = $btn.closest('.sh-members-actions, .sh-members-actions-results, .sh-favorite-results, .sh-favorites'); 23 if($wrap.length){ 24 // Prefer CTA within the same favorites block 25 var $cta = $wrap.find('.sh-fav-cta').first(); 26 if($cta.length){ 27 var onText = $cta.data('text-on') || 'Îδη ÏÏα αγαÏημÎνα'; 28 var offText = $cta.data('text-off') || 'Î ÏοÏθήκη ÏÏα αγαÏημÎνα'; 29 $cta.text(active ? onText : offText); 30 $cta.toggleClass('is-active', !!active); 31 } 32 } 33 } catch(_){ /* noop */ } 34 } 35 36 function fetchInitialState($btn){ 37 if(!window.SHFavorites) return; 38 var companyId = $btn.data('company-id'); 39 if(!companyId) return; 40 $.post(SHFavorites.ajaxUrl, { action: 'sh_get_favorite_company_state', company_id: companyId, nonce: $btn.data('nonce') || (window.SHFavorites ? SHFavorites.nonce : '') }, function(res){ 41 if(res && res.success){ setHeartState($btn, !!res.data.favorited); } 42 }); 43 } 44 45 $(document).on('click', '.sh-fav-btn', function(e){ 46 e.preventDefault(); 47 var $btn = $(this); 48 var companyId = $btn.data('company-id'); 49 var nonce = $btn.data('nonce') || (window.SHFavorites ? SHFavorites.nonce : ''); 50 if(!window.SHFavorites){ return; } 51 52 if(!SHFavorites.isLoggedIn){ 53 var target = SHFavorites.loginUrl; 54 try { 55 var current = window.location.href; 56 var sep = target.indexOf('?')> -1 ? '&' : '?'; 57 target = target + sep + 'redirect_to=' + encodeURIComponent(current); 58 } catch(_) {} 59 window.location.href = target; 60 return; 61 } 62 63 $btn.prop('disabled', true); 64 $.post(SHFavorites.ajaxUrl, { 65 action: 'sh_toggle_favorite_company', 66 nonce: nonce, 67 company_id: companyId 68 }, function(res){ 69 if(res && res.success){ 70 var fav = !!res.data.favorited; 71 setHeartState($btn, fav); 72 showToast(fav ? SHFavorites.texts.added : SHFavorites.texts.removed, 'success'); 73 } else if(res && res.data && res.data.login_required) { 74 // Ensure redirect_to back to current page when server requests login 75 var base = (res.data.login_url || SHFavorites.loginUrl || '/member-login/'); 76 try { 77 var currentUrl = window.location.href; 78 var sep2 = base.indexOf('?') > -1 ? '&' : '?'; 79 base = base + sep2 + 'redirect_to=' + encodeURIComponent(currentUrl); 80 } catch(_) {} 81 window.location.href = base; 82 } else { 83 var msg = (res && res.data && res.data.message) ? res.data.message :
83SHFavorites.texts.error; 84 showToast(msg, 'error'); 85 } 86 }).fail(function(){ 87 showToast(SHFavorites.texts.error, 'error'); 88 }).always(function(){ 89 $btn.prop('disabled', false); 90 }); 91 }); 92 93 // Allow CTA to trigger the same toggle as the heart button 94 $(document).on('click', '.sh-fav-cta', function(e){ 95 e.preventDefault(); 96 // Support multiple wrapper contexts and fallback to local favorites block 97 var $wrap = $(this).closest('.sh-members-actions, .sh-members-actions-results, .sh-favorite-results, .sh-favorites'); 98 var $btn = $wrap.find('.sh-fav-btn').first(); 99 if(!$btn.length){ 100 // Fallback: search within the same favorites component 101 $btn = $(this).closest('.sh-favorites, .sh-favorites-wrapper').find('.sh-fav-btn').first(); 102 } 103 if($btn.length){ $btn.trigger('click'); } 104 }); 105 106 $(function(){ 107 $('.sh-fav-btn').each(function(){ 108 var $btn = $(this); 109 fetchInitialState($btn); 110 // Initialize CTA text according to current heart state (in case SSR set it) 111 setHeartState($btn, $btn.hasClass('is-active')); 112 }); 113 }); 114})(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.