class SelectorBuilder {
/** @type {string} */
id
/** @type {Array<CircuitSet>} */
circuitSets
/**
* @param prefix {string} distinguish between different, is used in the id of the html element
* @param mode {window.definitions.mode} defines paths for the created CircuitMaps
* */
constructor(prefix = "", mode = window.definitions.mode.learn) {
this.id = prefix + "accordion"
this.prefix = prefix;
}
// Build accordion with items and modals
/**
* @param accordionId {string} id of the html element that is appended to the document
* @param circuitSets {Array<CircuitSet>} based on the circuit sets the accordion items are generated
* the set is saved in this.circuitSets and used later on for updates of the accordion*/
buildAccordionSelectors(accordionId, circuitSets) {
this.id = accordionId;
this.circuitSets = circuitSets;
let accordion = document.createElement("div");
accordion.classList.add("accordion", "accordion-flush", "mt-5", "mx-auto");
accordion.id = this.id;
accordion.style = "max-width: 500px;";
for (let circuitSet of this.circuitSets) {
if (circuitSet.identifier === window.definitions.selectorIDs.quickstart) continue;
let item = this.buildAccordionItem(circuitSet.identifier, accordionId);
let modal = this.buildOverviewModal(circuitSet);
accordion.appendChild(item);
document.body.appendChild(modal);
}
return accordion;
}
// Build one accordion item
buildAccordionItem(identifier, accordionId) {
let accordionItem = document.createElement("div");
accordionItem.classList.add("accordion-item");
accordionItem.innerHTML = `
<h2 class="accordion-header" id="flush-heading-${this.prefix}${identifier}" style="display: flex; justify-content: space-between; background-color: ${colors.currentBsBackground}; font-size: x-large">
<button id="${identifier}-${this.prefix}acc-btn"
style="color: ${colors.currentHeadingsForeground}; background-color: ${colors.currentBsBackground}"
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#flush-collapse-${this.prefix}${identifier}"
aria-expanded="false"
aria-controls="flush-collapse-${this.prefix}${identifier}">
${languageManager.currentLang.selector.selectorHeadings[identifier]}
</button>
</h2>
<div id="flush-collapse-${this.prefix}${identifier}"
class="accordion-collapse collapse"
aria-labelledby="flush-heading-${this.prefix}${identifier}"
data-bs-parent="#${accordionId}">
<div class="accordion-body" style="background-color: inherit">
<div class="container vcCheckBox"
style="text-align: left; max-width: 350px; padding: 0; color:${colors.currentHeadingsForeground};">
<button onclick="document.getElementById('${identifier}-${this.prefix}overviewModal').blur()"
id="${identifier}-${this.prefix}overviewModalBtn"
type="button"
class="btn my-1 btn-primary modalOverviewBtn"
data-bs-toggle="modal"
data-bs-target="#${identifier}-${this.prefix}overviewModal"
style="color: ${colors.currentHeadingsForeground}; border: 1px solid ${colors.currentHeadingsForeground};">
${languageManager.currentLang.selector.overviewModalBtn}
</button>
</div>
${this.createCarousel(identifier)}
</div>
</div>`;
return accordionItem;
}
buildOverviewModal(circuitSet) {
let modalId = `${circuitSet.identifier}-${this.prefix}overviewModal`;
let modal = document.createElement("div");
modal.classList.add("modal", "fade", "modal-xl");
modal.id = modalId;
modal.tabIndex = "-1";
modal.setAttribute("aria-labelledby", `${modalId}Label`);
modal.setAttribute("aria-hidden", "true");
modal.innerHTML = `
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" style="background: ${colors.currentBackground}; color: white;">
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" style="background: ${colors.currentBackground}; color: white;">
${this.generateOverviewGrid(circuitSet)}
</div>
<div class="modal-footer justify-content-center" style="background: ${colors.currentBackground}">
<button id="${modalId}CloseBtn" type="button" class="btn btn-secondary" data-bs-dismiss="modal">
${languageManager.currentLang.simplifier.closeBtn}
</button>
</div>
</div>
</div>`;
return modal;
}
/** @param circuitSet {CircuitSet} */
generateOverviewGrid(circuitSet) {
let grid = document.createElement("div");
grid.classList.add("row");
for (let circuit of circuitSet.circuitMaps) {
let col = document.createElement("div");
col.classList.add("col-md-4", "col-sm-6", "col-12", "mb-4", "text-center", "justify-content-center");
col.innerHTML = `
<div id="${circuit.circuitDivID}-overviewModal" class="svg-selector mx-auto" style="
border-color: black;"></div>
<button id="${circuit.btn}-modalBtn" onclick="document.getElementById('${circuit.btn}-modalBtn').blur()" class="btn btn-warning text-dark px-5 circuitStartBtnModal">start</button>
`;
grid.appendChild(col);
}
return grid.outerHTML;
}
// Build carousel wrapper
createCarousel(identifier) {
const carouselElements = this.createCarouselElements(identifier);
return `
<div id="${identifier}-${this.prefix}carousel" class="carousel slide" data-interval="false">
<div class="carousel-inner">
${carouselElements}
</div>
<button id="${identifier}-${this.prefix}prev-btn"
class="carousel-control-prev"
type="button"
data-bs-target="#${identifier}-${this.prefix}carousel"
data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true" style="background-color: ${colors.prevNextBtnBackgroundColor};"></span>
<span class="visually-hidden">Previous</span>
</button>
<button id="${identifier}-${this.prefix}next-btn"
class="carousel-control-next"
type="button"
data-bs-target="#${identifier}-${this.prefix}carousel"
data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true" style="background-color: ${colors.prevNextBtnBackgroundColor};"></span>
<span class="visually-hidden">Next</span>
</button>
</div>`;
}
// Carousel item for one circuit
carouselItem(circuit) {
return `
<div class="carousel-item justify-content-center">
<div id="${circuit.btnOverlay}" class="img-overlay">
<button id="${circuit.btn}" class="btn btn-warning text-dark px-5 circuitStartBtn">
<div class="fill-layer"></div>
<div class="progress-stripes"></div>
<span class="button-text">start</span>
</button>
</div>
<div id="${circuit.circuitDivID}" class="svg-selector mx-auto" style="border-color: ${colors.currentForeground}"></div>
</div>`;
}
// Collect all carousel items
createCarouselElements(identifier) {
let carouselElementString = "";
for (const circuitSet of this.circuitSets) {
if (circuitSet.identifier !== identifier) continue;
for (const circuit of circuitSet.circuitMaps) {
carouselElementString += this.carouselItem(circuit);
}
}
// Mark first as active
return carouselElementString.replace("carousel-item justify", "carousel-item active justify");
}
updateSelectorCounters() {
for (let circuitSet of this.circuitSets) {
// set number of done circuits/available circuits
let availableCircuits = circuitSet.circuitMaps.length;
let identifier = circuitSet.identifier;
// Search in storage for done circuits
// Storage will store e.g.: doneCircuits-res = ["00_hetznecker.txt", "01_ohm.txt"]
let doneCircuits = storageManager.circuitsDone.loadValue(identifier);
// Check names of done circuits with available circuits
let doneCount = 0;
if (identifier === window.definitions.selectorIDs.wheatstone) {
availableCircuits = state.options.length; // Wheatstone selector has different available circuits
for (let i = 0; i < state.options.length; i++) {
let optionName = "option_" + i;
if (doneCircuits.includes(optionName)) {
doneCount++;
}
}
} else {
for (const circuit of circuitSet.circuitMaps) {
if (doneCircuits.includes(circuit.circuitFile)) {
doneCount++;
}
}
}
// Set counter text
let counterText = `${doneCount}/${availableCircuits}`;
let counterElement = document.getElementById(`${identifier}-selector-counter`);
if (window.definitions.noCounter.includes(identifier)) {
continue;
}
else if (counterElement) {
counterElement.textContent = counterText;
counterElement.style.color = doneCount === availableCircuits ? colors.keyYellow : colors.keyGreyedOut;
if (doneCount === availableCircuits && availableCircuits > 0) {
let animationShown = storageManager.animationShown.loadValue(identifier)
if (animationShown !== "true") {
storageManager.animationShown.setValue(identifier, true);
if (pageManager.simplifierPage.style.display === "block") {
this.showFinishedSelectorAnimation(identifier);
}
}
}
} else {
console.warn(`Counter element for ${identifier} not found.`);
}
}
}
// ######################### Setup #######################################
/**
* @param circuitSet {CircuitSet} each map of the circuit set gets an overview svg and a start button overlay
* */
async setupSelector(circuitSet) {
return new Promise(async (resolve) => {
try {
for (const [idx, circuit] of circuitSet.circuitMaps.entries()) {
await this.setupSpecificCircuitSelector(circuit);
this._showFirstCircuitAsSelected(idx, circuitSet);
}
if (moreThanOneCircuitInSet(circuitSet)) {
this.setupNextAndPrevButtons(circuitSet);
} else {
this.hideNextAndPrevButtons(circuitSet);
}
resolve();
} catch (error) {
console.trace(error)
console.error(`Error setting up circuit selector for ${circuitSet.identifier}:`, error);
showMessage(error, "error", false);
pushErrorEventMatomo(errorActions.circuitSelectorSetupError, `(${circuitSet.identifier})` + error);
}
});
}
_showFirstCircuitAsSelected(idx, circuitSet) {
if ((idx === 0)) {
if (circuitSet.circuitMaps[0] !== undefined && circuitSet.circuitMaps[0] !== null) {
this.showCircuitAsSelected(document.getElementById(circuitSet.circuitMaps[0].circuitDivID),
document.getElementById(circuitSet.circuitMaps[0].btnOverlay));
}
}
}
/**
* [bar description]
* @param circuitMap {CircuitMap}
* @return {string} svg-data
*/
async setupSpecificCircuitSelector(circuitMap) {
/** @type {HTMLElement} */
const circuitDiv = document.getElementById(circuitMap.circuitDivID);
/** @type {HTMLElement} */
const startBtn = document.getElementById(circuitMap.btn);
/** @type {HTMLElement} */
const btnOverlay = document.getElementById(circuitMap.btnOverlay);
// Fill div with svg
try {
let svgData = await circuitMap.svgData()
svgData = setSvgWidthTo(svgData, "100%");
svgData = setSvgColorMode(svgData);
circuitDiv.innerHTML = svgData;
this.addVoltFreqOverlay(circuitDiv, circuitMap);
hideSvgArrows(circuitDiv);
hideLabels(circuitDiv);
// Setup specific circuit in overview modal
this.setupOverviewModalCircuit(circuitMap, circuitDiv);
this.setupSelectionCircuit(circuitDiv, startBtn, btnOverlay);
// Disable start buttons for all selector groups except quickstart when pyodide is not ready
if (circuitMap.selectorGroup !== window.definitions.selectorIDs.quickstart) {
if (!state.pyodideReady) {
startBtn.disabled = true;
} else {
startBtn.style.backgroundColor = colors.keyYellow;
}
} else {
startBtn.style.backgroundColor = colors.keyYellow;
}
startBtn.addEventListener("click", () =>
this.circuitSelectorStartButtonPressed(circuitMap));
} catch (error) {
console.trace(error)
console.error(`Error loading ${circuitMap.overViewSvgFile}:`, error);
showMessage(error, "error", false);
pushErrorEventMatomo(errorActions.loadingOverviewError, `(${circuitMap.selectorGroup})` + error);
}
}
enableStartBtns() {
let startBtns = document.getElementsByClassName("circuitStartBtn");
for (const startBtn of startBtns) {
startBtn.disabled = false;
}
startBtns = document.getElementsByClassName("circuitStartBtnModal");
for (const startBtn of startBtns) {
startBtn.disabled = false;
}
}
addVoltFreqOverlay(circuitDiv, circuitMap) {
// Add voltage and frequency overlay for R, L, C and mixed Circuits
if ([window.definitions.selectorIDs.quickstart, window.definitions.selectorIDs.symbolic, window.definitions.selectorIDs.wheatstone].includes(circuitMap.selectorGroup)){
// nothing here
} else {
if (circuitMap.frequency === undefined || circuitMap.frequency === null) {
circuitDiv.insertBefore(this.createVoltOverlay(circuitMap), circuitDiv.firstChild);
} else {
circuitDiv.insertBefore(this.createVoltFreqOverlay(circuitMap), circuitDiv.firstChild);
}
}
}
createVoltOverlay(circuitMap) {
let div = document.createElement("div");
div.id = `${circuitMap.btnOverlay}-volt-freq`;
div.classList.add("volt-freq-overlay");
div.innerHTML = `<p style="color: ${colors.currentForeground}; position:absolute; top:20px; right: 0; ">${circuitMap.voltage}</p>`;
return div;
}
createVoltFreqOverlay(circuitMap) {
let div = document.createElement("div");
div.id = `${circuitMap.btnOverlay}-volt-freq`;
div.classList.add("volt-freq-overlay");
div.innerHTML = `<p style="color: ${colors.currentForeground}; position:absolute; top:20px; right: 0; ">${circuitMap.voltage}</p>
<p style="color: ${colors.currentForeground}; position:absolute; top:40px; right: 0; ">${circuitMap.frequency}</p>`;
return div;
}
setupOverviewModalCircuit(circuitMap, circuitDiv) {
if (circuitMap.selectorGroup !== window.definitions.selectorIDs.quickstart) {
let gridElement;
let overviewStartBtn;
let modal;
gridElement = document.getElementById(`${circuitMap.circuitDivID}-overviewModal`);
overviewStartBtn = document.getElementById(`${circuitMap.btn}-modalBtn`);
modal = document.getElementById(`${circuitMap.selectorGroup}-${this.prefix}overviewModal`);
gridElement.innerHTML = circuitDiv.innerHTML; // copy svg without arrows to modal
if (!state.pyodideReady) {
overviewStartBtn.disabled = true;
}
overviewStartBtn.addEventListener("click", () => {
// we need the bootstrap modal instance in order to close it
var modalInstance = bootstrap.Modal.getInstance(modal) || new bootstrap.Modal(modal);
modalInstance.hide();
this.circuitSelectorStartButtonPressed(circuitMap);
});
}
}
resetSelectorSelections(circuitSet) {
for (const circuit of circuitSet) {
this.resetSelection(circuit);
}
}
setupNextAndPrevButtons(circuitSet) {
let next;
let prev;
next = document.getElementById(`${circuitSet.identifier}${this.prefix}-next-btn`);
prev = document.getElementById(`${circuitSet.identifier}${this.prefix}-prev-btn`);
if (!(next && prev)) return // not all carusels need all selectors -> cant find all next and prev elements
next.addEventListener("click", () => {
this.resetSelectorSelections(circuitSet.circuitMaps);
})
prev.addEventListener("click", () => {
this.resetSelectorSelections(circuitSet.circuitMaps);
})
}
hideNextAndPrevButtons(circuitSet) {
let next;
let prev;
next = document.getElementById(`${circuitSet.identifier}${this.prefix}-next-btn`);
prev = document.getElementById(`${circuitSet.identifier}${this.prefix}-prev-btn`);
if (next !== null && prev !== null) {
next.hidden = true;
prev.hidden = true;
}
}
/**
* sets the circuitMap passed as the current in the state object and starts the according simplifier page (
* stepwise, wheatstone, kirchhoff ...
* @param circuitMap {CircuitMap}
* */
async circuitSelectorStartButtonPressed(circuitMap) {
// this clears the container for each of the simplifier pages
SimplifierPage.clear();
state.currentCircuitMap = circuitMap;
state.pictureCounter = 0;
state.allValuesMap = new Map();
if (circuitMap.selectorGroup === window.definitions.selectorIDs.kirchhoff) {
pageManager.pages.newKirchhoffPage.reset()
pageManager.changePage(pageManager.pages.newKirchhoffPage, true);
}
else if (circuitMap.selectorGroup === window.definitions.selectorIDs.wheatstone) {
if (state.currentCircuitFromUserZip) {
state.options = getWheatstoneValues();
}
pageManager.pages.newWheatstonePage.reset()
pageManager.changePage(pageManager.pages.newWheatstonePage, true); //TODO isUserCircuit, change state.options or work on concept how to use user values, ...
}
else if (circuitMap.selectorGroup === window.definitions.selectorIDs.magnetic) {
pageManager.pages.newMagneticPage.reset()
pageManager.changePage(pageManager.pages.newMagneticPage, true)
}
else {
pageManager.pages.newStepwisePage.reset();
pageManager.changePage(pageManager.pages.newStepwisePage, true);
}
}
showCircuitAsSelected(circuit, btnOverlay) {
circuit.style.borderColor = colors.keyYellow;
circuit.style.opacity = "0.5";
btnOverlay.style.display = "block";
if (!(btnOverlay.id.includes(window.definitions.selectorIDs.quickstart)
|| btnOverlay.id.includes(window.definitions.selectorIDs.symbolic)
|| btnOverlay.id.includes(window.definitions.selectorIDs.wheatstone))) {
let overlay = document.getElementById(`${btnOverlay.id}-volt-freq`);
if (overlay) overlay.style.opacity = "0.5";
}
}
showCircuitAsUnselected(circuit, btnOverlay) {
circuit.style.borderColor = colors.currentForeground;
circuit.style.opacity = "1";
btnOverlay.style.display = "none";
if (!(btnOverlay.id.includes(window.definitions.selectorIDs.quickstart)
|| btnOverlay.id.includes(window.definitions.selectorIDs.symbolic)
|| btnOverlay.id.includes(window.definitions.selectorIDs.wheatstone))) {
let overlay = document.getElementById(`${btnOverlay.id}-volt-freq`);
if (overlay) overlay.style.opacity = "1";
}
}
setupSelectionCircuit(circuit, startBtn, startBtnOverlay) {
circuit.addEventListener("click", () => {this.showCircuitAsSelected(circuit, startBtnOverlay)})
startBtnOverlay.addEventListener("click", () => {this.showCircuitAsUnselected(circuit, startBtnOverlay)})
}
resetSelection(circuitMap) {
const circuit = document.getElementById(circuitMap.circuitDivID);
const overlay = document.getElementById(circuitMap.btnOverlay);
circuit.style.borderColor = colors.currentForeground;
circuit.style.opacity = "1";
overlay.style.display = "none";
if (!((circuitMap.selectorGroup === window.definitions.selectorIDs.quickstart) || (circuitMap.selectorGroup === window.definitions.selectorIDs.symbolic))) {
document.getElementById(`${circuitMap.btnOverlay}-volt-freq`).style.opacity = "1";
}
}
showFinishedSelectorAnimation(identifier) {
const container = document.createElement("div");
container.style.position = "fixed";
container.style.top = "50%";
container.style.left = "50%";
container.style.transform = "translate(-50%, -50%)";
container.style.zIndex = "9999";
container.style.display = "flex";
container.style.flexDirection = "column";
container.style.alignItems = "center";
container.style.pointerEvents = "none";
container.style.opacity = "0";
container.style.transition = "opacity 1s ease";
container.style.padding = "100%"; // full screen blurred
container.style.backdropFilter = "blur(10px)";
const star = document.createElement("div");
star.innerHTML = `<svg id="star-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="250px" viewBox="0 -0.5 33 33" version="1.1">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<title>star</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Vivid.JS" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Vivid-Icons" transform="translate(-903.000000, -411.000000)" fill="#FFC107">
<g id="Icons" transform="translate(37.000000, 169.000000)">
<g id="star" transform="translate(858.000000, 234.000000)">
<g transform="translate(7.000000, 8.000000)" id="Shape">
<polygon points="27.865 31.83 17.615 26.209 7.462 32.009 9.553 20.362 0.99 12.335 12.532 10.758 17.394 0 22.436 10.672 34 12.047 25.574 20.22"></polygon>
</g>
</g>
</g>
</g>
</g>
</svg>`;
const text = document.createElement("div");
text.textContent = languageManager.currentLang.selector.selectorHeadings[identifier];
text.style.fontSize = "48px";
text.style.color = colors.currentHeadingsForeground;
text.style.fontWeight = "bold";
text.style.marginTop = "20px";
text.style.position = "absolute";
text.style.top = "60%";
// Append elements to container
container.appendChild(star);
container.appendChild(text);
document.body.appendChild(container);
// Fade in
setTimeout(() => {
container.style.opacity = "1";
}, 250);
// Fade out
setTimeout(() => {
container.style.opacity = "0";
}, 3000);
// Remove
setTimeout(() => {
container.remove();
}, 4000);
let duration = 3;
let end = Date.now() + (duration * 1000 - 500); // Just a bit shorter :)
let confettiColors = ['#ffc107', '#ffc107'];
(function frame() {
confetti({
particleCount: 2,
angle: 60,
spread: 55,
origin: { x: 0 },
colors: confettiColors
});
confetti({
particleCount: 2,
angle: 120,
spread: 55,
origin: { x: 1 },
colors: confettiColors
});
if (Date.now() < end) {
requestAnimationFrame(frame);
}
}());
// Check if this was the last selector
this.checkAllDone();
}
checkAllDone() {
let allDone = true;
for (let circuitSet of this.circuitSets) {
if (circuitSet.identifier === window.definitions.selectorIDs.quickstart) continue;
let doneCircuits = storageManager.circuitsDone.loadValue(circuitSet.identifier);
if (circuitSet.identifier === window.definitions.selectorIDs.wheatstone) {
// Check options
if (doneCircuits.length < state.options.length) {
allDone = false;
break;
}
} else {
// Rest of the circuit sets
if (doneCircuits.length < circuitSet.circuitMaps.length) {
allDone = false;
break;
}
}
}
if (allDone) {
if (document.readyState === "loading") {
window.addEventListener("DOMContentLoaded", () => {
this.addSmoothStarsOverLogo();
});
} else {
this.addSmoothStarsOverLogo();
}
}
}
addSmoothStarsOverLogo() {
const logo = document.getElementById("nav-logo");
const wrapper = document.createElement("span");
wrapper.id = "smooth-stars-wrapper";
wrapper.style.position = "relative";
wrapper.style.display = "inline-block";
logo.parentNode.insertBefore(wrapper, logo);
wrapper.appendChild(logo);
function createStar() {
const star = document.createElement("span");
star.textContent = Math.random() > 0.5 ? "✦" : "★";
const size = Math.random() * 6 + 6;
const duration = Math.random() * 1000 + 1500;
const x = Math.random() * wrapper.offsetWidth;
const startY = wrapper.offsetHeight - 2;
// horizontale Verschiebung zufällig ±10px
const horizontalShift = (Math.random() - 0.5) * 20; // von -10 bis +10 px
Object.assign(star.style, {
position: "absolute",
left: `${x}px`,
top: `${startY}px`,
fontSize: `${size}px`,
color: "#ffc107",
opacity: 0,
pointerEvents: "none",
zIndex: 0,
transform: "translateX(0px) translateY(0px) scale(0.5)",
transition: `opacity ${duration * 0.3}ms ease-in, transform ${duration}ms ease-out`
});
wrapper.appendChild(star);
// Animation starten: opacity auf 1, vertikal + horizontal verschieben, skalieren
requestAnimationFrame(() => {
requestAnimationFrame(() => {
star.style.opacity = 1;
star.style.transform = `translateX(${horizontalShift}px) translateY(-40px) scale(1)`;
});
});
// Fade-out starten kurz vor Ende, opacity runter, transform bleibt gleich
setTimeout(() => {
star.style.opacity = 0;
}, duration * 0.8);
// Entfernen
setTimeout(() => {
star.remove();
}, duration);
}
setInterval(() => {
createStar();
}, 700);
}
updateColor(){
let selectorDiv = document.getElementById(this.id)
let items = selectorDiv.querySelectorAll(".accordion-item");
this.#updateColor(items)
items = selectorDiv.querySelectorAll(".carousel-item");
this.#updateSvgs(items)
}
updateLang(usedAccordionHeadings){
if (usedAccordionHeadings) {
// Accordion headings
for (let i = 0; i < usedAccordionHeadings.length; i++) {
const accBtn = document.getElementById(`${usedAccordionHeadings[i].identifier}-${this.prefix}acc-btn`);
if (accBtn) {
accBtn.innerHTML = languageManager.currentLang.selector.selectorHeadings[usedAccordionHeadings[i].identifier];
}
}
let accordion = document.getElementById(this.id);
for (let i = 0; i < usedAccordionHeadings.length; i++) {
let overviewModalBtn = accordion.querySelector(`#${usedAccordionHeadings[i].identifier}-${this.prefix}overviewModalBtn`);
if (overviewModalBtn) {
overviewModalBtn.innerHTML = languageManager.currentLang.selector.overviewModalBtn;
}
}
}
}
/** @param items {NodeListOf<HTMLElement>} */
#updateColor(items){
for (let item of items){
//update heading of selector accordion
let header = item.querySelector(".accordion-header");
header.style.backgroundColor = colors.currentBsBackground;
let btn = item.querySelector(".accordion-button")
btn.style.color = colors.currentHeadingsForeground;
btn.style.background = colors.currentBsBackground;
//update body of heading accordion
let body = item.querySelector(".accordion-body");
body.style.backgroundColor = colors.currentBsBackground;
let overviewBtn = body.querySelector(".btn.my-1.btn-primary.modalOverviewBtn")
overviewBtn.style.color = colors.currentHeadingsForeground;
overviewBtn.style.borderColor = colors.currentHeadingsForeground;
}
}
/** @param items {NodeListOf<HTMLElement>} */
#updateSvgs(items){
for (let item of items){
let svg = item.querySelector("svg")
svg.innerHTML = svg.innerHTML.replaceAll(colors.getOldSvgForegroundColor, colors.currentForeground);
let overlay = item.querySelector(".svg-selector")
overlay.style.borderColor = colors.currentForeground;
let voltOverlays = document.querySelectorAll(".volt-freq-overlay p");
for (let p of voltOverlays) {
p.style.color = colors.currentForeground;
}
}
}
}