From b8a64d4300115eeea76218cbfa301eb98fa69bb5 Mon Sep 17 00:00:00 2001 From: jlsnow301 Date: Sat, 29 Jun 2024 17:00:03 -0700 Subject: [PATCH] dir fix? --- .eslintignore | 3 - dist/{ => common}/assets.d.ts | 2 +- dist/{ => common}/assets.js | 0 dist/{ => common}/constants.d.ts | 0 dist/{ => common}/constants.js | 0 dist/common/events.d.ts | 23 +++ dist/common/events.js | 157 +++++++++++++++--- dist/{ => common}/format.d.ts | 0 dist/{ => common}/format.js | 0 dist/{ => common}/hotkeys.d.ts | 0 dist/{ => common}/hotkeys.js | 2 +- dist/{ => common}/http.d.ts | 0 dist/{ => common}/http.js | 0 dist/common/keys.d.ts | 2 +- dist/components/BodyZoneSelector.js | 2 +- dist/components/Box.js | 8 +- dist/components/ByondUi.js | 8 +- dist/components/DmIcon.js | 4 +- dist/components/KeyListener.d.ts | 2 +- dist/components/KeyListener.js | 2 +- dist/components/ProgressBar.js | 12 +- dist/components/Section.js | 10 +- dist/components/TimeDisplay.js | 2 +- dist/events.d.ts | 25 --- dist/events.js | 128 --------------- lib/{ => common}/assets.ts | 2 +- lib/{ => common}/constants.ts | 0 lib/common/events.ts | 223 ++++++++++++++++++++++++++ lib/{ => common}/format.ts | 0 lib/{ => common}/hotkeys.ts | 2 +- lib/{ => common}/http.ts | 0 lib/common/keys.ts | 2 +- lib/components/BodyZoneSelector.tsx | 4 +- lib/components/Box.tsx | 2 +- lib/components/ByondUi.jsx | 4 +- lib/components/DmIcon.tsx | 4 +- lib/components/Dropdown.tsx | 2 +- lib/components/KeyListener.tsx | 4 +- lib/components/ProgressBar.tsx | 2 +- lib/components/Section.tsx | 2 +- lib/components/TimeDisplay.jsx | 2 +- lib/events.ts | 237 ---------------------------- package.json | 6 +- 43 files changed, 427 insertions(+), 463 deletions(-) delete mode 100644 .eslintignore rename dist/{ => common}/assets.d.ts (71%) rename dist/{ => common}/assets.js (100%) rename dist/{ => common}/constants.d.ts (100%) rename dist/{ => common}/constants.js (100%) rename dist/{ => common}/format.d.ts (100%) rename dist/{ => common}/format.js (100%) rename dist/{ => common}/hotkeys.d.ts (100%) rename dist/{ => common}/hotkeys.js (97%) rename dist/{ => common}/http.d.ts (100%) rename dist/{ => common}/http.js (100%) delete mode 100644 dist/events.d.ts delete mode 100644 dist/events.js rename lib/{ => common}/assets.ts (93%) rename lib/{ => common}/constants.ts (100%) rename lib/{ => common}/format.ts (100%) rename lib/{ => common}/hotkeys.ts (99%) rename lib/{ => common}/http.ts (100%) delete mode 100644 lib/events.ts diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index c4cbfff..0000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -dist -node_modules -pnpm-lock.yaml diff --git a/dist/assets.d.ts b/dist/common/assets.d.ts similarity index 71% rename from dist/assets.d.ts rename to dist/common/assets.d.ts index 22f8e72..83bb7d3 100644 --- a/dist/assets.d.ts +++ b/dist/common/assets.d.ts @@ -1,4 +1,4 @@ -import { Middleware } from './common/redux'; +import { Middleware } from './redux'; export declare const resolveAsset: (name: string) => string; export declare const assetMiddleware: Middleware; diff --git a/dist/assets.js b/dist/common/assets.js similarity index 100% rename from dist/assets.js rename to dist/common/assets.js diff --git a/dist/constants.d.ts b/dist/common/constants.d.ts similarity index 100% rename from dist/constants.d.ts rename to dist/common/constants.d.ts diff --git a/dist/constants.js b/dist/common/constants.js similarity index 100% rename from dist/constants.js rename to dist/common/constants.js diff --git a/dist/common/events.d.ts b/dist/common/events.d.ts index 16000d3..3f62225 100644 --- a/dist/common/events.d.ts +++ b/dist/common/events.d.ts @@ -7,4 +7,27 @@ export declare class EventEmitter { emit(name: string, ...params: any[]): void; clear(): void; } +export declare const globalEvents: EventEmitter; +export declare const setupGlobalEvents: (options?: { + ignoreWindowFocus?: boolean; +}) => void; +export declare function canStealFocus(node: HTMLElement): boolean; +export declare function addScrollableNode(node: HTMLElement): void; +export declare function removeScrollableNode(node: HTMLElement): void; +export declare class KeyEvent { + event: KeyboardEvent; + type: 'keydown' | 'keyup'; + code: number; + ctrl: boolean; + shift: boolean; + alt: boolean; + repeat: boolean; + _str?: string; + constructor(e: KeyboardEvent, type: 'keydown' | 'keyup', repeat?: boolean); + hasModifierKeys(): boolean; + isModifierKey(): boolean; + isDown(): boolean; + isUp(): boolean; + toString(): string; +} export {}; diff --git a/dist/common/events.js b/dist/common/events.js index 48d162a..a7f41a8 100644 --- a/dist/common/events.js +++ b/dist/common/events.js @@ -1,32 +1,147 @@ -var h = Object.defineProperty; -var c = (e, s, t) => s in e ? h(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t; -var n = (e, s, t) => c(e, typeof s != "symbol" ? s + "" : s, t); -class u { +var _ = Object.defineProperty; +var v = (t, e, s) => e in t ? _(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s; +var i = (t, e, s) => v(t, typeof e != "symbol" ? e + "" : e, s); +import { KEY_CTRL as F, KEY_SHIFT as L, KEY_ALT as b, KEY_F1 as K, KEY_F12 as S } from "./keycodes.js"; +class C { constructor() { - n(this, "listeners"); + i(this, "listeners"); this.listeners = {}; } - on(s, t) { - this.listeners[s] = this.listeners[s] || [], this.listeners[s].push(t); - } - off(s, t) { - const r = this.listeners[s]; - if (!r) - throw new Error(`There is no listeners for "${s}"`); - this.listeners[s] = r.filter((i) => i !== t); - } - emit(s, ...t) { - const r = this.listeners[s]; - if (r) - for (let i = 0, l = r.length; i < l; i += 1) { - const o = r[i]; - o(...t); + on(e, s) { + this.listeners[e] = this.listeners[e] || [], this.listeners[e].push(s); + } + off(e, s) { + const n = this.listeners[e]; + if (!n) + throw new Error(`There is no listeners for "${e}"`); + this.listeners[e] = n.filter((l) => l !== s); + } + emit(e, ...s) { + const n = this.listeners[e]; + if (n) + for (let l = 0, k = n.length; l < k; l += 1) { + const g = n[l]; + g(...s); } } clear() { this.listeners = {}; } } +const o = new C(); +let m = !1; +const W = (t = {}) => { + m = !!t.ignoreWindowFocus; +}; +let d, f = !0; +function u(t, e) { + if (m) { + f = !0; + return; + } + if (d && (clearTimeout(d), d = null), e) { + d = setTimeout(() => u(t)); + return; + } + f !== t && (f = t, o.emit(t ? "window-focus" : "window-blur"), o.emit("window-focus-change", t)); +} +let r = null; +function E(t) { + const e = String(t.tagName).toLowerCase(); + return e === "input" || e === "textarea"; +} +function T(t) { + a(), r = t, r.addEventListener("blur", a); +} +function a() { + r && (r.removeEventListener("blur", a), r = null); +} +let w = null, c = null; +const h = []; +function A(t) { + h.push(t); +} +function B(t) { + const e = h.indexOf(t); + e >= 0 && h.splice(e, 1); +} +function N(t) { + if (r || !f) + return; + const e = document.body; + for (; t && t !== e; ) { + if (h.includes(t)) { + if (t.contains(w)) + return; + w = t, t.focus(); + return; + } + t = t.parentElement; + } +} +window.addEventListener("mousemove", (t) => { + const e = t.target; + e !== c && (c = e, N(e)); +}); +window.addEventListener("focusin", (t) => { + c = null, w = t.target, u(!0), E(t.target) && T(t.target); +}); +window.addEventListener("focusout", () => { + c = null, u(!1, !0); +}); +window.addEventListener("blur", () => { + c = null, u(!1, !0); +}); +window.addEventListener("beforeunload", () => { + u(!1); +}); +const y = {}; +class p { + constructor(e, s, n) { + i(this, "event"); + i(this, "type"); + i(this, "code"); + i(this, "ctrl"); + i(this, "shift"); + i(this, "alt"); + i(this, "repeat"); + i(this, "_str"); + this.event = e, this.type = s, this.code = e.keyCode, this.ctrl = e.ctrlKey, this.shift = e.shiftKey, this.alt = e.altKey, this.repeat = !!n; + } + hasModifierKeys() { + return this.ctrl || this.alt || this.shift; + } + isModifierKey() { + return this.code === F || this.code === L || this.code === b; + } + isDown() { + return this.type === "keydown"; + } + isUp() { + return this.type === "keyup"; + } + toString() { + return this._str ? this._str : (this._str = "", this.ctrl && (this._str += "Ctrl+"), this.alt && (this._str += "Alt+"), this.shift && (this._str += "Shift+"), this.code >= 48 && this.code <= 90 ? this._str += String.fromCharCode(this.code) : this.code >= K && this.code <= S ? this._str += "F" + (this.code - 111) : this._str += "[" + this.code + "]", this._str); + } +} +document.addEventListener("keydown", (t) => { + if (E(t.target)) + return; + const e = t.keyCode, s = new p(t, "keydown", y[e]); + o.emit("keydown", s), o.emit("key", s), y[e] = !0; +}); +document.addEventListener("keyup", (t) => { + if (E(t.target)) + return; + const e = t.keyCode, s = new p(t, "keyup"); + o.emit("keyup", s), o.emit("key", s), y[e] = !1; +}); export { - u as EventEmitter + C as EventEmitter, + p as KeyEvent, + A as addScrollableNode, + E as canStealFocus, + o as globalEvents, + B as removeScrollableNode, + W as setupGlobalEvents }; diff --git a/dist/format.d.ts b/dist/common/format.d.ts similarity index 100% rename from dist/format.d.ts rename to dist/common/format.d.ts diff --git a/dist/format.js b/dist/common/format.js similarity index 100% rename from dist/format.js rename to dist/common/format.js diff --git a/dist/hotkeys.d.ts b/dist/common/hotkeys.d.ts similarity index 100% rename from dist/hotkeys.d.ts rename to dist/common/hotkeys.d.ts diff --git a/dist/hotkeys.js b/dist/common/hotkeys.js similarity index 97% rename from dist/hotkeys.js rename to dist/common/hotkeys.js index 6aa8dd8..a0680b8 100644 --- a/dist/hotkeys.js +++ b/dist/common/hotkeys.js @@ -1,5 +1,5 @@ -import { KEY_ESCAPE as K, KEY_ENTER as E, KEY_SPACE as p, KEY_TAB as h, KEY_CTRL as d, KEY_SHIFT as g, KEY_UP as S, KEY_DOWN as Y, KEY_LEFT as _, KEY_RIGHT as b, KEY_F5 as B } from "./common/keycodes.js"; import { globalEvents as l } from "./events.js"; +import { KEY_ESCAPE as K, KEY_ENTER as E, KEY_SPACE as p, KEY_TAB as h, KEY_CTRL as d, KEY_SHIFT as g, KEY_UP as S, KEY_DOWN as Y, KEY_LEFT as _, KEY_RIGHT as b, KEY_F5 as B } from "./keycodes.js"; const m = {}, c = [ K, E, diff --git a/dist/http.d.ts b/dist/common/http.d.ts similarity index 100% rename from dist/http.d.ts rename to dist/common/http.d.ts diff --git a/dist/http.js b/dist/common/http.js similarity index 100% rename from dist/http.js rename to dist/common/http.js diff --git a/dist/common/keys.d.ts b/dist/common/keys.d.ts index d4c175a..7f217d2 100644 --- a/dist/common/keys.d.ts +++ b/dist/common/keys.d.ts @@ -10,7 +10,7 @@ * @url https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values * @usage * ```ts - * import { KEY } from 'tgui/common/keys'; + * import { KEY } from 'tgui/keys'; * * if (event.key === KEY.Enter) { * // do something diff --git a/dist/components/BodyZoneSelector.js b/dist/components/BodyZoneSelector.js index 6a6c8f2..97d0001 100644 --- a/dist/components/BodyZoneSelector.js +++ b/dist/components/BodyZoneSelector.js @@ -3,7 +3,7 @@ var _ = (e, t, s) => t in e ? g(e, t, { enumerable: !0, configurable: !0, writab var l = (e, t, s) => _(e, typeof t != "symbol" ? t + "" : t, s); import { jsxs as d, jsx as h } from "react/jsx-runtime"; import { Component as v, createRef as $ } from "react"; -import { resolveAsset as p } from "../assets.js"; +import { resolveAsset as p } from "../common/assets.js"; import { Image as f } from "./Image.js"; var b = /* @__PURE__ */ ((e) => (e.Chest = "chest", e.Eyes = "eyes", e.Groin = "groin", e.Head = "head", e.LeftArm = "l_arm", e.LeftLeg = "l_leg", e.Mouth = "mouth", e.RightArm = "r_arm", e.RightLeg = "r_leg", e))(b || {}); const C = (e, t) => { diff --git a/dist/components/Box.js b/dist/components/Box.js index 0a4cf74..5921baa 100644 --- a/dist/components/Box.js +++ b/dist/components/Box.js @@ -1,6 +1,6 @@ import { createElement as y } from "react"; -import { classes as b } from "../common/react.js"; -import { CSS_COLORS as u } from "../constants.js"; +import { CSS_COLORS as b } from "../common/constants.js"; +import { classes as u } from "../common/react.js"; function p(o) { if (typeof o == "string") return o.endsWith("px") ? parseFloat(o) / 12 + "rem" : o; @@ -17,7 +17,7 @@ function x(o) { return !a(o); } function a(o) { - return typeof o == "string" && u.includes(o); + return typeof o == "string" && b.includes(o); } const m = (o) => (t, i) => { (typeof i == "number" || typeof i == "string") && (t[o] = i); @@ -108,7 +108,7 @@ function S(o) { } function d(o) { const t = o.textColor || o.color, i = o.backgroundColor; - return b([ + return u([ a(t) && "color-" + t, a(i) && "color-bg-" + i ]); diff --git a/dist/components/ByondUi.js b/dist/components/ByondUi.js index 0cb9cd8..1dba974 100644 --- a/dist/components/ByondUi.js +++ b/dist/components/ByondUi.js @@ -1,7 +1,7 @@ import { jsx as s } from "react/jsx-runtime"; +import { Component as a, createRef as c } from "react"; import { shallowDiffers as r } from "../common/react.js"; -import { debounce as a } from "../common/timer.js"; -import { Component as c, createRef as m } from "react"; +import { debounce as m } from "../common/timer.js"; import { computeBoxProps as l } from "./Box.js"; const o = []; function h(t) { @@ -37,10 +37,10 @@ function u(t) { ] }; } -class U extends c { +class U extends a { constructor(n) { var e; - super(n), this.containerRef = m(), this.byondUiElement = h((e = n.params) == null ? void 0 : e.id), this.handleResize = a(() => { + super(n), this.containerRef = c(), this.byondUiElement = h((e = n.params) == null ? void 0 : e.id), this.handleResize = m(() => { this.forceUpdate(); }, 100); } diff --git a/dist/components/DmIcon.js b/dist/components/DmIcon.js index 569a581..acdb9bb 100644 --- a/dist/components/DmIcon.js +++ b/dist/components/DmIcon.js @@ -1,7 +1,7 @@ import { jsx as $ } from "react/jsx-runtime"; import { useState as R, useEffect as d } from "react"; -import { resolveAsset as j } from "../assets.js"; -import { fetchRetry as v } from "../http.js"; +import { resolveAsset as j } from "../common/assets.js"; +import { fetchRetry as v } from "../common/http.js"; import { Image as x } from "./Image.js"; let e; function b(n) { diff --git a/dist/components/KeyListener.d.ts b/dist/components/KeyListener.d.ts index f44b8db..70ca240 100644 --- a/dist/components/KeyListener.d.ts +++ b/dist/components/KeyListener.d.ts @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { KeyEvent } from '../events'; +import { KeyEvent } from '../common/events'; type KeyListenerProps = Partial<{ onKey: (key: KeyEvent) => void; diff --git a/dist/components/KeyListener.js b/dist/components/KeyListener.js index 910acca..624a3e8 100644 --- a/dist/components/KeyListener.js +++ b/dist/components/KeyListener.js @@ -2,7 +2,7 @@ var t = Object.defineProperty; var e = (s, o, p) => o in s ? t(s, o, { enumerable: !0, configurable: !0, writable: !0, value: p }) : s[o] = p; var i = (s, o, p) => e(s, typeof o != "symbol" ? o + "" : o, p); import { Component as r } from "react"; -import { listenForKeyEvents as h } from "../hotkeys.js"; +import { listenForKeyEvents as h } from "../common/hotkeys.js"; class d extends r { constructor(p) { super(p); diff --git a/dist/components/ProgressBar.js b/dist/components/ProgressBar.js index 3fd52bd..a05665f 100644 --- a/dist/components/ProgressBar.js +++ b/dist/components/ProgressBar.js @@ -1,7 +1,7 @@ import { jsxs as g, jsx as n } from "react/jsx-runtime"; -import { keyOfMatchingRange as v, toFixed as y, scale as N, clamp01 as _ } from "../common/math.js"; +import { CSS_COLORS as v } from "../common/constants.js"; +import { keyOfMatchingRange as y, toFixed as N, scale as _, clamp01 as B } from "../common/math.js"; import { classes as m } from "../common/react.js"; -import { CSS_COLORS as B } from "../constants.js"; import { s as o } from "../ProgressBar.module-BkAFfFy0.js"; import { computeBoxProps as S, computeBoxClassName as O } from "./Box.js"; function w(d) { @@ -14,14 +14,14 @@ function w(d) { ranges: h = {}, children: l, ...t - } = d, a = N(r, u, p), x = l !== void 0, s = C || v(r, h) || "default", e = S(t), c = [ + } = d, a = _(r, u, p), x = l !== void 0, s = C || y(r, h) || "default", e = S(t), c = [ o.progressBar, f, O(t) ], i = { - width: _(a) * 100 + "%" + width: B(a) * 100 + "%" }; - return B.includes(s) || s === "default" ? c.push(o["color__" + s]) : (e.style = { ...e.style, borderColor: s }, i.backgroundColor = s), /* @__PURE__ */ g("div", { className: m(c), ...e, children: [ + return v.includes(s) || s === "default" ? c.push(o["color__" + s]) : (e.style = { ...e.style, borderColor: s }, i.backgroundColor = s), /* @__PURE__ */ g("div", { className: m(c), ...e, children: [ /* @__PURE__ */ n( "div", { @@ -29,7 +29,7 @@ function w(d) { style: i } ), - /* @__PURE__ */ n("div", { className: o.content, children: x ? l : y(a * 100) + "%" }) + /* @__PURE__ */ n("div", { className: o.content, children: x ? l : N(a * 100) + "%" }) ] }); } export { diff --git a/dist/components/Section.js b/dist/components/Section.js index 5884c5c..bb70734 100644 --- a/dist/components/Section.js +++ b/dist/components/Section.js @@ -1,7 +1,7 @@ import { jsxs as r, jsx as s } from "react/jsx-runtime"; import { forwardRef as S, useEffect as j } from "react"; -import { classes as z, canRender as m } from "../common/react.js"; -import { addScrollableNode as B, removeScrollableNode as H } from "../events.js"; +import { addScrollableNode as z, removeScrollableNode as B } from "../common/events.js"; +import { classes as H, canRender as m } from "../common/react.js"; import { s as t } from "../Section.module-CLVHJ4yA.js"; import { computeBoxClassName as T, computeBoxProps as y } from "./Box.js"; const q = S( @@ -21,14 +21,14 @@ const q = S( } = a, x = m(n) || m(c); return j(() => { if (l != null && l.current && !(!i && !e)) - return B(l.current), () => { - l != null && l.current && H(l.current); + return z(l.current), () => { + l != null && l.current && B(l.current); }; }, []), /* @__PURE__ */ r( "div", { id: v || "", - className: z([ + className: H([ t.section, N && t.fill, b && t.fitted, diff --git a/dist/components/TimeDisplay.js b/dist/components/TimeDisplay.js index a119bd9..af7447a 100644 --- a/dist/components/TimeDisplay.js +++ b/dist/components/TimeDisplay.js @@ -1,5 +1,5 @@ import { Component as r } from "react"; -import { formatTime as u } from "../format.js"; +import { formatTime as u } from "../common/format.js"; function s(e) { return typeof e == "number" && Number.isFinite(e) && !Number.isNaN(e); } diff --git a/dist/events.d.ts b/dist/events.d.ts deleted file mode 100644 index c5b22be..0000000 --- a/dist/events.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { EventEmitter } from './common/events'; - -export declare const globalEvents: EventEmitter; -export declare const setupGlobalEvents: (options?: { - ignoreWindowFocus?: boolean; -}) => void; -export declare function canStealFocus(node: HTMLElement): boolean; -export declare function addScrollableNode(node: HTMLElement): void; -export declare function removeScrollableNode(node: HTMLElement): void; -export declare class KeyEvent { - event: KeyboardEvent; - type: 'keydown' | 'keyup'; - code: number; - ctrl: boolean; - shift: boolean; - alt: boolean; - repeat: boolean; - _str?: string; - constructor(e: KeyboardEvent, type: 'keydown' | 'keyup', repeat?: boolean); - hasModifierKeys(): boolean; - isModifierKey(): boolean; - isDown(): boolean; - isUp(): boolean; - toString(): string; -} diff --git a/dist/events.js b/dist/events.js deleted file mode 100644 index efce1c0..0000000 --- a/dist/events.js +++ /dev/null @@ -1,128 +0,0 @@ -var p = Object.defineProperty; -var k = (t, e, i) => e in t ? p(t, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[e] = i; -var s = (t, e, i) => k(t, typeof e != "symbol" ? e + "" : e, i); -import { EventEmitter as _ } from "./common/events.js"; -import { KEY_CTRL as g, KEY_SHIFT as v, KEY_ALT as F, KEY_F1 as L, KEY_F12 as b } from "./common/keycodes.js"; -/** - * Normalized browser focus events and BYOND-specific focus helpers. - * - * @file - * @copyright 2020 Aleksej Komarov - * @license MIT - */ -const o = new _(); -let y = !1; -const Y = (t = {}) => { - y = !!t.ignoreWindowFocus; -}; -let d, u = !0; -function c(t, e) { - if (y) { - u = !0; - return; - } - if (d && (clearTimeout(d), d = null), e) { - d = setTimeout(() => c(t)); - return; - } - u !== t && (u = t, o.emit(t ? "window-focus" : "window-blur"), o.emit("window-focus-change", t)); -} -let n = null; -function w(t) { - const e = String(t.tagName).toLowerCase(); - return e === "input" || e === "textarea"; -} -function K(t) { - f(), n = t, n.addEventListener("blur", f); -} -function f() { - n && (n.removeEventListener("blur", f), n = null); -} -let a = null, r = null; -const l = []; -function x(t) { - l.push(t); -} -function W(t) { - const e = l.indexOf(t); - e >= 0 && l.splice(e, 1); -} -function S(t) { - if (n || !u) - return; - const e = document.body; - for (; t && t !== e; ) { - if (l.includes(t)) { - if (t.contains(a)) - return; - a = t, t.focus(); - return; - } - t = t.parentElement; - } -} -window.addEventListener("mousemove", (t) => { - const e = t.target; - e !== r && (r = e, S(e)); -}); -window.addEventListener("focusin", (t) => { - r = null, a = t.target, c(!0), w(t.target) && K(t.target); -}); -window.addEventListener("focusout", () => { - r = null, c(!1, !0); -}); -window.addEventListener("blur", () => { - r = null, c(!1, !0); -}); -window.addEventListener("beforeunload", () => { - c(!1); -}); -const h = {}; -class m { - constructor(e, i, E) { - s(this, "event"); - s(this, "type"); - s(this, "code"); - s(this, "ctrl"); - s(this, "shift"); - s(this, "alt"); - s(this, "repeat"); - s(this, "_str"); - this.event = e, this.type = i, this.code = e.keyCode, this.ctrl = e.ctrlKey, this.shift = e.shiftKey, this.alt = e.altKey, this.repeat = !!E; - } - hasModifierKeys() { - return this.ctrl || this.alt || this.shift; - } - isModifierKey() { - return this.code === g || this.code === v || this.code === F; - } - isDown() { - return this.type === "keydown"; - } - isUp() { - return this.type === "keyup"; - } - toString() { - return this._str ? this._str : (this._str = "", this.ctrl && (this._str += "Ctrl+"), this.alt && (this._str += "Alt+"), this.shift && (this._str += "Shift+"), this.code >= 48 && this.code <= 90 ? this._str += String.fromCharCode(this.code) : this.code >= L && this.code <= b ? this._str += "F" + (this.code - 111) : this._str += "[" + this.code + "]", this._str); - } -} -document.addEventListener("keydown", (t) => { - if (w(t.target)) - return; - const e = t.keyCode, i = new m(t, "keydown", h[e]); - o.emit("keydown", i), o.emit("key", i), h[e] = !0; -}); -document.addEventListener("keyup", (t) => { - if (w(t.target)) - return; - const e = t.keyCode, i = new m(t, "keyup"); - o.emit("keyup", i), o.emit("key", i), h[e] = !1; -}); -export { - m as KeyEvent, - x as addScrollableNode, - w as canStealFocus, - o as globalEvents, - W as removeScrollableNode, - Y as setupGlobalEvents -}; diff --git a/lib/assets.ts b/lib/common/assets.ts similarity index 93% rename from lib/assets.ts rename to lib/common/assets.ts index ace57ae..3a9610d 100644 --- a/lib/assets.ts +++ b/lib/common/assets.ts @@ -1,4 +1,4 @@ -import { Action, AnyAction, Dispatch, Middleware } from './common/redux'; +import { Action, AnyAction, Dispatch, Middleware } from './redux'; const EXCLUDED_PATTERNS = [/v4shim/i]; const loadedMappings: Record = {}; diff --git a/lib/constants.ts b/lib/common/constants.ts similarity index 100% rename from lib/constants.ts rename to lib/common/constants.ts diff --git a/lib/common/events.ts b/lib/common/events.ts index 277ba37..b22364c 100644 --- a/lib/common/events.ts +++ b/lib/common/events.ts @@ -1,3 +1,5 @@ +import { KEY_ALT, KEY_CTRL, KEY_F1, KEY_F12, KEY_SHIFT } from './keycodes'; + type Fn = (...args: any[]) => void; export class EventEmitter { @@ -37,3 +39,224 @@ export class EventEmitter { this.listeners = {}; } } + +export const globalEvents = new EventEmitter(); +let ignoreWindowFocus = false; + +export const setupGlobalEvents = ( + options: { ignoreWindowFocus?: boolean } = {}, +): void => { + ignoreWindowFocus = !!options.ignoreWindowFocus; +}; + +// Window focus +// -------------------------------------------------------- + +let windowFocusTimeout: ReturnType | null; +let windowFocused = true; + +// Pretend to always be in focus. +function setWindowFocus(value: boolean, delayed?: boolean) { + if (ignoreWindowFocus) { + windowFocused = true; + return; + } + if (windowFocusTimeout) { + clearTimeout(windowFocusTimeout); + windowFocusTimeout = null; + } + if (delayed) { + windowFocusTimeout = setTimeout(() => setWindowFocus(value)); + return; + } + if (windowFocused !== value) { + windowFocused = value; + globalEvents.emit(value ? 'window-focus' : 'window-blur'); + globalEvents.emit('window-focus-change', value); + } +} + +// Focus stealing +// -------------------------------------------------------- + +let focusStolenBy: HTMLElement | null = null; + +export function canStealFocus(node: HTMLElement) { + const tag = String(node.tagName).toLowerCase(); + return tag === 'input' || tag === 'textarea'; +} + +function stealFocus(node: HTMLElement) { + releaseStolenFocus(); + focusStolenBy = node; + focusStolenBy.addEventListener('blur', releaseStolenFocus); +} + +function releaseStolenFocus() { + if (focusStolenBy) { + focusStolenBy.removeEventListener('blur', releaseStolenFocus); + focusStolenBy = null; + } +} + +// Focus follows the mouse +// -------------------------------------------------------- + +let focusedNode: HTMLElement | null = null; +let lastVisitedNode: HTMLElement | null = null; +const trackedNodes: HTMLElement[] = []; + +export function addScrollableNode(node: HTMLElement) { + trackedNodes.push(node); +} + +export function removeScrollableNode(node: HTMLElement) { + const index = trackedNodes.indexOf(node); + if (index >= 0) { + trackedNodes.splice(index, 1); + } +} + +function focusNearestTrackedParent(node: HTMLElement | null) { + if (focusStolenBy || !windowFocused) { + return; + } + const body = document.body; + while (node && node !== body) { + if (trackedNodes.includes(node)) { + // NOTE: Contains is a DOM4 method + if (node.contains(focusedNode)) { + return; + } + focusedNode = node; + node.focus(); + return; + } + node = node.parentElement; + } +} + +window.addEventListener('mousemove', (e) => { + const node = e.target as HTMLElement; + if (node !== lastVisitedNode) { + lastVisitedNode = node; + focusNearestTrackedParent(node); + } +}); + +// Focus event hooks +// -------------------------------------------------------- + +window.addEventListener('focusin', (e) => { + lastVisitedNode = null; + focusedNode = e.target as HTMLElement; + setWindowFocus(true); + if (canStealFocus(e.target as HTMLElement)) { + stealFocus(e.target as HTMLElement); + } +}); + +window.addEventListener('focusout', () => { + lastVisitedNode = null; + setWindowFocus(false, true); +}); + +window.addEventListener('blur', () => { + lastVisitedNode = null; + setWindowFocus(false, true); +}); + +window.addEventListener('beforeunload', () => { + setWindowFocus(false); +}); + +// Key events +// -------------------------------------------------------- + +const keyHeldByCode: Record = {}; + +export class KeyEvent { + event: KeyboardEvent; + type: 'keydown' | 'keyup'; + code: number; + ctrl: boolean; + shift: boolean; + alt: boolean; + repeat: boolean; + _str?: string; + + constructor(e: KeyboardEvent, type: 'keydown' | 'keyup', repeat?: boolean) { + this.event = e; + this.type = type; + this.code = e.keyCode; + this.ctrl = e.ctrlKey; + this.shift = e.shiftKey; + this.alt = e.altKey; + this.repeat = !!repeat; + } + + hasModifierKeys() { + return this.ctrl || this.alt || this.shift; + } + + isModifierKey() { + return ( + this.code === KEY_CTRL || this.code === KEY_SHIFT || this.code === KEY_ALT + ); + } + + isDown() { + return this.type === 'keydown'; + } + + isUp() { + return this.type === 'keyup'; + } + + toString() { + if (this._str) { + return this._str; + } + this._str = ''; + if (this.ctrl) { + this._str += 'Ctrl+'; + } + if (this.alt) { + this._str += 'Alt+'; + } + if (this.shift) { + this._str += 'Shift+'; + } + if (this.code >= 48 && this.code <= 90) { + this._str += String.fromCharCode(this.code); + } else if (this.code >= KEY_F1 && this.code <= KEY_F12) { + this._str += 'F' + (this.code - 111); + } else { + this._str += '[' + this.code + ']'; + } + return this._str; + } +} + +// IE8: Keydown event is only available on document. +document.addEventListener('keydown', (e) => { + if (canStealFocus(e.target as HTMLElement)) { + return; + } + const code = e.keyCode; + const key = new KeyEvent(e, 'keydown', keyHeldByCode[code]); + globalEvents.emit('keydown', key); + globalEvents.emit('key', key); + keyHeldByCode[code] = true; +}); + +document.addEventListener('keyup', (e) => { + if (canStealFocus(e.target as HTMLElement)) { + return; + } + const code = e.keyCode; + const key = new KeyEvent(e, 'keyup'); + globalEvents.emit('keyup', key); + globalEvents.emit('key', key); + keyHeldByCode[code] = false; +}); diff --git a/lib/format.ts b/lib/common/format.ts similarity index 100% rename from lib/format.ts rename to lib/common/format.ts diff --git a/lib/hotkeys.ts b/lib/common/hotkeys.ts similarity index 99% rename from lib/hotkeys.ts rename to lib/common/hotkeys.ts index 8314d8c..02b8345 100644 --- a/lib/hotkeys.ts +++ b/lib/common/hotkeys.ts @@ -1,5 +1,5 @@ -import * as keycodes from './common/keycodes'; import { globalEvents, KeyEvent } from './events'; +import * as keycodes from './keycodes'; // BYOND macros, in `key: command` format. const byondMacros: Record = {}; diff --git a/lib/http.ts b/lib/common/http.ts similarity index 100% rename from lib/http.ts rename to lib/common/http.ts diff --git a/lib/common/keys.ts b/lib/common/keys.ts index 34ac9e1..0b8deb9 100644 --- a/lib/common/keys.ts +++ b/lib/common/keys.ts @@ -10,7 +10,7 @@ * @url https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values * @usage * ```ts - * import { KEY } from 'tgui/common/keys'; + * import { KEY } from 'tgui/keys'; * * if (event.key === KEY.Enter) { * // do something diff --git a/lib/components/BodyZoneSelector.tsx b/lib/components/BodyZoneSelector.tsx index c5199f6..d27db73 100644 --- a/lib/components/BodyZoneSelector.tsx +++ b/lib/components/BodyZoneSelector.tsx @@ -1,6 +1,6 @@ import { Component, createRef } from 'react'; -import { resolveAsset } from '../assets'; +import { resolveAsset } from '../common/assets'; import { Image } from './Image'; export enum BodyZone { @@ -12,7 +12,7 @@ export enum BodyZone { LeftLeg = 'l_leg', Mouth = 'mouth', RightArm = 'r_arm', - RightLeg = 'r_leg' + RightLeg = 'r_leg', } const bodyZonePixelToZone = (x: number, y: number): BodyZone | null => { diff --git a/lib/components/Box.tsx b/lib/components/Box.tsx index 614db2c..4e3c61f 100644 --- a/lib/components/Box.tsx +++ b/lib/components/Box.tsx @@ -6,8 +6,8 @@ import { UIEventHandler, } from 'react'; +import { CSS_COLORS } from '../common/constants'; import { BooleanLike, classes } from '../common/react'; -import { CSS_COLORS } from '../constants'; type BooleanProps = Partial>; type StringProps = Partial< diff --git a/lib/components/ByondUi.jsx b/lib/components/ByondUi.jsx index 5c98ffb..7c73729 100644 --- a/lib/components/ByondUi.jsx +++ b/lib/components/ByondUi.jsx @@ -1,7 +1,7 @@ -import { shallowDiffers } from '../common/react'; -import { debounce } from '../common/timer'; import { Component, createRef } from 'react'; +import { shallowDiffers } from '../common/react'; +import { debounce } from '../common/timer'; import { computeBoxProps } from './Box'; // Stack of currently allocated BYOND UI element ids. diff --git a/lib/components/DmIcon.tsx b/lib/components/DmIcon.tsx index fb68165..a0b3113 100644 --- a/lib/components/DmIcon.tsx +++ b/lib/components/DmIcon.tsx @@ -1,7 +1,7 @@ import { ReactNode, useEffect, useState } from 'react'; -import { resolveAsset } from '../assets'; -import { fetchRetry } from '../http'; +import { resolveAsset } from '../common/assets'; +import { fetchRetry } from '../common/http'; import { BoxProps } from './Box'; import { Image } from './Image'; diff --git a/lib/components/Dropdown.tsx b/lib/components/Dropdown.tsx index 9d83fdf..d888d4c 100644 --- a/lib/components/Dropdown.tsx +++ b/lib/components/Dropdown.tsx @@ -56,7 +56,7 @@ type Props = { enum DIRECTION { Current = 'current', Next = 'next', - Previous = 'previous' + Previous = 'previous', } const NONE = -1; diff --git a/lib/components/KeyListener.tsx b/lib/components/KeyListener.tsx index 566026f..c96d7c5 100644 --- a/lib/components/KeyListener.tsx +++ b/lib/components/KeyListener.tsx @@ -1,7 +1,7 @@ import { Component } from 'react'; -import { KeyEvent } from '../events'; -import { listenForKeyEvents } from '../hotkeys'; +import { KeyEvent } from '../common/events'; +import { listenForKeyEvents } from '../common/hotkeys'; type KeyListenerProps = Partial<{ onKey: (key: KeyEvent) => void; diff --git a/lib/components/ProgressBar.tsx b/lib/components/ProgressBar.tsx index db1fad4..2263e7c 100644 --- a/lib/components/ProgressBar.tsx +++ b/lib/components/ProgressBar.tsx @@ -1,8 +1,8 @@ import { CSSProperties, PropsWithChildren } from 'react'; +import { CSS_COLORS } from '../common/constants'; import { clamp01, keyOfMatchingRange, scale, toFixed } from '../common/math'; import { classes } from '../common/react'; -import { CSS_COLORS } from '../constants'; import styles from '../styles/components/ProgressBar.module.scss'; import { BoxProps, computeBoxClassName, computeBoxProps } from './Box'; diff --git a/lib/components/Section.tsx b/lib/components/Section.tsx index c1a4989..39478ae 100644 --- a/lib/components/Section.tsx +++ b/lib/components/Section.tsx @@ -1,7 +1,7 @@ import { forwardRef, ReactNode, RefObject, useEffect } from 'react'; +import { addScrollableNode, removeScrollableNode } from '../common/events'; import { canRender, classes } from '../common/react'; -import { addScrollableNode, removeScrollableNode } from '../events'; import styles from '../styles/components/Section.module.scss'; import { BoxProps, computeBoxClassName, computeBoxProps } from './Box'; diff --git a/lib/components/TimeDisplay.jsx b/lib/components/TimeDisplay.jsx index 5a8fc9f..ab75825 100644 --- a/lib/components/TimeDisplay.jsx +++ b/lib/components/TimeDisplay.jsx @@ -1,6 +1,6 @@ import { Component } from 'react'; -import { formatTime } from '../format'; +import { formatTime } from '../common/format'; // AnimatedNumber Copypaste function isSafeNumber(value) { diff --git a/lib/events.ts b/lib/events.ts deleted file mode 100644 index 2579635..0000000 --- a/lib/events.ts +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Normalized browser focus events and BYOND-specific focus helpers. - * - * @file - * @copyright 2020 Aleksej Komarov - * @license MIT - */ - -import { EventEmitter } from './common/events'; -import { - KEY_ALT, - KEY_CTRL, - KEY_F1, - KEY_F12, - KEY_SHIFT, -} from './common/keycodes'; - -export const globalEvents = new EventEmitter(); -let ignoreWindowFocus = false; - -export const setupGlobalEvents = ( - options: { ignoreWindowFocus?: boolean } = {}, -): void => { - ignoreWindowFocus = !!options.ignoreWindowFocus; -}; - -// Window focus -// -------------------------------------------------------- - -let windowFocusTimeout: ReturnType | null; -let windowFocused = true; - -// Pretend to always be in focus. -function setWindowFocus(value: boolean, delayed?: boolean) { - if (ignoreWindowFocus) { - windowFocused = true; - return; - } - if (windowFocusTimeout) { - clearTimeout(windowFocusTimeout); - windowFocusTimeout = null; - } - if (delayed) { - windowFocusTimeout = setTimeout(() => setWindowFocus(value)); - return; - } - if (windowFocused !== value) { - windowFocused = value; - globalEvents.emit(value ? 'window-focus' : 'window-blur'); - globalEvents.emit('window-focus-change', value); - } -} - -// Focus stealing -// -------------------------------------------------------- - -let focusStolenBy: HTMLElement | null = null; - -export function canStealFocus(node: HTMLElement) { - const tag = String(node.tagName).toLowerCase(); - return tag === 'input' || tag === 'textarea'; -} - -function stealFocus(node: HTMLElement) { - releaseStolenFocus(); - focusStolenBy = node; - focusStolenBy.addEventListener('blur', releaseStolenFocus); -} - -function releaseStolenFocus() { - if (focusStolenBy) { - focusStolenBy.removeEventListener('blur', releaseStolenFocus); - focusStolenBy = null; - } -} - -// Focus follows the mouse -// -------------------------------------------------------- - -let focusedNode: HTMLElement | null = null; -let lastVisitedNode: HTMLElement | null = null; -const trackedNodes: HTMLElement[] = []; - -export function addScrollableNode(node: HTMLElement) { - trackedNodes.push(node); -} - -export function removeScrollableNode(node: HTMLElement) { - const index = trackedNodes.indexOf(node); - if (index >= 0) { - trackedNodes.splice(index, 1); - } -} - -function focusNearestTrackedParent(node: HTMLElement | null) { - if (focusStolenBy || !windowFocused) { - return; - } - const body = document.body; - while (node && node !== body) { - if (trackedNodes.includes(node)) { - // NOTE: Contains is a DOM4 method - if (node.contains(focusedNode)) { - return; - } - focusedNode = node; - node.focus(); - return; - } - node = node.parentElement; - } -} - -window.addEventListener('mousemove', (e) => { - const node = e.target as HTMLElement; - if (node !== lastVisitedNode) { - lastVisitedNode = node; - focusNearestTrackedParent(node); - } -}); - -// Focus event hooks -// -------------------------------------------------------- - -window.addEventListener('focusin', (e) => { - lastVisitedNode = null; - focusedNode = e.target as HTMLElement; - setWindowFocus(true); - if (canStealFocus(e.target as HTMLElement)) { - stealFocus(e.target as HTMLElement); - } -}); - -window.addEventListener('focusout', () => { - lastVisitedNode = null; - setWindowFocus(false, true); -}); - -window.addEventListener('blur', () => { - lastVisitedNode = null; - setWindowFocus(false, true); -}); - -window.addEventListener('beforeunload', () => { - setWindowFocus(false); -}); - -// Key events -// -------------------------------------------------------- - -const keyHeldByCode: Record = {}; - -export class KeyEvent { - event: KeyboardEvent; - type: 'keydown' | 'keyup'; - code: number; - ctrl: boolean; - shift: boolean; - alt: boolean; - repeat: boolean; - _str?: string; - - constructor(e: KeyboardEvent, type: 'keydown' | 'keyup', repeat?: boolean) { - this.event = e; - this.type = type; - this.code = e.keyCode; - this.ctrl = e.ctrlKey; - this.shift = e.shiftKey; - this.alt = e.altKey; - this.repeat = !!repeat; - } - - hasModifierKeys() { - return this.ctrl || this.alt || this.shift; - } - - isModifierKey() { - return ( - this.code === KEY_CTRL || this.code === KEY_SHIFT || this.code === KEY_ALT - ); - } - - isDown() { - return this.type === 'keydown'; - } - - isUp() { - return this.type === 'keyup'; - } - - toString() { - if (this._str) { - return this._str; - } - this._str = ''; - if (this.ctrl) { - this._str += 'Ctrl+'; - } - if (this.alt) { - this._str += 'Alt+'; - } - if (this.shift) { - this._str += 'Shift+'; - } - if (this.code >= 48 && this.code <= 90) { - this._str += String.fromCharCode(this.code); - } else if (this.code >= KEY_F1 && this.code <= KEY_F12) { - this._str += 'F' + (this.code - 111); - } else { - this._str += '[' + this.code + ']'; - } - return this._str; - } -} - -// IE8: Keydown event is only available on document. -document.addEventListener('keydown', (e) => { - if (canStealFocus(e.target as HTMLElement)) { - return; - } - const code = e.keyCode; - const key = new KeyEvent(e, 'keydown', keyHeldByCode[code]); - globalEvents.emit('keydown', key); - globalEvents.emit('key', key); - keyHeldByCode[code] = true; -}); - -document.addEventListener('keyup', (e) => { - if (canStealFocus(e.target as HTMLElement)) { - return; - } - const code = e.keyCode; - const key = new KeyEvent(e, 'keyup'); - globalEvents.emit('keyup', key); - globalEvents.emit('key', key); - keyHeldByCode[code] = false; -}); diff --git a/package.json b/package.json index 7e31593..b4dfceb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tgui-core", - "version": "1.1.0", + "version": "1.1.1", "description": "TGUI core component library", "keywords": [ "TGUI", @@ -11,10 +11,6 @@ "dist" ], "exports": { - "./common/*": { - "import": "./dist/*.js", - "require": "./dist/*.cjs" - }, "./components": { "import": "./dist/components/index.js", "require": "./dist/components/index.cjs"