PageSourceSearch

https://www.hawaii-guide.com/files/js/blog-daily-updates-floater-v1.js?v=f998d718d3

js hawaii-guide.com collected 2026-10-02 04:11:58 UTC 5,720 bytes, 137 lines download raw bytes

1/* Daily Updates floating CTA — loaded on /blog and the 5 hub pages.
2 *
3 * Injects a small bottom-right pill that expands into an inline form on click.
4 * Auto-hides for subscribed readers, dismissed-pill readers, and small viewports
5 * during page-load (lazy reveal after 8s to avoid stealing initial attention).
6 *
7 * Suppression cookies:
8 *   premium_email       — global "already a subscriber" cookie, set on any
9 *                         successful Drip identify across the site.
10 *   hg_du_floater_off   — set when reader clicks dismiss. 14 days.
11 *
12 * ES5 only. No dependencies. Renders shadow-DOM-free so the scoped CSS in
13 * blog-daily-updates-floater-v1.css governs presentation.
14 */
15(function () {
16  'use strict';
17
18  var SUBSCRIBED_COOKIE = 'premium_email';
19  var DISMISS_COOKIE = 'hg_du_floater_off';
20  var REVEAL_DELAY_MS = 8000;
21
22  function readCookie(name) {
23    var match = (' ' + document.cookie).match(new RegExp('[; ]' + name + '=([^;]+)'));
24    return match ? decodeURIComponent(match[1]) : null;
25  }
26  function setCookie(name, value, days) {
27    var d = new Date();
28    d.setTime(d.getTime() + days * 86400 * 1000);
29    document.cookie = name + '=' + encodeURIComponent(value) + ';expires=' + d.toUTCString() + ';path=/;SameSite=Lax;Secure';
30  }
31  function ready(fn) {
32    if (document.readyState !== 'loading') { fn(); return; }
33    document.addEventListener('DOMContentLoaded', fn);
34  }
35
36  ready(function () {
37    if (readCookie(SUBSCRIBED_COOKIE)) return;
38    if (readCookie(DISMISS_COOKIE)) return;
39    if (document.getElementById('hg-du-floater')) return;
40
41    var el = build();
42    document.body.appendChild(el);
43
44    setTimeout(function () { el.classList.add('is-visible'); }, REVEAL_DELAY_MS);
45
46    el.querySelector('.hg-du-floater-pill').addEventListener('click', function (e) {
47      if (e.target && e.target.closest && e.target.closest('.hg-du-floater-pill-close')) return;
48      el.classList.add('is-expanded');
49      var input = el.querySelector('input[type="email"]');
50      if (input) input.focus();
51    });
52
53    el.querySelector('.hg-du-floater-pill-close').addEventListener('click', function (e) {
54      e.stopPropagation();
55      dismiss(el);
56    });
57    el.querySelector('.hg-du-floater-card-close').addEventListener('click', function () {
58      el.classList.remove('is-expanded');
59    });
60
61    el.querySelector('.hg-du-floater-submit').addEventListener('click', function () {
62      submit(el);
63    });
64    el.querySelector('input[type="email"]').addEventListener('keydown', function (e) {
65      if (e.key === 'Enter') { e.preventDefault(); submit(el); }
66    });
67  });
68
69  function build() {
70    var el = document.createElement('div');
71    el.id = 'hg-du-floater';
72    el.className = 'hg-du-floater';
73    el.setAttribute('aria-live', 'polite');
74    el.innerHTML =
75      '<button type="button" class="hg-du-floater-pill" aria-label="Open Hawaii Daily Updates signup">' +
76        '<i class="fa fa-envelope" aria-hidden="true"></i>' +
77        '<span>Daily Updates</span>' +
78        '<button type="button" class="hg-du-floater-pill-close" aria-label="Dismiss">&times;</button>' +
79      '</button>' +
80      '<div class="hg-du-floater-card" role="dialog" aria-label="Hawaii Daily Updates by Email">' +
81        '<button type="button" class="hg-du-floater-card-close" aria-label="Close">&times;</button>' +
82        '<h3>Hawaii Daily Updates</h3>' +
83        '<p>One short morning email at 9 AM HST with every new article that day. Free. Unsubscribe anytime.</p>' +
84        '<form class="hg-du-floater-form" onsubmit="return false;">' +
85          '<label for="hg-du-floater-email" class="sr-only">Email address</label>' +
86          '<input type="email" id="hg-du-floater-email" placeholder="Your email address" required />' +
87          '<button type="button" class="hg-du-floater-submit">Subscribe <i class="fa fa-arrow-right" aria-hidden="true"></i></button>' +
88        '</form>' +
89        '<div class="hg-du-floater-success"><i class="fa fa-check-circle" aria-hidden="true"></i> Mahalo! Check your inbox to confirm.</div>' +
90      '</div>';
91    return el;
92  }
93
94  function dismiss(el) {
95    setCookie(DISMISS_COOKIE, '1', 14);
96    if (el.parentNode) el.parentNode.removeChild(el);
97  }
98
99  function submit(el) {
100    var input = el.querySelector('input[type="email"]');
101    var btn = el.querySelector('.hg-du-floater-submit');
102    var success = el.querySelector('.hg-du-floater-success');
103    var form = el.querySelector('.hg-du-floater-form');
104    if (!input || !btn || !success || !form) return;
105    var email = input.value.trim();
106    if (!email || (input.validity && !input.validity.valid)) { input.focus(); return; }
107    var originalLabel = btn.innerHTML;
108    btn.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Submitting...';
109    btn.disabled = true;
110
111    if (typeof window._dcq !== 'undefined') {
112      window._dcq.push(['identify', {
113        email: email,
114        referral_url: window.location.href,
115        tags: ['Daily Updates', 'Blog Subscriber', 'Floater Signup'],
116        success: function () {
117          form.style.display = 'none';
118          success.style.display = 'block';
119          if (typeof window.createHGCookie === 'function') {
120            window.createHGCookie(SUBSCRIBED_COOKIE, email, 365);
121          }
122          if (typeof window.plausible === 'function') {
123            window.plausible('Daily Updates Subscribe', {
124              props: { variant: 'floater', source: window.location.pathname }
125            });
126          }
127          setTimeout(function () {
128            if (el.parentNode) el.parentNode.removeChild(el);
129          }, 4500);
130        }
131      }]);
132    } else {
133      btn.innerHTML = originalLabel;
134      btn.disabled = false;
135    }
136  }
137})();

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.