aboutsummaryrefslogtreecommitdiff
path: root/src/Utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/Utils.ts')
-rw-r--r--src/Utils.ts348
1 files changed, 203 insertions, 145 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 6699aa133..528a429d0 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -1,5 +1,5 @@
import v4 = require('uuid/v4');
-import v5 = require("uuid/v5");
+import v5 = require('uuid/v5');
import { ColorState } from 'react-color';
import { Socket } from 'socket.io';
import { Colors } from './client/views/global/globalEnums';
@@ -16,7 +16,7 @@ export namespace Utils {
return new Promise((resolve, reject) => {
temporaryFileReader.onerror = () => {
temporaryFileReader.abort();
- reject(new DOMException("Problem parsing input file."));
+ reject(new DOMException('Problem parsing input file.'));
};
temporaryFileReader.onload = () => {
@@ -34,7 +34,7 @@ export namespace Utils {
return v5(seed, v5.URL);
}
- export function GetScreenTransform(ele?: HTMLElement): { scale: number, translateX: number, translateY: number } {
+ export function GetScreenTransform(ele?: HTMLElement): { scale: number; translateX: number; translateY: number } {
if (!ele) {
return { scale: 1, translateX: 1, translateY: 1 };
}
@@ -50,12 +50,12 @@ export namespace Utils {
['log', 'warn'].forEach(function (method) {
const old = (console as any)[method];
(console as any)[method] = function () {
- let stack = new Error("").stack?.split(/\n/);
+ let stack = new Error('').stack?.split(/\n/);
// Chrome includes a single "Error" line, FF doesn't.
if (stack && stack[0].indexOf('Error') === 0) {
stack = stack.slice(1);
}
- const message = (stack?.[1] || "Stack undefined!").trim();
+ const message = (stack?.[1] || 'Stack undefined!').trim();
const args = ([] as any[]).slice.apply(arguments).concat([message]);
return old.apply(console, args);
};
@@ -79,7 +79,7 @@ export namespace Utils {
}
export function CorsProxy(url: string): string {
- return prepend("/corsProxy/") + encodeURIComponent(url);
+ return prepend('/corsProxy/') + encodeURIComponent(url);
}
export function CopyText(text: string) {
@@ -88,14 +88,13 @@ export namespace Utils {
export function decimalToHexString(number: number) {
if (number < 0) {
- number = 0xFFFFFFFF + number + 1;
+ number = 0xffffffff + number + 1;
}
- return (number < 16 ? "0" : "") + number.toString(16).toUpperCase();
+ return (number < 16 ? '0' : '') + number.toString(16).toUpperCase();
}
export function colorString(color: ColorState) {
- return color.hex.startsWith("#") ?
- color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : "ff") : color.hex;
+ return color.hex.startsWith('#') ? color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : 'ff') : color.hex;
}
export function fromRGBAstr(rgba: string) {
@@ -110,8 +109,8 @@ export namespace Utils {
return { r: r, g: g, b: b, a: a };
}
- const isTransparentFunctionHack = "isTransparent(__value__)";
- export const noRecursionHack = "__noRecursion";
+ const isTransparentFunctionHack = 'isTransparent(__value__)';
+ export const noRecursionHack = '__noRecursion';
export function IsRecursiveFilter(val: string) {
return !val.includes(noRecursionHack);
}
@@ -120,18 +119,18 @@ export namespace Utils {
}
export function IsTransparentFilter() {
// bcz: isTransparent(__value__) is a hack. it would be nice to have acual functions be parsed, but now Doc.matchFieldValue is hardwired to recognize just this one
- return `backgroundColor:${isTransparentFunctionHack},${noRecursionHack}:check`;// bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
+ return `backgroundColor:${isTransparentFunctionHack},${noRecursionHack}:check`; // bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
}
export function IsOpaqueFilter() {
// bcz: isTransparent(__value__) is a hack. it would be nice to have acual functions be parsed, but now Doc.matchFieldValue is hardwired to recognize just this one
- return `backgroundColor:${isTransparentFunctionHack},${noRecursionHack}:x`;// bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
+ return `backgroundColor:${isTransparentFunctionHack},${noRecursionHack}:x`; // bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
}
export function PropUnsetFilter(prop: string) {
return `${prop}:any,${noRecursionHack}:unset`;
}
- export function toRGBAstr(col: { r: number, g: number, b: number, a?: number }) {
- return "rgba(" + col.r + "," + col.g + "," + col.b + (col.a !== undefined ? "," + col.a : "") + ")";
+ export function toRGBAstr(col: { r: number; g: number; b: number; a?: number }) {
+ return 'rgba(' + col.r + ',' + col.g + ',' + col.b + (col.a !== undefined ? ',' + col.a : '') + ')';
}
export function HSLtoRGB(h: number, s: number, l: number) {
@@ -140,23 +139,35 @@ export namespace Utils {
// l /= 100;
const c = (1 - Math.abs(2 * l - 1)) * s,
- x = c * (1 - Math.abs((h / 60) % 2 - 1)),
+ x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
m = l - c / 2;
let r = 0,
g = 0,
b = 0;
if (0 <= h && h < 60) {
- r = c; g = x; b = 0;
+ r = c;
+ g = x;
+ b = 0;
} else if (60 <= h && h < 120) {
- r = x; g = c; b = 0;
+ r = x;
+ g = c;
+ b = 0;
} else if (120 <= h && h < 180) {
- r = 0; g = c; b = x;
+ r = 0;
+ g = c;
+ b = x;
} else if (180 <= h && h < 240) {
- r = 0; g = x; b = c;
+ r = 0;
+ g = x;
+ b = c;
} else if (240 <= h && h < 300) {
- r = x; g = 0; b = c;
+ r = x;
+ g = 0;
+ b = c;
} else if (300 <= h && h < 360) {
- r = c; g = 0; b = x;
+ r = c;
+ g = 0;
+ b = x;
}
r = Math.round((r + m) * 255);
g = Math.round((g + m) * 255);
@@ -221,18 +232,17 @@ export namespace Utils {
export function distanceBetweenHorizontalLines(xs: number, xe: number, y: number, xs2: number, xe2: number, y2: number): [number, number[]] {
if ((xs2 <= xs && xe2 >= xs) || (xs2 <= xe && xe2 >= xe) || (xs2 >= xs && xe2 <= xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
if (xe2 <= xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
- //if (xs2 > xe)
+ //if (xs2 > xe)
return [Math.sqrt((xs2 - xe) * (xs2 - xe) + (y2 - y) * (y2 - y)), [xe, y, xe, y]];
}
export function distanceBetweenVerticalLines(x: number, ys: number, ye: number, x2: number, ys2: number, ye2: number): [number, number[]] {
if ((ys2 <= ys && ye2 >= ys) || (ys2 <= ye && ye2 >= ye) || (ys2 >= ys && ye2 <= ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
if (ye2 <= ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
- //if (ys2 > ye)
+ //if (ys2 > ye)
return [Math.sqrt((ys2 - ye) * (ys2 - ye) + (x2 - x) * (x2 - x)), [x, ye, x, ye]];
}
function project(px: number, py: number, ax: number, ay: number, bx: number, by: number) {
-
if (ax === bx && ay === by) return { point: { x: ax, y: ay }, left: false, dot: 0, t: 0 };
const atob = { x: bx - ax, y: by - ay };
const atop = { x: px - ax, y: py - ay };
@@ -245,30 +255,41 @@ export namespace Utils {
return {
point: {
x: ax + atob.x * t,
- y: ay + atob.y * t
+ y: ay + atob.y * t,
},
left: dot < 1,
dot: dot,
- t: t
+ t: t,
};
}
- export function closestPtBetweenRectangles(l: number, t: number, w: number, h: number,
- l1: number, t1: number, w1: number, h1: number,
- x: number, y: number) {
+ export function closestPtBetweenRectangles(l: number, t: number, w: number, h: number, l1: number, t1: number, w1: number, h1: number, x: number, y: number) {
const r = l + w,
b = t + h;
const r1 = l1 + w1,
b1 = t1 + h1;
- const hsegs = [[l, r, t, l1, r1, t1], [l, r, b, l1, r1, t1], [l, r, t, l1, r1, b1], [l, r, b, l1, r1, b1]];
- const vsegs = [[l, t, b, l1, t1, b1], [r, t, b, l1, t1, b1], [l, t, b, r1, t1, b1], [r, t, b, r1, t1, b1]];
- const res = hsegs.reduce((closest, seg) => {
- const res = distanceBetweenHorizontalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
- return (res[0] < closest[0]) ? res : closest;
- }, [Number.MAX_VALUE, []] as [number, number[]]);
+ const hsegs = [
+ [l, r, t, l1, r1, t1],
+ [l, r, b, l1, r1, t1],
+ [l, r, t, l1, r1, b1],
+ [l, r, b, l1, r1, b1],
+ ];
+ const vsegs = [
+ [l, t, b, l1, t1, b1],
+ [r, t, b, l1, t1, b1],
+ [l, t, b, r1, t1, b1],
+ [r, t, b, r1, t1, b1],
+ ];
+ const res = hsegs.reduce(
+ (closest, seg) => {
+ const res = distanceBetweenHorizontalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
+ return res[0] < closest[0] ? res : closest;
+ },
+ [Number.MAX_VALUE, []] as [number, number[]]
+ );
const fres = vsegs.reduce((closest, seg) => {
const res = distanceBetweenVerticalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
- return (res[0] < closest[0]) ? res : closest;
+ return res[0] < closest[0] ? res : closest;
}, res);
const near = project(x, y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
@@ -279,8 +300,7 @@ export namespace Utils {
const r = l + w,
b = t + h;
- x = clamp(x, l, r),
- y = clamp(y, t, b);
+ (x = clamp(x, l, r)), (y = clamp(y, t, b));
const dl = Math.abs(x - l),
dr = Math.abs(x - r),
@@ -289,18 +309,18 @@ export namespace Utils {
const m = Math.min(dl, dr, dt, db);
- return (m === dt) ? [x, t] :
- (m === db) ? [x, b] :
- (m === dl) ? [l, y] : [r, y];
+ return m === dt ? [x, t] : m === db ? [x, b] : m === dl ? [l, y] : [r, y];
}
export function GetClipboardText(): string {
- const textArea = document.createElement("textarea");
+ const textArea = document.createElement('textarea');
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
- try { document.execCommand('paste'); } catch (err) { }
+ try {
+ document.execCommand('paste');
+ } catch (err) {}
const val = textArea.value;
document.body.removeChild(textArea);
@@ -318,7 +338,7 @@ export namespace Utils {
if (logFilter !== undefined && logFilter !== message.type) {
return;
}
- const idString = (message.id || "").padStart(36, ' ');
+ const idString = (message.id || '').padStart(36, ' ');
prefix = prefix.padEnd(16, ' ');
console.log(`${prefix}: ${idString}, ${receiving ? 'receiving' : 'sending'} ${messageName} with data ${JSON.stringify(message)} `);
}
@@ -331,14 +351,14 @@ export namespace Utils {
}
export function Emit<T>(socket: Socket | SocketIOClient.Socket, message: Message<T>, args: T) {
- log("Emit", message.Name, args, false);
+ log('Emit', message.Name, args, false);
socket.emit(message.Message, args);
}
export function EmitCallback<T>(socket: Socket | SocketIOClient.Socket, message: Message<T>, args: T): Promise<any>;
export function EmitCallback<T>(socket: Socket | SocketIOClient.Socket, message: Message<T>, args: T, fn: (args: any) => any): void;
export function EmitCallback<T>(socket: Socket | SocketIOClient.Socket, message: Message<T>, args: T, fn?: (args: any) => any): void | Promise<any> {
- log("Emit", message.Name, args, false);
+ log('Emit', message.Name, args, false);
if (fn) {
socket.emit(message.Message, args, loggingCallback('Receiving', fn, message.Name));
} else {
@@ -358,30 +378,33 @@ export namespace Utils {
}
export type RoomHandler = (socket: Socket, room: string) => any;
export type UsedSockets = Socket | SocketIOClient.Socket;
- export type RoomMessage = "create or join" | "created" | "joined";
+ export type RoomMessage = 'create or join' | 'created' | 'joined';
export function AddRoomHandler(socket: Socket, message: RoomMessage, handler: RoomHandler) {
socket.on(message, room => handler(socket, room));
}
}
-export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any, extract: any } {
+export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any; extract: any } {
const omit: any = { ...obj };
const extract: any = {};
keys.forEach(key => {
extract[key] = omit[key];
delete omit[key];
});
- pattern && Array.from(Object.keys(omit)).filter(key => key.match(pattern)).forEach(key => {
- extract[key] = omit[key];
- delete omit[key];
- });
+ pattern &&
+ Array.from(Object.keys(omit))
+ .filter(key => key.match(pattern))
+ .forEach(key => {
+ extract[key] = omit[key];
+ delete omit[key];
+ });
addKeyFunc?.(omit);
return { omit, extract };
}
export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
const dup: any = {};
- keys.forEach(key => dup[key] = obj[key]);
+ keys.forEach(key => (dup[key] = obj[key]));
addKeyFunc && addKeyFunc(dup);
return dup;
}
@@ -402,31 +425,39 @@ export function timenow() {
export function incrementTitleCopy(title: string) {
const numstr = title.match(/.*(\{([0-9]*)\})+/);
- const copyNumStr = `{${1 + (numstr ? (+numstr[2]) : 0)}}`;
- return (numstr ? title.replace(numstr[1], "") : title) + copyNumStr;
+ const copyNumStr = `{${1 + (numstr ? +numstr[2] : 0)}}`;
+ return (numstr ? title.replace(numstr[1], '') : title) + copyNumStr;
}
export function formatTime(time: number) {
time = Math.round(time);
const hours = Math.floor(time / 60 / 60);
- const minutes = Math.floor(time / 60) - (hours * 60);
+ const minutes = Math.floor(time / 60) - hours * 60;
const seconds = time % 60;
- return (hours ? hours.toString() + ":" : "") + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0');
+ return (hours ? hours.toString() + ':' : '') + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0');
}
// x is furthest left, y is furthest top, r is furthest right, b is furthest bottom
-export function aggregateBounds(boundsList: { x: number, y: number, width?: number, height?: number }[], xpad: number, ypad: number) {
- const bounds = boundsList.map(b => ({ x: b.x, y: b.y, r: b.x + (b.width || 0), b: b.y + (b.height || 0) })).reduce((bounds, b) => ({
- x: Math.min(b.x, bounds.x), y: Math.min(b.y, bounds.y),
- r: Math.max(b.r, bounds.r), b: Math.max(b.b, bounds.b)
- }), { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE });
+export function aggregateBounds(boundsList: { x: number; y: number; width?: number; height?: number }[], xpad: number, ypad: number) {
+ const bounds = boundsList
+ .map(b => ({ x: b.x, y: b.y, r: b.x + (b.width || 0), b: b.y + (b.height || 0) }))
+ .reduce(
+ (bounds, b) => ({
+ x: Math.min(b.x, bounds.x),
+ y: Math.min(b.y, bounds.y),
+ r: Math.max(b.r, bounds.r),
+ b: Math.max(b.b, bounds.b),
+ }),
+ { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE }
+ );
return {
- x: bounds.x !== Number.MAX_VALUE ? bounds.x - xpad : bounds.x, y: bounds.y !== Number.MAX_VALUE ? bounds.y - ypad : bounds.y,
- r: bounds.r !== -Number.MAX_VALUE ? bounds.r + xpad : bounds.r, b: bounds.b !== -Number.MAX_VALUE ? bounds.b + ypad : bounds.b
+ x: bounds.x !== Number.MAX_VALUE ? bounds.x - xpad : bounds.x,
+ y: bounds.y !== Number.MAX_VALUE ? bounds.y - ypad : bounds.y,
+ r: bounds.r !== -Number.MAX_VALUE ? bounds.r + xpad : bounds.r,
+ b: bounds.b !== -Number.MAX_VALUE ? bounds.b + ypad : bounds.b,
};
}
-export function intersectRect(r1: { left: number, top: number, width: number, height: number },
- r2: { left: number, top: number, width: number, height: number }) {
+export function intersectRect(r1: { left: number; top: number; width: number; height: number }, r2: { left: number; top: number; width: number; height: number }) {
return !(r2.left > r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top);
}
@@ -434,36 +465,63 @@ export function percent2frac(percent: string) {
return Number(percent.substr(0, percent.length - 1)) / 100;
}
-export function numberRange(num: number) { return num > 0 && num < 1000 ? Array.from(Array(num)).map((v, i) => i) : []; }
+export function numberRange(num: number) {
+ return num > 0 && num < 1000 ? Array.from(Array(num)).map((v, i) => i) : [];
+}
-export function returnTransparent() { return "transparent"; }
+export function returnTransparent() {
+ return 'transparent';
+}
-export function returnTrue() { return true; }
+export function returnTrue() {
+ return true;
+}
-export function returnFalse() { return false; }
+export function returnFalse() {
+ return false;
+}
-export function returnAll() { return "all"; }
+export function returnAll() {
+ return 'all';
+}
-export function returnNone() { return "none"; }
+export function returnNone() {
+ return 'none';
+}
-export function returnVal(val1?: number, val2?: number) { return val1 !== undefined ? val1 : val2 !== undefined ? val2 : 0; }
+export function returnVal(val1?: number, val2?: number) {
+ return val1 !== undefined ? val1 : val2 !== undefined ? val2 : 0;
+}
-export function returnOne() { return 1; }
+export function returnOne() {
+ return 1;
+}
-export function returnZero() { return 0; }
+export function returnZero() {
+ return 0;
+}
-export function returnEmptyString() { return ""; }
+export function returnEmptyString() {
+ return '';
+}
-export function returnEmptyFilter() { return [] as string[]; }
+export function returnEmptyFilter() {
+ return [] as string[];
+}
-export function returnEmptyDoclist() { return [] as any[]; }
+export function returnEmptyDoclist() {
+ return [] as any[];
+}
export let emptyPath = [];
-export function emptyFunction() { return undefined; }
-
-export function unimplementedFunction() { throw new Error("This function is not implemented, but should be."); }
+export function emptyFunction() {
+ return undefined;
+}
+export function unimplementedFunction() {
+ throw new Error('This function is not implemented, but should be.');
+}
export type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
@@ -484,7 +542,6 @@ export function DeepCopy<K, V>(source: Map<K, V>, predicate?: Predicate<K, V>) {
}
export namespace JSONUtils {
-
export function tryParse(source: string) {
let results: any;
try {
@@ -494,7 +551,6 @@ export namespace JSONUtils {
}
return results;
}
-
}
const easeInOutQuad = (currentTime: number, start: number, change: number, duration: number) => {
@@ -509,52 +565,57 @@ const easeInOutQuad = (currentTime: number, start: number, change: number, durat
};
export function smoothScroll(duration: number, element: HTMLElement | HTMLElement[], to: number) {
- const elements = (element instanceof HTMLElement ? [element] : element);
+ const elements = element instanceof HTMLElement ? [element] : element;
const starts = elements.map(element => element.scrollTop);
const startDate = new Date().getTime();
const animateScroll = () => {
const currentDate = new Date().getTime();
const currentTime = currentDate - startDate;
- elements.map((element, i) => element.scrollTop = easeInOutQuad(currentTime, starts[i], to - starts[i], duration));
+ elements.map((element, i) => (element.scrollTop = easeInOutQuad(currentTime, starts[i], to - starts[i], duration)));
if (currentTime < duration) {
requestAnimationFrame(animateScroll);
} else {
- elements.forEach(element => element.scrollTop = to);
+ elements.forEach(element => (element.scrollTop = to));
}
};
animateScroll();
}
export function smoothScrollHorizontal(duration: number, element: HTMLElement | HTMLElement[], to: number) {
- const elements = (element instanceof HTMLElement ? [element] : element);
+ const elements = element instanceof HTMLElement ? [element] : element;
const starts = elements.map(element => element.scrollLeft);
const startDate = new Date().getTime();
const animateScroll = () => {
const currentDate = new Date().getTime();
const currentTime = currentDate - startDate;
- elements.map((element, i) => element.scrollLeft = easeInOutQuad(currentTime, starts[i], to - starts[i], duration));
+ elements.map((element, i) => (element.scrollLeft = easeInOutQuad(currentTime, starts[i], to - starts[i], duration)));
if (currentTime < duration) {
requestAnimationFrame(animateScroll);
} else {
- elements.forEach(element => element.scrollLeft = to);
+ elements.forEach(element => (element.scrollLeft = to));
}
};
animateScroll();
}
-export function addStyleSheet(styleType: string = "text/css") {
- const style = document.createElement("style");
+export function addStyleSheet(styleType: string = 'text/css') {
+ const style = document.createElement('style');
style.type = styleType;
const sheets = document.head.appendChild(style);
return (sheets as any).sheet;
}
-export function addStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = ".") {
- const propText = typeof css === "string" ? css : Object.keys(css).map(p => p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p])).join(";");
- return sheet.insertRule(selectorPrefix + selector + "{" + propText + "}", sheet.cssRules.length);
+export function addStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
+ const propText =
+ typeof css === 'string'
+ ? css
+ : Object.keys(css)
+ .map(p => p + ':' + (p === 'content' ? "'" + css[p] + "'" : css[p]))
+ .join(';');
+ return sheet.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length);
}
export function removeStyleSheetRule(sheet: any, rule: number) {
if (sheet.rules.length) {
@@ -573,33 +634,35 @@ export function clearStyleSheetRules(sheet: any) {
export function simulateMouseClick(element: Element | null | undefined, x: number, y: number, sx: number, sy: number, rightClick = true) {
if (!element) return;
- ["pointerdown", "pointerup"].map(event => element.dispatchEvent(
- new PointerEvent(event, {
+ ['pointerdown', 'pointerup'].map(event => {
+ const me = new PointerEvent(event, {
view: window,
bubbles: true,
cancelable: true,
button: 2,
- pointerType: "mouse",
+ pointerType: 'mouse',
clientX: x,
clientY: y,
screenX: sx,
screenY: sy,
- })));
+ });
+ (me as any).dash = true;
+ element.dispatchEvent(me);
+ });
if (rightClick) {
- const me =
- new MouseEvent("contextmenu", {
- view: window,
- bubbles: true,
- cancelable: true,
- button: 2,
- clientX: x,
- clientY: y,
- movementX: 0,
- movementY: 0,
- screenX: sx,
- screenY: sy,
- });
+ const me = new MouseEvent('contextmenu', {
+ view: window,
+ bubbles: true,
+ cancelable: true,
+ button: 2,
+ clientX: x,
+ clientY: y,
+ movementX: 0,
+ movementY: 0,
+ screenX: sx,
+ screenY: sy,
+ });
(me as any).dash = true;
element.dispatchEvent(me);
}
@@ -607,27 +670,25 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe
export function DashColor(color: string) {
try {
- return color ? Color(color.toLowerCase()) : Color("transparent");
+ return color ? Color(color.toLowerCase()) : Color('transparent');
} catch (e) {
- console.log("COLOR error:", e);
- return Color("red");
+ console.log('COLOR error:', e);
+ return Color('red');
}
}
export function lightOrDark(color: any) {
- if (color === "transparent") return "gray";
- if (color.startsWith?.("linear")) return "black";
- const nonAlphaColor = color.startsWith("#") ? (color as string).substring(0, 7) :
- color.startsWith("rgba") ? color.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : color;
+ if (color === 'transparent') return 'gray';
+ if (color.startsWith?.('linear')) return 'black';
+ const nonAlphaColor = color.startsWith('#') ? (color as string).substring(0, 7) : color.startsWith('rgba') ? color.replace(/,.[^,]*\)/, ')').replace('rgba', 'rgb') : color;
const col = DashColor(nonAlphaColor).rgb();
- const colsum = (col.red() + col.green() + col.blue());
+ const colsum = col.red() + col.green() + col.blue();
if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return Colors.DARK_GRAY;
else return Colors.WHITE;
}
-
export function getWordAtPoint(elem: any, x: number, y: number): string | undefined {
- if (elem.tagName === "INPUT") return "input";
+ if (elem.tagName === 'INPUT') return 'input';
if (elem.nodeType === elem.TEXT_NODE) {
const range = elem.ownerDocument.createRange();
range.selectNodeContents(elem);
@@ -637,12 +698,11 @@ export function getWordAtPoint(elem: any, x: number, y: number): string | undefi
range.setStart(elem, currentPos);
range.setEnd(elem, currentPos + 1);
const rangeRect = range.getBoundingClientRect();
- if (rangeRect.left <= x && rangeRect.right >= x &&
- rangeRect.top <= y && rangeRect.bottom >= y) {
- range.expand?.("word"); // doesn't exist in firefox
+ if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) {
+ range.expand?.('word'); // doesn't exist in firefox
const ret = range.toString();
range.detach();
- return (ret);
+ return ret;
}
currentPos += 1;
}
@@ -651,8 +711,7 @@ export function getWordAtPoint(elem: any, x: number, y: number): string | undefi
const range = childNode.ownerDocument.createRange();
range.selectNodeContents(childNode);
const rangeRect = range.getBoundingClientRect();
- if (rangeRect.left <= x && rangeRect.right >= x &&
- rangeRect.top <= y && rangeRect.bottom >= y) {
+ if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) {
range.detach();
const word = getWordAtPoint(childNode, x, y);
if (word) return word;
@@ -681,17 +740,17 @@ export function StopEvent(e: React.PointerEvent | React.MouseEvent) {
* Helper method for converting pixel string eg. '32px' into number eg. 32
* @param value: string with 'px' ending
* @returns value: number
- *
+ *
* Example:
* '32px' -> 32
*/
-export function numberValue(value: string | undefined):number {
+export function numberValue(value: string | undefined): number {
if (value == undefined) return 0;
return parseInt(value);
}
export function numbersAlmostEqual(num1: number, num2: number) {
- return Math.abs( num1 - num2 ) < 0.2;
+ return Math.abs(num1 - num2) < 0.2;
}
export function setupMoveUpEvents(
@@ -705,7 +764,7 @@ export function setupMoveUpEvents(
noDoubleTapTimeout?: () => void
) {
const doubleTapTimeout = 300;
- (target as any)._doubleTap = (Date.now() - (target as any)._lastTap < doubleTapTimeout);
+ (target as any)._doubleTap = Date.now() - (target as any)._lastTap < doubleTapTimeout;
(target as any)._lastTap = Date.now();
(target as any)._downX = (target as any)._lastX = e.clientX;
(target as any)._downY = (target as any)._lastY = e.clientY;
@@ -717,10 +776,9 @@ export function setupMoveUpEvents(
clearTimeout((target as any)._doubleTime);
(target as any)._doubleTime = undefined;
}
- if (moveEvent(e, [(target as any)._downX, (target as any)._downY],
- [e.clientX - (target as any)._lastX, e.clientY - (target as any)._lastY])) {
- document.removeEventListener("pointermove", _moveEvent);
- document.removeEventListener("pointerup", _upEvent);
+ if (moveEvent(e, [(target as any)._downX, (target as any)._downY], [e.clientX - (target as any)._lastX, e.clientY - (target as any)._lastY])) {
+ document.removeEventListener('pointermove', _moveEvent);
+ document.removeEventListener('pointerup', _upEvent);
}
}
(target as any)._lastX = e.clientX;
@@ -743,18 +801,18 @@ export function setupMoveUpEvents(
}
(target as any)._noClick = clickEvent(e, (target as any)._doubleTap);
}
- document.removeEventListener("pointermove", _moveEvent);
- document.removeEventListener("pointerup", _upEvent);
+ document.removeEventListener('pointermove', _moveEvent);
+ document.removeEventListener('pointerup', _upEvent);
};
const _clickEvent = (e: MouseEvent): void => {
if ((target as any)._noClick) e.stopPropagation();
- document.removeEventListener("click", _clickEvent, true);
- }
+ document.removeEventListener('click', _clickEvent, true);
+ };
if (stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
- document.addEventListener("pointermove", _moveEvent);
- document.addEventListener("pointerup", _upEvent);
- document.addEventListener("click", _clickEvent, true);
-} \ No newline at end of file
+ document.addEventListener('pointermove', _moveEvent);
+ document.addEventListener('pointerup', _upEvent);
+ document.addEventListener('click', _clickEvent, true);
+}