Types on src/share
This commit is contained in:
parent
2b8c37e57f
commit
0cffb09e24
11 changed files with 88 additions and 54 deletions
|
@ -1,6 +1,6 @@
|
||||||
import * as re from 'shared/utils/re';
|
import * as re from './utils/re';
|
||||||
|
|
||||||
const includes = (blacklist, url) => {
|
const includes = (blacklist: string[], url: string): boolean => {
|
||||||
let u = new URL(url);
|
let u = new URL(url);
|
||||||
return blacklist.some((item) => {
|
return blacklist.some((item) => {
|
||||||
if (!item.includes('/')) {
|
if (!item.includes('/')) {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
const onWebMessage = (listener) => {
|
type WebMessageSender = Window | MessagePort | ServiceWorker | null;
|
||||||
window.addEventListener('message', (event) => {
|
type WebMessageListener = (msg: any, sender: WebMessageSender | null) => void;
|
||||||
|
|
||||||
|
const onWebMessage = (listener: WebMessageListener) => {
|
||||||
|
window.addEventListener('message', (event: MessageEvent) => {
|
||||||
let sender = event.source;
|
let sender = event.source;
|
||||||
let message = null;
|
let message = null;
|
||||||
try {
|
try {
|
||||||
|
@ -12,11 +15,15 @@ const onWebMessage = (listener) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onBackgroundMessage = (listener) => {
|
const onBackgroundMessage = (
|
||||||
|
listener: (msg: any, sender: browser.runtime.MessageSender,
|
||||||
|
) => void) => {
|
||||||
browser.runtime.onMessage.addListener(listener);
|
browser.runtime.onMessage.addListener(listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMessage = (listener) => {
|
const onMessage = (
|
||||||
|
listener: (msg: any, sender: WebMessageSender | browser.runtime.MessageSender,
|
||||||
|
) => void) => {
|
||||||
onWebMessage(listener);
|
onWebMessage(listener);
|
||||||
onBackgroundMessage(listener);
|
onBackgroundMessage(listener);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default {
|
const operations: { [key: string]: string } = {
|
||||||
// Hide console, or cancel some user actions
|
// Hide console, or cancel some user actions
|
||||||
CANCEL: 'cancel',
|
CANCEL: 'cancel',
|
||||||
|
|
||||||
|
@ -76,3 +76,5 @@ export default {
|
||||||
MARK_SET_PREFIX: 'mark.set.prefix',
|
MARK_SET_PREFIX: 'mark.set.prefix',
|
||||||
MARK_JUMP_PREFIX: 'mark.jump.prefix',
|
MARK_JUMP_PREFIX: 'mark.jump.prefix',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default operations;
|
||||||
|
|
|
@ -2,20 +2,20 @@
|
||||||
// mystr: 'string',
|
// mystr: 'string',
|
||||||
// mynum: 'number',
|
// mynum: 'number',
|
||||||
// mybool: 'boolean',
|
// mybool: 'boolean',
|
||||||
const types = {
|
const types: { [key: string]: string } = {
|
||||||
hintchars: 'string',
|
hintchars: 'string',
|
||||||
smoothscroll: 'boolean',
|
smoothscroll: 'boolean',
|
||||||
complete: 'string',
|
complete: 'string',
|
||||||
};
|
};
|
||||||
|
|
||||||
// describe default values of a property
|
// describe default values of a property
|
||||||
const defaults = {
|
const defaults: { [key: string]: string | number | boolean } = {
|
||||||
hintchars: 'abcdefghijklmnopqrstuvwxyz',
|
hintchars: 'abcdefghijklmnopqrstuvwxyz',
|
||||||
smoothscroll: false,
|
smoothscroll: false,
|
||||||
complete: 'sbh',
|
complete: 'sbh',
|
||||||
};
|
};
|
||||||
|
|
||||||
const docs = {
|
const docs: { [key: string]: string } = {
|
||||||
hintchars: 'hint characters on follow mode',
|
hintchars: 'hint characters on follow mode',
|
||||||
smoothscroll: 'smooth scroll',
|
smoothscroll: 'smooth scroll',
|
||||||
complete: 'which are completed at the open page',
|
complete: 'which are completed at the open page',
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import DefaultSettings from './default';
|
import DefaultSettings from './default';
|
||||||
import * as settingsValues from './values';
|
import * as settingsValues from './values';
|
||||||
|
|
||||||
const loadRaw = async() => {
|
const loadRaw = async(): Promise<any> => {
|
||||||
let { settings } = await browser.storage.local.get('settings');
|
let { settings } = await browser.storage.local.get('settings');
|
||||||
if (!settings) {
|
if (!settings) {
|
||||||
return DefaultSettings;
|
return DefaultSettings;
|
||||||
}
|
}
|
||||||
return { ...DefaultSettings, ...settings };
|
return { ...DefaultSettings, ...settings as object };
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadValue = async() => {
|
const loadValue = async() => {
|
||||||
|
@ -23,7 +23,7 @@ const loadValue = async() => {
|
||||||
return { ...settingsValues.valueFromJson(DefaultSettings.json), ...value };
|
return { ...settingsValues.valueFromJson(DefaultSettings.json), ...value };
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = (settings) => {
|
const save = (settings: any): Promise<any> => {
|
||||||
return browser.storage.local.set({
|
return browser.storage.local.set({
|
||||||
settings,
|
settings,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import operations from 'shared/operations';
|
import operations from '../operations';
|
||||||
import * as properties from './properties';
|
import * as properties from './properties';
|
||||||
|
|
||||||
const VALID_TOP_KEYS = ['keymaps', 'search', 'blacklist', 'properties'];
|
const VALID_TOP_KEYS = ['keymaps', 'search', 'blacklist', 'properties'];
|
||||||
|
@ -6,7 +6,7 @@ const VALID_OPERATION_VALUES = Object.keys(operations).map((key) => {
|
||||||
return operations[key];
|
return operations[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
const validateInvalidTopKeys = (settings) => {
|
const validateInvalidTopKeys = (settings: any): void => {
|
||||||
let invalidKey = Object.keys(settings).find((key) => {
|
let invalidKey = Object.keys(settings).find((key) => {
|
||||||
return !VALID_TOP_KEYS.includes(key);
|
return !VALID_TOP_KEYS.includes(key);
|
||||||
});
|
});
|
||||||
|
@ -15,7 +15,7 @@ const validateInvalidTopKeys = (settings) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateKeymaps = (keymaps) => {
|
const validateKeymaps = (keymaps: any): void => {
|
||||||
for (let key of Object.keys(keymaps)) {
|
for (let key of Object.keys(keymaps)) {
|
||||||
let value = keymaps[key];
|
let value = keymaps[key];
|
||||||
if (!VALID_OPERATION_VALUES.includes(value.type)) {
|
if (!VALID_OPERATION_VALUES.includes(value.type)) {
|
||||||
|
@ -24,7 +24,7 @@ const validateKeymaps = (keymaps) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateSearch = (search) => {
|
const validateSearch = (search: any): void => {
|
||||||
let engines = search.engines;
|
let engines = search.engines;
|
||||||
for (let key of Object.keys(engines)) {
|
for (let key of Object.keys(engines)) {
|
||||||
if ((/\s/).test(key)) {
|
if ((/\s/).test(key)) {
|
||||||
|
@ -49,7 +49,7 @@ const validateSearch = (search) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateProperties = (props) => {
|
const validateProperties = (props: any): void => {
|
||||||
for (let name of Object.keys(props)) {
|
for (let name of Object.keys(props)) {
|
||||||
if (!properties.types[name]) {
|
if (!properties.types[name]) {
|
||||||
throw new Error(`Unknown property name: "${name}"`);
|
throw new Error(`Unknown property name: "${name}"`);
|
||||||
|
@ -60,7 +60,7 @@ const validateProperties = (props) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const validate = (settings) => {
|
const validate = (settings: any): void => {
|
||||||
validateInvalidTopKeys(settings);
|
validateInvalidTopKeys(settings);
|
||||||
if (settings.keymaps) {
|
if (settings.keymaps) {
|
||||||
validateKeymaps(settings.keymaps);
|
validateKeymaps(settings.keymaps);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as properties from './properties';
|
import * as properties from './properties';
|
||||||
|
|
||||||
const operationFromFormName = (name) => {
|
const operationFromFormName = (name: string): any => {
|
||||||
let [type, argStr] = name.split('?');
|
let [type, argStr] = name.split('?');
|
||||||
let args = {};
|
let args = {};
|
||||||
if (argStr) {
|
if (argStr) {
|
||||||
|
@ -9,7 +9,7 @@ const operationFromFormName = (name) => {
|
||||||
return { type, ...args };
|
return { type, ...args };
|
||||||
};
|
};
|
||||||
|
|
||||||
const operationToFormName = (op) => {
|
const operationToFormName = (op: any): string => {
|
||||||
let type = op.type;
|
let type = op.type;
|
||||||
let args = { ...op };
|
let args = { ...op };
|
||||||
delete args.type;
|
delete args.type;
|
||||||
|
@ -20,12 +20,12 @@ const operationToFormName = (op) => {
|
||||||
return op.type + '?' + JSON.stringify(args);
|
return op.type + '?' + JSON.stringify(args);
|
||||||
};
|
};
|
||||||
|
|
||||||
const valueFromJson = (json) => {
|
const valueFromJson = (json: string): object => {
|
||||||
return JSON.parse(json);
|
return JSON.parse(json);
|
||||||
};
|
};
|
||||||
|
|
||||||
const valueFromForm = (form) => {
|
const valueFromForm = (form: any): object => {
|
||||||
let keymaps = undefined;
|
let keymaps: any = undefined;
|
||||||
if (form.keymaps) {
|
if (form.keymaps) {
|
||||||
keymaps = {};
|
keymaps = {};
|
||||||
for (let name of Object.keys(form.keymaps)) {
|
for (let name of Object.keys(form.keymaps)) {
|
||||||
|
@ -34,7 +34,7 @@ const valueFromForm = (form) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let search = undefined;
|
let search: any = undefined;
|
||||||
if (form.search) {
|
if (form.search) {
|
||||||
search = { default: form.search.default };
|
search = { default: form.search.default };
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ const valueFromForm = (form) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const jsonFromValue = (value) => {
|
const jsonFromValue = (value: any): string => {
|
||||||
return JSON.stringify(value, undefined, 2);
|
return JSON.stringify(value, undefined, 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
const formFromValue = (value, allowedOps) => {
|
const formFromValue = (value: any, allowedOps: any[]): any => {
|
||||||
let keymaps = undefined;
|
let keymaps: any = undefined;
|
||||||
|
|
||||||
if (value.keymaps) {
|
if (value.keymaps) {
|
||||||
let allowedSet = new Set(allowedOps);
|
let allowedSet = new Set(allowedOps);
|
||||||
|
@ -73,7 +73,7 @@ const formFromValue = (value, allowedOps) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let search = undefined;
|
let search: any = undefined;
|
||||||
if (value.search) {
|
if (value.search) {
|
||||||
search = { default: value.search.default };
|
search = { default: value.search.default };
|
||||||
if (value.search.engines) {
|
if (value.search.engines) {
|
||||||
|
@ -93,11 +93,11 @@ const formFromValue = (value, allowedOps) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const jsonFromForm = (form) => {
|
const jsonFromForm = (form: any): string => {
|
||||||
return jsonFromValue(valueFromForm(form));
|
return jsonFromValue(valueFromForm(form));
|
||||||
};
|
};
|
||||||
|
|
||||||
const formFromJson = (json, allowedOps) => {
|
const formFromJson = (json: string, allowedOps: any[]): any => {
|
||||||
let value = valueFromJson(json);
|
let value = valueFromJson(json);
|
||||||
return formFromValue(value, allowedOps);
|
return formFromValue(value, allowedOps);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const trimStart = (str) => {
|
const trimStart = (str: string): string => {
|
||||||
// NOTE String.trimStart is available on Firefox 61
|
// NOTE String.trimStart is available on Firefox 61
|
||||||
return str.replace(/^\s+/, '');
|
return str.replace(/^\s+/, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
const SUPPORTED_PROTOCOLS = ['http:', 'https:', 'ftp:', 'mailto:', 'about:'];
|
const SUPPORTED_PROTOCOLS = ['http:', 'https:', 'ftp:', 'mailto:', 'about:'];
|
||||||
|
|
||||||
const searchUrl = (keywords, searchSettings) => {
|
const searchUrl = (keywords: string, searchSettings: any): string => {
|
||||||
try {
|
try {
|
||||||
let u = new URL(keywords);
|
let u = new URL(keywords);
|
||||||
if (SUPPORTED_PROTOCOLS.includes(u.protocol.toLowerCase())) {
|
if (SUPPORTED_PROTOCOLS.includes(u.protocol.toLowerCase())) {
|
||||||
|
@ -28,7 +28,7 @@ const searchUrl = (keywords, searchSettings) => {
|
||||||
return template.replace('{}', encodeURIComponent(query));
|
return template.replace('{}', encodeURIComponent(query));
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeUrl = (url) => {
|
const normalizeUrl = (url: string): string => {
|
||||||
try {
|
try {
|
||||||
let u = new URL(url);
|
let u = new URL(url);
|
||||||
if (SUPPORTED_PROTOCOLS.includes(u.protocol.toLowerCase())) {
|
if (SUPPORTED_PROTOCOLS.includes(u.protocol.toLowerCase())) {
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
const isContentEditable = (element) => {
|
const isContentEditable = (element: Element): boolean => {
|
||||||
return element.hasAttribute('contenteditable') && (
|
let value = element.getAttribute('contenteditable');
|
||||||
element.getAttribute('contenteditable').toLowerCase() === 'true' ||
|
if (value === null) {
|
||||||
element.getAttribute('contenteditable').toLowerCase() === ''
|
return false;
|
||||||
);
|
}
|
||||||
|
return value.toLowerCase() === 'true' || value.toLowerCase() === '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const rectangleCoordsRect = (coords) => {
|
interface Rect {
|
||||||
|
left: number;
|
||||||
|
top: number;
|
||||||
|
right: number;
|
||||||
|
bottom: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rectangleCoordsRect = (coords: string): Rect => {
|
||||||
let [left, top, right, bottom] = coords.split(',').map(n => Number(n));
|
let [left, top, right, bottom] = coords.split(',').map(n => Number(n));
|
||||||
return { left, top, right, bottom };
|
return { left, top, right, bottom };
|
||||||
};
|
};
|
||||||
|
|
||||||
const circleCoordsRect = (coords) => {
|
const circleCoordsRect = (coords: string): Rect => {
|
||||||
let [x, y, r] = coords.split(',').map(n => Number(n));
|
let [x, y, r] = coords.split(',').map(n => Number(n));
|
||||||
return {
|
return {
|
||||||
left: x - r,
|
left: x - r,
|
||||||
|
@ -20,7 +28,7 @@ const circleCoordsRect = (coords) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const polygonCoordsRect = (coords) => {
|
const polygonCoordsRect = (coords: string): Rect => {
|
||||||
let params = coords.split(',');
|
let params = coords.split(',');
|
||||||
let minx = Number(params[0]),
|
let minx = Number(params[0]),
|
||||||
maxx = Number(params[0]),
|
maxx = Number(params[0]),
|
||||||
|
@ -46,18 +54,24 @@ const polygonCoordsRect = (coords) => {
|
||||||
return { left: minx, top: miny, right: maxx, bottom: maxy };
|
return { left: minx, top: miny, right: maxx, bottom: maxy };
|
||||||
};
|
};
|
||||||
|
|
||||||
const viewportRect = (e) => {
|
const viewportRect = (e: Element): Rect => {
|
||||||
if (e.tagName !== 'AREA') {
|
if (e.tagName !== 'AREA') {
|
||||||
return e.getBoundingClientRect();
|
return e.getBoundingClientRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mapElement = e.parentNode;
|
let mapElement = e.parentNode as HTMLMapElement;
|
||||||
let imgElement = document.querySelector(`img[usemap="#${mapElement.name}"]`);
|
let imgElement = document.querySelector(
|
||||||
|
`img[usemap="#${mapElement.name}"]`
|
||||||
|
) as HTMLImageElement;
|
||||||
let {
|
let {
|
||||||
left: mapLeft,
|
left: mapLeft,
|
||||||
top: mapTop
|
top: mapTop
|
||||||
} = imgElement.getBoundingClientRect();
|
} = imgElement.getBoundingClientRect();
|
||||||
let coords = e.getAttribute('coords');
|
let coords = e.getAttribute('coords');
|
||||||
|
if (!coords) {
|
||||||
|
return e.getBoundingClientRect();
|
||||||
|
}
|
||||||
|
|
||||||
let rect = { left: 0, top: 0, right: 0, bottom: 0 };
|
let rect = { left: 0, top: 0, right: 0, bottom: 0 };
|
||||||
switch (e.getAttribute('shape')) {
|
switch (e.getAttribute('shape')) {
|
||||||
case 'rect':
|
case 'rect':
|
||||||
|
@ -81,7 +95,7 @@ const viewportRect = (e) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const isVisible = (element) => {
|
const isVisible = (element: Element): boolean => {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let style = window.getComputedStyle(element);
|
let style = window.getComputedStyle(element);
|
||||||
|
|
||||||
|
@ -94,7 +108,8 @@ const isVisible = (element) => {
|
||||||
if (window.innerWidth < rect.left && window.innerHeight < rect.top) {
|
if (window.innerWidth < rect.left && window.innerHeight < rect.top) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (element.nodeName === 'INPUT' && element.type.toLowerCase() === 'hidden') {
|
if (element instanceof HTMLInputElement &&
|
||||||
|
element.type.toLowerCase() === 'hidden') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
const modifiedKeyName = (name) => {
|
interface Key {
|
||||||
|
key: string;
|
||||||
|
shiftKey: boolean | undefined;
|
||||||
|
ctrlKey: boolean | undefined;
|
||||||
|
altKey: boolean | undefined;
|
||||||
|
metaKey: boolean | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const modifiedKeyName = (name: string): string => {
|
||||||
if (name === ' ') {
|
if (name === ' ') {
|
||||||
return 'Space';
|
return 'Space';
|
||||||
}
|
}
|
||||||
|
@ -10,7 +18,7 @@ const modifiedKeyName = (name) => {
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fromKeyboardEvent = (e) => {
|
const fromKeyboardEvent = (e: KeyboardEvent): Key => {
|
||||||
let key = modifiedKeyName(e.key);
|
let key = modifiedKeyName(e.key);
|
||||||
let shift = e.shiftKey;
|
let shift = e.shiftKey;
|
||||||
if (key.length === 1 && key.toUpperCase() === key.toLowerCase()) {
|
if (key.length === 1 && key.toUpperCase() === key.toLowerCase()) {
|
||||||
|
@ -28,7 +36,7 @@ const fromKeyboardEvent = (e) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fromMapKey = (key) => {
|
const fromMapKey = (key: string): Key => {
|
||||||
if (key.startsWith('<') && key.endsWith('>')) {
|
if (key.startsWith('<') && key.endsWith('>')) {
|
||||||
let inner = key.slice(1, -1);
|
let inner = key.slice(1, -1);
|
||||||
let shift = inner.includes('S-');
|
let shift = inner.includes('S-');
|
||||||
|
@ -55,8 +63,10 @@ const fromMapKey = (key) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fromMapKeys = (keys) => {
|
const fromMapKeys = (keys: string): Key[] => {
|
||||||
const fromMapKeysRecursive = (remainings, mappedKeys) => {
|
const fromMapKeysRecursive = (
|
||||||
|
remainings: string, mappedKeys: Key[],
|
||||||
|
): Key[] => {
|
||||||
if (remainings.length === 0) {
|
if (remainings.length === 0) {
|
||||||
return mappedKeys;
|
return mappedKeys;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +88,7 @@ const fromMapKeys = (keys) => {
|
||||||
return fromMapKeysRecursive(keys, []);
|
return fromMapKeysRecursive(keys, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
const equals = (e1, e2) => {
|
const equals = (e1: Key, e2: Key): boolean => {
|
||||||
return e1.key === e2.key &&
|
return e1.key === e2.key &&
|
||||||
e1.ctrlKey === e2.ctrlKey &&
|
e1.ctrlKey === e2.ctrlKey &&
|
||||||
e1.metaKey === e2.metaKey &&
|
e1.metaKey === e2.metaKey &&
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const fromWildcard = (pattern) => {
|
const fromWildcard = (pattern: string): RegExp => {
|
||||||
let regexStr = '^' + pattern.replace(/\*/g, '.*') + '$';
|
let regexStr = '^' + pattern.replace(/\*/g, '.*') + '$';
|
||||||
return new RegExp(regexStr);
|
return new RegExp(regexStr);
|
||||||
};
|
};
|
||||||
|
|
Reference in a new issue