UNPKG

@steambrew/client

Version:
105 lines (104 loc) 3.77 kB
/** * Create a Regular Expression to search for a React component that uses certain props in order. * * @export * @param {string[]} propList Ordererd list of properties to search for * @returns {RegExp} RegEx to call .test(component.toString()) on */ export function createPropListRegex(propList, fromStart = true) { let regexString = fromStart ? "const\{" : ""; propList.forEach((prop, propIdx) => { regexString += `"?${prop}"?:[a-zA-Z_$]{1,2}`; if (propIdx < propList.length - 1) { regexString += ","; } }); // TODO provide a way to enable this // console.debug(`[DFL:Utils] createPropListRegex generated regex "${regexString}" for props`, propList); return new RegExp(regexString); } export function fakeRenderComponent(fun, customHooks = {}) { const hooks = window.SP_REACT.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher .current; // 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, }; hooks.useCallback = (cb) => cb; hooks.useContext = (cb) => cb._currentValue; hooks.useLayoutEffect = (_) => { }; //cb(); hooks.useMemo = (cb, _) => cb; hooks.useEffect = (_) => { }; //cb(); hooks.useRef = (val) => ({ current: val || {} }); hooks.useState = (v) => { let val = v; return [val, (n) => (val = n)]; }; Object.assign(hooks, customHooks); const res = fun(hooks); Object.assign(hooks, oldHooks); return res; } export function wrapReactType(node, prop = 'type') { if (node[prop]?.__DECKY_WRAPPED) { return node[prop]; } else { return (node[prop] = { ...node[prop], __DECKY_WRAPPED: true }); } } export function wrapReactClass(node, prop = 'type') { var _a; if (node[prop]?.__DECKY_WRAPPED) { return node[prop]; } else { const cls = node[prop]; const wrappedCls = (_a = class extends cls { }, _a.__DECKY_WRAPPED = true, _a); return (node[prop] = wrappedCls); } } export function getReactRoot(o) { return ( // @ts-ignore o[Object.keys(o).find((k) => k.startsWith('__reactContainer$'))] || // @ts-ignore o['_reactRootContainer']?._internalRoot?.current); } export function getReactInstance(o) { return ( // @ts-ignore o[Object.keys(o).find((k) => k.startsWith('__reactFiber'))] || // @ts-ignore o[Object.keys(o).find((k) => k.startsWith('__reactInternalInstance'))]); } export const findInTree = (parent, filter, opts) => { 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) => x); }; export const findInReactTree = (node, filter) => findInTree(node, filter, { // Specialised findInTree for React nodes walkable: ['props', 'children', 'child', 'sibling'], });