this repo has no description
1import { InternalItem, Menu, MenuElement } from "@moonlight-mod/types/coreExtensions/contextMenu"; 2import spacepack from "@moonlight-mod/wp/spacepack_spacepack"; 3import parser from "@moonlight-mod/wp/contextMenu_evilMenu"; 4 5// NOTE: We originally had item as a function that returned this, but it didn't 6// quite know how to work out the type and thought it was a JSX element (it 7// *technically* was). This has less type safety, but a @ts-expect-error has 8// zero, so it's better than nothing. 9type ReturnType = MenuElement | MenuElement[]; 10 11type Patch = { 12 navId: string; 13 item: React.FC<any>; 14 anchor: string | RegExp; 15 before: boolean; 16}; 17 18function addItem<T = any>(navId: string, item: React.FC<T>, anchor: string | RegExp, before = false) { 19 if (anchor instanceof RegExp && anchor.flags.includes("g")) 20 throw new Error("anchor regular expression should not be global"); 21 patches.push({ navId, item, anchor, before }); 22} 23 24const patches: Patch[] = []; 25function _patchMenu(props: React.ComponentProps<Menu>, items: InternalItem[]) { 26 const matches = patches.filter((p) => p.navId === props.navId); 27 if (!matches.length) return items; 28 29 for (const patch of matches) { 30 const idx = items.findIndex((i) => 31 typeof patch.anchor === "string" ? i.key === patch.anchor : patch.anchor.test(i.key!) 32 ); 33 if (idx === -1) continue; 34 items.splice(idx + 1 - +patch.before, 0, ...parser(patch.item(menuProps) as ReturnType)); 35 } 36 37 return items; 38} 39 40let menuProps: any; 41function _saveProps(self: any, el: any) { 42 menuProps = el.props; 43 44 const original = self.props.closeContextMenu; 45 self.props.closeContextMenu = function (...args: any[]) { 46 menuProps = undefined; 47 return original?.apply(this, args); 48 }; 49 50 return el; 51} 52 53module.exports = { 54 patches, 55 addItem, 56 _patchMenu, 57 _saveProps 58}; 59 60// Unmangle Menu elements 61const code = 62 spacepack.require.m[ 63 spacepack.findByCode("Menu API only allows Items and groups of Items as children.")[0].id 64 ].toString(); 65 66let MangledMenu; 67 68const typeRegex = /if\(.\.type===(.)\.(.+?)\).+?type:"(.+?)"/g; 69const typeMap: Record<string, string | undefined> = { 70 checkbox: "MenuCheckboxItem", 71 control: "MenuControlItem", 72 groupstart: "MenuGroup", 73 customitem: "MenuItem", 74 radio: "MenuRadioItem", 75 separator: "MenuSeparator" 76}; 77 78for (const [, modIdent, mangled, type] of code.matchAll(typeRegex)) { 79 if (!MangledMenu) { 80 const modId = code.match(new RegExp(`${modIdent}=.\\((\\d+?)\\)`))![1]; 81 MangledMenu = spacepack.require(modId); 82 } 83 84 const prop = typeMap[type]; 85 if (!prop) continue; 86 module.exports[prop] = MangledMenu[mangled]; 87}