Fix some typescript issues
This commit is contained in:
parent
6c197d8353
commit
1513f0b022
@ -51,7 +51,7 @@ export const DB = new class DB {
|
||||
const store = transaction.objectStore(STORE);
|
||||
const index = store.index("by_position");
|
||||
index.openCursor().onsuccess = event => {
|
||||
const cursor = (<IDBRequest<IDBCursorWithValue>> event.target).result;
|
||||
const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;
|
||||
if (!cursor) {
|
||||
resolve(items);
|
||||
return;
|
||||
|
@ -78,7 +78,7 @@ const SIZE_SCALE = 875;
|
||||
const SIZE_KILO = 1024;
|
||||
|
||||
export const formatSize = memoize(function formatSize(
|
||||
size: number, fractions: boolean = true) {
|
||||
size: number, fractions = true) {
|
||||
const neg = size < 0;
|
||||
size = Math.abs(size);
|
||||
let i = 0;
|
||||
|
85
lib/i18n.ts
85
lib/i18n.ts
@ -3,6 +3,50 @@
|
||||
|
||||
import {memoize} from "./memoize";
|
||||
|
||||
function load() {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const {i18n} = require("webextension-polyfill");
|
||||
|
||||
return i18n;
|
||||
}
|
||||
catch (ex) {
|
||||
// We might be running under node for tests
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const messages = require("../_locales/en/messages.json");
|
||||
|
||||
const map = new Map();
|
||||
for (const [k, v] of Object.entries<any>(messages)) {
|
||||
const {placeholders = {}} = v;
|
||||
let {message = ""} = v;
|
||||
for (const [pname, pval] of Object.entries<any>(placeholders)) {
|
||||
message = message.replace(`$${pname.toUpperCase()}$`, `${pval.content}$`);
|
||||
}
|
||||
map.set(k, message);
|
||||
}
|
||||
|
||||
return {
|
||||
getMessage(id: string, subst: string[]) {
|
||||
const m = map.get(id);
|
||||
if (typeof subst === undefined) {
|
||||
return m;
|
||||
}
|
||||
if (!Array.isArray(subst)) {
|
||||
subst = [subst];
|
||||
}
|
||||
return m.replace(/\$\d+\$/g, (r: string) => {
|
||||
const idx = parseInt(r.substr(1, r.length - 2), 10) - 1;
|
||||
return subst[idx] || "";
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const i18n = load();
|
||||
const memoGetMessage = memoize(i18n.getMessage, 10 * 1000, 0);
|
||||
|
||||
/**
|
||||
* Localize a message
|
||||
* @param {string} id Identifier of the string to localize
|
||||
@ -58,46 +102,5 @@ function localize(elem: HTMLElement) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
function load() {
|
||||
try {
|
||||
const {i18n} = require("webextension-polyfill");
|
||||
|
||||
return i18n;
|
||||
}
|
||||
catch (ex) {
|
||||
// We might be running under node for tests
|
||||
|
||||
const messages = require("../_locales/en/messages.json");
|
||||
|
||||
const map = new Map();
|
||||
for (const [k, v] of Object.entries<any>(messages)) {
|
||||
const {placeholders = {}} = v;
|
||||
let {message = ""} = v;
|
||||
for (const [pname, pval] of Object.entries<any>(placeholders)) {
|
||||
message = message.replace(`$${pname.toUpperCase()}$`, `${pval.content}$`);
|
||||
}
|
||||
map.set(k, message);
|
||||
}
|
||||
|
||||
return {
|
||||
getMessage(id: string, subst: string[]) {
|
||||
const m = map.get(id);
|
||||
if (typeof subst === undefined) {
|
||||
return m;
|
||||
}
|
||||
if (!Array.isArray(subst)) {
|
||||
subst = [subst];
|
||||
}
|
||||
return m.replace(/\$\d+\$/g, (r: string) => {
|
||||
const idx = parseInt(r.substr(1, r.length - 2), 10) - 1;
|
||||
return subst[idx] || "";
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const i18n = load();
|
||||
const memoGetMessage = memoize(i18n.getMessage, 10 * 1000, 0);
|
||||
|
||||
export {localize, _};
|
||||
|
@ -95,14 +95,15 @@ export class BaseDownload {
|
||||
}
|
||||
|
||||
assign(options: any) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self: any = this;
|
||||
for (const prop of SAVEDPROPS) {
|
||||
if (prop in options) {
|
||||
self[prop] = options[prop];
|
||||
}
|
||||
}
|
||||
this.uURL = <URLd> new URL(this.url);
|
||||
this.uReferrer = <URLd> (this.referrer && new URL(this.referrer));
|
||||
this.uURL = new URL(this.url) as URLd;
|
||||
this.uReferrer = (this.referrer && new URL(this.referrer)) as URLd;
|
||||
this.startDate = new Date(options.startDate || Date.now());
|
||||
if (options.paused) {
|
||||
this.state = PAUSED;
|
||||
@ -133,6 +134,7 @@ export class BaseDownload {
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self: any = this;
|
||||
const rv: any = {};
|
||||
for (const prop of SAVEDPROPS) {
|
||||
|
@ -74,7 +74,7 @@ export const Limits = new class Limits extends EventEmitter {
|
||||
this.concurrent = await Prefs.get("concurrent", this.concurrent);
|
||||
const rawlimits = await Prefs.get("limits");
|
||||
this.limits = new Map(rawlimits.map((e: any) => [e.domain, new Limit(e)]));
|
||||
this.load = <() => Promise<void>> <unknown> (() => {});
|
||||
this.load = (() => {}) as unknown as () => Promise<void>;
|
||||
this.emit("changed");
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,10 @@ import { API } from "../api";
|
||||
import { BaseDownload } from "./basedownload";
|
||||
|
||||
type SID = {sid: number};
|
||||
type SIDS = {sids: number[], forced?: boolean};
|
||||
type SIDS = {
|
||||
sids: number[];
|
||||
forced?: boolean;
|
||||
};
|
||||
|
||||
export class ManagerPort {
|
||||
private manager: any;
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
"use strict";
|
||||
// License: MIT
|
||||
|
||||
@ -169,6 +170,7 @@ export default class Renamer {
|
||||
|
||||
toString() {
|
||||
const {mask} = this.d;
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self: any = this;
|
||||
// XXX flat
|
||||
return sanitizePath(mask.replace(REPLACE_EXPR, function(type: string) {
|
||||
@ -230,7 +232,7 @@ function makeHTMLMap() {
|
||||
|
||||
export function hookButton(maskButton: HTMLElement) {
|
||||
let maskMap: HTMLElement;
|
||||
maskButton.addEventListener("click", (evt : MouseEvent) => {
|
||||
maskButton.addEventListener("click", (evt: MouseEvent) => {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
|
||||
|
@ -31,14 +31,14 @@ type MemoizeFun<T> = (...args: any[]) => T;
|
||||
*
|
||||
* @param {Function} func The function to be memoized
|
||||
* @param {Number} [limit] Optional. Cache size (default: 3000)
|
||||
* @param {Number} [num_args] Options. Number of arguments the function expects
|
||||
* @param {Number} [numArgs] Options. Number of arguments the function expects
|
||||
* (default: func.length)
|
||||
* @returns {Function} Memoized function
|
||||
*/
|
||||
export function memoize<T>(
|
||||
func: MemoizeFun<T>, limit?: number, num_args?: number): MemoizeFun<T> {
|
||||
func: MemoizeFun<T>, limit?: number, numArgs?: number): MemoizeFun<T> {
|
||||
const climit = limit && limit > 0 ? limit : DEFAULT_LIMIT;
|
||||
num_args = num_args || func.length;
|
||||
numArgs = numArgs || func.length;
|
||||
|
||||
const cache = new Map();
|
||||
memoes.push(cache);
|
||||
@ -46,12 +46,12 @@ export function memoize<T>(
|
||||
const args: any[] = [];
|
||||
let key; let result;
|
||||
|
||||
switch (num_args) {
|
||||
switch (numArgs) {
|
||||
case 0:
|
||||
throw new Error("memoize does not support functions without arguments");
|
||||
|
||||
case 1:
|
||||
return function memoize_one_arg(a: any) {
|
||||
return function memoizeOne(a: any) {
|
||||
key = a.spec || a;
|
||||
if (cache.has(key)) {
|
||||
return cache.get(key);
|
||||
@ -66,7 +66,7 @@ export function memoize<T>(
|
||||
};
|
||||
|
||||
case 2:
|
||||
return function memoize_two_args(a: any, b: any) {
|
||||
return function memoizeTwo(a: any, b: any) {
|
||||
args[0] = a; args[1] = b;
|
||||
key = JSON.stringify(args);
|
||||
args.length = 0;
|
||||
@ -84,7 +84,7 @@ export function memoize<T>(
|
||||
};
|
||||
|
||||
case 3:
|
||||
return function memoize_three_args(a: any, b: any, c: any) {
|
||||
return function memoizeThree(a: any, b: any, c: any) {
|
||||
args[0] = a; args[1] = b; args[2] = c;
|
||||
key = JSON.stringify(args);
|
||||
args.length = 0;
|
||||
@ -102,7 +102,7 @@ export function memoize<T>(
|
||||
};
|
||||
|
||||
case 4:
|
||||
return function memoize_four_args(a: any, b: any, c: any, d: any) {
|
||||
return function memoizeFour(a: any, b: any, c: any, d: any) {
|
||||
args[0] = a; args[1] = b; args[2] = c; args[3] = d;
|
||||
key = JSON.stringify(args);
|
||||
args.length = 0;
|
||||
|
@ -5,7 +5,7 @@ const RUNNING = Symbol();
|
||||
const LIMIT = Symbol();
|
||||
const ITEMS = Symbol();
|
||||
|
||||
function nothing() {}
|
||||
function nothing() { /* ignored */ }
|
||||
|
||||
type Wrapped<T> = (...args: any[]) => Promise<T>;
|
||||
|
||||
@ -79,7 +79,7 @@ export class PromiseSerializer {
|
||||
return this.scheduled + this.running;
|
||||
}
|
||||
|
||||
static wrapNew<T>(limit: number, ctx: any, fn: Function) : Wrapped<T> {
|
||||
static wrapNew<T>(limit: number, ctx: any, fn: Function): Wrapped<T> {
|
||||
return new PromiseSerializer(limit).wrap(ctx, fn);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
"use strict";
|
||||
// License: MIT
|
||||
|
||||
const re_tokenize = /(0x[0-9a-f]+|[+-]?[0-9]+(?:\.[0-9]*(?:e[+-]?[0-9]+)?)?|\d+)/i;
|
||||
const re_hex = /^0x[0-9a-z]+$/i;
|
||||
const re_trimmore = /\s+/g;
|
||||
const RE_TOKENIZE = /(0x[0-9a-f]+|[+-]?[0-9]+(?:\.[0-9]*(?:e[+-]?[0-9]+)?)?|\d+)/i;
|
||||
const RE_HEX = /^0x[0-9a-z]+$/i;
|
||||
const RE_TRIMMORE = /\s+/g;
|
||||
|
||||
type KeyFunc<T> = (v: T) => any;
|
||||
type CompareFunc<T> = (a: T, b: T) => number;
|
||||
@ -14,31 +14,29 @@ type CompareFunc<T> = (a: T, b: T) => number;
|
||||
* @param {*} b Second value
|
||||
* @returns {number} Comparision result
|
||||
*/
|
||||
export function default_compare(a: any, b: any) {
|
||||
export function defaultCompare(a: any, b: any) {
|
||||
return a < b ? -1 : (a > b ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
function parseToken(chunk: string) {
|
||||
chunk = chunk.replace(re_trimmore, " ").trim();
|
||||
if (re_hex.test(chunk)) {
|
||||
chunk = chunk.replace(RE_TRIMMORE, " ").trim();
|
||||
if (RE_HEX.test(chunk)) {
|
||||
return parseInt(chunk.slice(2), 16);
|
||||
}
|
||||
const val = parseFloat(chunk);
|
||||
return Number.isNaN(val) ? chunk : val;
|
||||
}
|
||||
|
||||
|
||||
function token_filter(str: string) {
|
||||
function filterTokens(str: string) {
|
||||
return str && str.trim();
|
||||
}
|
||||
|
||||
|
||||
function tokenize(val: any) {
|
||||
if (typeof val === "number") {
|
||||
return [[`${val}`], [val]];
|
||||
}
|
||||
const tokens = `${val}`.split(re_tokenize).filter(token_filter);
|
||||
const tokens = `${val}`.split(RE_TOKENIZE).filter(filterTokens);
|
||||
const numeric = tokens.map(parseToken);
|
||||
return [tokens, numeric];
|
||||
}
|
||||
@ -76,8 +74,8 @@ export function naturalCompare(a: any, b: any): number {
|
||||
if (xisnum) {
|
||||
// both are numbers
|
||||
// Compare the numbers and if they are the same, the tokens too
|
||||
const res = default_compare(xnum, ynum) ||
|
||||
default_compare(xTokens[i], yTokens[i]);
|
||||
const res = defaultCompare(xnum, ynum) ||
|
||||
defaultCompare(xTokens[i], yTokens[i]);
|
||||
if (!res) {
|
||||
continue;
|
||||
}
|
||||
@ -86,13 +84,13 @@ export function naturalCompare(a: any, b: any): number {
|
||||
|
||||
// both must be stringey
|
||||
// Compare the actual tokens.
|
||||
const res = default_compare(xTokens[i], yTokens[i]);
|
||||
const res = defaultCompare(xTokens[i], yTokens[i]);
|
||||
if (!res) {
|
||||
continue;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return default_compare(xTokenLen, yTokenLen);
|
||||
return defaultCompare(xTokenLen, yTokenLen);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,19 +112,19 @@ export function naturalCaseCompare(a: any, b: any) {
|
||||
* @param {cmpf} [cmp] Compare function or default_compare
|
||||
* @returns {number} Comparison result
|
||||
*/
|
||||
export function array_compare(a: any, b: any, cmp: CompareFunc<any>): number {
|
||||
cmp = cmp || default_compare;
|
||||
export function arrayCompare(a: any, b: any, cmp: CompareFunc<any>): number {
|
||||
cmp = cmp || defaultCompare;
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
const {length: alen} = a;
|
||||
const {length: blen} = b;
|
||||
const len = Math.min(alen, blen);
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const rv = array_compare(a[i], b[i], cmp);
|
||||
const rv = arrayCompare(a[i], b[i], cmp);
|
||||
if (rv) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return default_compare(alen, blen);
|
||||
return defaultCompare(alen, blen);
|
||||
}
|
||||
return cmp(a, b);
|
||||
}
|
||||
@ -137,12 +135,12 @@ interface MapValue {
|
||||
value: any;
|
||||
}
|
||||
|
||||
function mapped_compare(
|
||||
fn: CompareFunc<any>, a: MapValue, b: MapValue) : number {
|
||||
function mappedCompare(
|
||||
fn: CompareFunc<any>, a: MapValue, b: MapValue): number {
|
||||
const {key: ka} = a;
|
||||
const {key: kb} = b;
|
||||
return array_compare(ka, kb, fn) ||
|
||||
/* stable */ default_compare(a.index, b.index);
|
||||
return arrayCompare(ka, kb, fn) ||
|
||||
/* stable */ defaultCompare(a.index, b.index);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,8 +167,8 @@ function mapped_compare(
|
||||
* @returns {*[]} New sorted array
|
||||
*/
|
||||
export function sort<T>(arr: T[], key?: KeyFunc<T>, cmp?: CompareFunc<T>) {
|
||||
cmp = cmp || default_compare;
|
||||
const carr = <MapValue[]> <unknown> arr;
|
||||
cmp = cmp || defaultCompare;
|
||||
const carr = arr as unknown as MapValue[];
|
||||
if (key) {
|
||||
arr.forEach((value, index) => {
|
||||
carr[index] = {value, key: key(value), index};
|
||||
@ -181,7 +179,7 @@ export function sort<T>(arr: T[], key?: KeyFunc<T>, cmp?: CompareFunc<T>) {
|
||||
carr[index] = {value, key: value, index};
|
||||
});
|
||||
}
|
||||
arr.sort(mapped_compare.bind(null, cmp));
|
||||
arr.sort(mappedCompare.bind(null, cmp));
|
||||
carr.forEach((i, idx) => {
|
||||
arr[idx] = i.value;
|
||||
});
|
||||
@ -198,7 +196,7 @@ export function sort<T>(arr: T[], key?: KeyFunc<T>, cmp?: CompareFunc<T>) {
|
||||
* @returns {*[]} New sorted array
|
||||
*/
|
||||
export function sorted<T>(arr: T[], key?: KeyFunc<T>, cmp?: CompareFunc<T>) {
|
||||
cmp = cmp || default_compare;
|
||||
cmp = cmp || defaultCompare;
|
||||
let carr: MapValue[];
|
||||
if (key) {
|
||||
carr = arr.map((value, index) => {
|
||||
@ -210,6 +208,6 @@ export function sorted<T>(arr: T[], key?: KeyFunc<T>, cmp?: CompareFunc<T>) {
|
||||
return {value, key: value, index};
|
||||
});
|
||||
}
|
||||
carr.sort(mapped_compare.bind(null, cmp));
|
||||
carr.sort(mappedCompare.bind(null, cmp));
|
||||
return carr.map(v => v.value);
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ export class FakeLink {
|
||||
}
|
||||
|
||||
getAttribute(attr: string) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self: any = this;
|
||||
return (attr in self) ? self[attr] : null;
|
||||
}
|
||||
|
40
lib/util.ts
40
lib/util.ts
@ -47,7 +47,21 @@ export function lazy<T>(object: any, name: string, fun: (...any: any[]) => T) {
|
||||
return object;
|
||||
}
|
||||
|
||||
export function none() { }
|
||||
export function none() { /* ignored */ }
|
||||
|
||||
export const sanitizePath = identity(function sanitizePath(path: string) {
|
||||
return path.
|
||||
replace(/:+/g, "ː").
|
||||
replace(/\?+/g, "_").
|
||||
replace(/\*+/g, "_").
|
||||
replace(/<+/g, "◄").
|
||||
replace(/>+/g, "▶").
|
||||
replace(/"+/g, "'").
|
||||
replace(/\|+/g, "¦").
|
||||
replace(/#+/g, "♯").
|
||||
replace(/[.\s]+$/g, "").
|
||||
trim();
|
||||
});
|
||||
|
||||
// XXX cleanup + test
|
||||
export const parsePath = memoize(function parsePath(path: string | URL) {
|
||||
@ -89,21 +103,6 @@ export const parsePath = memoize(function parsePath(path: string | URL) {
|
||||
};
|
||||
});
|
||||
|
||||
export const sanitizePath = identity(function sanitizePath(path: string) {
|
||||
return path.
|
||||
replace(/:+/g, "ː").
|
||||
replace(/\?+/g, "_").
|
||||
replace(/\*+/g, "_").
|
||||
replace(/<+/g, "◄").
|
||||
replace(/>+/g, "▶").
|
||||
replace(/"+/g, "'").
|
||||
replace(/\|+/g, "¦").
|
||||
replace(/#+/g, "♯").
|
||||
replace(/[.\s]+$/g, "").
|
||||
trim();
|
||||
});
|
||||
|
||||
|
||||
export class CoalescedUpdate<T> extends Set<T> {
|
||||
private readonly to: number;
|
||||
|
||||
@ -141,7 +140,7 @@ export class CoalescedUpdate<T> extends Set<T> {
|
||||
export const hostToDomain = memoize(psl.get, 1000);
|
||||
|
||||
export interface URLd extends URL {
|
||||
domain: string
|
||||
domain: string;
|
||||
}
|
||||
|
||||
Object.defineProperty(URL.prototype, "domain", {
|
||||
@ -188,7 +187,8 @@ export function filterInSitu<T>(arr: T[], cb: (value: T) => boolean, tp?: any) {
|
||||
*/
|
||||
export function mapInSitu<TRes, T>(arr: T[], cb: (value: T) => TRes, tp?: any) {
|
||||
tp = tp || null;
|
||||
const carr = <TRes[]> <unknown> arr;
|
||||
const carr = arr as unknown as TRes[];
|
||||
|
||||
for (let i = 0, e = arr.length; i < e; i++) {
|
||||
carr[i] = cb.call(tp, arr[i], i, arr);
|
||||
}
|
||||
@ -209,7 +209,7 @@ export function filterMapInSitu<TRes, T>(
|
||||
mapStep: (value: T) => TRes,
|
||||
tp?: any) {
|
||||
tp = tp || null;
|
||||
const carr = <TRes[]> <unknown> arr;
|
||||
const carr = arr as unknown as TRes[];
|
||||
|
||||
let i; let k; let e;
|
||||
for (i = 0, k = 0, e = arr.length; i < e; i++) {
|
||||
@ -238,7 +238,7 @@ export function mapFilterInSitu<TRes, T>(
|
||||
filterStep: (value: T) => boolean,
|
||||
tp?: any) {
|
||||
tp = tp || null;
|
||||
const carr = <TRes[]> <unknown> arr;
|
||||
const carr = arr as unknown as TRes[];
|
||||
|
||||
let i; let k; let e;
|
||||
for (i = 0, k = 0, e = arr.length; i < e; i++) {
|
||||
|
@ -12,6 +12,7 @@ try {
|
||||
};
|
||||
}
|
||||
catch (ex) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const cr = require("crypto");
|
||||
|
||||
return function(size: number) {
|
||||
|
@ -67,6 +67,7 @@ export class AbstractTable extends EventEmitter {
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setCellCheck(rowid: number, colid: number, value: boolean) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,6 +113,7 @@ export class AnimationPool {
|
||||
* Your newly bound function.
|
||||
*/
|
||||
wrap(fn: Function) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self = this;
|
||||
return function wrapped(...args: any[]) {
|
||||
return self.schedule(this, fn, ...args);
|
||||
|
@ -79,7 +79,7 @@ export class BaseTable extends AbstractTable {
|
||||
|
||||
[COLS]: Columns;
|
||||
|
||||
constructor(elem : any, config: any, version?: number) {
|
||||
constructor(elem: any, config: any, version?: number) {
|
||||
config = (config && config.version === version && config) || {};
|
||||
super();
|
||||
|
||||
@ -168,6 +168,7 @@ export class BaseTable extends AbstractTable {
|
||||
}
|
||||
|
||||
init() {
|
||||
// ignored
|
||||
}
|
||||
|
||||
/* do not override unless you know what you're doing */
|
||||
@ -471,7 +472,7 @@ export class BaseTable extends AbstractTable {
|
||||
}
|
||||
|
||||
isCheckClick(evt: MouseEvent) {
|
||||
return /virtualtable-check/.test((<HTMLElement> evt.target).className) &&
|
||||
return /virtualtable-check/.test((evt.target as HTMLElement).className) &&
|
||||
!evt.ctrlKey && !evt.shiftKey && !evt.metaKey;
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,8 @@ function toKeyText(key: string) {
|
||||
}
|
||||
|
||||
export interface MenuPosition {
|
||||
clientX: number,
|
||||
clientY: number,
|
||||
clientX: number;
|
||||
clientY: number;
|
||||
}
|
||||
|
||||
export class MenuItemBase {
|
||||
@ -137,6 +137,7 @@ export class SubMenuItem extends MenuItemBase {
|
||||
this.elem.setAttribute("aria-role", "menuitem");
|
||||
this.elem.setAttribute("aria-haspopup", "true");
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
this.menu = new ContextMenu();
|
||||
|
||||
this.expandElem = document.createElement("span");
|
||||
@ -177,7 +178,7 @@ export class SubMenuItem extends MenuItemBase {
|
||||
|
||||
entered(event: MouseEvent) {
|
||||
const {target} = event;
|
||||
const htarget = <HTMLElement> target;
|
||||
const htarget = target as HTMLElement;
|
||||
if (htarget.classList.contains("context-menu")) {
|
||||
return;
|
||||
}
|
||||
@ -307,7 +308,7 @@ export class ContextMenu extends EventEmitter {
|
||||
Math.abs(event.clientY - origEvent.clientY) < CLICK_DIFF) {
|
||||
return;
|
||||
}
|
||||
let el = <HTMLElement> event.target;
|
||||
let el = event.target as HTMLElement;
|
||||
while (el) {
|
||||
if (el.classList.contains("context-menu")) {
|
||||
return;
|
||||
@ -386,7 +387,7 @@ export class ContextMenu extends EventEmitter {
|
||||
el.parentElement.removeChild(el);
|
||||
}
|
||||
if (el.localName === "template") {
|
||||
el = <HTMLElement> (<HTMLTemplateElement> el).content.firstElementChild;
|
||||
el = (el as HTMLTemplateElement).content.firstElementChild as HTMLElement;
|
||||
}
|
||||
if (el.className) {
|
||||
this.elem.className = el.className;
|
||||
@ -408,24 +409,24 @@ export class ContextMenu extends EventEmitter {
|
||||
if (sub) {
|
||||
throw new Error("Already has a submenu");
|
||||
}
|
||||
if ((<HTMLElement> sc).localName !== "ul") {
|
||||
if ((sc as HTMLElement).localName !== "ul") {
|
||||
throw new Error("Not a valid submenu");
|
||||
}
|
||||
sub = sc;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid node: ${(<HTMLElement> sc).localName}`);
|
||||
throw new Error(`Invalid node: ${(sc as HTMLElement).localName}`);
|
||||
}
|
||||
}
|
||||
const joined = text.join(" ").trim();
|
||||
let item = null;
|
||||
const ce = <HTMLElement> child;
|
||||
const ce = child as HTMLElement;
|
||||
if (joined === "-") {
|
||||
item = new MenuSeperatorItem(this, child.id);
|
||||
}
|
||||
else if (sub) {
|
||||
item = new SubMenuItem(this, child.id, joined, ce.dataset);
|
||||
item.constructFromTemplate(<HTMLElement> sub);
|
||||
item.constructFromTemplate(sub as HTMLElement);
|
||||
}
|
||||
else {
|
||||
item = new MenuItem(this, child.id, joined, ce.dataset);
|
||||
|
@ -63,6 +63,7 @@ export class EventEmitter {
|
||||
once(event: string, cb: (...args: any[]) => any) {
|
||||
const wrapped = (...args: any[]) => {
|
||||
try {
|
||||
// eslint-disable-next-line prefer-spread
|
||||
return cb.apply(null, args);
|
||||
}
|
||||
finally {
|
||||
@ -102,6 +103,7 @@ export class EventEmitter {
|
||||
}
|
||||
for (const e of Array.from(handlers)) {
|
||||
try {
|
||||
// eslint-disable-next-line prefer-spread
|
||||
handled = handled || !!e.apply(null, args);
|
||||
}
|
||||
catch (ex) {
|
||||
|
@ -87,7 +87,7 @@ export default class ModalDialog {
|
||||
return el;
|
||||
}
|
||||
|
||||
get content() : DocumentFragment | HTMLElement {
|
||||
get content(): DocumentFragment | HTMLElement {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
@ -119,13 +119,14 @@ export default class ModalDialog {
|
||||
}
|
||||
|
||||
shown() {
|
||||
// ignored
|
||||
}
|
||||
|
||||
focusDefault() {
|
||||
this._default && this._default.focus();
|
||||
}
|
||||
|
||||
convertValue(value: string) : any {
|
||||
convertValue(value: string): any {
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -148,7 +149,7 @@ export default class ModalDialog {
|
||||
if (e.key !== "Enter") {
|
||||
return;
|
||||
}
|
||||
const {localName} = <HTMLElement> e.target;
|
||||
const {localName} = e.target as HTMLElement;
|
||||
if (localName === "textarea" && !e.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ export class TableSelection extends EventEmitter {
|
||||
newSelection._add(pos, r.end + offset);
|
||||
}
|
||||
this.ranges.length = 0;
|
||||
this.ranges.push.apply(this.ranges, newSelection.ranges);
|
||||
this.ranges.push(...newSelection.ranges);
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
@ -38,7 +38,7 @@ export class Broadcaster {
|
||||
}
|
||||
|
||||
onkey(evt: KeyboardEvent) {
|
||||
const {localName} = <HTMLElement> evt.target;
|
||||
const {localName} = evt.target as HTMLElement;
|
||||
if (localName === "input" || localName === "textarea") {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ export class Dropdown extends EventEmitter {
|
||||
this.container.classList.add("dropdown");
|
||||
|
||||
input = input.parentElement.replaceChild(this.container, input);
|
||||
this.input = <HTMLInputElement> input;
|
||||
this.input = input as HTMLInputElement;
|
||||
this.container.appendChild(this.input);
|
||||
|
||||
this.select = document.createElement("select");
|
||||
|
@ -8,7 +8,7 @@ export class Icons extends Map {
|
||||
|
||||
constructor(el: HTMLStyleElement) {
|
||||
super();
|
||||
this.sheet = <CSSStyleSheet> el.sheet;
|
||||
this.sheet = el.sheet as CSSStyleSheet;
|
||||
this.running = 0;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ export class Buttons extends EventEmitter {
|
||||
}
|
||||
|
||||
clicked(evt: MouseEvent) {
|
||||
let target = <HTMLElement | null> evt.target;
|
||||
let target = evt.target as HTMLElement | null;
|
||||
while (target && target !== this.parent) {
|
||||
if (target.classList.contains("button")) {
|
||||
const {id} = target;
|
||||
|
@ -12,8 +12,9 @@ import {
|
||||
MenuPosition,
|
||||
} from "../../uikit/lib/contextmenu";
|
||||
import {EventEmitter} from "../../lib/events";
|
||||
import {filters, Matcher} from "../../lib/filters";
|
||||
import {sort, default_compare, naturalCaseCompare} from "../../lib/sorting";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import {filters, Matcher, Filter} from "../../lib/filters";
|
||||
import {sort, defaultCompare, naturalCaseCompare} from "../../lib/sorting";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import {DownloadItem, DownloadTable} from "./table";
|
||||
import {formatSize} from "../../lib/formatters";
|
||||
@ -162,7 +163,10 @@ export class MenuFilter extends ItemFilter {
|
||||
if (!callback) {
|
||||
continue;
|
||||
}
|
||||
this.toggleItem(<MenuItem> item);
|
||||
if (!(item instanceof MenuItem)) {
|
||||
continue;
|
||||
}
|
||||
this.toggleItem(item);
|
||||
callback.apply(this);
|
||||
}
|
||||
}
|
||||
@ -188,7 +192,10 @@ export class MenuFilter extends ItemFilter {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
this.toggleItem(<MenuItem> item);
|
||||
if (!(item instanceof MenuItem)) {
|
||||
return;
|
||||
}
|
||||
this.toggleItem(item);
|
||||
if (callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
@ -300,7 +307,7 @@ export class SizeMenuFilter extends FixedMenuFilter {
|
||||
export class UrlMenuFilter extends MenuFilter {
|
||||
collection: FilteredCollection;
|
||||
|
||||
filters: Set<any>;
|
||||
filters: Set<Filter>;
|
||||
|
||||
domains: Set<string>;
|
||||
|
||||
@ -364,7 +371,7 @@ export class UrlMenuFilter extends MenuFilter {
|
||||
}
|
||||
else {
|
||||
const exprs = Array.from(this.filters).map(f => Array.from(f)).flat();
|
||||
this.matcher = new Matcher(<RegExp[]> exprs);
|
||||
this.matcher = new Matcher(exprs);
|
||||
}
|
||||
|
||||
this.collection.addFilter(this);
|
||||
@ -570,7 +577,7 @@ export class FilteredCollection extends EventEmitter {
|
||||
* @param {boolean} [natural] Sort naturally
|
||||
*/
|
||||
sort(keyfn: (i: DownloadItem) => any, descending = false, natural = false) {
|
||||
const cmp = natural ? naturalCaseCompare : default_compare;
|
||||
const cmp = natural ? naturalCaseCompare : defaultCompare;
|
||||
let cmpfn = cmp;
|
||||
if (descending) {
|
||||
cmpfn = (a, b) => -cmp(a, b);
|
||||
|
@ -147,7 +147,10 @@ export class Tooltip {
|
||||
this.update = this.update.bind(this);
|
||||
this.item = item;
|
||||
const tmpl = (
|
||||
<HTMLTemplateElement> document.querySelector("#tooltip-template"));
|
||||
document.querySelector<HTMLTemplateElement>("#tooltip-template"));
|
||||
if (!tmpl) {
|
||||
throw new Error("template failed");
|
||||
}
|
||||
const el = tmpl.content.firstElementChild;
|
||||
if (!el) {
|
||||
throw new Error("invalid template");
|
||||
@ -155,8 +158,9 @@ export class Tooltip {
|
||||
this.elem = localize(el.cloneNode(true) as HTMLElement);
|
||||
this.adjust(pos);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self: any = this;
|
||||
ELEMS.forEach(e => {
|
||||
const self: any = this;
|
||||
self[e] = this.elem.querySelector(`#tooltip-${e}`);
|
||||
});
|
||||
document.body.appendChild(this.elem);
|
||||
|
Loading…
x
Reference in New Issue
Block a user