Proper types for localize and $
This commit is contained in:
parent
70c7e0b0f3
commit
a89acad0c9
@ -61,7 +61,7 @@ const memoGetMessage = memoize(i18n.getMessage, 10 * 1000, 10);
|
||||
* @param {string[]} [subst] Message substituations
|
||||
* @returns {string} Localized message
|
||||
*/
|
||||
function _(id: string, ...subst: any[]) {
|
||||
export function _(id: string, ...subst: any[]) {
|
||||
if (!subst.length) {
|
||||
return memoGetMessage(id);
|
||||
}
|
||||
@ -76,7 +76,7 @@ function _(id: string, ...subst: any[]) {
|
||||
* @param {Element} elem DOM to localize
|
||||
* @returns {Element} Passed in element (fluent)
|
||||
*/
|
||||
function localize(elem: HTMLElement) {
|
||||
export function localize<T extends HTMLElement | DocumentFragment>(elem: T): T {
|
||||
for (const el of elem.querySelectorAll<HTMLElement>("*[data-i18n]")) {
|
||||
const {i18n: i} = el.dataset;
|
||||
if (!i) {
|
||||
@ -107,8 +107,5 @@ function localize(elem: HTMLElement) {
|
||||
for (const el of document.querySelectorAll("*[data-l18n]")) {
|
||||
console.error("wrong!", el);
|
||||
}
|
||||
return elem;
|
||||
return elem as T;
|
||||
}
|
||||
|
||||
|
||||
export {localize, _};
|
||||
|
@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
// License: MIT
|
||||
|
||||
import {Keys} from "./keys";
|
||||
|
||||
const $ = document.querySelector.bind(document);
|
||||
import { Keys } from "./keys";
|
||||
import { $ } from "./winutil";
|
||||
|
||||
export class Broadcaster {
|
||||
private readonly els: HTMLElement[];
|
||||
@ -38,7 +37,7 @@ export class Broadcaster {
|
||||
}
|
||||
|
||||
onkey(evt: KeyboardEvent) {
|
||||
const {localName} = evt.target as HTMLElement;
|
||||
const { localName } = evt.target as HTMLElement;
|
||||
if (localName === "input" || localName === "textarea") {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
// License: MIT
|
||||
|
||||
import { EventEmitter } from "../../lib/events";
|
||||
|
||||
const $ = document.querySelector.bind(document);
|
||||
import { $ } from "../winutil";
|
||||
|
||||
export class Buttons extends EventEmitter {
|
||||
private readonly parent: HTMLElement;
|
||||
|
@ -19,12 +19,11 @@ import {sort, defaultCompare, naturalCaseCompare} from "../../lib/sorting";
|
||||
import {DownloadItem, DownloadTable} from "./table";
|
||||
import {formatSize} from "../../lib/formatters";
|
||||
import {_} from "../../lib/i18n";
|
||||
import {$} from "../winutil";
|
||||
import {StateTexts} from "./state";
|
||||
|
||||
const TIMEOUT_SEARCH = 750;
|
||||
|
||||
const $ = document.querySelector.bind(document);
|
||||
|
||||
class ItemFilter {
|
||||
public readonly id: string;
|
||||
|
||||
@ -119,8 +118,10 @@ export class MenuFilter extends ItemFilter {
|
||||
constructor(id: string) {
|
||||
super(id);
|
||||
this.items = new Map();
|
||||
const tmpl = $<HTMLTemplateElement>("#menufilter-template").
|
||||
content.cloneNode(true);
|
||||
this.menu = new ContextMenu(
|
||||
$("#menufilter-template").content.cloneNode(true).firstElementChild);
|
||||
(tmpl as HTMLElement).firstElementChild);
|
||||
this.menu.on("clicked", this.onclicked.bind(this));
|
||||
this.menu.on("ctx-menufilter-invert", () => this.invert());
|
||||
this.menu.on("ctx-menufilter-clear", () => this.clear());
|
||||
|
@ -5,8 +5,7 @@ import ModalDialog from "../../uikit/lib/modal";
|
||||
import { _, localize } from "../../lib/i18n";
|
||||
import { Prefs } from "../../lib/prefs";
|
||||
import { Keys } from "../keys";
|
||||
|
||||
const $ = document.querySelector.bind(document);
|
||||
import { $ } from "../winutil";
|
||||
|
||||
export default class RemovalModalDialog extends ModalDialog {
|
||||
private readonly text: string;
|
||||
@ -23,10 +22,11 @@ export default class RemovalModalDialog extends ModalDialog {
|
||||
}
|
||||
|
||||
get content() {
|
||||
const content = $("#removal-template").content.cloneNode(true);
|
||||
const content = $<HTMLTemplateElement>("#removal-template").
|
||||
content.cloneNode(true) as DocumentFragment;
|
||||
localize(content);
|
||||
this.check = content.querySelector(".removal-remember");
|
||||
content.querySelector(".removal-text").textContent = this.text;
|
||||
$(".removal-text", content).textContent = this.text;
|
||||
return content;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import { Tooltip } from "./tooltip";
|
||||
import "../../lib/util";
|
||||
import { CellTypes } from "../../uikit/lib/constants";
|
||||
import { downloads } from "../../lib/browser";
|
||||
import { $ } from "../winutil";
|
||||
|
||||
const TREE_CONFIG_VERSION = 2;
|
||||
const RUNNING_TIMEOUT = 1000;
|
||||
@ -53,8 +54,6 @@ const ICON_BASE_SIZE = 16;
|
||||
|
||||
const TEXT_SIZE_UNKNOWM = _("size-unknown");
|
||||
|
||||
const $ = document.querySelector.bind(document);
|
||||
|
||||
const prettyNumber = (function() {
|
||||
const rv = new Intl.NumberFormat(undefined, {
|
||||
style: "decimal",
|
||||
@ -403,7 +402,7 @@ export class DownloadTable extends VirtualTable {
|
||||
this.sids = new Map<number, DownloadItem>();
|
||||
this.icons = new Icons($("#icons"));
|
||||
|
||||
localize($("#table-context").content);
|
||||
localize($<HTMLTemplateElement>("#table-context").content);
|
||||
const ctx = this.contextMenu = new ContextMenu("#table-context");
|
||||
Keys.adoptContext(ctx);
|
||||
Keys.adoptButtons($("#toolbar"));
|
||||
|
@ -11,12 +11,12 @@ import { TYPE_LINK, TYPE_MEDIA } from "../lib/constants";
|
||||
import { iconForPath, visible } from "../lib/windowutils";
|
||||
import { VirtualTable } from "../uikit/lib/table";
|
||||
import { Icons } from "./icons";
|
||||
import { $ } from "./winutil";
|
||||
|
||||
const ICON_BASE_SIZE = 16;
|
||||
|
||||
const $ = document.querySelector.bind(document);
|
||||
|
||||
class UIPref<T> extends PrefWatcher {
|
||||
class UIPref<T extends HTMLElement> extends PrefWatcher {
|
||||
id: string;
|
||||
|
||||
pref: string;
|
||||
@ -101,20 +101,22 @@ class OptionPref extends UIPref<HTMLElement> {
|
||||
}
|
||||
|
||||
class CreateFilterDialog extends ModalDialog {
|
||||
label: any;
|
||||
label: HTMLInputElement;
|
||||
|
||||
expr: any;
|
||||
expr: HTMLInputElement;
|
||||
|
||||
link: any;
|
||||
link: HTMLInputElement;
|
||||
|
||||
media: any;
|
||||
media: HTMLInputElement;
|
||||
|
||||
get content() {
|
||||
const rv = localize($("#create-filter-template").content.cloneNode(true));
|
||||
this.label = rv.querySelector("#filter-create-label");
|
||||
this.expr = rv.querySelector("#filter-create-expr");
|
||||
this.link = rv.querySelector("#filter-create-type-link");
|
||||
this.media = rv.querySelector("#filter-create-type-media");
|
||||
const tmpl = $<HTMLTemplateElement>("#create-filter-template").
|
||||
content.cloneNode(true) as DocumentFragment;
|
||||
const rv = localize(tmpl);
|
||||
this.label = $("#filter-create-label", rv);
|
||||
this.expr = $("#filter-create-expr", rv);
|
||||
this.link = $("#filter-create-type-link", rv);
|
||||
this.media = $("#filter-create-type-media", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,9 @@ import { sort, naturalCaseCompare } from "../lib/sorting";
|
||||
import { hookButton } from "../lib/manager/renamer";
|
||||
import { CellTypes } from "../uikit/lib/constants";
|
||||
import { runtime } from "../lib/browser";
|
||||
import { $ } from "./winutil";
|
||||
|
||||
const PORT = runtime.connect(null, { name: "select" });
|
||||
const $ = document.querySelector.bind(document);
|
||||
|
||||
const TREE_CONFIG_VERSION = 1;
|
||||
|
||||
@ -52,7 +52,8 @@ function matched(item: any) {
|
||||
|
||||
class PausedModalDialog extends ModalDialog {
|
||||
get content() {
|
||||
const content = $("#paused-template").content.cloneNode(true);
|
||||
const tmpl = $<HTMLTemplateElement>("#paused-template");
|
||||
const content = tmpl.content.cloneNode(true) as DocumentFragment;
|
||||
localize(content);
|
||||
return content;
|
||||
}
|
||||
@ -154,7 +155,7 @@ class SelectionTable extends VirtualTable {
|
||||
super("#items", treeConfig, TREE_CONFIG_VERSION);
|
||||
|
||||
this.checkClasser = new CheckClasser(NUM_FILTER_CLASSES);
|
||||
this.icons = new Icons($("#icons"));
|
||||
this.icons = new Icons($("#icons") as HTMLStyleElement);
|
||||
this.links = links;
|
||||
this.media = media;
|
||||
this.type = type;
|
||||
@ -181,7 +182,7 @@ class SelectionTable extends VirtualTable {
|
||||
this.linksFilters = $("#linksFilters");
|
||||
this.mediaFilters = $("#mediaFilters");
|
||||
|
||||
localize($("#table-context").content);
|
||||
localize(($("#table-context") as HTMLTemplateElement).content);
|
||||
this.contextMenu = new ContextMenu("#table-context");
|
||||
Keys.adoptContext(this.contextMenu);
|
||||
|
||||
@ -553,9 +554,9 @@ async function download(paused = false) {
|
||||
items,
|
||||
paused,
|
||||
mask,
|
||||
maskOnce: $("#maskOnceCheck").checked,
|
||||
maskOnce: $<HTMLInputElement>("#maskOnceCheck").checked,
|
||||
fast: FastFilter.value,
|
||||
fastOnce: $("#fastOnceCheck").checked,
|
||||
fastOnce: $<HTMLInputElement>("#fastOnceCheck").checked,
|
||||
});
|
||||
}
|
||||
catch (ex) {
|
||||
@ -670,7 +671,7 @@ addEventListener("DOMContentLoaded", function dom() {
|
||||
$("#fastDisableOthers").addEventListener("change", () => {
|
||||
PORT.postMessage({
|
||||
msg: "onlyfast",
|
||||
fast: $("#fastDisableOthers").checked
|
||||
fast: $<HTMLInputElement>("#fastDisableOthers").checked
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -12,9 +12,9 @@ import { Dropdown } from "./dropdown";
|
||||
import { Keys } from "./keys";
|
||||
import { hookButton } from "../lib/manager/renamer";
|
||||
import { runtime } from "../lib/browser";
|
||||
import { $ } from "./winutil";
|
||||
|
||||
const PORT = runtime.connect(null, { name: "single" });
|
||||
const $ = document.querySelector.bind(document);
|
||||
|
||||
let ITEM: any;
|
||||
let Mask: Dropdown;
|
||||
@ -28,11 +28,11 @@ class BatchModalDialog extends ModalDialog {
|
||||
}
|
||||
|
||||
get content() {
|
||||
const content = $("#batch-template").content.cloneNode(true);
|
||||
const tmpl = $("#batch-template") as HTMLTemplateElement;
|
||||
const content = tmpl.content.cloneNode(true) as DocumentFragment;
|
||||
localize(content);
|
||||
const $$ = content.querySelector.bind(content);
|
||||
$$(".batch-items").textContent = this.gen.length.toLocaleString();
|
||||
$$(".batch-preview").textContent = this.gen.preview;
|
||||
$(".batch-items", content).textContent = this.gen.length.toLocaleString();
|
||||
$(".batch-preview", content).textContent = this.gen.preview;
|
||||
return content;
|
||||
}
|
||||
|
||||
@ -73,11 +73,11 @@ function setItem(item: any) {
|
||||
usableReferrer = "",
|
||||
mask = ""
|
||||
} = item;
|
||||
$("#URL").value = usable;
|
||||
$("#filename").value = fileName;
|
||||
$("#title").value = title;
|
||||
$("#description").value = description;
|
||||
$("#referrer").value = usableReferrer;
|
||||
$<HTMLInputElement>("#URL").value = usable;
|
||||
$<HTMLInputElement>("#filename").value = fileName;
|
||||
$<HTMLInputElement>("#title").value = title;
|
||||
$<HTMLInputElement>("#description").value = description;
|
||||
$<HTMLInputElement>("#referrer").value = usableReferrer;
|
||||
if (mask) {
|
||||
Mask.value = mask;
|
||||
}
|
||||
@ -90,7 +90,7 @@ function displayError(err: string) {
|
||||
}
|
||||
|
||||
async function downloadInternal(paused: boolean) {
|
||||
let usable = $("#URL").value.trim();
|
||||
let usable = $<HTMLInputElement>("#URL").value.trim();
|
||||
let url;
|
||||
try {
|
||||
url = new URL(usable).toString();
|
||||
@ -98,7 +98,7 @@ async function downloadInternal(paused: boolean) {
|
||||
catch (ex) {
|
||||
try {
|
||||
url = new URL(`https://${usable}`).toString();
|
||||
$("#URL").value = usable = `https://${usable}`;
|
||||
$<HTMLInputElement>("#URL").value = usable = `https://${usable}`;
|
||||
}
|
||||
catch (ex) {
|
||||
return displayError("error.invalidURL");
|
||||
@ -107,7 +107,7 @@ async function downloadInternal(paused: boolean) {
|
||||
|
||||
const gen = new BatchGenerator(usable);
|
||||
|
||||
const usableReferrer = $("#referrer").value.trim();
|
||||
const usableReferrer = $<HTMLInputElement>("#referrer").value.trim();
|
||||
let referrer;
|
||||
try {
|
||||
referrer = usableReferrer ? new URL(usableReferrer).toString() : "";
|
||||
@ -116,9 +116,9 @@ async function downloadInternal(paused: boolean) {
|
||||
return displayError("error.invalidReferrer");
|
||||
}
|
||||
|
||||
const fileName = $("#filename").value.trim();
|
||||
const title = $("#title").value.trim();
|
||||
const description = $("#description").value.trim();
|
||||
const fileName = $<HTMLInputElement>("#filename").value.trim();
|
||||
const title = $<HTMLInputElement>("#title").value.trim();
|
||||
const description = $<HTMLInputElement>("#description").value.trim();
|
||||
const mask = Mask.value.trim();
|
||||
if (!mask) {
|
||||
return displayError("error.invalidMask");
|
||||
@ -183,7 +183,7 @@ async function downloadInternal(paused: boolean) {
|
||||
paused,
|
||||
items,
|
||||
mask,
|
||||
maskOnce: $("#maskOnceCheck").checked,
|
||||
maskOnce: $<HTMLInputElement>("#maskOnceCheck").checked,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
10
windows/winutil.ts
Normal file
10
windows/winutil.ts
Normal file
@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
// License: MIT
|
||||
|
||||
export function $<T extends HTMLElement>(
|
||||
q: string, el?: HTMLElement | DocumentFragment): T {
|
||||
if (!el) {
|
||||
el = document;
|
||||
}
|
||||
return el.querySelector<T>(q) as T;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user