Skip to content

Commit

Permalink
[Docs Site]: minor TS improvements to assets (cloudflare#15267)
Browse files Browse the repository at this point in the history
* chore: minor TS improvements

* chore: more nullish element protections

* chore: more TS assets improvements

* chore: more querySelector

* chore: remove debug log
  • Loading branch information
Cherry authored Jun 24, 2024
1 parent 906f9ad commit d6412fe
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 86 deletions.
20 changes: 10 additions & 10 deletions assets/contents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ export function toc() {
let target = document.querySelector('ul.DocsTableOfContents');
let article = target && document.querySelector('article.DocsMarkdown');

if (article) {
if (article && target) {
let headers = article.querySelectorAll('h2,h3,h4');
let i = 0,
tmp: Element,
last: ListItem,
container = target;

let i = 0;
let tmp;
let last;
let container = target;
if (!headers.length) return; // exit & leave hidden

for (; i < headers.length; i++) {
Expand All @@ -24,16 +24,16 @@ export function toc() {
// eg; "H4" > "H2" ==> true
container = last.appendChild(document.createElement('ul'));
} else if (last && tmp.nodeName < last.h) {
container = container.parentElement || target;
container = container?.parentElement || target;
}

last = document.createElement('li') as ListItem;
let a = document.createElement('a');
a.classList.add('DocsTableOfContents-link');
a.href = '#' + tmp.id;
a.textContent = tmp.lastElementChild.textContent.trim();
a.textContent = tmp?.lastElementChild?.textContent?.trim() ?? '';
last.append(a);
container.appendChild(last);
container?.appendChild(last);
last.h = tmp.nodeName;
}

Expand Down Expand Up @@ -81,7 +81,7 @@ export function toc() {
}
return;
}
const topMostVisibleLink = [...tocLinks][topVisibleIndex];
const topMostVisibleLink = [...tocLinks][topVisibleIndex ?? 0];

// find a new link to highlight
const highlightLink = [...tocLinks].find(
Expand Down
117 changes: 66 additions & 51 deletions assets/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function $focus(elem: HTMLElement, bool: boolean) {
if (SEARCH_ID && SEARCH_ID.test(elem.id)) {
SEARCH_INPUT = elem;

if(!elem.parentElement || !elem.parentElement.parentElement) return;
elem.parentElement.parentElement.toggleAttribute("is-focused", bool);
elem.setAttribute("aria-expanded", "" + bool);

Expand All @@ -35,12 +36,14 @@ export function $tabbable(links: NodeListOf<Element>, bool: boolean) {
// but only on load if `#hash` in URL
export function load() {
let hash = location.hash.substring(1);
let item = hash && document.getElementById(hash.toLowerCase());
let item = hash && document.querySelector(`#${hash.toLowerCase()}`);
let timer =
item &&
setInterval(() => {
if (document.readyState !== "complete") return;
clearInterval(timer);
if(timer){
clearInterval(timer);
}
setTimeout(() => {
item.scrollIntoView({ behavior: "smooth" });
}, 250);
Expand All @@ -59,9 +62,9 @@ export function mobile() {
});

// clicking on mobile search icon
let input: HTMLInputElement =
document.querySelector("#DocsSearch--input") ||
document.querySelector("#SiteSearch--input");
let input =
document.querySelector<HTMLInputElement>("#DocsSearch--input") ||
document.querySelector<HTMLInputElement>("#SiteSearch--input");

// register init handler
if (input)
Expand Down Expand Up @@ -94,20 +97,23 @@ function $tab(ev: MouseEvent) {
.closest("[data-id]")
?.getAttribute("data-id");

let tabs = document.querySelectorAll(
let tabs = document.querySelectorAll<HTMLElement>(
`div[tab-wrapper-id="${tabBlockId}"] > .tab`
);

for (let i = 0; i < tabs.length; i++) {
(tabs[i] as HTMLElement).style.display = "none";
tabs[i].style.display = "none";
}

let link = (ev.target as HTMLElement)
.closest("[data-link]")
?.getAttribute("data-link");

document.getElementById(`${link}-${tabBlockId}`).style.display = "block";
zaraz.track("tab click", {selected_option: ev.target.innerText})
const linkElement = document.querySelector<HTMLElement>(`#${link}-${tabBlockId}`);
if(linkElement){
linkElement.style.display = "block";
}
zaraz.track("tab click", {selected_option: (ev.target as HTMLElement).innerText})
}

export function tabs() {
Expand All @@ -116,9 +122,9 @@ export function tabs() {

addEventListener("DOMContentLoaded", () => {
for (let i = 0; i < wrappers.length; i++) {
const labels = wrappers[i].querySelectorAll(".tab-label");
const tabs = wrappers[i].querySelectorAll(".tab");
const defaultTab = wrappers[i].querySelector(".tab.tab-default");
const labels = wrappers[i].querySelectorAll<HTMLElement>(".tab-label");
const tabs = wrappers[i].querySelectorAll<HTMLElement>(".tab");
const defaultTab = wrappers[i].querySelector<HTMLElement>(".tab.tab-default");

if (tabs.length > 0) {
// if a tab has been specified as default, set that
Expand All @@ -133,11 +139,13 @@ export function tabs() {
`a[data-link="${tabId}"]`
);

(defaultTab as HTMLElement).style.display = "block";
(defaultTabLabel as HTMLElement).classList.add("active");
defaultTab.style.display = "block";
if(defaultTabLabel){
defaultTabLabel.classList.add("active");
}
} else {
(tabs[0] as HTMLElement).style.display = "block";
(labels[0] as HTMLElement).classList.add("active");
tabs[0].style.display = "block";
labels[0].classList.add("active");
}

for (let i = 0; i < labels.length; i++)
Expand All @@ -148,16 +156,18 @@ export function tabs() {
}

export function activeTab() {
const blocks = document.getElementsByClassName("tab-active");
const blocks = document.querySelectorAll(".tab-active");
if (blocks) {
for (const block of blocks) {
const blockId = block.getAttribute("block-id");

var tabs = block.querySelectorAll(`.tab-label`);
var tabs = block.querySelectorAll<HTMLElement>(`.tab-label`);
for (var i = 0; i < tabs.length; i++) {
(tabs[i] as HTMLElement).addEventListener("click", function name() {
tabs[i].addEventListener("click", function name() {
let current = block.querySelector(`.active`);
current.classList.remove("active");
if(current){
current.classList.remove("active");
}
this.classList.add("active");
});
}
Expand All @@ -175,7 +185,8 @@ export function dropdowns() {
let focused = 0; // index

if (btn && links.length > 0) {
let arrows: EventListener = (ev: KeyboardEvent) => {
let arrows: EventListener = (rawEv: Event) => {
const ev = rawEv as KeyboardEvent;
let key = ev.which;
let isTAB = key === 9;

Expand Down Expand Up @@ -236,10 +247,12 @@ export function dropdowns() {
}

export function toggleSidebar() {
const toggleButton = document.getElementsByClassName("toggleSidebar");
const toggleButton = document.querySelectorAll(".toggleSidebar");
if (toggleButton.length > 0) {
let div = document.querySelector(".DocsSidebar--sections .toggleSidebar");
if(!div) return;
let btn = div.querySelector("button");
if(!btn) return;
btn.addEventListener("click", () => {
let classToggleList = [
".DocsSidebar",
Expand All @@ -253,6 +266,7 @@ export function toggleSidebar() {

classToggleList.forEach(function (querySelector) {
let item = document.querySelector(querySelector);
if(!item) return;
item.classList.toggle("collapsed");
});

Expand All @@ -266,11 +280,12 @@ export function toggleSidebar() {

attrToggleList.forEach(function (querySelector) {
let item = document.querySelector(querySelector);
if(!item) return;
let isHidden = item.hasAttribute(attr);
item.toggleAttribute(attr, !isHidden);
});

let moduleCounters = document.getElementsByClassName("moduleCounter")
let moduleCounters = document.querySelectorAll(".moduleCounter")
if (moduleCounters) {
for (const counter of moduleCounters) {
let isHidden2 = counter.hasAttribute(attr);
Expand All @@ -282,15 +297,15 @@ export function toggleSidebar() {
}

export function zarazTrackDocEvents() {
const links = document.getElementsByClassName("DocsMarkdown--link");
const dropdowns = document.getElementsByTagName("details")
const glossaryTooltips = document.getElementsByClassName("glossary-tooltip")
const playgroundLinks = document.getElementsByClassName("playground-link")
const copyCodeBlockButtons = document.getElementsByClassName("copyCode-button")
const links = document.querySelectorAll<HTMLAnchorElement>(".DocsMarkdown--link");
const dropdowns = document.querySelectorAll("details")
const glossaryTooltips = document.querySelectorAll(".glossary-tooltip")
const playgroundLinks = document.querySelectorAll<HTMLAnchorElement>(".playground-link")
const copyCodeBlockButtons = document.querySelectorAll(".copyCode-button")
addEventListener("DOMContentLoaded", () => {
if (links.length > 0) {
for (const link of links as any) { // Type cast to any for iteration
const linkURL = new URL(link)
for (const link of links) {
const linkURL = new URL(link.href)
const cfSubdomainRegex = new RegExp(`^[^.]+?\.cloudflare\.com`)
if (linkURL.hostname !== "developers.cloudflare.com") {
if (linkURL.hostname === "workers.cloudflare.com" && linkURL.pathname.startsWith("/playground#")) {
Expand All @@ -310,14 +325,14 @@ export function zarazTrackDocEvents() {
}
}
if (dropdowns.length > 0) {
for (const dropdown of dropdowns as any) {
for (const dropdown of dropdowns) {
dropdown.addEventListener("click", () => {
$zarazDropdownEvent(dropdown.getElementsByTagName("summary")[0]);
$zarazDropdownEvent(dropdown.querySelectorAll("summary")[0]);
});
}
}
if (glossaryTooltips.length > 0) {
for (const tooltip of glossaryTooltips as any) {
for (const tooltip of glossaryTooltips) {
tooltip.addEventListener("pointerleave", () => {
$zarazGlossaryTooltipEvent(tooltip.getAttribute('aria-label'))
});
Expand All @@ -327,65 +342,65 @@ export function zarazTrackDocEvents() {
}
}
if (playgroundLinks.length > 0) {
for (const playgroundLink of playgroundLinks as any) {
for (const playgroundLink of playgroundLinks) {
playgroundLink.addEventListener("click", () => {
$zarazLinkEvent('playground link click', playgroundLink);
});
}
}
if (copyCodeBlockButtons.length > 0) {
for (const copyButton of copyCodeBlockButtons as any) {
for (const copyButton of copyCodeBlockButtons) {
copyButton.addEventListener("click", () => {
const codeBlockElement = copyButton.parentElement.parentElement.firstElementChild;
const codeBlockElement = copyButton?.parentElement?.parentElement?.firstElementChild;
zaraz.track('copy button link click', {
title: codeBlockElement.getAttribute('title') ?? 'title not set',
language: codeBlockElement.getAttribute('language') ?? 'language not set',});
title: codeBlockElement?.getAttribute('title') ?? 'title not set',
language: codeBlockElement?.getAttribute('language') ?? 'language not set',});
});
}
}
});
}

function $zarazLinkEvent(type: string, link: Element) {
function $zarazLinkEvent(type: string, link: HTMLAnchorElement) {
zaraz.track(type, {href: link.href, hostname: link.hostname})
}

function $zarazDropdownEvent(summary: string) {
function $zarazDropdownEvent(summary: HTMLElement) {
zaraz.track('dropdown click', {text: summary.innerText})
}

function $zarazGlossaryTooltipEvent(term: string) {
function $zarazGlossaryTooltipEvent(term: string | null) {
zaraz.track('glossary tooltip view', {term: term})
}

export function zarazTrackHomepageLinks() {
const links = document.getElementsByClassName("DocsMarkdown--link");
const playgroundLinks = document.getElementsByClassName("playground-link")
const copyCodeBlockButtons = document.getElementsByClassName("copyCode-button")
const links = document.querySelectorAll<HTMLAnchorElement>(".DocsMarkdown--link");
const playgroundLinks = document.querySelectorAll<HTMLAnchorElement>(".playground-link")
const copyCodeBlockButtons = document.querySelectorAll<HTMLButtonElement>(".copyCode-button")
addEventListener("DOMContentLoaded", () => {
if (links.length > 0) {
for (const link of links as any) { // Type cast to any for iteration
for (const link of links) {
link.addEventListener("click", () => {
zaraz.track('homepage link click', {href: link.href})
});
}
}
if (playgroundLinks.length > 0) {
for (const playgroundLink of playgroundLinks as any) {
for (const playgroundLink of playgroundLinks) {
playgroundLink.addEventListener("click", () => {
$zarazLinkEvent('playground link click', playgroundLink);
});
}
}
if (copyCodeBlockButtons.length > 0) {
for (const copyButton of copyCodeBlockButtons as any) {
for (const copyButton of copyCodeBlockButtons) {
copyButton.addEventListener("click", () => {
const codeBlockElement = copyButton.parentElement.parentElement.firstElementChild;
const codeBlockElement = copyButton?.parentElement?.parentElement?.firstElementChild;
zaraz.track('copy button link click', {
title: codeBlockElement.getAttribute('title') ?? 'title not set',
language: codeBlockElement.getAttribute('language') ?? 'language not set',});
title: codeBlockElement?.getAttribute('title') ?? 'title not set',
language: codeBlockElement?.getAttribute('language') ?? 'language not set',});
});
}
}
});
}
}
12 changes: 11 additions & 1 deletion assets/json-collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@ import * as cybersafe from "data/learning-paths/cybersafe.json";
import * as zero_trust_web_access from "data/learning-paths/zero-trust-web-access.json";
import * as secure_internet_traffic from "data/learning-paths/secure-internet-traffic.json";

let learning_paths = [
export type LearningPath = {
title: string;
path: string;
priority: number;
description: string;
products: string[];
product_group: string;
additional_groups?: string[];
}

let learning_paths: LearningPath[] = [
get_started_free,
load_balancing,
prevent_ddos_attacks,
Expand Down
Loading

0 comments on commit d6412fe

Please sign in to comment.