PageSourceSearch

https://umbc.edu/wp-content/themes/umbc-theme-2.0/js/umbc-nav-state.js?ver=1790186981

js umbc.edu collected 2026-09-24 07:39:13 UTC 6,624 bytes, 181 lines download raw bytes

1/**
2 * UMBC Nav State — role-personalized utility strip
3 *
4 * Reads the `umbc_roles` cookie set by myUMBC (30-day, refreshed on login).
5 * Format: comma-separated, priority-ordered, e.g. "faculty,staff"
6 *
7 * Replaces the server-rendered anonymous utility strip with a role-specific
8 * one client-side. PHP always renders the anonymous state; this upgrades it
9 * when a known role is detected. No WP login required.
10 *
11 * Role priority (first match wins, people can have multiple):
12 *   1. faculty
13 *   2. staff
14 *   3. graduate-student | undergraduate-student
15 *   4. cookie present, no recognised role → generic logged-in nav
16 *   5. no cookie → anonymous nav (PHP default, no JS change)
17 *
18 * To add this to another UMBC-family site, change COOKIE_NAME if needed.
19 * Everything else is self-contained.
20 */
21
22(function () {
23  "use strict";
24
25  var COOKIE_NAME = "umbc_roles";
26
27  /* ------------------------------------------------------------------
28   * Link definitions per role
29   * Each entry: [label, url, mobile-only-cta?]
30   * Shared by both desktop (.uh-utility-strip) and mobile (.mobile-utility-strip)
31   * so links only need updating in one place.
32   * ------------------------------------------------------------------ */
33  var LINKS = {
34    "undergraduate-student": [
35      { label: "myUMBC", url: "https://my.umbc.edu", cta: true },
36      { label: "Directory", url: "/directory/" },
37      {
38        label: "Undergrad Programs",
39        url: "/programs/?degree_level=undergraduate",
40      },
41    ],
42    "graduate-student": [
43      { label: "myUMBC", url: "https://my.umbc.edu", cta: true },
44      { label: "Directory", url: "/directory/" },
45      { label: "Graduate Programs", url: "/programs/?degree_level=graduate" },
46    ],
47    faculty: [
48      { label: "myUMBC", url: "https://my.umbc.edu", cta: true },
49      { label: "Directory", url: "/directory/" },
50      { label: "Make a Gift", url: "https://give.umbc.edu/campaigns/41278/donations/new?a=7548658&utm_source=umbc.edu&utm_medium=utility-nav&utm_campaign=make-a-gift" },
51      {
52        label: "Faculty Research",
53        url: "https://umbc.discovery.academicanalytics.com",
54      },
55    ],
56    staff: [
57      { label: "myUMBC", url: "https://my.umbc.edu", cta: true },
58      { label: "Directory", url: "/directory/" },
59      { label: "Make a Gift", url: "https://give.umbc.edu/campaigns/41278/donations/new?a=7548658&utm_source=umbc.edu&utm_medium=utility-nav&utm_campaign=make-a-gift" },
60    ],
61    member: [
62      { label: "myUMBC", url: "https://my.umbc.edu", cta: true },
63      { label: "Directory", url: "/directory/" },
64      { label: "Make a Gift", url: "https://give.umbc.edu/campaigns/41278/donations/new?a=7548658&utm_source=umbc.edu&utm_medium=utility-nav&utm_campaign=make-a-gift" },
65    ],
66  };
67
68  /* Build HTML for the desktop strip (.uh-utility-strip).
69       Non-CTA links render as plain utility links; the CTA entry
70       becomes the gold button at the end of the strip. */
71  function buildDesktop(links) {
72    var plain = links.filter(function (l) {
73      return !l.cta;
74    });
75    var cta = links.filter(function (l) {
76      return l.cta;
77    })[0];
78    var html = plain
79      .map(function (l) {
80        return (
81          '<a href="' + l.url + '" class="uh-utility-link">' + l.label + "</a>"
82        );
83      })
84      .join("\n");
85    if (cta) {
86      html +=
87        '\n<a href="' +
88        cta.url +
89        '" class="uh-utility-cta">' +
90        cta.label +
91        "</a>";
92    }
93    return html;
94  }
95
96  /* Build HTML for the mobile strip (.mobile-utility-strip) */
97  function buildMobile(links) {
98    return links
99      .map(function (l) {
100        var cls = l.cta
101          ? "mobile-utility-link mobile-utility-link--cta"
102          : "mobile-utility-link";
103        return (
104          '<a href="' + l.url + '" class="' + cls + '">' + l.label + "</a>"
105        );
106      })
107      .join("\n");
108  }
109
110  /* ------------------------------------------------------------------
111   * Helpers
112   * ------------------------------------------------------------------ */
113  function getCookie(name) {
114    var match = document.cookie.match(
115      new RegExp(
116        "(?:^|;)\\s*" +
117          name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") +
118          "=([^;]*)",
119      ),
120    );
121    return match ? decodeURIComponent(match[1]) : null;
122  }
123
124  function resolveRole(cookieValue) {
125    // Priority order — first match wins (cookie is already ordered by myUMBC)
126    var roles = cookieValue.split(",").map(function (r) {
127      return r.trim();
128    });
129    if (roles.indexOf("faculty") !== -1) return "faculty";
130    if (roles.indexOf("staff") !== -1) return "staff";
131    if (roles.indexOf("graduate-student") !== -1) return "graduate-student";
132    if (roles.indexOf("undergraduate-student") !== -1)
133      return "undergraduate-student";
134    return "member"; // authenticated but unrecognised role
135  }
136
137  function applyNav(role) {
138    var links = LINKS[role];
139    if (!links) return;
140
141    var desktop = document.querySelector(".uh-utility-strip");
142    if (desktop) {
143      // The dark-mode toggle lives inside the strip — detach it before
144      // replacing the links, then re-append the SAME node so its click
145      // listener (bound in header.php) survives the rebuild.
146      var toggle = desktop.querySelector(".dark-mode-toggle");
147      desktop.innerHTML = buildDesktop(links);
148      if (toggle) desktop.appendChild(toggle);
149    }
150
151    var mobile = document.querySelector(".mobile-utility-strip");
152    if (mobile) mobile.innerHTML = buildMobile(links);
153  }
154
155  /* ------------------------------------------------------------------
156   * Boot
157   * ------------------------------------------------------------------ */
158  function boot() {
159    var cookieValue = getCookie(COOKIE_NAME);
160    if (!cookieValue) return; // no cookie → anonymous/prospective; leave PHP nav as-is + affiliation unset
161
162    var role = resolveRole(cookieValue);
163
164    // Expose affiliation to analytics as a user-scoped dimension (read by GTM
165    // as the `user_affiliation` Data Layer Variable). Pushed client-side from
166    // the umbc_roles cookie — NOT server-rendered — so it is never baked into
167    // Pantheon's page cache. Anonymous visitors get no push (correct: they
168    // read as "prospective" / unset in GA4). See plan §11.4.
169    window.dataLayer = window.dataLayer || [];
170    window.dataLayer.push({ user_affiliation: role });
171
172    applyNav(role);
173  }
174
175  // Runs in footer so DOM is already ready — but guard anyway
176  if (document.readyState === "loading") {
177    document.addEventListener("DOMContentLoaded", boot);
178  } else {
179    boot();
180  }
181})();

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.