1jQuery(document).ready(function($) { 2 3 // Hilfsfunktion: Details-Tabelle generieren 4 function buildDetailsTable(card) { 5 const table = $('<table>', { class: 'minimalisticards-table' }); 6 const hasAddress = (card.street || card.house_number || card.postal_code || card.city) && card.show_address; 7 const hasMobile = card.mobile && card.show_mobile; 8 const hasLandline = card.landline && card.show_landline; 9 const hasEmail = card.email && card.show_email; 10 11 function addRow(label, value, valueClass = '') { 12 const row = $('<tr>'); 13 row.append($('<td>', { class: 'minimalisticards-label', text: label })); 14 row.append($('<td>', { class: `minimalisticards-value ${valueClass}`.trim(), text: value })); 15 table.append(row); 16 } 17 18 function formatEmail(value) { 19 return String(value || '').replace('@', '\n@'); 20 } 21 22 if (hasAddress) { 23 const lines = []; 24 if (card.street || card.house_number) { 25 lines.push(`${card.street || ''} ${card.house_number || ''}`.trim()); 26 } 27 if (card.postal_code || card.city) { 28 lines.push(`${card.postal_code || ''} ${card.city || ''}`.trim()); 29 } 30 addRow('Anschrift:', lines.join('\n')); 31 } 32 if (hasMobile) { 33 addRow('Mobil:', card.mobile); 34 } 35 if (hasLandline) { 36 addRow('Festnetz:', card.landline); 37 } 38 if (hasEmail) { 39 addRow('E-Mail:', formatEmail(card.email), 'minimalisticards-email'); 40 } 41 42 return table; 43 } 44 45 function buildErrorMessage() { 46 return $('<div>', { 47 class: 'minimalisticards-error', 48 text: 'Fehler beim Laden der Details' 49 }); 50 } 51 52 53 // Details per Button anzeigen (Datenschutzmodus, AJAX) 54 $('.minimalisticards-toggle-details').on('click', function(e) { 55 e.preventDefault(); 56 const cardDiv = $(this).closest('.minimalisticards-card'); 57 const details = cardDiv.find('.minimalisticards-details'); 58 const isVisible = $(this).data('visible') === 'true'; 59 // Determine card id: prefer explicit data-card-id, then try data-card JSON, fallback to 1-based DOM position 60 let cardId = null; 61 const rawIdAttr = cardDiv.attr('data-card-id'); 62 if (rawIdAttr !== undefined && rawIdAttr !== null && rawIdAttr !== '') { 63 const parsed = parseInt(rawIdAttr, 10); 64 if (!isNaN(parsed)) cardId = parsed; 65 } 66 if (cardId === null) { 67 // try to parse data-card JSON 68 let cardData = cardDiv.data('card'); 69 if (typeof cardData === 'string') { 70 try { cardData = JSON.parse(cardData); } catch(e) { cardData = null; } 71 } 72 if (cardData && cardData.id) { 73 const parsed2 = parseInt(cardData.id, 10); 74 if (!isNaN(parsed2)) cardId = parsed2; 75 } 76 } 77 if (cardId === null) { 78 // last resort: 1-based DOM position for legacy markup without data-card-id 79 cardId = $('.minimalisticards-card').index(cardDiv) + 1; 80 console.warn('minimalisticards: falling back to DOM index for card_id', cardId); 81 } 82 if (!isVisible) { 83 if (details.is(':empty')) { 84 // AJAX-Request an Server 85 $.post({ 86 url: minimalisticards_ajax.ajax_url, 87 data: { 88 action: 'minimalisticards_get_details', 89 card_id: cardId 90 }, 91 success: function(response) { 92 if (response.success) { 93 details.empty().append(buildDetailsTable(response.data)); 94 details.slideDown(); 95 } else { 96 details.empty().append(buildErrorMessage()).slideDown(); 97 } 98 }, 99 error: function() { 100 details.empty().append(buildErrorMessage()).slideDown(); 101 } 102 }); 103 } else { 104 details.slideDown(); 105 } 106 $(this).data('visible', 'true').addClass('active').attr('title', 'Details verbergen'); 107 $(this).find('.dashicons').removeClass('dashicons-visibility').addClass('dashicons-hidden'); 108 } else { 109 details.slideUp(); 110 $(this).data('visible', 'false').removeClass('active').attr('title', 'Details anzeigen'); 111 $(this).find('.dashicons').removeClass('dashicons-hidden').addClass('dashicons-visibility'); 112 } 113 }); 114 115 // Details direkt anzeigen, wenn Datenschutzmodus aus (hier weiterhin aus data-card, da unkritisch) 116 $('.minimalisticards-card').each(function() { 117 const card = $(this).data('card'); 118 if (card && (!card.privacy || card.privacy === false)) { 119 const details = $(this).find('.minimalisticards-detail
119s'); 120 details.empty().append(buildDetailsTable(card)).show(); 121 } 122 }); 123 124 // Decode Base64 email and generate mailto link 125 $('.minimalisticards-icon-email').on('click', function(e) { 126 e.preventDefault(); 127 const encodedEmail = $(this).data('email'); 128 if (encodedEmail) { 129 const email = atob(encodedEmail); // Decode Base64 130 window.location.href = 'mailto:' + email; 131 } 132 }); 133 134 // Decode Base64 mobile and generate tel link 135 $('.minimalisticards-icon-mobile').on('click', function(e) { 136 e.preventDefault(); 137 const encodedMobile = $(this).data('mobile'); 138 if (encodedMobile) { 139 const mobile = atob(encodedMobile); // Decode Base64 140 window.location.href = 'tel:' + mobile; 141 } 142 }); 143 // Decode Base64 landline and generate tel link 144 $('.minimalisticards-icon-landline').on('click', function(e) { 145 e.preventDefault(); 146 const encodedLandline = $(this).data('landline'); 147 if (encodedLandline) { 148 const landline = atob(encodedLandline); // Decode Base64 149 window.location.href = 'tel:' + landline; 150 } 151 }); 152});
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.