Indent code with spaces instead of tabs

This commit is contained in:
foxster-mp4
2023-05-22 10:35:56 -07:00
parent adbc642cb9
commit 0d8e89dd2f
17 changed files with 923 additions and 923 deletions

304
js/app.js
View File

@@ -2,181 +2,181 @@ if (!urlSearchParams.has('id')) exit();
const bundleId = urlSearchParams.get('id');
(function () {
// Hide/show navigation bar title & install button
let hidden = false;
window.onscroll = function (e) {
const appName = document.querySelector(".app-header .text>.title");
const title = document.getElementById("title");
const button = document.querySelector("#nav-bar .install");
// Hide/show navigation bar title & install button
let hidden = false;
window.onscroll = function (e) {
const appName = document.querySelector(".app-header .text>.title");
const title = document.getElementById("title");
const button = document.querySelector("#nav-bar .install");
if (hidden && appName.getBoundingClientRect().y >= 72) { // App name not visible
hidden = false;
title.classList.add("hidden");
button.classList.add("hidden");
button.disaled = true;
} else if (!hidden && appName.getBoundingClientRect().y < 72) {
hidden = true;
title.classList.remove("hidden");
button.classList.remove("hidden");
button.disaled = false;
}
}
if (hidden && appName.getBoundingClientRect().y >= 72) { // App name not visible
hidden = false;
title.classList.add("hidden");
button.classList.add("hidden");
button.disaled = true;
} else if (!hidden && appName.getBoundingClientRect().y < 72) {
hidden = true;
title.classList.remove("hidden");
button.classList.remove("hidden");
button.disaled = false;
}
}
})();
function main(json) {
const app = getAppWithBundleId(bundleId);
if (!app) exit();
const app = getAppWithBundleId(bundleId);
if (!app) exit();
// Set tab title
document.title = `${app.name} - ${json.name}`;
// Set tab title
document.title = `${app.name} - ${json.name}`;
const tintColor = `#${app.tintColor?.replaceAll("#", "")}`;
// Set tint color
if (tintColor) document.querySelector(':root').style.setProperty("--app-tint-color", `${tintColor}`);
const tintColor = `#${app.tintColor?.replaceAll("#", "")}`;
// Set tint color
if (tintColor) document.querySelector(':root').style.setProperty("--app-tint-color", `${tintColor}`);
// Tint back button
document.getElementById("back").style.color = tintColor;
// Tint back button
document.getElementById("back").style.color = tintColor;
// Set up install buttons
document.querySelectorAll("a.install").forEach(button => {
button.href = `altstore://install?url=${app.downloadURL}`;
});
// Set up install buttons
document.querySelectorAll("a.install").forEach(button => {
button.href = `altstore://install?url=${app.downloadURL}`;
});
// Set up download button
document.getElementById("download").href = app.downloadURL;
// Set up download button
document.getElementById("download").href = app.downloadURL;
//
// Navigation bar
const navigationBar = document.getElementById("nav-bar");
// Title
navigationBar.querySelector("#title>p").textContent = app.name;
// App icon
navigationBar.querySelector("#title>img").src = app.iconURL;
// Install button
navigationBar.querySelector(".uibutton").style.backgroundColor = `${tintColor}`;
//
// Navigation bar
const navigationBar = document.getElementById("nav-bar");
// Title
navigationBar.querySelector("#title>p").textContent = app.name;
// App icon
navigationBar.querySelector("#title>img").src = app.iconURL;
// Install button
navigationBar.querySelector(".uibutton").style.backgroundColor = `${tintColor}`;
//
// App header
const appHeader = document.querySelector("#main .app-header");
// Icon
appHeader.querySelector("img").src = app.iconURL;
// App name
appHeader.querySelector(".title").textContent = app.name;
// Developer name
appHeader.querySelector(".subtitle").textContent = app.developerName;
// Install button
appHeader.querySelector(".uibutton").style.backgroundColor = tintColor;
// Background
appHeader.querySelector(".background").style.backgroundColor = tintColor;
//
// App header
const appHeader = document.querySelector("#main .app-header");
// Icon
appHeader.querySelector("img").src = app.iconURL;
// App name
appHeader.querySelector(".title").textContent = app.name;
// Developer name
appHeader.querySelector(".subtitle").textContent = app.developerName;
// Install button
appHeader.querySelector(".uibutton").style.backgroundColor = tintColor;
// Background
appHeader.querySelector(".background").style.backgroundColor = tintColor;
const more = `
<a id="more" onclick="revealTruncatedText(this);">
<button style="color: ${tintColor};">more</button>
</a>`;
const more = `
<a id="more" onclick="revealTruncatedText(this);">
<button style="color: ${tintColor};">more</button>
</a>`;
this.revealTruncatedText = moreButton => {
const textId = moreButton.parentNode.id;
const text = document.getElementById(textId);
text.style.display = "block";
text.style.overflow = "auto";
text.style.webkitLineClamp = "none";
text.style.lineClamp = "none";
text.removeChild(moreButton)
}
this.revealTruncatedText = moreButton => {
const textId = moreButton.parentNode.id;
const text = document.getElementById(textId);
text.style.display = "block";
text.style.overflow = "auto";
text.style.webkitLineClamp = "none";
text.style.lineClamp = "none";
text.removeChild(moreButton)
}
//
// Preview
const preview = document.getElementById("preview");
// Subtitle
preview.querySelector("#subtitle").textContent = app.subtitle;
// Screenshots
app.screenshotURLs.forEach(url => {
preview.querySelector("#screenshots").insertAdjacentHTML("beforeend", `<img src="${url}" alt="">`);
});
// Description
const previewDescription = preview.querySelector("#description");
previewDescription.innerHTML = formatString(app.localizedDescription);
if (previewDescription.scrollHeight > previewDescription.clientHeight)
previewDescription.insertAdjacentHTML("beforeend", more);
//
// Preview
const preview = document.getElementById("preview");
// Subtitle
preview.querySelector("#subtitle").textContent = app.subtitle;
// Screenshots
app.screenshotURLs.forEach(url => {
preview.querySelector("#screenshots").insertAdjacentHTML("beforeend", `<img src="${url}" alt="">`);
});
// Description
const previewDescription = preview.querySelector("#description");
previewDescription.innerHTML = formatString(app.localizedDescription);
if (previewDescription.scrollHeight > previewDescription.clientHeight)
previewDescription.insertAdjacentHTML("beforeend", more);
//
// Version info
const versionDateElement = document.getElementById("version-date");
const versionNumberElement = document.getElementById("version");
const versionSizeElement = document.getElementById("version-size");
const versionDescriptionElement = document.getElementById("version-description");
const versionDate = new Date(app.versionDate),
month = versionDate.toUTCString().split(" ")[2],
date = versionDate.getDate();
const today = new Date();
const msPerDay = 60 * 60 * 24 * 1000;
const msDifference = today.valueOf() - versionDate.valueOf();
//
// Version info
const versionDateElement = document.getElementById("version-date");
const versionNumberElement = document.getElementById("version");
const versionSizeElement = document.getElementById("version-size");
const versionDescriptionElement = document.getElementById("version-description");
const versionDate = new Date(app.versionDate),
month = versionDate.toUTCString().split(" ")[2],
date = versionDate.getDate();
const today = new Date();
const msPerDay = 60 * 60 * 24 * 1000;
const msDifference = today.valueOf() - versionDate.valueOf();
// Version date
versionDateElement.textContent = versionDate.valueOf() ? `${month} ${date}, ${versionDate.getFullYear()}` : app.versionDate.split("T")[0];
if (msDifference <= msPerDay && today.getDate() == versionDate.getDate())
versionDateElement.textContent = "Today";
else if (msDifference <= msPerDay * 2)
versionDateElement.textContent = "Yesterday";
// Version date
versionDateElement.textContent = versionDate.valueOf() ? `${month} ${date}, ${versionDate.getFullYear()}` : app.versionDate.split("T")[0];
if (msDifference <= msPerDay && today.getDate() == versionDate.getDate())
versionDateElement.textContent = "Today";
else if (msDifference <= msPerDay * 2)
versionDateElement.textContent = "Yesterday";
// Version number
versionNumberElement.textContent = `Version ${app.version}`;
// Version number
versionNumberElement.textContent = `Version ${app.version}`;
// Version size
const units = ["B", "KB", "MB", "GB"];
var appSize = app.size, i = 0;
while (appSize > 1024) { i++;
appSize = parseFloat(appSize / 1024).toFixed(1);
}
versionSizeElement.textContent = `${appSize} ${units[i]}`;
// Version size
const units = ["B", "KB", "MB", "GB"];
var appSize = app.size, i = 0;
while (appSize > 1024) { i++;
appSize = parseFloat(appSize / 1024).toFixed(1);
}
versionSizeElement.textContent = `${appSize} ${units[i]}`;
// Version description
versionDescriptionElement.innerHTML = formatString(app.versionDescription);
if (versionDescriptionElement.scrollHeight > versionDescriptionElement.clientHeight)
versionDescriptionElement.insertAdjacentHTML("beforeend", more);
// Version description
versionDescriptionElement.innerHTML = formatString(app.versionDescription);
if (versionDescriptionElement.scrollHeight > versionDescriptionElement.clientHeight)
versionDescriptionElement.insertAdjacentHTML("beforeend", more);
//
// Permissions
const permissions = document.getElementById("permissions");
// If permissions specified
if (app.permissions)
// Remove placeholder permission
permissions.querySelector(".permission").remove();
else return;
//
// Permissions
const permissions = document.getElementById("permissions");
// If permissions specified
if (app.permissions)
// Remove placeholder permission
permissions.querySelector(".permission").remove();
else return;
app.permissions?.forEach(permission => {
var permissionType, icon;
switch (permission.type) {
case "background-audio":
permissionType = "Background Audio";
icon = "volume-up-fill";
break;
case "background-fetch":
permissionType = "Background Fetch";
icon = "arrow-repeat"
break;
case "photos":
permissionType = "Photos"
icon = "image-fill";
break;
default:
permissionType = permission.type.replaceAll("-", " ");
icon = "gear-wide-connected";
break;
}
app.permissions?.forEach(permission => {
var permissionType, icon;
switch (permission.type) {
case "background-audio":
permissionType = "Background Audio";
icon = "volume-up-fill";
break;
case "background-fetch":
permissionType = "Background Fetch";
icon = "arrow-repeat"
break;
case "photos":
permissionType = "Photos"
icon = "image-fill";
break;
default:
permissionType = permission.type.replaceAll("-", " ");
icon = "gear-wide-connected";
break;
}
permissions.insertAdjacentHTML("beforeend", `
<div class="permission">
<i class="bi-${icon}" style="color: ${tintColor};"></i>
<div class="text">
<p class="title">${permissionType}</p>
<p class="description">${permission.usageDescription ?? "No description provided."}</p>
</div>
</div>`);
});
permissions.insertAdjacentHTML("beforeend", `
<div class="permission">
<i class="bi-${icon}" style="color: ${tintColor};"></i>
<div class="text">
<p class="title">${permissionType}</p>
<p class="description">${permission.usageDescription ?? "No description provided."}</p>
</div>
</div>`);
});
}
function exit() {
window.location.replace(`home.html?source=${sourceURL}`);
window.location.replace(`home.html?source=${sourceURL}`);
}

