PageSourceSearch

https://latinprayer.org/wp-content/plugins/dwappsplash/assets/app-banner.js?ver=1788480135

js latinprayer.org collected 2026-10-02 01:07:16 UTC 3,742 bytes, 81 lines download raw bytes

1/**
2 * WHAT:    Decides whether the Android "get the app" bar appears, and what it says.
3 * WHY:     The markup ships to every visitor because the page HTML is cached and
4 *          shared (see includes/app-banner.php) — so the platform check, the
5 *          install check and the reader's dismissal all have to happen here.
6 * INPUT:   window.LP_GETAPP (localized by app-banner.php) + #lp-getapp.
7 * OUTPUT:  the bar unhidden with one of two wordings, or nothing at all.
8 * DEPENDS ON: nothing — no framework, no build step.
9 * TESTED BY: tests/banner.mjs — it drives THIS file in a real browser on both
10 *          platforms, which is where every decision below actually happens, plus
11 *          by hand on an Android phone. The PHP side is covered by the same suite
12 *          and by dwlatinprayer/tests/test-app-links.php (which pages qualify).
13 *          ⚠ This line used to name tests/test-app-banner.php "the PHP side". No
14 *          such file exists; includes/app-banner.php names the real ones.
15 */
16(function () {
17  'use strict';
18
19  var KEY = 'lp-getapp-dismissed';
20  var el = document.getElementById('lp-getapp');
21  var cfg = window.LP_GETAPP;
22  if (!el || !cfg) return;
23
24  // iOS is deliberately not handled here: Safari draws Apple's own Smart App
25  // Banner from the <meta> tag, and unlike anything we can write it KNOWS
26  // whether the app is installed. Two banners on one page would be worse than
27  // either alone.
28  if (!/Android/i.test(navigator.userAgent)) return;
29
30  // A reader who closed it once has answered the question.
31  try {
32    if (localStorage.getItem(KEY)) return;
33  } catch (e) {
34    // Private mode / storage disabled. Showing the bar is the safe side of
35    // this: worst case it reappears, where a thrown error would take the
36    // whole script down before it ever ran.
37  }
38
39  /**
40   * Show the bar in one of its two states.
41   * @param {boolean} installed Does this device already have the app?
42   */
43  function render(installed) {
44    // No Android route configured and no app installed: there is nothing to
45    // offer, so say nothing.
46    if (!installed && !cfg.getUrl) return;
47
48    var cta = el.querySelector('.lp-getapp__cta');
49    el.querySelector('.lp-getapp__lead').textContent = installed ? cfg.openLead : cfg.getLead;
50    // The button shows one word and announces the whole sentence.
51    cta.textContent = installed ? cfg.openCta : cfg.getCta;
52    cta.setAttribute('aria-label', installed ? cfg.openAria : cfg.getAria);
53    cta.href = installed ? cfg.openUrl : cfg.getUrl;
54    if (!installed) cta.rel = 'noopener';
55    el.hidden = false;
56  }
57
58  el.querySelector('.lp-getapp__close').addEventListener('click', function () {
59    el.hidden = true;
60    // The date is stored rather than a bare flag purely so the value can be
61    // read later; any value at all counts as dismissed.
62    try { localStorage.setItem(KEY, new Date().toISOString().slice(0, 10)); } catch (e) {}
63  });
64
65  // The one honest install check the web offers, and only Chrome on Android
66  // has it. It answers from the site manifest's `related_applications` and the
67  // app's assetlinks.json TOGETHER — both are served by dwlatinprayer, so a
68  // false "not installed" here means one of those two stopped resolving.
69  // Where the API is missing we assume not-installed: offering the app to
70  // someone who has it costs one dismissal; hiding it from someone who does
71  // not costs the install.
72  if (typeof navigator.getInstalledRelatedApps === 'function' && cfg.package) {
73    navigator.getInstalledRelatedApps().then(function (apps) {
74      render(apps.some(function (app) { return app.id === cfg.package; }));
75    }, function () {
76      render(false);
77    });
78  } else {
79    render(false);
80  }
81})();

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.