Files
brk/website_next/wallets/redaction/index.js
T
2026-06-17 11:25:42 +02:00

132 lines
3.1 KiB
JavaScript

const FIXED_PRIVATE_TEXT = "*****";
let hidden = false;
function isHidden() {
return hidden;
}
/**
* @param {string} value
*/
function createText(value) {
return [...value].map((character) => {
return character === " " ? " " : "*";
}).join("");
}
/**
* @param {string} value
* @param {string | null} mode
*/
function mask(value, mode) {
return mode === "fixed" ? FIXED_PRIVATE_TEXT : createText(value);
}
/**
* @param {HTMLElement} element
* @param {string} value
* @param {"exact" | "fixed"} [mode]
*/
function setValue(element, value, mode = "exact") {
element.setAttribute("data-wallets-private-value", value);
element.setAttribute("data-wallets-private-mode", mode);
element.textContent = hidden
? mask(value, mode)
: value;
}
/**
* @param {HTMLElement} element
* @param {string} value
*/
function setTitle(element, value) {
element.setAttribute("data-wallets-private-title", value);
element.title = hidden ? createText(value) : value;
}
/**
* @template {keyof HTMLElementTagNameMap} Tag
* @param {Tag} tag
* @param {string} value
* @param {"exact" | "fixed"} [mode]
*/
function createValue(tag, value, mode = "exact") {
const element = document.createElement(tag);
setValue(element, value, mode);
return element;
}
/**
* @param {HTMLElement} root
* @param {(text: string) => HTMLElement} createAddress
*/
function sync(root, createAddress) {
const values = root.querySelectorAll("[data-wallets-private-value]");
const titles = root.querySelectorAll("[data-wallets-private-title]");
const addresses = root.querySelectorAll("[data-wallets-private-address]");
const inputs = root.querySelectorAll("[data-wallets-private-input]");
for (const value of values) {
const text = value.getAttribute("data-wallets-private-value") ?? "";
const mode = value.getAttribute("data-wallets-private-mode");
value.textContent = hidden
? mask(text, mode)
: text;
}
for (const element of titles) {
const title = /** @type {HTMLElement} */ (element);
const text = title.getAttribute("data-wallets-private-title") ?? "";
title.title = hidden
? createText(text)
: text;
}
for (const address of addresses) {
const text = address.getAttribute("data-wallets-private-address") ?? "";
const next = hidden ? createText(text) : text;
address.replaceChildren(...createAddress(next).childNodes);
}
for (const input of inputs) {
if (input instanceof HTMLInputElement) {
input.type = hidden ? "password" : "text";
}
}
}
/**
* @param {HTMLButtonElement} button
*/
function syncButton(button) {
button.textContent = hidden ? "Reveal" : "Privacy";
button.setAttribute("aria-pressed", hidden ? "true" : "false");
}
/**
* @param {HTMLElement} root
* @param {HTMLButtonElement} button
* @param {(text: string) => HTMLElement} createAddress
*/
function toggle(root, button, createAddress) {
hidden = !hidden;
sync(root, createAddress);
syncButton(button);
}
export const redaction = /** @type {const} */ ({
isHidden,
createText,
setValue,
setTitle,
createValue,
syncButton,
toggle,
});