PageSourceSearch

https://astrologyreadings.online/online_calcs/js/swipe-share-ai.js?v=10

js astrologyreadings.online collected 2026-10-02 10:01:30 UTC 6,018 bytes, 148 lines download raw bytes

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.