forked from darkreader/darkreader
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.ts
More file actions
124 lines (106 loc) · 3.9 KB
/
Copy pathutils.ts
File metadata and controls
124 lines (106 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import {isFirefox} from '../utils/platform';
export function classes(...args: (string | {[cls: string]: boolean})[]) {
const classes = [];
args.filter((c) => Boolean(c)).forEach((c) => {
if (typeof c === 'string') {
classes.push(c);
} else if (typeof c === 'object') {
classes.push(...Object.keys(c).filter((key) => Boolean(c[key])));
}
});
return classes.join(' ');
}
export function compose<T extends Malevic.Component>(type: T, ...wrappers: ((t: T) => T)[]) {
return wrappers.reduce((t, w) => w(t), type);
}
export function openFile(options: {extensions: string[]}, callback: (content: string) => void) {
const input = document.createElement('input');
input.type = 'file';
input.style.display = 'none';
if (options.extensions && options.extensions.length > 0) {
input.accept = options.extensions.map((ext) => `.${ext}`).join(',');
}
const reader = new FileReader();
reader.onloadend = () => callback(reader.result as string);
input.onchange = () => {
if (input.files[0]) {
reader.readAsText(input.files[0]);
document.body.removeChild(input);
}
};
document.body.appendChild(input);
input.click();
}
export function saveFile(name: string, content: string) {
if (isFirefox()) {
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([content]));
a.download = name;
a.click();
} else {
chrome.runtime.sendMessage({type: 'save-file', data: {name, content}});
}
}
type AnyVoidFunction = (...args: any[]) => void;
export function throttle<F extends AnyVoidFunction>(callback: F): F {
let frameId = null;
return ((...args: any[]) => {
if (!frameId) {
callback(...args);
frameId = requestAnimationFrame(() => (frameId = null));
}
}) as F;
}
interface SwipeEventObject {
clientX: number;
clientY: number;
}
type SwipeEventHandler<T = void> = (e: SwipeEventObject, nativeEvent: MouseEvent | TouchEvent) => T;
type StartSwipeHandler = SwipeEventHandler<{move: SwipeEventHandler; up: SwipeEventHandler}>;
function onSwipeStart(
startEventObj: MouseEvent | TouchEvent,
startHandler: StartSwipeHandler,
) {
const isTouchEvent =
typeof TouchEvent !== 'undefined' &&
startEventObj instanceof TouchEvent;
const touchId = isTouchEvent
? (startEventObj as TouchEvent).changedTouches[0].identifier
: null;
const pointerMoveEvent = isTouchEvent ? 'touchmove' : 'mousemove';
const pointerUpEvent = isTouchEvent ? 'touchend' : 'mouseup';
if (!isTouchEvent) {
startEventObj.preventDefault();
}
function getSwipeEventObject(e: MouseEvent | TouchEvent) {
const {clientX, clientY} = isTouchEvent
? getTouch(e as TouchEvent)
: e as MouseEvent;
return {clientX, clientY};
}
const startSE = getSwipeEventObject(startEventObj);
const {move: moveHandler, up: upHandler} = startHandler(startSE, startEventObj);
function getTouch(e: TouchEvent) {
return Array.from(e.changedTouches).find(
({identifier: id}) => id === touchId,
);
}
const onPointerMove = throttle((e) => {
const se = getSwipeEventObject(e);
moveHandler(se, e);
});
function onPointerUp(e) {
unsubscribe();
const se = getSwipeEventObject(e);
upHandler(se, e);
}
function unsubscribe() {
window.removeEventListener(pointerMoveEvent, onPointerMove);
window.removeEventListener(pointerUpEvent, onPointerUp);
}
window.addEventListener(pointerMoveEvent, onPointerMove, {passive: true});
window.addEventListener(pointerUpEvent, onPointerUp, {passive: true});
}
export function createSwipeHandler(startHandler: StartSwipeHandler) {
return (e: MouseEvent | TouchEvent) => onSwipeStart(e, startHandler);
}