Initial commit

Co-Authored-By: Eric Tuvesson <eric.tuvesson@gmail.com>
Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com>
Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com>
Co-Authored-By: Anders Larsson <64838990+anders-topp@users.noreply.github.com>
Co-Authored-By: Johan  <4934465+joolsus@users.noreply.github.com>
Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com>
Co-Authored-By: victoratndl <99176179+victoratndl@users.noreply.github.com>
This commit is contained in:
Michael Cartner
2024-01-26 11:52:55 +01:00
commit b9c60b07dc
2789 changed files with 868795 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
export default class Inspector {
constructor({ onInspect, onHighlight, onDisableHighlight }) {
this.onMouseMove = (e) => {
onDisableHighlight();
const noodlNode = this.findNoodlNode(e.target);
if (noodlNode) {
document.body.style.cursor = 'pointer';
onHighlight(noodlNode.id);
} else {
document.body.style.cursor = 'initial';
}
e.stopPropagation();
};
this.onClick = (e) => {
onDisableHighlight();
const noodlNode = this.findNoodlNode(e.target);
if (noodlNode) {
onInspect([noodlNode.id]);
}
e.stopPropagation();
e.preventDefault();
//not sure how to stop React input elements from getting focus, so blurring the potential element tha got focus on click
if (document.activeElement) {
document.activeElement.blur();
}
};
this.onContextMenu = (e) => {
const nodeIds = document
.elementsFromPoint(e.clientX, e.clientY)
.map((dom) => this.findNoodlNode(dom))
.filter((node) => !!node)
.map((node) => node.id);
if (nodeIds.length) {
onInspect(nodeIds);
}
e.stopPropagation();
e.preventDefault();
//not sure how to stop React input elements from getting focus, so blurring the potential element tha got focus on click
if (document.activeElement) {
document.activeElement.blur();
}
};
this.onMouseOut = (e) => {
onDisableHighlight();
};
this.blockEvent = (e) => {
e.stopPropagation();
};
this.onDisableHighlight = onDisableHighlight;
}
setComponent(component) {
this.component = component;
}
enable() {
//blur active element, if any
if (document.activeElement) {
document.activeElement.blur();
}
//get events from capture phase, before they tunnel down the tree
document.addEventListener('mouseenter', this.blockEvent, true);
document.addEventListener('mouseover', this.blockEvent, true);
document.addEventListener('mousedown', this.blockEvent, true);
document.addEventListener('mouseup', this.blockEvent, true);
document.addEventListener('mousemove', this.onMouseMove, true);
document.addEventListener('mouseout', this.onMouseOut, true);
document.addEventListener('click', this.onClick, true);
document.addEventListener('contextmenu', this.onContextMenu, true);
}
disable() {
document.body.style.cursor = 'initial';
document.removeEventListener('mouseenter', this.blockEvent, true);
document.removeEventListener('mouseover', this.blockEvent, true);
document.removeEventListener('mousedown', this.blockEvent, true);
document.removeEventListener('mouseup', this.blockEvent, true);
document.removeEventListener('mousemove', this.onMouseMove, true);
document.removeEventListener('mouseout', this.onMouseOut, true);
document.removeEventListener('click', this.onClick, true);
document.removeEventListener('contextmenu', this.onContextMenu, true);
this.onDisableHighlight();
}
findNoodlNode(dom) {
//walk the dom tree upwards until a dom element with react state is found
let domFiber;
while (!domFiber && dom) {
const key = Object.keys(dom).find((key) => key.startsWith('__reactInternalInstance$'));
domFiber = dom[key];
if (!domFiber) dom = dom.parentElement;
}
//found none
if (!domFiber) {
return undefined;
}
const GetCompFiber = (fiber) => {
let parentFiber = fiber.return;
while (parentFiber && typeof parentFiber.type == 'string') {
parentFiber = parentFiber.return;
}
return parentFiber;
};
//found a react node, now walk the react tree until a noodl node is found
//(identified by having a noodlNode prop)
let compFiber = GetCompFiber(domFiber);
while (compFiber && (!compFiber.stateNode || !compFiber.stateNode.props || !compFiber.stateNode.props.noodlNode)) {
compFiber = GetCompFiber(compFiber);
}
const noodlNode = compFiber ? compFiber.stateNode.props.noodlNode : undefined;
if (!noodlNode) return;
if (this.component) {
let node = noodlNode;
while (node) {
if (node.parentNodeScope) {
if (node.parentNodeScope.componentOwner.name === this.component.name) {
return node;
}
node = node.parentNodeScope.componentOwner;
} else {
if (node.nodeScope.componentOwner.name === this.component.name) {
return node;
}
node = node.nodeScope.componentOwner;
}
}
return node;
}
return noodlNode;
}
}