PageSourceSearch

https://apps.nasponline.org/widgets/launcher/nasp-launcher.js

js nasponline.org collected 2026-09-25 08:35:13 UTC 13,748 bytes, 383 lines download raw bytes

1(function () {
2
3    console.log("NASP Launcher JS loaded");
4
5    function getLauncherBaseUrl() {
6        var script = document.currentScript;
7
8        if (!script) {
9            return "/widgets/launcher/";
10        }
11
12        return script.src.substring(0, script.src.lastIndexOf("/") + 1);
13    }
14
15    function getAppsBaseUrl(baseUrl) {
16        var anchor = document.createElement("a");
17        anchor.href = baseUrl;
18
19        return anchor.protocol + "//" + anchor.host;
20    }
21
22    function loadLauncherCss(baseUrl) {
23        console.log("NASP Launcher: loadLauncherCss called");
24
25        var cssUrl = baseUrl + "nasp-launcher.css";
26
27        if (document.querySelector("link[href='" + cssUrl + "']")) {
28            return;
29        }
30
31        var link = document.createElement("link");
32
33        link.rel = "stylesheet";
34        link.type = "text/css";
35        link.href = cssUrl;
36
37        document.head.appendChild(link);
38    }
39
40    function addLauncherUtm(url, linkName) {
41        var separator = url.indexOf("?") >= 0 ? "&" : "?";
42
43        return url + separator +
44            "utm_source=nasp_launcher" +
45            "&utm_medium=floating_launcher" +
46            "&utm_campaign=staff_tools" +
47            "&utm_content=" + encodeURIComponent(linkName);
48    }
49
50    function removeNaspLauncher() {
51        var old = document.getElementById("naspLauncher");
52
53        if (old) {
54            old.parentNode.removeChild(old);
55        }
56
57        var oldRestore = document.getElementById("naspLauncherRestore");
58
59        if (oldRestore) {
60            oldRestore.parentNode.removeChild(oldRestore);
61        }
62    }
63
64    function createNaspLauncher(options) {
65        removeNaspLauncher();
66
67        var isLoggedIn = options.isLoggedIn === true;
68        var isStaff = options.isStaff === true;
69        var isWebStaff = options.isWebStaff === true;
70        var isConvStaff = options.isConvStaff === true;
71        var isMembershipStaff = options.isMembershipStaff === true;
72        var isTest = options.isTest === true;
73        var appsBaseUrl = options.appsBaseUrl;
74
75        if ((!isLoggedIn || !isStaff) && !isTest) {
76            return;
77        }
78
79        console.log("NASP Launcher: creating launcher");
80
81        var launcher = document.createElement("div");
82        launcher.id = "naspLauncher";
83
84        if (isTest) {
85            launcher.classList.add("test");
86        }
87
88        var panel = document.createElement("div");
89        panel.id = "naspLauncherPanel";
90
91        var header = document.createElement("div");
92        header.className = "launcher-header" + (isTest ? " test" : "");
93
94        var title = "";
95        var subtitle = "";
96
97        var restoreHtml = isTest
98            ? "Test"
99            : "<img src=\"" + appsBaseUrl + "/img/NASP-Tree_RGB-White Green.png\" width=\"75%\" alt=\"Staff Portal\" />";
100
101        if (isTest && isStaff) {
102            title = "Test Site";
103            subtitle = "Staff tools available";
104        } else if (isTest) {
105            title = "Test Site";
106            subtitle = "Internal testing only";
107        } else {
108            title = "Staff Portal";
109            subtitle = "Internal resources";
110        }
111
112        header.innerHTML =
113            "<div class=\"launcher-title\">" +
114            title +
115            "<span class=\"launcher-subtitle\">" +
116            subtitle +
117            "</span></div>";
118
119        var actions = document.createElement("div");
120        actions.className = "launcher-actions";
121
122        if (isTest) {
123            actions.innerHTML +=
124                "<a class=\"launcher-action warning\" href=\"#\">" +
125                "<span class=\"launcher-icon\">!</span>" +
126                "<span>Test Website</span>" +
127                "</a>";
128        }
129
130        if (isStaff || isTest) {
131            actions.innerHTML +=
132                "<a class=\"launcher-action\" href=\"" +
133                addLauncherUtm(appsBaseUrl + "/intranet/index.aspx", "nasp_intranet") +
134                "\" data-launcher-link=\"nasp_intranet\">" +
135                "<span class=\"launcher-icon\">⌂</span>" +
136                "<span>NASP Intranet</span>" +
137                "</a>";
138
139            if (isWebStaff || isTest) {
140                actions.innerHTML +=
141                    "<a class=\"launcher-action\" href=\"" +
142                    addLauncherUtm(appsBaseUrl + "/admin/tools/project-manager/default.aspx", "project_management") +
143                    "\" data-launcher-link=\"project_management\">" +
144                    "<span class=\"launcher-icon material-symbols-outlined\">assignment</span>" +
145                    "<span>Project Manager</span>" +
146                    "</a>";
147            }
148
149            actions.innerHTML +=
150                "<a class=\"launcher-action\" href=\"" +
151                addLauncherUtm(appsBaseUrl + "/intranet/helpdesk/ListTickets.aspx", "helpdesk") +
152                "\" data-launcher-link=\"helpdesk\">" +
153                "<span class=\"launcher-icon\">?</span>" +
154                "<span>Helpdesk</span>" +
155                "</a>";
156
157            actions.innerHTML +=
158                "<a class=\"launcher-action\" href=\"" +
159                addLauncherUtm(appsBaseUrl + "/intranet/documents.aspx", "document_library") +
160                "\" data-launcher-link=\"document_library\">" +
161                "<span class=\"launcher-icon\">▤</span>" +
162                "<span>Document Library</span>" +
163                "</a>";
164
165            actions.innerHTML +=
166                "<a class=\"launcher-action\" href=\"" +
167                addLauncherUtm(appsBaseUrl + "/leadership-tools/index.aspx", "leadership_tools") +
168                "\" data-launcher-link=\"leadership_tools\">" +
169                "<span class=\"launcher-icon\">★</span>" +
170                "<span>Leadership Tools</span>" +
171                "</a>";
172
173            if (isConvStaff || isWebStaff || isTest) {
174                actions.innerHTML +=
175                    "<a class=\"launcher-action\" href=\"" +
176                    addLauncherUtm(appsBaseUrl + "/professional-development/cfp/admin/default.aspx", "convention_admin") +
177                    "\" data-launcher-link=\"convention_admin\">" +
178                    "<span class=\"launcher-icon material-symbols-outlined\">dashboard</span>" +
179                    "<span>Convention Admin</span>" +
180                    "</a>";
181            }
182        }
183
184        var footer = document.createElement("div");
185        footer.className = "launcher-footer";
186        footer.innerHTML = "Click the pill to expand or collapse";
187
188        panel.appendChild(header);
189        panel.appendChild(actions);
190        panel.appendChild(footer);
191
192        var button = document.createElement("div");
193        button.id = "naspLauncherButton";
194        button.className = isTest ? "test" : "";
195
196        button.innerHTML =
197            "<button id=\"naspLauncherToggle\" type=\"button\" class=\"launcher-button-main\">" +
198            "<span class=\"hamburger\">☰</span>" +
199            "<span class=\"launcher-button-text\">" +
200            title +
201            "<span>" +
202            subtitle +
203            "</span></span>" +
204            "</button>" +
205            "<button id=\"naspLauncherClose\" type=\"button\" class=\"launcher-close\" aria-label=\"Minimize launcher\">×</button>";
206
207        var restore = document.createElement("button");
208        restore.id = "naspLauncherRestore";
209        restore.type = "button";
210        restore.className = isTest ? "test" : "";
211        restore.innerHTML = restoreHtml;
212        restore.title = "Restore NASP launcher";
213
214        launcher.appendChild(panel);
215        launcher.appendChild(button);
216
217        document.body.appendChild(launcher);
218        document.body.appendChild(restore);
219
220        var launcherLinks = launcher.querySelectorAll("[data-launcher-link]");
221
222        for (var i = 0; i < launcherLinks.length; i++) {
223            launcherLinks[i].onclick = function () {
224                var linkName = this.getAttribute("data-launcher-link");
225
226                if (typeof gtag === "function") {
227                    gtag("event", "nasp_launcher_click", {
228                        launcher_link: linkName,
229                        launcher_is_test: isTest ? "true" : "false",
230                        launcher_is_staff: isStaff ? "true" : "false",
231                        launcher_is_web_staff: isWebStaff ? "true" : "false",
232                        launcher_is_conv_staff: isConvStaff ? "true" : "false",
233                        launcher_is_membership_staff: isMembershipStaff ? "true" : "false"
234                    });
235                }
236            };
237        }
238
239        document.getElementById("naspLauncherToggle").onclick = function () {
240            launcher.classList.toggle("open");
241        };
242
243        document.getElementById("naspLauncherClose").onclick = function () {
244            launcher.style.display = "none";
245            restore.style.display = "block";
246
247            localStorage.setItem("naspLauncherMinimized", "true");
248        };
249
250        restore.onclick = function () {
251            launcher.style.display = "block";
252            restore.style.display = "none";
253
254            localStorage.removeItem("naspLauncherMinimized");
255        };
256
257        if (localStorage.getItem("naspLauncherMinimized") == "true") {
258            launcher.style.display = "none";
259            restore.style.display = "block";
260        }
261    }
262
263    function reconcileNaspLauncher(baseUrl) {
264        console.log("NASP Launcher: redirecting for reconciliation");
265
266        var reconcileUrl =
267            baseUrl +
268            "reconcile.ashx?returnUrl=" +
269            encodeURIComponent(window.location.href);
270
271        window.location.href = reconcileUrl;
272    }
273
274    function loadNaspLauncher(baseUrl) {
275        var contextUrl = baseUrl + "context.ashx";
276        var appsBaseUrl = getAppsBaseUrl(baseUrl);
277
278        console.log("NASP Launcher: checking context");
279        console.log("NASP Launcher: context URL", contextUrl);
280        console.log("NASP Launcher: apps base URL", appsBaseUrl);
281
282        fetch(contextUrl, {
283            method: "GET",
284            credentials: "include",
285            cache: "no-store"
286        })
287            .then(function (response) {
288                console.log("NASP Launcher: context status", response.status);
289                console.log("NASP Launcher: context response URL", response.url);
290                console.log("NASP Launcher: context redirected", response.redirected);
291
292                if (!response.ok) {
293                    console.log("NASP Launcher: context request failed");
294                    return null;
295                }
296
297                return response.json();
298            })
299            .then(function (data) {
300                console.log("NASP Launcher: context data", data);
301
302                if (!data) {
303                    return;
304                }
305
306                /*
307                 * Test/local/webdev behaves differently.
308                 * No production SSO reconciliation is required.
309                 */
310                if (data.IsTest === true) {
311                    console.log("NASP Launcher: test environment");
312
313                    loadLauncherCss(baseUrl);
314
315                    createNaspLauncher({
316                        isLoggedIn: data.IsLoggedIn === true,
317                        isStaff: data.IsStaff === true,
318                        isWebStaff: data.IsWebStaff === true,
319                        isConvStaff: data.IsConvStaff === true,
320                        isMembershipStaff: data.IsMembershipStaff === true,
321                        isTest: true,
322                        appsBaseUrl: appsBaseUrl
323                    });
324
325                    return;
326                }
327
328                /*
329                 * Production only.
330                 */
331                if (data.NeedsReconcile === true) {
332                    console.log("NASP Launcher: reconciliation required");
333
334                    reconcileNaspLauncher(baseUrl);
335                    return;
336                }
337
338                if (data.IsLoggedIn !== true) {
339                    console.log("NASP Launcher: user is not logged in");
340                    return;
341                }
342
343                if (data.IsStaff !== true) {
344                    console.log("NASP Launcher: user is logged in but is not staff");
345                    return;
346                }
347
348                console.log("NASP Launcher: user authorized");
349
350                loadLauncherCss(baseUrl);
351
352                createNaspLauncher({
353                    isLoggedIn: true,
354                    isStaff: true,
355                    isWebStaff: data.IsWebStaff === true,
356                    isConvStaff: data.IsConvStaff === true,
357                    isMembershipStaff: data.IsMembershipStaff === true,
358                    isTest: false,
359                    appsBaseUrl: appsBaseUrl
360                });
361            })
362            .catch(function (error) {
363                console.log("NASP Launcher: context error", error);
364            });
365    }
366
367    var baseUrl = getLauncherBaseUrl();
368
369    console.log("NASP Launcher: base URL", baseUrl);
370
371    if (document.readyState === "loading") {
372        document.addEventListener("DOMContentLoaded", function () {
373            console.log("NASP Launcher: DOMContentLoaded");
374
375            loadNaspLauncher(baseUrl);
376        });
377    } else {
378        console.log("NASP Launcher: DOM already loaded");
379
380        loadNaspLauncher(baseUrl);
381    }
382
383})();

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.