/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
fixtures/fiber-debugger/src/Fibers.js
407 строк
10 KB
Jan Kassens
Upgrade prettier (#26081)
31 янв 2023, 16:25
Не верифицирован
31 янв 2023, 16:25
6b30832
Код
Авторство
О чём код?
import React from 'react'; import {Motion, spring} from 'react-motion'; import dagre from 'dagre'; // import prettyFormat from 'pretty-format'; // import reactElement from 'pretty-format/plugins/ReactElement'; function getFiberColor(fibers, id) { if (fibers.currentIDs.indexOf(id) > -1) { return 'lightgreen'; } if (id === fibers.workInProgressID) { return 'yellow'; } return 'lightyellow'; } function Graph(props) { const {rankdir, trackActive} = props.settings; var g = new dagre.graphlib.Graph(); g.setGraph({ width: 1000, height: 1000, nodesep: 50, edgesep: 150, ranksep: 100, marginx: 100, marginy: 100, rankdir, }); var edgeLabels = {}; React.Children.forEach(props.children, function (child) { if (!child) { return; } if (child.type.isVertex) { g.setNode(child.key, { label: child, width: child.props.width, height: child.props.height, }); } else if (child.type.isEdge) { const relationshipKey = child.props.source + ':' + child.props.target; if (!edgeLabels[relationshipKey]) { edgeLabels[relationshipKey] = []; } edgeLabels[relationshipKey].push(child); } }); Object.keys(edgeLabels).forEach(key => { const children = edgeLabels[key]; const child = children[0]; g.setEdge(child.props.source, child.props.target, { label: child, allChildren: children.map(c => c.props.children), weight: child.props.weight, }); }); dagre.layout(g); var activeNode = g .nodes() .map(v => g.node(v)) .find(node => node.label.props.isActive); const [winX, winY] = [window.innerWidth / 2, window.innerHeight / 2]; var focusDx = trackActive && activeNode ? winX - activeNode.x : 0; var focusDy = trackActive && activeNode ? winY - activeNode.y : 0; var nodes = g.nodes().map(v => { var node = g.node(v); return ( <Motion style={{ x: props.isDragging ? node.x + focusDx : spring(node.x + focusDx), y: props.isDragging ? node.y + focusDy : spring(node.y + focusDy), }} key={node.label.key}> {interpolatingStyle => React.cloneElement(node.label, { x: interpolatingStyle.x + props.dx, y: interpolatingStyle.y + props.dy, vanillaX: node.x, vanillaY: node.y, }) } </Motion> ); }); var edges = g.edges().map(e => { var edge = g.edge(e); let idx = 0; return ( <Motion style={edge.points.reduce((bag, point) => { bag[idx + ':x'] = props.isDragging ? point.x + focusDx : spring(point.x + focusDx); bag[idx + ':y'] = props.isDragging ? point.y + focusDy : spring(point.y + focusDy); idx++; return bag; }, {})} key={edge.label.key}> {interpolatedStyle => { let points = []; Object.keys(interpolatedStyle).forEach(key => { const [idx, prop] = key.split(':'); if (!points[idx]) { points[idx] = {x: props.dx, y: props.dy}; } points[idx][prop] += interpolatedStyle[key]; }); return React.cloneElement(edge.label, { points, id: edge.label.key, children: edge.allChildren.join(', '), }); }} </Motion> ); }); return ( <div style={{ position: 'relative', height: '100%', }}> {edges} {nodes} </div> ); } function Vertex(props) { if (Number.isNaN(props.x) || Number.isNaN(props.y)) { return null; } return ( <div style={{ position: 'absolute', border: '1px solid black', left: props.x - props.width / 2, top: props.y - props.height / 2, width: props.width, height: props.height, overflow: 'hidden', padding: '4px', wordWrap: 'break-word', }}> {props.children} </div> ); } Vertex.isVertex = true; const strokes = { alt: 'blue', child: 'green', sibling: 'darkgreen', return: 'red', fx: 'purple', }; function Edge(props) { var points = props.points; var path = 'M' + points[0].x + ' ' + points[0].y + ' '; if (!points[0].x || !points[0].y) { return null; } for (var i = 1; i < points.length; i++) { path += 'L' + points[i].x + ' ' + points[i].y + ' '; if (!points[i].x || !points[i].y) { return null; } } var lineID = props.id; return ( <svg width="100%" height="100%" style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, }}> <defs> <path d={path} id={lineID} /> <marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5"> <circle cx="5" cy="5" r="3" style={{stroke: 'none', fill: 'black'}} /> </marker> <marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto"> <path d="M2,2 L2,11 L10,6 L2,2" style={{fill: 'black'}} /> </marker> </defs> <use xlinkHref={`#${lineID}`} fill="none" stroke={strokes[props.kind]} style={{ markerStart: 'url(#markerCircle)', markerEnd: 'url(#markerArrow)', }} /> <text> <textPath xlinkHref={`#${lineID}`}> {' '} {props.children} </textPath> </text> </svg> ); } Edge.isEdge = true; function formatPriority(priority) { switch (priority) { case 1: return 'synchronous'; case 2: return 'task'; case 3: return 'hi-pri work'; case 4: return 'lo-pri work'; case 5: return 'offscreen work'; default: throw new Error('Unknown priority.'); } } export default function Fibers({fibers, show, graphSettings, ...rest}) { const items = Object.keys(fibers.descriptions).map( id => fibers.descriptions[id] ); const isDragging = rest.className.indexOf('dragging') > -1; const [_, sdx, sdy] = rest.style.transform.match(/translate\((-?\d+)px,(-?\d+)px\)/) || []; const dx = Number(sdx); const dy = Number(sdy); return ( <div {...rest} style={{ width: '100%', height: '100%', position: 'absolute', top: 0, left: 0, ...rest.style, transform: null, }}> <Graph className="graph" dx={dx} dy={dy} isDragging={isDragging} settings={graphSettings}> {items.map(fiber => [ <Vertex key={fiber.id} width={150} height={100} isActive={fiber.id === fibers.workInProgressID}> <div style={{ width: '100%', height: '100%', backgroundColor: getFiberColor(fibers, fiber.id), }} title={ /*prettyFormat(fiber, { plugins: [reactElement ]})*/ 'todo: this was hanging last time I tried to pretty print' }> <small> {fiber.tag} #{fiber.id} </small> <br /> {fiber.type} <br /> {fibers.currentIDs.indexOf(fiber.id) === -1 ? ( <small> {fiber.pendingWorkPriority !== 0 && [ <span key="span"> Needs: {formatPriority(fiber.pendingWorkPriority)} </span>, <br key="br" />, ]} {fiber.memoizedProps !== null && fiber.pendingProps !== null && [ fiber.memoizedProps === fiber.pendingProps ? 'Can reuse memoized.' : 'Cannot reuse memoized.', <br key="br" />, ]} </small> ) : ( <small>Committed</small> )} {fiber.flags && [ <br key="br" />, <small key="small">Effect: {fiber.flags}</small>, ]} </div> </Vertex>, fiber.child && show.child && ( <Edge source={fiber.id} target={fiber.child} kind="child" weight={1000} key={`${fiber.id}-${fiber.child}-child`}> child </Edge> ), fiber.sibling && show.sibling && ( <Edge source={fiber.id} target={fiber.sibling} kind="sibling" weight={2000} key={`${fiber.id}-${fiber.sibling}-sibling`}> sibling </Edge> ), fiber.return && show.return && ( <Edge source={fiber.id} target={fiber.return} kind="return" weight={1000} key={`${fiber.id}-${fiber.return}-return`}> return </Edge> ), fiber.nextEffect && show.fx && ( <Edge source={fiber.id} target={fiber.nextEffect} kind="fx" weight={100} key={`${fiber.id}-${fiber.nextEffect}-nextEffect`}> nextFx </Edge> ), fiber.firstEffect && show.fx && ( <Edge source={fiber.id} target={fiber.firstEffect} kind="fx" weight={100} key={`${fiber.id}-${fiber.firstEffect}-firstEffect`}> firstFx </Edge> ), fiber.lastEffect && show.fx && ( <Edge source={fiber.id} target={fiber.lastEffect} kind="fx" weight={100} key={`${fiber.id}-${fiber.lastEffect}-lastEffect`}> lastFx </Edge> ), fiber.alternate && show.alt && ( <Edge source={fiber.id} target={fiber.alternate} kind="alt" weight={10} key={`${fiber.id}-${fiber.alternate}-alt`}> alt </Edge> ), ])} </Graph> </div> ); }