2019-06-22 06:37:19 +02:00
|
|
|
import DiscordModules from "./discordmodules";
|
|
|
|
import Patcher from "./patcher";
|
|
|
|
|
|
|
|
const React = DiscordModules.React;
|
|
|
|
const components = {};
|
|
|
|
const unknownComponents = new Set();
|
|
|
|
const listeners = new Set();
|
|
|
|
|
|
|
|
export default new class ReactComponents {
|
|
|
|
|
|
|
|
get named() {return components;}
|
|
|
|
get unknown() {return unknownComponents;}
|
|
|
|
get listeners() {return listeners;}
|
|
|
|
|
2019-06-26 05:17:16 +02:00
|
|
|
constructor() {
|
2019-06-22 06:37:19 +02:00
|
|
|
Patcher.after("ReactComponents", React, "createElement", (_, __, returnValue) => {
|
|
|
|
this.walkRenderTree(returnValue);
|
|
|
|
});
|
|
|
|
Patcher.instead("ReactComponents", React.Component.prototype, "componentWillMount", (thisObject) => {
|
|
|
|
this.addComponent(thisObject.constructor);
|
|
|
|
});
|
|
|
|
Patcher.instead("ReactComponents", React.Component.prototype, "UNSAFE_componentWillMount", (thisObject) => {
|
|
|
|
this.addComponent(thisObject.constructor);
|
|
|
|
});
|
2019-06-26 05:17:16 +02:00
|
|
|
|
|
|
|
Patcher.instead("ReactComponents", React.PureComponent.prototype, "componentWillMount", (thisObject) => {
|
|
|
|
this.addComponent(thisObject.constructor);
|
|
|
|
});
|
|
|
|
Patcher.instead("ReactComponents", React.PureComponent.prototype, "UNSAFE_componentWillMount", (thisObject) => {
|
|
|
|
this.addComponent(thisObject.constructor);
|
|
|
|
});
|
2019-06-22 06:37:19 +02:00
|
|
|
}
|
|
|
|
|
2019-06-26 20:34:01 +02:00
|
|
|
initialize() {
|
|
|
|
this.walkReactTree(document.querySelector("#app-mount")._reactRootContainer._internalRoot.current);
|
|
|
|
}
|
2019-06-26 05:17:16 +02:00
|
|
|
|
2019-06-22 06:37:19 +02:00
|
|
|
get(name, filter) {
|
|
|
|
return new Promise(resolve => {
|
|
|
|
if (components[name]) return resolve(components[name]);
|
|
|
|
listeners.add({name, filter, resolve});
|
|
|
|
if (!filter) return;
|
|
|
|
for (const component of unknownComponents) {
|
|
|
|
if (!filter(component)) continue;
|
|
|
|
component.displayName = name;
|
|
|
|
unknownComponents.delete(component);
|
|
|
|
this.addNamedComponent(component);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
addNamedComponent(component) {
|
|
|
|
const name = component.displayName;
|
|
|
|
if (!components[name]) {
|
|
|
|
components[name] = component;
|
|
|
|
for (const listener of listeners) {
|
|
|
|
if (listener.name !== name) continue;
|
|
|
|
listener.resolve(component);
|
|
|
|
listeners.delete(listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
addUnknownComponent(component) {
|
|
|
|
if (unknownComponents.has(component)) return;
|
|
|
|
for (const listener of listeners) {
|
|
|
|
if (!listener.filter || !listener.filter(component)) continue;
|
|
|
|
component.displayName = listener.name;
|
|
|
|
this.addNamedComponent(component);
|
|
|
|
}
|
|
|
|
if (!component.displayName) unknownComponents.add(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
addComponent(component) {
|
|
|
|
if (component.displayName) return this.addNamedComponent(component);
|
|
|
|
return this.addUnknownComponent(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
walkRenderTree(tree) {
|
|
|
|
if (!tree) return;
|
|
|
|
if (typeof(tree.type) == "function") this.addComponent(tree.type);
|
|
|
|
if (Array.isArray(tree)) for (const value of tree) this.walkRenderTree(value);
|
|
|
|
if (tree.props && tree.props.children) this.walkRenderTree(tree.props.children);
|
|
|
|
}
|
|
|
|
|
|
|
|
walkReactTree(tree) {
|
|
|
|
if (!tree) return;
|
|
|
|
if (typeof(tree.type) == "function") this.addComponent(tree.type);
|
|
|
|
if (tree.child) this.walkReactTree(tree.child);
|
|
|
|
if (tree.sibling) this.walkReactTree(tree.sibling);
|
|
|
|
}
|
|
|
|
};
|