chore(prettier): fix prettier

This commit is contained in:
AAGaming
2022-10-24 20:33:40 -04:00
parent 2e52cca8a2
commit 1f2694aec8
27 changed files with 652 additions and 597 deletions

View File

@@ -1,22 +1,21 @@
export * from "./patcher";
export * from "./react";
export * from './patcher';
export * from './react';
export function joinClassNames(...classes: string[]): string {
return classes.join(" ");
return classes.join(' ');
}
export function sleep(ms: number) {
return new Promise(res => setTimeout(res, ms));
return new Promise((res) => setTimeout(res, ms));
}
/**
* Finds the SP window, since it is a render target as of {10-19-2022}'s beta
*/
export function findSP(): Window {
// old (SP as host)
if (document.title == 'SP') return window;
// new (SP as popup)
return FocusNavController.m_ActiveContext.m_rgGamepadNavigationTrees.find((x: any) => x.m_ID == 'root_1_').Root
.Element.ownerDocument.defaultView;
}
// old (SP as host)
if (document.title == 'SP') return window;
// new (SP as popup)
return FocusNavController.m_ActiveContext.m_rgGamepadNavigationTrees.find((x: any) => x.m_ID == 'root_1_').Root
.Element.ownerDocument.defaultView;
}

View File

@@ -1,112 +1,160 @@
// TODO: implement storing patches as an option so we can offer unpatchAll selectively
// Return this in a replacePatch to call the original method (can still modify args).
export let callOriginal = Symbol("DECKY_CALL_ORIGINAL");
export let callOriginal = Symbol('DECKY_CALL_ORIGINAL');
export interface PatchOptions {
singleShot?: boolean
singleShot?: boolean;
}
type GenericPatchHandler = (args: any[], ret?: any) => any;
export interface Patch {
original: Function;
property: string;
object: any;
patchedFunction: any;
hasUnpatched: boolean;
handler: GenericPatchHandler;
original: Function;
property: string;
object: any;
patchedFunction: any;
hasUnpatched: boolean;
handler: GenericPatchHandler;
unpatch: () => void
};
unpatch: () => void;
}
// let patches = new Set<Patch>();
export function beforePatch(object: any, property: string, handler: (args: any[]) => any, options: PatchOptions = {}): Patch {
const orig = object[property];
object[property] = function (...args: any[]) {
handler.call(this, args);
const ret = patch.original.call(this, ...args);
if (options.singleShot) {
patch.unpatch();
}
return ret;
export function beforePatch(
object: any,
property: string,
handler: (args: any[]) => any,
options: PatchOptions = {},
): Patch {
const orig = object[property];
object[property] = function (...args: any[]) {
handler.call(this, args);
const ret = patch.original.call(this, ...args);
if (options.singleShot) {
patch.unpatch();
}
const patch = processPatch(object, property, handler, object[property], orig);
return patch;
return ret;
};
const patch = processPatch(object, property, handler, object[property], orig);
return patch;
}
export function afterPatch(object: any, property: string, handler: (args: any[], ret: any) => any, options: PatchOptions = {}): Patch {
const orig = object[property];
object[property] = function (...args: any[]) {
let ret = patch.original.call(this, ...args);
ret = handler.call(this, args, ret);
if (options.singleShot) {
patch.unpatch();
}
return ret;
export function afterPatch(
object: any,
property: string,
handler: (args: any[], ret: any) => any,
options: PatchOptions = {},
): Patch {
const orig = object[property];
object[property] = function (...args: any[]) {
let ret = patch.original.call(this, ...args);
ret = handler.call(this, args, ret);
if (options.singleShot) {
patch.unpatch();
}
const patch = processPatch(object, property, handler, object[property], orig);
return patch;
return ret;
};
const patch = processPatch(object, property, handler, object[property], orig);
return patch;
}
export function replacePatch(object: any, property: string, handler: (args: any[]) => any, options: PatchOptions = {}): Patch {
const orig = object[property];
object[property] = function (...args: any[]) {
const ret = handler.call(this, args);
if (ret == callOriginal) return patch.original.call(this, ...args);
if (options.singleShot) {
patch.unpatch();
}
return ret;
};
const patch = processPatch(object, property, handler, object[property], orig);
return patch;
export function replacePatch(
object: any,
property: string,
handler: (args: any[]) => any,
options: PatchOptions = {},
): Patch {
const orig = object[property];
object[property] = function (...args: any[]) {
const ret = handler.call(this, args);
if (ret == callOriginal) return patch.original.call(this, ...args);
if (options.singleShot) {
patch.unpatch();
}
return ret;
};
const patch = processPatch(object, property, handler, object[property], orig);
return patch;
}
function processPatch(object: any, property: any, handler: GenericPatchHandler, patchedFunction: any, original: any): Patch {
// Assign all props of original function to new one
Object.assign(object[property], original);
// Allow toString webpack filters to continue to work
object[property].toString = () => original.toString();
function processPatch(
object: any,
property: any,
handler: GenericPatchHandler,
patchedFunction: any,
original: any,
): Patch {
// Assign all props of original function to new one
Object.assign(object[property], original);
// Allow toString webpack filters to continue to work
object[property].toString = () => original.toString();
// HACK: for compatibility, remove when all plugins are using new patcher
Object.defineProperty(object[property], "__deckyOrig", {
get: () => patch.original,
set: (val: any) => patch.original = val
})
// HACK: for compatibility, remove when all plugins are using new patcher
Object.defineProperty(object[property], '__deckyOrig', {
get: () => patch.original,
set: (val: any) => (patch.original = val),
});
// Build a Patch object of this patch
const patch: Patch = {
object,
property,
handler,
patchedFunction,
original,
hasUnpatched: false,
unpatch: () => unpatch(patch)
};
// Build a Patch object of this patch
const patch: Patch = {
object,
property,
handler,
patchedFunction,
original,
hasUnpatched: false,
unpatch: () => unpatch(patch),
};
object[property].__deckyPatch = patch;
object[property].__deckyPatch = patch;
return patch;
return patch;
}
function unpatch(patch: Patch): void {
const { object, property, handler, patchedFunction, original } = patch;
if (patch.hasUnpatched) throw new Error("Function is already unpatched.")
let realProp = property;
let realObject = object;
console.debug("[Patcher] unpatching", {realObject, realProp, object, property, handler, patchedFunction, original, isEqual: realObject[realProp] === patchedFunction})
const { object, property, handler, patchedFunction, original } = patch;
if (patch.hasUnpatched) throw new Error('Function is already unpatched.');
let realProp = property;
let realObject = object;
console.debug('[Patcher] unpatching', {
realObject,
realProp,
object,
property,
handler,
patchedFunction,
original,
isEqual: realObject[realProp] === patchedFunction,
});
// If another patch has been applied to this function after this one, move down until we find the correct patch
while (realObject[realProp] && realObject[realProp] !== patchedFunction) {
realObject = realObject[realProp].__deckyPatch;
realProp = "original";
console.debug("[Patcher] moved to next", {realObject, realProp, object, property, handler, patchedFunction, original, isEqual: realObject[realProp] === patchedFunction})
}
// If another patch has been applied to this function after this one, move down until we find the correct patch
while (realObject[realProp] && realObject[realProp] !== patchedFunction) {
realObject = realObject[realProp].__deckyPatch;
realProp = 'original';
console.debug('[Patcher] moved to next', {
realObject,
realProp,
object,
property,
handler,
patchedFunction,
original,
isEqual: realObject[realProp] === patchedFunction,
});
}
realObject[realProp] = realObject[realProp].__deckyPatch.original
realObject[realProp] = realObject[realProp].__deckyPatch.original;
patch.hasUnpatched = true;
console.debug("[Patcher] unpatched", {realObject, realProp, object, property, handler, patchedFunction, original, isEqual: realObject[realProp] === patchedFunction})
}
patch.hasUnpatched = true;
console.debug('[Patcher] unpatched', {
realObject,
realProp,
object,
property,
handler,
patchedFunction,
original,
isEqual: realObject[realProp] === patchedFunction,
});
}

View File

@@ -1,86 +1,95 @@
import * as React from "react";
import * as React from 'react';
// this shouldn't need to be redeclared but it does for some reason
declare global {
interface Window {
SP_REACT: typeof React;
}
interface Window {
SP_REACT: typeof React;
}
}
export function fakeRenderComponent(fun: Function): any {
const hooks = (window.SP_REACT as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
export function fakeRenderComponent(fun: Function, customHooks: any = {}): any {
const hooks = (window.SP_REACT as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher
.current;
// TODO: add more hooks
// TODO: add more hooks
let oldHooks = {
useContext: hooks.useContext,
useCallback: hooks.useCallback,
useLayoutEffect: hooks.useLayoutEffect,
useEffect: hooks.useEffect,
useMemo: hooks.useMemo,
useRef: hooks.useRef,
useState: hooks.useState,
}
let oldHooks = {
useContext: hooks.useContext,
useCallback: hooks.useCallback,
useLayoutEffect: hooks.useLayoutEffect,
useEffect: hooks.useEffect,
useMemo: hooks.useMemo,
useRef: hooks.useRef,
useState: hooks.useState,
};
hooks.useCallback = (cb: Function) => cb;
hooks.useContext = (cb: any) => cb._currentValue;
hooks.useLayoutEffect = (_: Function) => {}//cb();
hooks.useMemo = (cb: Function, _: any[]) => cb;
hooks.useEffect = (_: Function) => {}//cb();
hooks.useRef = (val: any) => ({current: val || {}});
hooks.useState = (v: any) => {
let val = v;
hooks.useCallback = (cb: Function) => cb;
hooks.useContext = (cb: any) => cb._currentValue;
hooks.useLayoutEffect = (_: Function) => {}; //cb();
hooks.useMemo = (cb: Function, _: any[]) => cb;
hooks.useEffect = (_: Function) => {}; //cb();
hooks.useRef = (val: any) => ({ current: val || {} });
hooks.useState = (v: any) => {
let val = v;
return [val, (n: any) => val = n];
};
return [val, (n: any) => (val = n)];
};
const res = fun(hooks);
Object.assign(hooks, customHooks);
Object.assign(hooks, oldHooks);
const res = fun(hooks);
return res;
Object.assign(hooks, oldHooks);
return res;
}
export function wrapReactType(node: any, prop: any = 'type') {
return node[prop] = {...node[prop]};
return (node[prop] = { ...node[prop] });
}
export function wrapReactClass(node: any, prop: any = 'type') {
const cls = node[prop];
const wrappedCls = class extends cls {};
return node[prop] = wrappedCls;
const cls = node[prop];
const wrappedCls = class extends cls {};
return (node[prop] = wrappedCls);
}
export function getReactInstance(o: HTMLElement | Element | Node) {
return o[Object.keys(o).find(k => k.startsWith('__reactInternalInstance')) as string]
return o[Object.keys(o).find((k) => k.startsWith('__reactInternalInstance')) as string];
}
// Based on https://github.com/GooseMod/GooseMod/blob/9ef146515a9e59ed4e25665ed365fd72fc0dcf23/src/util/react.js#L20
export interface findInTreeOpts {
walkable?: string[],
ignore?: string[]
walkable?: string[];
ignore?: string[];
}
export declare type findInTreeFilter = (element: any) => boolean
export declare type findInTreeFilter = (element: any) => boolean;
export const findInTree = (parent: any, filter: findInTreeFilter, opts: findInTreeOpts): any => {
const { walkable = null, ignore = [] } = opts ?? {};
if (!parent || typeof parent !== 'object') { // Parent is invalid to search through
return null;
}
if (filter(parent)) return parent; // Parent matches, just return
if (Array.isArray(parent)) { // Parent is an array, go through values
return parent.map((x) => findInTree(x, filter, opts)).find((x) => x);
}
// Parent is an object, go through values (or option to only use certain keys)
return (walkable || Object.keys(parent)).map((x) => !ignore.includes(x) && findInTree(parent[x], filter, opts)).find((x: any) => x);
const { walkable = null, ignore = [] } = opts ?? {};
if (!parent || typeof parent !== 'object') {
// Parent is invalid to search through
return null;
}
if (filter(parent)) return parent; // Parent matches, just return
if (Array.isArray(parent)) {
// Parent is an array, go through values
return parent.map((x) => findInTree(x, filter, opts)).find((x) => x);
}
// Parent is an object, go through values (or option to only use certain keys)
return (walkable || Object.keys(parent))
.map((x) => !ignore.includes(x) && findInTree(parent[x], filter, opts))
.find((x: any) => x);
};
export const findInReactTree = (node: any, filter: findInTreeFilter) => findInTree(node, filter, { // Specialised findInTree for React nodes
walkable: [ 'props', 'children', 'child', 'sibling' ]
});
export const findInReactTree = (node: any, filter: findInTreeFilter) =>
findInTree(node, filter, {
// Specialised findInTree for React nodes
walkable: ['props', 'children', 'child', 'sibling'],
});