1/** 2 * 3 Features for astrologyreadings.online report pages: 3 * 1. Mobile swipe to switch tabs 4 * 2. Social share buttons 5 * 3. Share raw data with AI 6 * 7 * Add to footer.php before </body>: 8 * <script src="/online_calcs/js/swipe-share-ai.js"></script> 9 */ 10 11(function ($) { 12 "use strict"; 13 14 // Run on pages with report tabs OR horary pages with parameters 15 var $tabContent = $("#my-tab-content"); 16 var isHorary = window.location.pathname.indexOf("/horary") !== -1 && window.location.search.length > 1; 17 // A report qualifies if it has the tab container, OR is horary, OR simply has a 18 // chart wheel on it. The wheel test is what lets reports that never carried 19 // id="my-tab-content" or id="chart" get the button. 20 var hasWheel = $("img.shareable-wheel, img.myvideo").length > 0; 21 if (!$tabContent.length && !isHorary && !hasWheel) return; 22 23 // WHERE THE BUTTON GOES AND WHERE ITS DATA COMES FROM. 24 // #chart is the original hook and still wins, so nothing that works today moves. 25 // Reports without it are located by their wheel instead: the button lands in the 26 // pane the wheel sits in, or beside the wheel if there are no tabs at all. 27 function aiAnchor() { 28 var $c = $("#chart"); 29 if ($c.length) return $c; 30 var $wheel = $("img.shareable-wheel, img.myvideo").first(); 31 if (!$wheel.length) return $(); 32 var $pane = $wheel.closest(".tab-pane"); 33 return $pane.length ? $pane : $wheel.parent(); 34 } 35 var $anchor = aiAnchor(); 36 37 38 // ============================================= 39 // 3. SHARE RAW DATA WITH AI 40 // ============================================= 41 // Collect structured data from the report tables 42 function collectReportData() { 43 var data = []; 44 var $source = isHorary ? $(document.body) : $anchor; 45 46 data.push("=== ASTROLOGY REPORT DATA ==="); 47 data.push("URL: " + window.location.href); 48 data.push("Generated: " + new Date().toISOString().split("T")[0]); 49 data.push(""); 50 51 if (!isHorary) { 52 // Get the person's name and birth info from the page 53 var nameEl = $source.find("h1, h2").first(); 54 if (nameEl.length) data.push("Report: " + nameEl.text().trim()); 55 data.push(""); 56 } 57 58 // For horary, also grab the AJAX output text 59 if (isHorary) { 60 $(".horary-output").each(function () { 61 var $out = $(this); 62 $out.find("h2, h3, h4, h5, p").each(function () { 63 var txt = $(this).text().trim(); 64 if (txt) data.push(txt); 65 }); 66 }); 67 data.push(""); 68 } 69 70 // Extract tables (horary: only from .dignity-table-wrapper and .horary-output) 71 var $tables = isHorary ? $("table.table").not("iframe table, iframe *") : $source.find("table"); 72 $tables.each(function () { 73 var $table = $(this); 74 var caption = 75 $table.find("caption").text() || 76 $table.prev("h2, h3, h4").text() || 77 ""; 78 if (caption) data.push("--- " + caption.trim() + " ---"); 79 80 $table.find("tr").each(function () { 81 var cells = []; 82 $(this) 83 .find("th, td") 84 .each(function () { 85 var $cell = $(this).clone(); 86 $cell.find(".customfont, .moonfont").remove(); 87 cells.push($cell.text().trim().replace(/\s+/g, " ")); 88 }); 89 if (cells.length) data.push(cells.join(" | ")); 90 }); 91 data.push(""); 92 }); 93 94 return data.join("\n"); 95 } 96 97 // Add AI share button 98 var aiButtonHtml = 99 '<div class="ai-share-container">' + 100 ' <button class="ai-share-btn" id="aiShareBtn">' + 101 ' <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a4 4 0 014 4v1h2a2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V9a2 2 0 012-2h2V6a4 4 0 014-4zm0 2a2 2 0 00-2 2v1h4V6a2 2 0 00-2-2z"/><circle cx="9" cy="14" r="1"/><circle cx="15" cy="14" r="1"/></svg>' + 102 " Copy Report Data for AI" + 103 " </button>" + 104 ' <span class="ai-share-hint">Copy your chart data to paste into ChatGPT, Claude, or any AI assistant</span>' + 105 "</div>"; 106 107 if (isHorary) { 108 // For horary, append AI button after the last dignity-table-wrapper 109 $(".dignity-table-wrapper").last().after(aiButtonHtml); 110 } else { 111 // Anchor resolved above: the #chart pane, else the pane holding the wheel, 112 // else the wheel's own container. 113 var $chartPane = $anchor; 114 if ($chartPane.length) { 115 /* CHART TAB ONLY, Tanya's call 21 Sep 2026 after seeing it live on every tab. 116 The all-tabs experiment is reverted; the teal restyle and the light-theme fix 117 from the same batch stay, since those were the half that actually helped. 118 What it copies is the chart pane either way: collectReportData() reads $anchor. */ 119 $chartPane.append(aiButtonHtml); 120 121 // Hide while a different tab is open. An anchor that is not a tab pane has no 122 // tab to be hidden behind, so it stays visible. 123 function toggleAiButton() { 124 $(".ai-share-container").toggle( 125 !$chartPane.hasClass("tab-pane") || $chartPane.hasClass("active") 126 ); 127 } 128 toggleAiButton(); 129 $('a[data-toggle="tab"]').on("shown.bs.tab", toggleAiButton); 130 } 131 } 132 133 $("#aiShareBtn").on("click", function () { 134 var $btn = $(this); 135 var reportData = collectReportData(); 136 137 navigator.clipboard.writeText(reportData).then(function () { 138 $btn.html( 139 '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg> Copied! Paste into your AI assistant' 140 ); 141 setTimeout(function () { 142 $btn.html( 143 '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a4 4 0 014 4v1h2a2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V9a2 2 0 012-2h2V6a4 4 0 014-4zm0 2a2 2 0 00-2 2v1h4V6a2 2 0 00-2-2z"/><circle cx="9" cy="14" r="1"/><circle cx="15" cy="14" r="1"/></svg> Copy Report Data for AI' 144 ); 145 }, 3000); 146 }); 147 }); 148})(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.