|
@@ -178,74 +178,158 @@ function setupLazyImages() {
|
|
}, 5);
|
|
}, 5);
|
|
}
|
|
}
|
|
|
|
|
|
-function setupCollapsibleLists() {
|
|
|
|
- const collapsibleListElements = document.getElementsByClassName("list-collapsible");
|
|
|
|
-
|
|
|
|
- if (collapsibleListElements.length == 0) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+function attachExpandToggleButton(collapsibleContainer) {
|
|
const showMoreText = "Show more";
|
|
const showMoreText = "Show more";
|
|
const showLessText = "Show less";
|
|
const showLessText = "Show less";
|
|
|
|
|
|
- const attachExpandToggleButton = (listElement) => {
|
|
|
|
- let expanded = false;
|
|
|
|
- const button = document.createElement("button");
|
|
|
|
- const arrowElement = document.createElement("span");
|
|
|
|
- arrowElement.classList.add("list-collapsible-label-icon");
|
|
|
|
- const textNode = document.createTextNode(showMoreText);
|
|
|
|
- button.classList.add("list-collapsible-label");
|
|
|
|
- button.append(textNode, arrowElement);
|
|
|
|
- button.addEventListener("click", () => {
|
|
|
|
- expanded = !expanded;
|
|
|
|
-
|
|
|
|
- if (expanded) {
|
|
|
|
- listElement.classList.add("list-collapsible-expanded");
|
|
|
|
- button.classList.add("list-collapsible-label-expanded");
|
|
|
|
- textNode.nodeValue = showLessText;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ let expanded = false;
|
|
|
|
+ const button = document.createElement("button");
|
|
|
|
+ const icon = document.createElement("span");
|
|
|
|
+ icon.classList.add("expand-toggle-button-icon");
|
|
|
|
+ const textNode = document.createTextNode(showMoreText);
|
|
|
|
+ button.classList.add("expand-toggle-button");
|
|
|
|
+ button.append(textNode, icon);
|
|
|
|
+ button.addEventListener("click", () => {
|
|
|
|
+ expanded = !expanded;
|
|
|
|
+
|
|
|
|
+ if (expanded) {
|
|
|
|
+ collapsibleContainer.classList.add("container-expanded");
|
|
|
|
+ button.classList.add("container-expanded");
|
|
|
|
+ textNode.nodeValue = showLessText;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
- const topBefore = button.getClientRects()[0].top;
|
|
|
|
|
|
+ const topBefore = button.getClientRects()[0].top;
|
|
|
|
|
|
- listElement.classList.remove("list-collapsible-expanded");
|
|
|
|
- button.classList.remove("list-collapsible-label-expanded");
|
|
|
|
- textNode.nodeValue = showMoreText;
|
|
|
|
|
|
+ collapsibleContainer.classList.remove("container-expanded");
|
|
|
|
+ button.classList.remove("container-expanded");
|
|
|
|
+ textNode.nodeValue = showMoreText;
|
|
|
|
|
|
- const topAfter = button.getClientRects()[0].top;
|
|
|
|
|
|
+ const topAfter = button.getClientRects()[0].top;
|
|
|
|
|
|
- if (topAfter > 0)
|
|
|
|
- return;
|
|
|
|
|
|
+ if (topAfter > 0)
|
|
|
|
+ return;
|
|
|
|
|
|
- window.scrollBy({
|
|
|
|
- top: topAfter - topBefore,
|
|
|
|
- behavior: "instant"
|
|
|
|
- });
|
|
|
|
|
|
+ window.scrollBy({
|
|
|
|
+ top: topAfter - topBefore,
|
|
|
|
+ behavior: "instant"
|
|
});
|
|
});
|
|
|
|
+ });
|
|
|
|
|
|
- listElement.after(button);
|
|
|
|
- };
|
|
|
|
|
|
+ collapsibleContainer.after(button);
|
|
|
|
+
|
|
|
|
+ return button;
|
|
|
|
+};
|
|
|
|
|
|
- for (let i = 0; i < collapsibleListElements.length; i++) {
|
|
|
|
- const listElement = collapsibleListElements[i];
|
|
|
|
|
|
|
|
- if (listElement.dataset.collapseAfter === undefined) {
|
|
|
|
|
|
+function setupCollapsibleLists() {
|
|
|
|
+ const collapsibleLists = document.querySelectorAll(".list.collapsible-container");
|
|
|
|
+
|
|
|
|
+ if (collapsibleLists.length == 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < collapsibleLists.length; i++) {
|
|
|
|
+ const list = collapsibleLists[i];
|
|
|
|
+
|
|
|
|
+ if (list.dataset.collapseAfter === undefined) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- const collapseAfter = parseInt(listElement.dataset.collapseAfter);
|
|
|
|
|
|
+ const collapseAfter = parseInt(list.dataset.collapseAfter);
|
|
|
|
+
|
|
|
|
+ if (collapseAfter == -1) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
|
|
- if (listElement.children.length <= collapseAfter) {
|
|
|
|
|
|
+ if (list.children.length <= collapseAfter) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- attachExpandToggleButton(listElement);
|
|
|
|
|
|
+ attachExpandToggleButton(list);
|
|
|
|
|
|
- for (let c = collapseAfter; c < listElement.children.length; c++) {
|
|
|
|
- const child = listElement.children[c];
|
|
|
|
- child.classList.add("list-collapsible-item");
|
|
|
|
|
|
+ for (let c = collapseAfter; c < list.children.length; c++) {
|
|
|
|
+ const child = list.children[c];
|
|
|
|
+ child.classList.add("collapsible-item");
|
|
child.style.animationDelay = ((c - collapseAfter) * 20).toString() + "ms";
|
|
child.style.animationDelay = ((c - collapseAfter) * 20).toString() + "ms";
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ list.classList.add("ready");
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function setupCollapsibleGrids() {
|
|
|
|
+ const collapsibleGridElements = document.querySelectorAll(".cards-grid.collapsible-container");
|
|
|
|
+
|
|
|
|
+ if (collapsibleGridElements.length == 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < collapsibleGridElements.length; i++) {
|
|
|
|
+ const gridElement = collapsibleGridElements[i];
|
|
|
|
+
|
|
|
|
+ if (gridElement.dataset.collapseAfterRows === undefined) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const collapseAfterRows = parseInt(gridElement.dataset.collapseAfterRows);
|
|
|
|
+
|
|
|
|
+ if (collapseAfterRows == -1) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const getCardsPerRow = () => {
|
|
|
|
+ return parseInt(getComputedStyle(gridElement).getPropertyValue('--cards-per-row'));
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const button = attachExpandToggleButton(gridElement);
|
|
|
|
+
|
|
|
|
+ let cardsPerRow = 2;
|
|
|
|
+
|
|
|
|
+ const resolveCollapsibleItems = () => {
|
|
|
|
+ const hideItemsAfterIndex = cardsPerRow * collapseAfterRows;
|
|
|
|
+
|
|
|
|
+ if (hideItemsAfterIndex >= gridElement.children.length) {
|
|
|
|
+ button.style.display = "none";
|
|
|
|
+ } else {
|
|
|
|
+ button.style.removeProperty("display");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let row = 0;
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < gridElement.children.length; i++) {
|
|
|
|
+ const child = gridElement.children[i];
|
|
|
|
+
|
|
|
|
+ if (i >= hideItemsAfterIndex) {
|
|
|
|
+ child.classList.add("collapsible-item");
|
|
|
|
+ child.style.animationDelay = (row * 40).toString() + "ms";
|
|
|
|
+
|
|
|
|
+ if (i % cardsPerRow + 1 == cardsPerRow) {
|
|
|
|
+ row++;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ child.classList.remove("collapsible-item");
|
|
|
|
+ child.style.removeProperty("animation-delay");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ cardsPerRow = getCardsPerRow();
|
|
|
|
+ resolveCollapsibleItems();
|
|
|
|
+ gridElement.classList.add("ready");
|
|
|
|
+ }, 1);
|
|
|
|
+
|
|
|
|
+ window.addEventListener("resize", () => {
|
|
|
|
+ const newCardsPerRow = getCardsPerRow();
|
|
|
|
+
|
|
|
|
+ if (cardsPerRow == newCardsPerRow) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cardsPerRow = newCardsPerRow;
|
|
|
|
+ resolveCollapsibleItems();
|
|
|
|
+ });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -264,6 +348,7 @@ async function setupPage() {
|
|
setupLazyImages();
|
|
setupLazyImages();
|
|
setupCarousels();
|
|
setupCarousels();
|
|
setupCollapsibleLists();
|
|
setupCollapsibleLists();
|
|
|
|
+ setupCollapsibleGrids();
|
|
setupDynamicRelativeTime();
|
|
setupDynamicRelativeTime();
|
|
} finally {
|
|
} finally {
|
|
pageElement.classList.add("content-ready");
|
|
pageElement.classList.add("content-ready");
|