mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove fiber-specific fixtures from 15.6 branch (#9902)
* Remove fixtures that only work with Fiber **what is the change?:** Removes three directories in the 'fixtures' directory. **why make this change?:** These fixtures were designed to work with Fiber, and were accidentally pulled into this branch. They were causing errors when we try to build the other fixtures. **test plan:** `cd react/fixtures && node ./build-all.js` no longer throws an error from `fiber-debugger/App.js` - although it still throws another error **issue:** https://github.com/facebook/react/issues/9900 * Add back the 'babel-standalone' fixture **what is the change?:** Add this fixture back to the 15.6 branch **why make this change?:** This fixture is not fiber specific **test plan:** `node ./build-all.js` inside of ./fixtures **issue:** https://github.com/facebook/react/issues/9900
This commit is contained in:
@@ -1 +0,0 @@
|
||||
NODE_PATH=../../build/packages
|
||||
@@ -1,14 +0,0 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# testing
|
||||
coverage
|
||||
|
||||
# production
|
||||
build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
@@ -1,25 +0,0 @@
|
||||
# Fiber Debugger
|
||||
|
||||
This is a debugger handy for visualizing how [Fiber](https://github.com/facebook/react/issues/6170) works internally.
|
||||
|
||||
**It is only meant to be used by React contributors, and not by React users.**
|
||||
|
||||
It is likely that it might get broken at some point. If it's broken, ping [Dan](https://twitter.com/dan_abramov).
|
||||
|
||||
### Running
|
||||
|
||||
First, `npm run build` in React root repo folder.
|
||||
|
||||
Then `npm install` and `npm start` in this folder.
|
||||
|
||||
Open `http://localhost:3000` in Chrome.
|
||||
|
||||
### Features
|
||||
|
||||
* Edit code that uses `ReactNoop` renderer
|
||||
* Visualize how relationships between fibers change over time
|
||||
* Current tree is displayed in green
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "react-fiber-debugger",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"react-scripts": "0.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"dagre": "^0.7.4",
|
||||
"pretty-format": "^4.2.1",
|
||||
"react-draggable": "^2.2.2",
|
||||
"react-motion": "^0.4.5"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB |
@@ -1,13 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.14.0/babel.min.js"></script>
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,196 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import Draggable from 'react-draggable';
|
||||
import ReactNoop from 'react-noop-renderer';
|
||||
import ReactFiberInstrumentation from 'react-noop-renderer/lib/ReactFiberInstrumentation';
|
||||
import Editor from './Editor';
|
||||
import Fibers from './Fibers';
|
||||
import describeFibers from './describeFibers';
|
||||
|
||||
function getFiberState(root, workInProgress) {
|
||||
if (!root) {
|
||||
return null;
|
||||
}
|
||||
return describeFibers(root.current, workInProgress);
|
||||
}
|
||||
|
||||
const defaultCode = `
|
||||
log('Render <div>Hello</div>');
|
||||
ReactNoop.render(<div>Hello</div>);
|
||||
ReactNoop.flush();
|
||||
|
||||
log('Render <h1>Goodbye</h1>');
|
||||
ReactNoop.render(<h1>Goodbye</h1>);
|
||||
ReactNoop.flush();
|
||||
`;
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
code: localStorage.getItem('fiber-debugger-code') || defaultCode,
|
||||
isEditing: false,
|
||||
history: [],
|
||||
currentStep: 0,
|
||||
show: {
|
||||
alt: false,
|
||||
child: true,
|
||||
sibling: true,
|
||||
return: false,
|
||||
fx: false,
|
||||
progressedChild: false,
|
||||
progressedDel: false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.runCode(this.state.code);
|
||||
}
|
||||
|
||||
runCode(code) {
|
||||
let currentStage;
|
||||
let currentRoot;
|
||||
|
||||
ReactFiberInstrumentation.debugTool = null;
|
||||
ReactNoop.render(null);
|
||||
ReactNoop.flush();
|
||||
ReactFiberInstrumentation.debugTool = {
|
||||
onMountContainer: (root) => {
|
||||
currentRoot = root;
|
||||
},
|
||||
onUpdateContainer: (root) => {
|
||||
currentRoot = root;
|
||||
},
|
||||
onBeginWork: (fiber) => {
|
||||
const fibers = getFiberState(currentRoot, fiber);
|
||||
const stage = currentStage;
|
||||
this.setState(({ history }) => ({
|
||||
history: [
|
||||
...history, {
|
||||
action: 'BEGIN',
|
||||
fibers,
|
||||
stage
|
||||
}
|
||||
]
|
||||
}));
|
||||
},
|
||||
onCompleteWork: (fiber) => {
|
||||
const fibers = getFiberState(currentRoot, fiber);
|
||||
const stage = currentStage;
|
||||
this.setState(({ history }) => ({
|
||||
history: [
|
||||
...history, {
|
||||
action: 'COMPLETE',
|
||||
fibers,
|
||||
stage
|
||||
}
|
||||
]
|
||||
}));
|
||||
},
|
||||
onCommitWork: (fiber) => {
|
||||
const fibers = getFiberState(currentRoot, fiber);
|
||||
const stage = currentStage;
|
||||
this.setState(({ history }) => ({
|
||||
history: [
|
||||
...history, {
|
||||
action: 'COMMIT',
|
||||
fibers,
|
||||
stage
|
||||
}
|
||||
]
|
||||
}));
|
||||
},
|
||||
};
|
||||
window.React = React;
|
||||
window.ReactNoop = ReactNoop;
|
||||
window.expect = () => ({
|
||||
toBe() {},
|
||||
toContain() {},
|
||||
toEqual() {},
|
||||
});
|
||||
window.log = s => currentStage = s;
|
||||
// eslint-disable-next-line
|
||||
eval(window.Babel.transform(code, {
|
||||
presets: ['react', 'es2015']
|
||||
}).code);
|
||||
}
|
||||
|
||||
handleEdit = (e) => {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
isEditing: true
|
||||
});
|
||||
}
|
||||
|
||||
handleCloseEdit = (nextCode) => {
|
||||
localStorage.setItem('fiber-debugger-code', nextCode);
|
||||
this.setState({
|
||||
isEditing: false,
|
||||
history: [],
|
||||
currentStep: 0,
|
||||
code: nextCode
|
||||
});
|
||||
this.runCode(nextCode);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { history, currentStep, isEditing, code } = this.state;
|
||||
if (isEditing) {
|
||||
return <Editor code={code} onClose={this.handleCloseEdit} />;
|
||||
}
|
||||
|
||||
const { fibers, action, stage } = history[currentStep] || {};
|
||||
let friendlyAction;
|
||||
if (fibers) {
|
||||
let wipFiber = fibers.descriptions[fibers.workInProgressID];
|
||||
let friendlyFiber = wipFiber.type || wipFiber.tag + ' #' + wipFiber.id;
|
||||
friendlyAction = `After ${action} on ${friendlyFiber}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ height: '100%' }}>
|
||||
{fibers &&
|
||||
<Draggable>
|
||||
<Fibers fibers={fibers} show={this.state.show} />
|
||||
</Draggable>
|
||||
}
|
||||
<div style={{
|
||||
width: '100%',
|
||||
textAlign: 'center',
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
padding: 10,
|
||||
zIndex: 1,
|
||||
backgroundColor: '#fafafa',
|
||||
border: '1px solid #ccc'
|
||||
}}>
|
||||
<input
|
||||
type="range"
|
||||
style={{ width: '25%' }}
|
||||
min={0}
|
||||
max={history.length - 1}
|
||||
value={currentStep}
|
||||
onChange={e => this.setState({ currentStep: Number(e.target.value) })}
|
||||
/>
|
||||
<p>Step {currentStep}: {friendlyAction} (<a style={{ color: 'gray' }} onClick={this.handleEdit} href='#'>Edit</a>)</p>
|
||||
{stage && <p>Stage: {stage}</p>}
|
||||
{Object.keys(this.state.show).map(key =>
|
||||
<label style={{ marginRight: '10px' }} key={key}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={this.state.show[key]}
|
||||
onChange={e => {
|
||||
this.setState(({ show }) => ({
|
||||
show: {...show, [key]: !show[key]}
|
||||
}));
|
||||
}} />
|
||||
{key}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -1,35 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
class Editor extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
code: props.code
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{
|
||||
height: '100%',
|
||||
width: '100%'
|
||||
}}>
|
||||
<textarea
|
||||
value={this.state.code}
|
||||
onChange={e => this.setState({ code: e.target.value })}
|
||||
style={{
|
||||
height: '80%',
|
||||
width: '100%',
|
||||
fontSize: '15px'
|
||||
}} />
|
||||
<div style={{ height: '20%', textAlign: 'center' }}>
|
||||
<button onClick={() => this.props.onClose(this.state.code)} style={{ fontSize: 'large' }}>
|
||||
Run
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Editor;
|
||||
@@ -1,395 +0,0 @@
|
||||
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) {
|
||||
var g = new dagre.graphlib.Graph();
|
||||
g.setGraph({
|
||||
width: 1000,
|
||||
height: 1000,
|
||||
nodesep: 50,
|
||||
edgesep: 150,
|
||||
ranksep: 150,
|
||||
marginx: 100,
|
||||
marginy: 100,
|
||||
});
|
||||
|
||||
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 = activeNode ? (winX - activeNode.x) : 0;
|
||||
var focusDy = 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',
|
||||
progressedChild: 'cyan',
|
||||
progressedDel: 'brown'
|
||||
};
|
||||
|
||||
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 'animation';
|
||||
case 4:
|
||||
return 'hi-pri work';
|
||||
case 5:
|
||||
return 'lo-pri work';
|
||||
case 6:
|
||||
return 'offscreen work';
|
||||
default:
|
||||
throw new Error('Unknown priority.');
|
||||
}
|
||||
}
|
||||
|
||||
export default function Fibers({ fibers, show, ...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}
|
||||
>
|
||||
{items.map(fiber => [
|
||||
<Vertex
|
||||
key={fiber.id}
|
||||
width={200}
|
||||
height={100}
|
||||
isActive={fiber.id === fibers.workInProgressID}>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: getFiberColor(fibers, fiber.id)
|
||||
}}
|
||||
title={prettyFormat(fiber, { plugins: [reactElement ]})}>
|
||||
<small>{fiber.tag} #{fiber.id}</small>
|
||||
<br />
|
||||
{fiber.type}
|
||||
<br />
|
||||
{fibers.currentIDs.indexOf(fiber.id) === -1 ?
|
||||
<small>
|
||||
{fiber.pendingWorkPriority !== 0 && [
|
||||
<span style={{
|
||||
fontWeight: fiber.pendingWorkPriority <= fiber.progressedPriority ?
|
||||
'bold' :
|
||||
'normal'
|
||||
}} key="span">
|
||||
Needs: {formatPriority(fiber.pendingWorkPriority)}
|
||||
</span>,
|
||||
<br key="br" />
|
||||
]}
|
||||
{fiber.progressedPriority !== 0 && [
|
||||
`Finished: ${formatPriority(fiber.progressedPriority)}`,
|
||||
<br key="br" />
|
||||
]}
|
||||
{fiber.memoizedProps !== null && fiber.pendingProps !== null && [
|
||||
fiber.memoizedProps === fiber.pendingProps ?
|
||||
'Can reuse memoized.' :
|
||||
'Cannot reuse memoized.',
|
||||
<br />
|
||||
]}
|
||||
</small> :
|
||||
<small>
|
||||
Committed
|
||||
</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.progressedChild && show.progressedChild &&
|
||||
<Edge
|
||||
source={fiber.id}
|
||||
target={fiber.progressedChild}
|
||||
kind="progressedChild"
|
||||
weight={1000}
|
||||
key={`${fiber.id}-${fiber.progressedChild}-pChild`}>
|
||||
pChild
|
||||
</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.progressedFirstDeletion && show.progressedDel &&
|
||||
<Edge
|
||||
source={fiber.id}
|
||||
target={fiber.progressedFirstDeletion}
|
||||
kind="progressedDel"
|
||||
weight={100}
|
||||
key={`${fiber.id}-${fiber.progressedFirstDeletion}-pFD`}>
|
||||
pFDel
|
||||
</Edge>,
|
||||
fiber.progressedLastDeletion && show.progressedDel &&
|
||||
<Edge
|
||||
source={fiber.id}
|
||||
target={fiber.progressedLastDeletion}
|
||||
kind="progressedDel"
|
||||
weight={100}
|
||||
key={`${fiber.id}-${fiber.progressedLastDeletion}-pLD`}>
|
||||
pLDel
|
||||
</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>
|
||||
);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
let nextFiberID = 1;
|
||||
const fiberIDMap = new WeakMap();
|
||||
|
||||
function getFiberUniqueID(fiber) {
|
||||
if (!fiberIDMap.has(fiber)) {
|
||||
fiberIDMap.set(fiber, nextFiberID++);
|
||||
}
|
||||
return fiberIDMap.get(fiber);
|
||||
}
|
||||
|
||||
function getFriendlyTag(tag) {
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return '[indeterminate]';
|
||||
case 1:
|
||||
return '[fn]';
|
||||
case 2:
|
||||
return '[class]';
|
||||
case 3:
|
||||
return '[root]';
|
||||
case 4:
|
||||
return '[portal]';
|
||||
case 5:
|
||||
return '[host]';
|
||||
case 6:
|
||||
return '[text]';
|
||||
case 7:
|
||||
return '[coroutine]';
|
||||
case 8:
|
||||
return '[handler]';
|
||||
case 9:
|
||||
return '[yield]';
|
||||
case 10:
|
||||
return '[frag]';
|
||||
default:
|
||||
throw new Error('Unknown tag.');
|
||||
}
|
||||
}
|
||||
|
||||
export default function describeFibers(rootFiber, workInProgress) {
|
||||
let descriptions = {};
|
||||
function acknowledgeFiber(fiber) {
|
||||
if (!fiber) {
|
||||
return null;
|
||||
}
|
||||
if (!fiber.return && fiber.tag !== 3) {
|
||||
return null;
|
||||
}
|
||||
const id = getFiberUniqueID(fiber);
|
||||
if (descriptions[id]) {
|
||||
return id;
|
||||
}
|
||||
descriptions[id] = {};
|
||||
Object.assign(descriptions[id], {
|
||||
...fiber,
|
||||
id: id,
|
||||
tag: getFriendlyTag(fiber.tag),
|
||||
type: (fiber.type && ('<' + (fiber.type.name || fiber.type) + '>')),
|
||||
stateNode: `[${typeof fiber.stateNode}]`,
|
||||
return: acknowledgeFiber(fiber.return),
|
||||
child: acknowledgeFiber(fiber.child),
|
||||
sibling: acknowledgeFiber(fiber.sibling),
|
||||
nextEffect: acknowledgeFiber(fiber.nextEffect),
|
||||
firstEffect: acknowledgeFiber(fiber.firstEffect),
|
||||
lastEffect: acknowledgeFiber(fiber.lastEffect),
|
||||
progressedChild: acknowledgeFiber(fiber.progressedChild),
|
||||
progressedFirstDeletion: acknowledgeFiber(fiber.progressedFirstDeletion),
|
||||
progressedLastDeletion: acknowledgeFiber(fiber.progressedLastDeletion),
|
||||
alternate: acknowledgeFiber(fiber.alternate),
|
||||
});
|
||||
return id;
|
||||
}
|
||||
|
||||
const rootID = acknowledgeFiber(rootFiber);
|
||||
const workInProgressID = acknowledgeFiber(workInProgress);
|
||||
|
||||
let currentIDs = new Set();
|
||||
function markAsCurent(id) {
|
||||
currentIDs.add(id);
|
||||
const fiber = descriptions[id];
|
||||
if (fiber.sibling) {
|
||||
markAsCurent(fiber.sibling);
|
||||
}
|
||||
if (fiber.child) {
|
||||
markAsCurent(fiber.child);
|
||||
}
|
||||
}
|
||||
markAsCurent(rootID);
|
||||
|
||||
return {
|
||||
descriptions,
|
||||
rootID,
|
||||
currentIDs: Array.from(currentIDs),
|
||||
workInProgressID
|
||||
};
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
height: 100vh;
|
||||
cursor: -webkit-grab; cursor: -moz-grab;
|
||||
}
|
||||
|
||||
#root {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
import './index.css';
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('root')
|
||||
);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Fiber Example</title>
|
||||
<link rel="stylesheet" href="../shared/css/base.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Fiber Example</h1>
|
||||
<div id="container">
|
||||
<p>
|
||||
To install React, follow the instructions on
|
||||
<a href="https://github.com/facebook/react/">GitHub</a>.
|
||||
</p>
|
||||
<p>
|
||||
If you can see this, React is <strong>not</strong> working right.
|
||||
If you checked out the source from GitHub make sure to run <code>grunt</code>.
|
||||
</p>
|
||||
</div>
|
||||
<script src="../../build/react.js"></script>
|
||||
<script src="../../build/react-dom-fiber.js"></script>
|
||||
<script>
|
||||
function ExampleApplication(props) {
|
||||
var elapsed = Math.round(props.elapsed / 100);
|
||||
var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' );
|
||||
var message =
|
||||
'React has been successfully running for ' + seconds + ' seconds.';
|
||||
|
||||
return React.DOM.p(null, message);
|
||||
}
|
||||
|
||||
// Call React.createFactory instead of directly call ExampleApplication({...}) in React.render
|
||||
var ExampleApplicationFactory = React.createFactory(ExampleApplication);
|
||||
|
||||
var start = new Date().getTime();
|
||||
setInterval(function() {
|
||||
ReactDOMFiber.render(
|
||||
ExampleApplicationFactory({elapsed: new Date().getTime() - start}),
|
||||
document.getElementById('container')
|
||||
);
|
||||
}, 50);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user