View File

@@ -1,31 +1,31 @@
insertNavigationBar("All Apps");
function main(json) {
// Set tab title
document.title = `Apps - ${json.name}`;
// Set tab title
document.title = `Apps - ${json.name}`;
// Sort apps in decending order of version date (newest first)
json.apps.sort((a, b) => (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf());
// Sort apps in decending order of version date (newest first)
json.apps.sort((a, b) => (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf());
// Create & insert app items
json.apps.forEach(app => {
if (app.beta) return; // Ignore beta apps
// Create & insert app items
json.apps.forEach(app => {
if (app.beta) return; // Ignore beta apps
let html = `
<div class="app-container">
${appHeaderHTML(app) }
<p style="text-align: center; font-size: 0.9em;">${app.subtitle ?? ""}</p>`;
if (app.screenshotURLs) {
html += `
<div class="screenshots">`;
for (let i = 0; i < app.screenshotURLs.length, i < 2; i++) html += `
<img src="${app.screenshotURLs[i]}" class="screenshot">`;
html += `
</div>`;
}
html += `
</div>`;
let html = `
<div class="app-container">
${appHeaderHTML(app) }
<p style="text-align: center; font-size: 0.9em;">${app.subtitle ?? ""}</p>`;
if (app.screenshotURLs) {
html += `
<div class="screenshots">`;
for (let i = 0; i < app.screenshotURLs.length, i < 2; i++) html += `
<img src="${app.screenshotURLs[i]}" class="screenshot">`;
html += `
</div>`;
}
html += `
</div>`;
document.getElementById("apps").insertAdjacentHTML("beforeend", html);
});
document.getElementById("apps").insertAdjacentHTML("beforeend", html);
});
}

View File

@@ -1,56 +1,56 @@
function main(json) {
// Set "View All News" link
document.querySelector("#news a").href = `news.html?source=${sourceURL}`;
// Set "View All Apps" link
document.querySelector("#apps a").href = `apps.html?source=${sourceURL}`;
// Set "View All News" link
document.querySelector("#news a").href = `news.html?source=${sourceURL}`;
// Set "View All Apps" link
document.querySelector("#apps a").href = `apps.html?source=${sourceURL}`;
// Set tab title
document.title = json.name;
// Set page title
document.getElementById("title").innerText = json.name;
// Set tab title
document.title = json.name;
// Set page title
document.getElementById("title").innerText = json.name;
//
// News
if (json.news && json.news.length >= 1) {
// Sort news in decending order of date (latest first)
json.news.sort((a, b) => // If b < a
(new Date(b.date)).valueOf() - (new Date(a.date)).valueOf());
//
// News
if (json.news && json.news.length >= 1) {
// Sort news in decending order of date (latest first)
json.news.sort((a, b) => // If b < a
(new Date(b.date)).valueOf() - (new Date(a.date)).valueOf());
if (json.news.length == 1) {
document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[0], true));
document.getElementById("news-items").classList.add("one");
} else for (let i = 0; i < 5 && i < json.news.length; i++)
document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[i], true));
} else document.getElementById("news").remove();
if (json.news.length == 1) {
document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[0], true));
document.getElementById("news-items").classList.add("one");
} else for (let i = 0; i < 5 && i < json.news.length; i++)
document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[i], true));
} else document.getElementById("news").remove();
// Sort apps in descending order of version date
json.apps.sort((a, b) => (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf());
//
// Featured apps
let count = 1;
json.apps.forEach(app => {
// Max: 3 featured apps if not specified
if (count > 3) return;
// Sort apps in descending order of version date
json.apps.sort((a, b) => (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf());
//
// Featured apps
let count = 1;
json.apps.forEach(app => {
// Max: 3 featured apps if not specified
if (count > 3) return;
// Ignore beta apps
if (app.beta) return;
// Ignore beta apps
if (app.beta) return;
// If there are featured apps, ignore non-featured apps
if (json.featuredApps && !json.featuredApps.includes(app.bundleIdentifier)) return;
// If there are featured apps, ignore non-featured apps
if (json.featuredApps && !json.featuredApps.includes(app.bundleIdentifier)) return;
document.getElementById("apps").insertAdjacentHTML("beforeend", appHeaderHTML(app));
document.getElementById("apps").insertAdjacentHTML("beforeend", appHeaderHTML(app));
count++;
});
count++;
});
//
// About
var description = formatString(json.description);
if (description) document.getElementById("about").insertAdjacentHTML("beforeend", `
<div class="item">
<p>${description}</p>
</div>
`);
else document.getElementById("about").remove();
//
// About
var description = formatString(json.description);
if (description) document.getElementById("about").insertAdjacentHTML("beforeend", `
<div class="item">
<p>${description}</p>
</div>
`);
else document.getElementById("about").remove();
}

View File

@@ -1,44 +1,44 @@
(function () {
// If no source
if (!urlSearchParams.has('source'))
search();
// If source is not a valid HTTP URL
else if (!isValidHTTPURL(sourceURL)) {
alert("Invalid HTTP URL.");
search();
} else insertAddToAltStoreBanner();
// If no source
if (!urlSearchParams.has('source'))
search();
// If source is not a valid HTTP URL
else if (!isValidHTTPURL(sourceURL)) {
alert("Invalid HTTP URL.");
search();
} else insertAddToAltStoreBanner();
})();
fetch(sourceURL)
.then(response => response.json())
.then(json => {
// Set tint color
const tintColor = json.tintColor?.replaceAll("#", "");
if (tintColor) setTintColor(tintColor);
.then(response => response.json())
.then(json => {
// Set tint color
const tintColor = json.tintColor?.replaceAll("#", "");
if (tintColor) setTintColor(tintColor);
setApps(json.apps);
main(json);
waitForAllImagesToLoad();
})
.catch(error => console.error("An error occurred.", error));
setApps(json.apps);
main(json);
waitForAllImagesToLoad();
})
.catch(error => console.error("An error occurred.", error));
function waitForAllImagesToLoad() {
const allImages = document.querySelectorAll("img");
var count = 0;
const allImages = document.querySelectorAll("img");
var count = 0;
allImages.forEach(image => {
// New img element that won't be rendered to the DOM
var newImage = document.createElement("img");
// Attach load listener
newImage.addEventListener("load", loaded);
// Set src
newImage.src = image.src;
});
allImages.forEach(image => {
// New img element that won't be rendered to the DOM
var newImage = document.createElement("img");
// Attach load listener
newImage.addEventListener("load", loaded);
// Set src
newImage.src = image.src;
});
function loaded() {
if (++count == allImages.length) {
document.querySelector("body").classList.remove("loading");
document.getElementById("loading").remove();
}
}
function loaded() {
if (++count == allImages.length) {
document.querySelector("body").classList.remove("loading");
document.getElementById("loading").remove();
}
}
}

View File

@@ -1,12 +1,12 @@
insertNavigationBar("All News");
function main(json) {
// Set tab title
document.title = `News - ${json.name}`;
// Set tab title
document.title = `News - ${json.name}`;
// Sort news by latest
json.news.sort((a, b) => (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf());
// Sort news by latest
json.news.sort((a, b) => (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf());
// Create & insert news items
json.news.forEach(news => document.getElementById("news").insertAdjacentHTML("beforeend", newsItemHTML(news)));
// Create & insert news items
json.news.forEach(news => document.getElementById("news").insertAdjacentHTML("beforeend", newsItemHTML(news)));
}

View File

@@ -1,19 +1,19 @@
(function main() {
const success = url => window.location.replace(`index.html?source=${url}`);
const success = url => window.location.replace(`index.html?source=${url}`);
// If valid source provided
if (urlSearchParams.has('source') && isValidHTTPURL(sourceURL))
success(sourceURL);
// If valid source provided
if (urlSearchParams.has('source') && isValidHTTPURL(sourceURL))
success(sourceURL);
const textField = document.querySelector("input");
textField.addEventListener("keypress", function (event) {
if (event.key === "Enter") {
event.preventDefault();
const textField = document.querySelector("input");
textField.addEventListener("keypress", function (event) {
if (event.key === "Enter") {
event.preventDefault();
const url = textField.value;
if (!isValidHTTPURL(url))
alert("Invalid HTTP URL.");
else success(url);
}
});
const url = textField.value;
if (!isValidHTTPURL(url))
alert("Invalid HTTP URL.");
else success(url);
}
});
})();

View File

@@ -4,132 +4,132 @@ const sourceURL = urlSearchParams.get('source');
const urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
(function (global) {
var apps;
global.setApps = array =>
apps = array;
global.getAppWithBundleId = bundleId =>
apps?.find(app => app.bundleIdentifier == bundleId) ?? undefined;
var apps;
global.setApps = array =>
apps = array;
global.getAppWithBundleId = bundleId =>
apps?.find(app => app.bundleIdentifier == bundleId) ?? undefined;
setUpBackButton();
setUpBackButton();
})(this);
const newsItemHTML = (news, minimal = false) => `
<div class="news-item-wrapper"> ${news.url ?
"<a href='" + news.url + "'>" : ""}
<div class="item" style="background-color: #${news.tintColor};">
<div class="text">
<h3>${news.title}</h3>
<p>${news.caption}</p>
</div>${news.imageURL && !minimal ?
"<div class='image-wrapper'>" +
"<img src='" + news.imageURL + "'>" +
"</div>" : ""}
</div> ${news.url ?
"</a>" : ""} ${news.appID && !minimal ?
appHeaderHTML(getAppWithBundleId(news.appID)) ?? "" : ""}
"<a href='" + news.url + "'>" : ""}
<div class="item" style="background-color: #${news.tintColor};">
<div class="text">
<h3>${news.title}</h3>
<p>${news.caption}</p>
</div>${news.imageURL && !minimal ?
"<div class='image-wrapper'>" +
"<img src='" + news.imageURL + "'>" +
"</div>" : ""}
</div> ${news.url ?
"</a>" : ""} ${news.appID && !minimal ?
appHeaderHTML(getAppWithBundleId(news.appID)) ?? "" : ""}
</div>`;
const appHeaderHTML = app => app ? `
<div class="item">
<div class="app-header">
<div class="content">
<img src="${app.iconURL}" alt="">
<div class="right">
<div class="text">
<p class="title">${app.name}</p>
<p class="subtitle">${app.developerName}</p>
</div>
<a href="app.html?source=${sourceURL}&id=${app.bundleIdentifier}">
<button class="uibutton" style="background-color: #${app.tintColor};">View</button>
</a>
</div>
</div>
<div class="background" style="background-color: #${app.tintColor};"></div>
</div>
<div class="app-header">
<div class="content">
<img src="${app.iconURL}" alt="">
<div class="right">
<div class="text">
<p class="title">${app.name}</p>
<p class="subtitle">${app.developerName}</p>
</div>
<a href="app.html?source=${sourceURL}&id=${app.bundleIdentifier}">
<button class="uibutton" style="background-color: #${app.tintColor};">View</button>
</a>
</div>
</div>
<div class="background" style="background-color: #${app.tintColor};"></div>
</div>
</div>` : undefined;
function insertAddToAltStoreBanner() {
document.getElementById("top")?.insertAdjacentHTML("afterbegin", `
<div class="uibanner">
<img src="https://user-images.githubusercontent.com/705880/65270980-1eb96f80-dad1-11e9-9367-78ccd25ceb02.png" alt="altstore-icon" class="icon">
<div class="content">
<div class="text-container">
<p class="title-text">AltStore <span class="small beta badge"></span></p>
<p class="detail-text">
Add this source to AltStore to receive app updates (requires AltStore beta)
</p>
</div>
<a href="altstore://source?url=${sourceURL}">
<button>Add</button>
</a>
</div>
</div>`);
document.getElementById("top")?.insertAdjacentHTML("afterbegin", `
<div class="uibanner">
<img src="https://user-images.githubusercontent.com/705880/65270980-1eb96f80-dad1-11e9-9367-78ccd25ceb02.png" alt="altstore-icon" class="icon">
<div class="content">
<div class="text-container">
<p class="title-text">AltStore <span class="small beta badge"></span></p>
<p class="detail-text">
Add this source to AltStore to receive app updates (requires AltStore beta)
</p>
</div>
<a href="altstore://source?url=${sourceURL}">
<button>Add</button>
</a>
</div>
</div>`);
}
function insertNavigationBar(title) {
document.getElementById("top")?.insertAdjacentHTML("beforeend", `
<div id="nav-bar">
<button id="back" type="button">
<i class="bi bi-chevron-left"></i>
Back
</button>
<div id="title">
<p>${title ?? ""}</p>
</div>
<button id="back" class="hidden">
<i class="bi bi-chevron-left"></i>
Back
</button>
</div>`);
setUpBackButton();
document.getElementById("top")?.insertAdjacentHTML("beforeend", `
<div id="nav-bar">
<button id="back" type="button">
<i class="bi bi-chevron-left"></i>
Back
</button>
<div id="title">
<p>${title ?? ""}</p>
</div>
<button id="back" class="hidden">
<i class="bi bi-chevron-left"></i>
Back
</button>
</div>`);
setUpBackButton();
}
// https://stackoverflow.com/a/43467144/19227228
function isValidHTTPURL(string) {
var url;
try {
url = new URL(string);
} catch (error) {
console.error("An error occurred.", error);
return false;
}
return url.protocol == "http:" || url.protocol == "https:";
var url;
try {
url = new URL(string);
} catch (error) {
console.error("An error occurred.", error);
return false;
}
return url.protocol == "http:" || url.protocol == "https:";
}
function formatString(string) {
if (!string) return undefined;
if (!string) return undefined;
// URLs
const urlArray = string.match(urlRegex);
// const urlSet = [...new Set(urlArray)]; // Converting to set to remove duplicates
var result = "";
urlArray?.forEach(url => {
string = string.replace(url, `<a href="${url}">${url}</a>`)
// Remove formatted substring so it won't get formatted again (prevents <a> tag within the href attribute another <a> tag)
let endIndexOfClosingTag = string.indexOf("</a>") + 4;
let formattedSubstring = string.substring(0, endIndexOfClosingTag);
result += formattedSubstring;
string = string.replace(formattedSubstring, "");
});
// URLs
const urlArray = string.match(urlRegex);
// const urlSet = [...new Set(urlArray)]; // Converting to set to remove duplicates
var result = "";
urlArray?.forEach(url => {
string = string.replace(url, `<a href="${url}">${url}</a>`)
// Remove formatted substring so it won't get formatted again (prevents <a> tag within the href attribute another <a> tag)
let endIndexOfClosingTag = string.indexOf("</a>") + 4;
let formattedSubstring = string.substring(0, endIndexOfClosingTag);
result += formattedSubstring;
string = string.replace(formattedSubstring, "");
});
result += string;
result += string;
// New lines
return result.replaceAll("\n", "<br>");
// New lines
return result.replaceAll("\n", "<br>");
}
function setTintColor(color) {
document.querySelector(':root')?.style.setProperty("--accent-color", `#${color}`);
document.querySelector(':root')?.style.setProperty("--accent-color", `#${color}`);
}
function setUpBackButton() {
document.getElementById("back")?.addEventListener("click", () => history.back(1));
document.getElementById("back")?.addEventListener("click", () => history.back(1));
}
function search() {
window.location.replace("search.html");
window.location.replace("search.html");
}
const $ = selector => selector.startsWith("#") && !selector.includes(".") && !selector.includes(" ")
? document.getElementById(selector.substring(1))
: document.querySelectorAll(selector);
? document.getElementById(selector.substring(1))
: document.querySelectorAll(selector);