Compare commits
23 Commits
devtools-v
...
unrevert
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7b984349c | ||
|
|
32d221a9a9 | ||
|
|
507f0fb372 | ||
|
|
efa5dbe7a5 | ||
|
|
da0a47bec3 | ||
|
|
69aafbf4df | ||
|
|
c80678c760 | ||
|
|
2d68bd0960 | ||
|
|
96eb703bbf | ||
|
|
56f93a7f38 | ||
|
|
dce430ad92 | ||
|
|
6ae6a7c020 | ||
|
|
56d1b0fb59 | ||
|
|
e89c19d16c | ||
|
|
d97af798d2 | ||
|
|
21e793fb4f | ||
|
|
c1d3f7f1a9 | ||
|
|
6f86294e68 | ||
|
|
600c57a9b9 | ||
|
|
9b5985b3c1 | ||
|
|
ebd1f5ddb0 | ||
|
|
a9304e79d4 | ||
|
|
6edff8f5e1 |
@@ -12,10 +12,3 @@ scripts/bench/benchmarks/**/*.js
|
||||
|
||||
# React repository clone
|
||||
scripts/bench/remote-repo/
|
||||
|
||||
packages/react-devtools-core/dist
|
||||
packages/react-devtools-extensions/chrome/build
|
||||
packages/react-devtools-extensions/firefox/build
|
||||
packages/react-devtools-extensions/shared/build
|
||||
packages/react-devtools-inline/dist
|
||||
packages/react-devtools-shell/dist
|
||||
11
.gitignore
vendored
@@ -22,14 +22,3 @@ chrome-user-data
|
||||
.vscode
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
packages/react-devtools-core/dist
|
||||
packages/react-devtools-extensions/chrome/build
|
||||
packages/react-devtools-extensions/chrome/*.crx
|
||||
packages/react-devtools-extensions/chrome/*.pem
|
||||
packages/react-devtools-extensions/firefox/build
|
||||
packages/react-devtools-extensions/firefox/*.xpi
|
||||
packages/react-devtools-extensions/firefox/*.pem
|
||||
packages/react-devtools-extensions/shared/build
|
||||
packages/react-devtools-inline/dist
|
||||
packages/react-devtools-shell/dist
|
||||
@@ -1,6 +0,0 @@
|
||||
packages/react-devtools-core/dist
|
||||
packages/react-devtools-extensions/chrome/build
|
||||
packages/react-devtools-extensions/firefox/build
|
||||
packages/react-devtools-extensions/shared/build
|
||||
packages/react-devtools-inline/dist
|
||||
packages/react-devtools-shell/dist
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 14.9</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@0.14.9/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@0.14.9/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/14.9.html">http://localhost:3000/fixtures/regression/14.9.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 15.0</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@15.0/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.0/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/15.0.html">http://localhost:3000/fixtures/regression/15.0.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 15.1</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@15.1/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.1/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/15.1.html">http://localhost:3000/fixtures/regression/15.1.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 15.2</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@15.2/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.2/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/15.2.html">http://localhost:3000/fixtures/regression/15.2.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 15.3</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@15.3/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.3/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/15.3.html">http://localhost:3000/fixtures/regression/15.3.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 15.4</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@15.4/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.4/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/15.4.html">http://localhost:3000/fixtures/regression/15.4.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 15.5</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@15.5/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.5/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/15.5.html">http://localhost:3000/fixtures/regression/15.5.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 15.6</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@15.6/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.6/dist/react-dom.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/15.6.html">http://localhost:3000/fixtures/regression/15.6.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.0</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@16.0/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.0/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.0.html">http://localhost:3000/fixtures/regression/16.0.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.1</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@16.1/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.1/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.1.html">http://localhost:3000/fixtures/regression/16.1.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.2</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@16.2/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.2/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.2.html">http://localhost:3000/fixtures/regression/16.2.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.3</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@16.3/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.3/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.3.html">http://localhost:3000/fixtures/regression/16.3.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.4</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/react@16.4/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.4/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.4.html">http://localhost:3000/fixtures/regression/16.4.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.5</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/schedule@0.5.0/umd/schedule.development.js"></script>
|
||||
<script src="https://unpkg.com/schedule@0.5.0/umd/schedule-tracing.development.js"></script>
|
||||
<script src="https://unpkg.com/react@16.5/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.5/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.5.html">http://localhost:3000/fixtures/regression/16.5.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,41 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.6</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/scheduler@0.10.0/umd/scheduler.development.js"></script>
|
||||
<script src="https://unpkg.com/scheduler@0.10.0/umd/scheduler-tracing.development.js"></script>
|
||||
<script src="https://unpkg.com/react@16.6/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.6/umd/react-dom.development.js"></script>
|
||||
<script src="https://unpkg.com/react-cache@2.0.0-alpha.1/umd/react-cache.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.6.html">http://localhost:3000/fixtures/regression/16.6.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,41 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React 16.7</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/scheduler@0.12.0/umd/scheduler.development.js"></script>
|
||||
<script src="https://unpkg.com/scheduler@0.12.0/umd/scheduler-tracing.development.js"></script>
|
||||
<script src="https://unpkg.com/react@16.7/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16.7/umd/react-dom.development.js"></script>
|
||||
<script src="https://unpkg.com/react-cache@2.0.0-alpha.1/umd/react-cache.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/16.7.html">http://localhost:3000/fixtures/regression/16.7.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,41 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React canary</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/scheduler@canary/umd/scheduler.development.js"></script>
|
||||
<script src="https://unpkg.com/scheduler@canary/umd/scheduler-tracing.development.js"></script>
|
||||
<script src="https://unpkg.com/react@canary/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@canary/umd/react-dom.development.js"></script>
|
||||
<script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/canary.html">http://localhost:3000/fixtures/regression/canary.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,28 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React DevTools regression test</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="canary.html"></iframe>
|
||||
<iframe src="next.html"></iframe>
|
||||
<iframe src="16.7.html"></iframe>
|
||||
<iframe src="16.6.html"></iframe>
|
||||
<iframe src="16.5.html"></iframe>
|
||||
<iframe src="16.4.html"></iframe>
|
||||
<iframe src="16.3.html"></iframe>
|
||||
<iframe src="16.2.html"></iframe>
|
||||
<iframe src="16.1.html"></iframe>
|
||||
<iframe src="16.0.html"></iframe>
|
||||
<iframe src="15.6.html"></iframe>
|
||||
<iframe src="15.5.html"></iframe>
|
||||
<iframe src="15.4.html"></iframe>
|
||||
<iframe src="15.3.html"></iframe>
|
||||
<iframe src="15.2.html"></iframe>
|
||||
<iframe src="15.1.html"></iframe>
|
||||
<iframe src="15.0.html"></iframe>
|
||||
<iframe src="14.9.html"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,41 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>React next</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
// Enable DevTools to inspect React inside of an <iframe>
|
||||
// This must run before React is loaded
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
</script>
|
||||
|
||||
<script src="https://unpkg.com/scheduler@next/umd/scheduler.development.js"></script>
|
||||
<script src="https://unpkg.com/scheduler@next/umd/scheduler-tracing.development.js"></script>
|
||||
<script src="https://unpkg.com/react@next/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@next/umd/react-dom.development.js"></script>
|
||||
<script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
|
||||
<br/><br/>
|
||||
Use the <code>server</code> script instead:
|
||||
<br/><br/>
|
||||
<code>node ./fixtures/regression/server.js</code><br/>
|
||||
<code>open <a href="http://localhost:3000/fixtures/regression/next.html">http://localhost:3000/fixtures/regression/next.html</a></code>
|
||||
</div>
|
||||
|
||||
<script src="shared.js" type="text/babel"></script>
|
||||
|
||||
<!--
|
||||
This is a great way to try React but it's not suitable for production.
|
||||
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
|
||||
Learn more at https://reactjs.org/docs/getting-started.html
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const finalhandler = require('finalhandler');
|
||||
const http = require('http');
|
||||
const serveStatic = require('serve-static');
|
||||
|
||||
// Serve fixtures folder
|
||||
const serve = serveStatic(__dirname, {index: 'index.html'});
|
||||
|
||||
// Create server
|
||||
const server = http.createServer(function onRequest(req, res) {
|
||||
serve(req, res, finalhandler(req, res));
|
||||
});
|
||||
|
||||
// Listen
|
||||
server.listen(3000);
|
||||
@@ -1,328 +0,0 @@
|
||||
/* eslint-disable no-fallthrough, react/react-in-jsx-scope, react/jsx-no-undef */
|
||||
/* global React ReactCache ReactDOM SchedulerTracing ScheduleTracing */
|
||||
|
||||
const apps = [];
|
||||
|
||||
const pieces = React.version.split('.');
|
||||
const major =
|
||||
pieces[0] === '0' ? parseInt(pieces[1], 10) : parseInt(pieces[0], 10);
|
||||
const minor =
|
||||
pieces[0] === '0' ? parseInt(pieces[2], 10) : parseInt(pieces[1], 10);
|
||||
|
||||
// Convenience wrapper to organize API features in DevTools.
|
||||
function Feature({children, label, version}) {
|
||||
return (
|
||||
<div className="Feature">
|
||||
<div className="FeatureHeader">
|
||||
<code className="FeatureCode">{label}</code>
|
||||
<small>{version}</small>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Simplify interaction tracing for tests below.
|
||||
let trace = null;
|
||||
if (typeof SchedulerTracing !== 'undefined') {
|
||||
trace = SchedulerTracing.unstable_trace;
|
||||
} else if (typeof ScheduleTracing !== 'undefined') {
|
||||
trace = ScheduleTracing.unstable_trace;
|
||||
} else {
|
||||
trace = (_, __, callback) => callback();
|
||||
}
|
||||
|
||||
// https://github.com/facebook/react/blob/master/CHANGELOG.md
|
||||
switch (major) {
|
||||
case 16:
|
||||
switch (minor) {
|
||||
case 7:
|
||||
if (typeof React.useState === 'function') {
|
||||
// Hooks
|
||||
function Hooks() {
|
||||
const [count, setCount] = React.useState(0);
|
||||
const incrementCount = React.useCallback(
|
||||
() => setCount(count + 1),
|
||||
[count]
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
count: {count}{' '}
|
||||
<button onClick={incrementCount}>increment</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
apps.push(
|
||||
<Feature key="Hooks" label="Hooks" version="16.7+">
|
||||
<Hooks />
|
||||
</Feature>
|
||||
);
|
||||
}
|
||||
case 6:
|
||||
// memo
|
||||
function LabelComponent({label}) {
|
||||
return <label>{label}</label>;
|
||||
}
|
||||
const AnonymousMemoized = React.memo(({label}) => (
|
||||
<label>{label}</label>
|
||||
));
|
||||
const Memoized = React.memo(LabelComponent);
|
||||
const CustomMemoized = React.memo(LabelComponent);
|
||||
CustomMemoized.displayName = 'MemoizedLabelFunction';
|
||||
apps.push(
|
||||
<Feature key="memo" label="memo" version="16.6+">
|
||||
<AnonymousMemoized label="AnonymousMemoized" />
|
||||
<Memoized label="Memoized" />
|
||||
<CustomMemoized label="CustomMemoized" />
|
||||
</Feature>
|
||||
);
|
||||
|
||||
// Suspense
|
||||
const loadResource = ([text, ms]) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve(text);
|
||||
}, ms);
|
||||
});
|
||||
};
|
||||
const getResourceKey = ([text, ms]) => text;
|
||||
const Resource = ReactCache.unstable_createResource(
|
||||
loadResource,
|
||||
getResourceKey
|
||||
);
|
||||
class Suspending extends React.Component {
|
||||
state = {useSuspense: false};
|
||||
useSuspense = () => this.setState({useSuspense: true});
|
||||
render() {
|
||||
if (this.state.useSuspense) {
|
||||
const text = Resource.read(['loaded', 2000]);
|
||||
return text;
|
||||
} else {
|
||||
return <button onClick={this.useSuspense}>load data</button>;
|
||||
}
|
||||
}
|
||||
}
|
||||
apps.push(
|
||||
<Feature key="Suspense" label="Suspense" version="16.6+">
|
||||
<React.Suspense fallback={<div>loading...</div>}>
|
||||
<Suspending />
|
||||
</React.Suspense>
|
||||
</Feature>
|
||||
);
|
||||
|
||||
// lazy
|
||||
const LazyWithDefaultProps = React.lazy(
|
||||
() =>
|
||||
new Promise(resolve => {
|
||||
function FooWithDefaultProps(props) {
|
||||
return (
|
||||
<h1>
|
||||
{props.greeting}, {props.name}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
FooWithDefaultProps.defaultProps = {
|
||||
name: 'World',
|
||||
greeting: 'Bonjour',
|
||||
};
|
||||
resolve({
|
||||
default: FooWithDefaultProps,
|
||||
});
|
||||
})
|
||||
);
|
||||
apps.push(
|
||||
<Feature key="lazy" label="lazy" version="16.6+">
|
||||
<React.Suspense fallback={<div>loading...</div>}>
|
||||
<LazyWithDefaultProps greeting="Hello" />
|
||||
</React.Suspense>
|
||||
</Feature>
|
||||
);
|
||||
case 5:
|
||||
case 4:
|
||||
// unstable_Profiler
|
||||
class ProfilerChild extends React.Component {
|
||||
state = {count: 0};
|
||||
incrementCount = () =>
|
||||
this.setState(prevState => ({count: prevState.count + 1}));
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
count: {this.state.count}{' '}
|
||||
<button onClick={this.incrementCount}>increment</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
const onRender = (...args) => {};
|
||||
const Profiler = React.unstable_Profiler || React.Profiler;
|
||||
apps.push(
|
||||
<Feature
|
||||
key="unstable_Profiler"
|
||||
label="unstable_Profiler"
|
||||
version="16.4+">
|
||||
<Profiler id="count" onRender={onRender}>
|
||||
<div>
|
||||
<ProfilerChild />
|
||||
</div>
|
||||
</Profiler>
|
||||
</Feature>
|
||||
);
|
||||
case 3:
|
||||
// createContext()
|
||||
const LocaleContext = React.createContext();
|
||||
LocaleContext.displayName = 'LocaleContext';
|
||||
const ThemeContext = React.createContext();
|
||||
apps.push(
|
||||
<Feature key="createContext" label="createContext" version="16.3+">
|
||||
<ThemeContext.Provider value="blue">
|
||||
<ThemeContext.Consumer>
|
||||
{theme => <div>theme: {theme}</div>}
|
||||
</ThemeContext.Consumer>
|
||||
</ThemeContext.Provider>
|
||||
<LocaleContext.Provider value="en-US">
|
||||
<LocaleContext.Consumer>
|
||||
{locale => <div>locale: {locale}</div>}
|
||||
</LocaleContext.Consumer>
|
||||
</LocaleContext.Provider>
|
||||
</Feature>
|
||||
);
|
||||
|
||||
// forwardRef()
|
||||
const AnonymousFunction = React.forwardRef((props, ref) => (
|
||||
<div ref={ref}>{props.children}</div>
|
||||
));
|
||||
const NamedFunction = React.forwardRef(function named(props, ref) {
|
||||
return <div ref={ref}>{props.children}</div>;
|
||||
});
|
||||
const CustomName = React.forwardRef((props, ref) => (
|
||||
<div ref={ref}>{props.children}</div>
|
||||
));
|
||||
CustomName.displayName = 'CustomNameForwardRef';
|
||||
apps.push(
|
||||
<Feature key="forwardRef" label="forwardRef" version="16.3+">
|
||||
<AnonymousFunction>AnonymousFunction</AnonymousFunction>
|
||||
<NamedFunction>NamedFunction</NamedFunction>
|
||||
<CustomName>CustomName</CustomName>
|
||||
</Feature>
|
||||
);
|
||||
|
||||
// StrictMode
|
||||
class StrictModeChild extends React.Component {
|
||||
render() {
|
||||
return 'StrictModeChild';
|
||||
}
|
||||
}
|
||||
apps.push(
|
||||
<Feature key="StrictMode" label="StrictMode" version="16.3+">
|
||||
<React.StrictMode>
|
||||
<StrictModeChild />
|
||||
</React.StrictMode>
|
||||
</Feature>
|
||||
);
|
||||
|
||||
// unstable_AsyncMode (later renamed to unstable_ConcurrentMode, then ConcurrentMode)
|
||||
const ConcurrentMode =
|
||||
React.ConcurrentMode ||
|
||||
React.unstable_ConcurrentMode ||
|
||||
React.unstable_AsyncMode;
|
||||
apps.push(
|
||||
<Feature
|
||||
key="AsyncMode/ConcurrentMode"
|
||||
label="AsyncMode/ConcurrentMode"
|
||||
version="16.3+">
|
||||
<ConcurrentMode>
|
||||
<div>
|
||||
unstable_AsyncMode was added in 16.3, renamed to
|
||||
unstable_ConcurrentMode in 16.5, and then renamed to
|
||||
ConcurrentMode in 16.7
|
||||
</div>
|
||||
</ConcurrentMode>
|
||||
</Feature>
|
||||
);
|
||||
case 2:
|
||||
// Fragment
|
||||
apps.push(
|
||||
<Feature key="Fragment" label="Fragment" version="16.4+">
|
||||
<React.Fragment>
|
||||
<div>one</div>
|
||||
<div>two</div>
|
||||
</React.Fragment>
|
||||
</Feature>
|
||||
);
|
||||
case 1:
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
break;
|
||||
case 14:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
function Even() {
|
||||
return <small>(even)</small>;
|
||||
}
|
||||
|
||||
// Simple stateful app shared by all React versions
|
||||
class SimpleApp extends React.Component {
|
||||
state = {count: 0};
|
||||
incrementCount = () => {
|
||||
const updaterFn = prevState => ({count: prevState.count + 1});
|
||||
trace('Updating count', performance.now(), () => this.setState(updaterFn));
|
||||
};
|
||||
render() {
|
||||
const {count} = this.state;
|
||||
return (
|
||||
<div>
|
||||
{count % 2 === 0 ? (
|
||||
<span>
|
||||
count: {count} <Even />
|
||||
</span>
|
||||
) : (
|
||||
<span>count: {count}</span>
|
||||
)}{' '}
|
||||
<button onClick={this.incrementCount}>increment</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
apps.push(
|
||||
<Feature key="Simple stateful app" label="Simple stateful app" version="any">
|
||||
<SimpleApp />
|
||||
</Feature>
|
||||
);
|
||||
|
||||
// This component, with the version prop, helps organize DevTools at a glance.
|
||||
function TopLevelWrapperForDevTools({version}) {
|
||||
let header = <h1>React {version}</h1>;
|
||||
if (version.includes('canary')) {
|
||||
const commitSha = version.match(/.+canary-(.+)/)[1];
|
||||
header = (
|
||||
<h1>
|
||||
React canary{' '}
|
||||
<a href={`https://github.com/facebook/react/commit/${commitSha}`}>
|
||||
{commitSha}
|
||||
</a>
|
||||
</h1>
|
||||
);
|
||||
} else if (version.includes('alpha')) {
|
||||
header = <h1>React next</h1>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{header}
|
||||
{apps}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
TopLevelWrapperForDevTools.displayName = 'React';
|
||||
|
||||
ReactDOM.render(
|
||||
<TopLevelWrapperForDevTools version={React.version} />,
|
||||
document.getElementById('root')
|
||||
);
|
||||
@@ -1,37 +0,0 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 1rem 0 0;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
code {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.Feature {
|
||||
margin: 1rem 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
.FeatureHeader {
|
||||
font-size: 16px;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.FeatureCode {
|
||||
background-color: #eee;
|
||||
padding: 0.25rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>TODO List</title>
|
||||
|
||||
<!-- DevTools -->
|
||||
<script src="http://localhost:8097"></script>
|
||||
|
||||
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Don't use this in production: -->
|
||||
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
.Input {
|
||||
font-size: 1rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.IconButton {
|
||||
padding: 0.25rem;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.List {
|
||||
margin: 0.5rem 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ListItem {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.Label {
|
||||
cursor: pointer;
|
||||
padding: 0.25rem;
|
||||
color: #555;
|
||||
}
|
||||
.Label:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.IconButton {
|
||||
padding: 0.25rem;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="text/babel">
|
||||
const { Fragment, useCallback, useState } = React;
|
||||
|
||||
function List(props) {
|
||||
const [newItemText, setNewItemText] = useState("");
|
||||
const [items, setItems] = useState([
|
||||
{ id: 1, isComplete: true, text: "First" },
|
||||
{ id: 2, isComplete: true, text: "Second" },
|
||||
{ id: 3, isComplete: false, text: "Third" }
|
||||
]);
|
||||
const [uid, setUID] = useState(4);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (newItemText !== "") {
|
||||
setItems([
|
||||
...items,
|
||||
{
|
||||
id: uid,
|
||||
isComplete: false,
|
||||
text: newItemText
|
||||
}
|
||||
]);
|
||||
setUID(uid + 1);
|
||||
setNewItemText("");
|
||||
}
|
||||
}, [newItemText, items, uid]);
|
||||
|
||||
const handleKeyPress = useCallback(
|
||||
event => {
|
||||
if (event.key === "Enter") {
|
||||
handleClick();
|
||||
}
|
||||
},
|
||||
[handleClick]
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
event => {
|
||||
setNewItemText(event.currentTarget.value);
|
||||
},
|
||||
[setNewItemText]
|
||||
);
|
||||
|
||||
const removeItem = useCallback(
|
||||
itemToRemove => setItems(items.filter(item => item !== itemToRemove)),
|
||||
[items]
|
||||
);
|
||||
|
||||
const toggleItem = useCallback(
|
||||
itemToToggle => {
|
||||
const index = items.indexOf(itemToToggle);
|
||||
|
||||
setItems(
|
||||
items
|
||||
.slice(0, index)
|
||||
.concat({
|
||||
...itemToToggle,
|
||||
isComplete: !itemToToggle.isComplete
|
||||
})
|
||||
.concat(items.slice(index + 1))
|
||||
);
|
||||
},
|
||||
[items]
|
||||
);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<h1>List</h1>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="New list item..."
|
||||
className="Input"
|
||||
value={newItemText}
|
||||
onChange={handleChange}
|
||||
onKeyPress={handleKeyPress}
|
||||
/>
|
||||
<button
|
||||
className="IconButton"
|
||||
disabled={newItemText === ""}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<span role="img" aria-label="Add item">
|
||||
➕
|
||||
</span>
|
||||
</button>
|
||||
<ul className="List">
|
||||
{items.map(item => (
|
||||
<ListItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
removeItem={removeItem}
|
||||
toggleItem={toggleItem}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
function ListItem({ item, removeItem, toggleItem }) {
|
||||
const handleDelete = useCallback(() => {
|
||||
removeItem(item);
|
||||
}, [item, removeItem]);
|
||||
|
||||
const handleToggle = useCallback(() => {
|
||||
toggleItem(item);
|
||||
}, [item, toggleItem]);
|
||||
|
||||
return (
|
||||
<li className="ListItem">
|
||||
<button className="IconButton" onClick={handleDelete}>
|
||||
🗑
|
||||
</button>
|
||||
<label className="Label">
|
||||
<input
|
||||
className="Input"
|
||||
checked={item.isComplete}
|
||||
onChange={handleToggle}
|
||||
type="checkbox"
|
||||
/>{" "}
|
||||
{item.text}
|
||||
</label>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
function SimpleValues() {
|
||||
return (
|
||||
<ChildComponent
|
||||
string="abc"
|
||||
emptyString=""
|
||||
number={123}
|
||||
undefined={undefined}
|
||||
null={null}
|
||||
nan={NaN}
|
||||
infinity={Infinity}
|
||||
true={true}
|
||||
false={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
class Custom {
|
||||
_number = 42;
|
||||
get number() {
|
||||
return this._number;
|
||||
}
|
||||
}
|
||||
|
||||
function CustomObject() {
|
||||
return <ChildComponent customObject={new Custom()} />;
|
||||
}
|
||||
|
||||
const object = {
|
||||
string: "abc",
|
||||
longString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKJLMNOPQRSTUVWXYZ1234567890",
|
||||
emptyString: "",
|
||||
number: 123,
|
||||
boolean: true,
|
||||
undefined: undefined,
|
||||
null: null
|
||||
};
|
||||
|
||||
function ObjectProps() {
|
||||
return (
|
||||
<ChildComponent
|
||||
object={{
|
||||
outer: {
|
||||
inner: object
|
||||
}
|
||||
}}
|
||||
array={["first", "second", "third"]}
|
||||
objectInArray={[object]}
|
||||
arrayInObject={{ array: ["first", "second", "third"] }}
|
||||
deepObject={{
|
||||
// Known limitation: we won't go deeper than several levels.
|
||||
// In the future, we might offer a way to request deeper access on demand.
|
||||
a: {
|
||||
b: {
|
||||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: {
|
||||
g: {
|
||||
h: {
|
||||
i: {
|
||||
j: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function ChildComponent(props: any) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function InspectableElements() {
|
||||
return (
|
||||
<Fragment>
|
||||
<SimpleValues />
|
||||
<ObjectProps />
|
||||
<CustomObject />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Fragment>
|
||||
<List />
|
||||
<InspectableElements />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -19,8 +19,17 @@ ESLintTester.setDefaultConfig({
|
||||
},
|
||||
});
|
||||
|
||||
const eslintTester = new ESLintTester();
|
||||
eslintTester.run('react-hooks', ReactHooksESLintRule, {
|
||||
// ***************************************************
|
||||
// For easier local testing, you can add to any case:
|
||||
// {
|
||||
// skip: true,
|
||||
// --or--
|
||||
// only: true,
|
||||
// ...
|
||||
// }
|
||||
// ***************************************************
|
||||
|
||||
const tests = {
|
||||
valid: [
|
||||
`
|
||||
// Valid because components can use hooks.
|
||||
@@ -223,21 +232,20 @@ eslintTester.run('react-hooks', ReactHooksESLintRule, {
|
||||
(class {i() { useState(); }});
|
||||
`,
|
||||
`
|
||||
// Currently valid although we *could* consider these invalid.
|
||||
// It doesn't make a lot of difference because it would crash early.
|
||||
// Valid because they're not matching use[A-Z].
|
||||
fooState();
|
||||
use();
|
||||
_use();
|
||||
useState();
|
||||
_useState();
|
||||
use42();
|
||||
useHook();
|
||||
use_hook();
|
||||
React.useState();
|
||||
`,
|
||||
`
|
||||
// Regression test for the popular "history" library
|
||||
const {createHistory, useBasename} = require('history-2.1.2');
|
||||
const browserHistory = useBasename(createHistory)({
|
||||
// This is grey area.
|
||||
// Currently it's valid (although React.useCallback would fail here).
|
||||
// We could also get stricter and disallow it, just like we did
|
||||
// with non-namespace use*() top-level calls.
|
||||
const History = require('history-2.1.2');
|
||||
const browserHistory = History.useBasename(History.createHistory)({
|
||||
basename: '/',
|
||||
});
|
||||
`,
|
||||
@@ -669,8 +677,63 @@ eslintTester.run('react-hooks', ReactHooksESLintRule, {
|
||||
conditionalError('useState'),
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `
|
||||
// Invalid because it's dangerous and might not warn otherwise.
|
||||
// This *must* be invalid.
|
||||
function useHook({ bar }) {
|
||||
let foo1 = bar && useState();
|
||||
let foo2 = bar || useState();
|
||||
let foo3 = bar ?? useState();
|
||||
}
|
||||
`,
|
||||
errors: [
|
||||
conditionalError('useState'),
|
||||
conditionalError('useState'),
|
||||
// TODO: ideally this *should* warn, but ESLint
|
||||
// doesn't plan full support for ?? until it advances.
|
||||
// conditionalError('useState'),
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `
|
||||
// Invalid because it's dangerous.
|
||||
// Normally, this would crash, but not if you use inline requires.
|
||||
// This *must* be invalid.
|
||||
// It's expected to have some false positives, but arguably
|
||||
// they are confusing anyway due to the use*() convention
|
||||
// already being associated with Hooks.
|
||||
useState();
|
||||
if (foo) {
|
||||
const foo = React.useCallback(() => {});
|
||||
}
|
||||
useCustomHook();
|
||||
`,
|
||||
errors: [
|
||||
topLevelError('useState'),
|
||||
topLevelError('React.useCallback'),
|
||||
topLevelError('useCustomHook'),
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `
|
||||
// Technically this is a false positive.
|
||||
// We *could* make it valid (and it used to be).
|
||||
//
|
||||
// However, top-level Hook-like calls can be very dangerous
|
||||
// in environments with inline requires because they can mask
|
||||
// the runtime error by accident.
|
||||
// So we prefer to disallow it despite the false positive.
|
||||
|
||||
const {createHistory, useBasename} = require('history-2.1.2');
|
||||
const browserHistory = useBasename(createHistory)({
|
||||
basename: '/',
|
||||
});
|
||||
`,
|
||||
errors: [topLevelError('useBasename')],
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
function conditionalError(hook, hasPreviousFinalizer = false) {
|
||||
return {
|
||||
@@ -708,3 +771,42 @@ function genericError(hook) {
|
||||
'Hook function.',
|
||||
};
|
||||
}
|
||||
|
||||
function topLevelError(hook) {
|
||||
return {
|
||||
message:
|
||||
`React Hook "${hook}" cannot be called at the top level. React Hooks ` +
|
||||
'must be called in a React function component or a custom React ' +
|
||||
'Hook function.',
|
||||
};
|
||||
}
|
||||
|
||||
// For easier local testing
|
||||
if (!process.env.CI) {
|
||||
let only = [];
|
||||
let skipped = [];
|
||||
[...tests.valid, ...tests.invalid].forEach(t => {
|
||||
if (t.skip) {
|
||||
delete t.skip;
|
||||
skipped.push(t);
|
||||
}
|
||||
if (t.only) {
|
||||
delete t.only;
|
||||
only.push(t);
|
||||
}
|
||||
});
|
||||
const predicate = t => {
|
||||
if (only.length > 0) {
|
||||
return only.indexOf(t) !== -1;
|
||||
}
|
||||
if (skipped.length > 0) {
|
||||
return skipped.indexOf(t) === -1;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
tests.valid = tests.valid.filter(predicate);
|
||||
tests.invalid = tests.invalid.filter(predicate);
|
||||
}
|
||||
|
||||
const eslintTester = new ESLintTester();
|
||||
eslintTester.run('react-hooks', ReactHooksESLintRule, tests);
|
||||
|
||||
@@ -432,9 +432,12 @@ export default {
|
||||
'React Hook function.';
|
||||
context.report({node: hook, message});
|
||||
} else if (codePathNode.type === 'Program') {
|
||||
// For now, ignore if it's in top level scope.
|
||||
// We could warn here but there are false positives related
|
||||
// configuring libraries like `history`.
|
||||
// These are dangerous if you have inline requires enabled.
|
||||
const message =
|
||||
`React Hook "${context.getSource(hook)}" cannot be called ` +
|
||||
'at the top level. React Hooks must be called in a ' +
|
||||
'React function component or a custom React Hook function.';
|
||||
context.report({node: hook, message});
|
||||
} else {
|
||||
// Assume in all other cases the user called a hook in some
|
||||
// random function callback. This should usually be true for
|
||||
|
||||
@@ -11,6 +11,8 @@ import {
|
||||
} from './ReactControlledComponent';
|
||||
import {enableFlareAPI} from 'shared/ReactFeatureFlags';
|
||||
|
||||
import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils';
|
||||
|
||||
// Used as a way to call batchedUpdates when we don't have a reference to
|
||||
// the renderer. Such as when we're dispatching events or if third party
|
||||
// libraries need to call batchedUpdates. Eventually, this API will go away when
|
||||
@@ -28,6 +30,7 @@ let flushDiscreteUpdatesImpl = function() {};
|
||||
let batchedEventUpdatesImpl = batchedUpdatesImpl;
|
||||
|
||||
let isInsideEventHandler = false;
|
||||
let isBatchingEventUpdates = false;
|
||||
|
||||
function finishEventHandler() {
|
||||
// Here we wait until all updates have propagated, which is important
|
||||
@@ -60,20 +63,31 @@ export function batchedUpdates(fn, bookkeeping) {
|
||||
}
|
||||
|
||||
export function batchedEventUpdates(fn, a, b) {
|
||||
if (isInsideEventHandler) {
|
||||
if (isBatchingEventUpdates) {
|
||||
// If we are currently inside another batch, we need to wait until it
|
||||
// fully completes before restoring state.
|
||||
return fn(a, b);
|
||||
}
|
||||
isInsideEventHandler = true;
|
||||
isBatchingEventUpdates = true;
|
||||
try {
|
||||
return batchedEventUpdatesImpl(fn, a, b);
|
||||
} finally {
|
||||
isInsideEventHandler = false;
|
||||
isBatchingEventUpdates = false;
|
||||
finishEventHandler();
|
||||
}
|
||||
}
|
||||
|
||||
export function executeUserEventHandler(fn: any => void, value: any) {
|
||||
const previouslyInEventHandler = isInsideEventHandler;
|
||||
try {
|
||||
isInsideEventHandler = true;
|
||||
const type = typeof value === 'object' && value !== null ? value.type : '';
|
||||
invokeGuardedCallbackAndCatchFirstError(type, fn, undefined, value);
|
||||
} finally {
|
||||
isInsideEventHandler = previouslyInEventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
export function discreteUpdates(fn, a, b, c) {
|
||||
const prevIsInsideEventHandler = isInsideEventHandler;
|
||||
isInsideEventHandler = true;
|
||||
|
||||
2
packages/react-art/src/ReactART.js
vendored
@@ -66,7 +66,7 @@ class Surface extends React.Component {
|
||||
|
||||
this._surface = Mode.Surface(+width, +height, this._tagRef);
|
||||
|
||||
this._mountNode = createContainer(this._surface, LegacyRoot, false);
|
||||
this._mountNode = createContainer(this._surface, LegacyRoot, false, null);
|
||||
updateContainer(this.props.children, this._mountNode, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -253,14 +253,14 @@ const Dispatcher: DispatcherType = {
|
||||
|
||||
// Inspect
|
||||
|
||||
export type HooksNode = {
|
||||
type HooksNode = {
|
||||
id: number | null,
|
||||
isStateEditable: boolean,
|
||||
name: string,
|
||||
value: mixed,
|
||||
subHooks: Array<HooksNode>,
|
||||
};
|
||||
export type HooksTree = Array<HooksNode>;
|
||||
type HooksTree = Array<HooksNode>;
|
||||
|
||||
// Don't assume
|
||||
//
|
||||
|
||||
@@ -41,4 +41,4 @@ require("react-devtools-core/standalone")
|
||||
.startServer(port);
|
||||
```
|
||||
|
||||
Reference the `react-devtools` package for a complete integration example.
|
||||
Reference the `react-devtools` package for a complete integration example.
|
||||
1
packages/react-devtools-core/backend.js
vendored
@@ -1 +0,0 @@
|
||||
module.exports = require('./dist/backend');
|
||||
@@ -1,32 +1,5 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "react-devtools-core",
|
||||
"version": "4.0.0-alpha.9",
|
||||
"description": "Use react-devtools outside of the browser",
|
||||
"license": "MIT",
|
||||
"main": "./dist/backend.js",
|
||||
"repository": {
|
||||
"url": "https://github.com/bvaughn/react-devtools-experimental.git",
|
||||
"type": "git"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"backend.js",
|
||||
"build-info.json",
|
||||
"standalone.js"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "yarn build:backend && yarn build:standalone",
|
||||
"build:backend": "cross-env NODE_ENV=production webpack --config webpack.backend.js",
|
||||
"build:standalone": "cross-env NODE_ENV=production webpack --config webpack.standalone.js",
|
||||
"prepublish": "yarn run build",
|
||||
"start:backend": "cross-env NODE_ENV=development webpack --config webpack.backend.js --watch",
|
||||
"start:standalone": "cross-env NODE_ENV=development webpack --config webpack.standalone.js --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"shell-quote": "^1.6.1",
|
||||
"ws": "^7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^3.1.4"
|
||||
}
|
||||
"version": "0.0.0"
|
||||
}
|
||||
|
||||
277
packages/react-devtools-core/src/backend.js
vendored
@@ -1,277 +0,0 @@
|
||||
// @flow
|
||||
|
||||
import Agent from 'react-devtools-shared/src/backend/agent';
|
||||
import Bridge from 'react-devtools-shared/src/bridge';
|
||||
import {installHook} from 'react-devtools-shared/src/hook';
|
||||
import {initBackend} from 'react-devtools-shared/src/backend';
|
||||
import {__DEBUG__} from 'react-devtools-shared/src/constants';
|
||||
import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
|
||||
import {getDefaultComponentFilters} from 'react-devtools-shared/src/utils';
|
||||
|
||||
import type {BackendBridge} from 'react-devtools-shared/src/bridge';
|
||||
import type {ComponentFilter} from 'react-devtools-shared/src/types';
|
||||
import type {DevToolsHook} from 'react-devtools-shared/src/backend/types';
|
||||
import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
|
||||
|
||||
type ConnectOptions = {
|
||||
host?: string,
|
||||
nativeStyleEditorValidAttributes?: $ReadOnlyArray<string>,
|
||||
port?: number,
|
||||
resolveRNStyle?: ResolveNativeStyle,
|
||||
isAppActive?: () => boolean,
|
||||
websocket?: ?WebSocket,
|
||||
};
|
||||
|
||||
installHook(window);
|
||||
|
||||
const hook: DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
|
||||
let savedComponentFilters: Array<
|
||||
ComponentFilter,
|
||||
> = getDefaultComponentFilters();
|
||||
|
||||
function debug(methodName: string, ...args) {
|
||||
if (__DEBUG__) {
|
||||
console.log(
|
||||
`%c[core/backend] %c${methodName}`,
|
||||
'color: teal; font-weight: bold;',
|
||||
'font-weight: bold;',
|
||||
...args,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function connectToDevTools(options: ?ConnectOptions) {
|
||||
const {
|
||||
host = 'localhost',
|
||||
nativeStyleEditorValidAttributes,
|
||||
port = 8097,
|
||||
websocket,
|
||||
resolveRNStyle = null,
|
||||
isAppActive = () => true,
|
||||
} =
|
||||
options || {};
|
||||
|
||||
let retryTimeoutID: TimeoutID | null = null;
|
||||
|
||||
function scheduleRetry() {
|
||||
if (retryTimeoutID === null) {
|
||||
// Two seconds because RN had issues with quick retries.
|
||||
retryTimeoutID = setTimeout(() => connectToDevTools(options), 2000);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAppActive()) {
|
||||
// If the app is in background, maybe retry later.
|
||||
// Don't actually attempt to connect until we're in foreground.
|
||||
scheduleRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
let bridge: BackendBridge | null = null;
|
||||
|
||||
const messageListeners = [];
|
||||
const uri = 'ws://' + host + ':' + port;
|
||||
|
||||
// If existing websocket is passed, use it.
|
||||
// This is necessary to support our custom integrations.
|
||||
// See D6251744.
|
||||
const ws = websocket ? websocket : new window.WebSocket(uri);
|
||||
ws.onclose = handleClose;
|
||||
ws.onerror = handleFailed;
|
||||
ws.onmessage = handleMessage;
|
||||
ws.onopen = function() {
|
||||
bridge = new Bridge({
|
||||
listen(fn) {
|
||||
messageListeners.push(fn);
|
||||
return () => {
|
||||
const index = messageListeners.indexOf(fn);
|
||||
if (index >= 0) {
|
||||
messageListeners.splice(index, 1);
|
||||
}
|
||||
};
|
||||
},
|
||||
send(event: string, payload: any, transferable?: Array<any>) {
|
||||
if (ws.readyState === ws.OPEN) {
|
||||
if (__DEBUG__) {
|
||||
debug('wall.send()', event, payload);
|
||||
}
|
||||
|
||||
ws.send(JSON.stringify({event, payload}));
|
||||
} else {
|
||||
if (__DEBUG__) {
|
||||
debug(
|
||||
'wall.send()',
|
||||
'Shutting down bridge because of closed WebSocket connection',
|
||||
);
|
||||
}
|
||||
|
||||
if (bridge !== null) {
|
||||
bridge.emit('shutdown');
|
||||
}
|
||||
|
||||
scheduleRetry();
|
||||
}
|
||||
},
|
||||
});
|
||||
bridge.addListener(
|
||||
'inspectElement',
|
||||
({id, rendererID}: {id: number, rendererID: number}) => {
|
||||
const renderer = agent.rendererInterfaces[rendererID];
|
||||
if (renderer != null) {
|
||||
// Send event for RN to highlight.
|
||||
const nodes: ?Array<HTMLElement> = renderer.findNativeNodesForFiberID(
|
||||
id,
|
||||
);
|
||||
if (nodes != null && nodes[0] != null) {
|
||||
agent.emit('showNativeHighlight', nodes[0]);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
bridge.addListener(
|
||||
'updateComponentFilters',
|
||||
(componentFilters: Array<ComponentFilter>) => {
|
||||
// Save filter changes in memory, in case DevTools is reloaded.
|
||||
// In that case, the renderer will already be using the updated values.
|
||||
// We'll lose these in between backend reloads but that can't be helped.
|
||||
savedComponentFilters = componentFilters;
|
||||
},
|
||||
);
|
||||
|
||||
// The renderer interface doesn't read saved component filters directly,
|
||||
// because they are generally stored in localStorage within the context of the extension.
|
||||
// Because of this it relies on the extension to pass filters.
|
||||
// In the case of the standalone DevTools being used with a website,
|
||||
// saved filters are injected along with the backend script tag so we shouldn't override them here.
|
||||
// This injection strategy doesn't work for React Native though.
|
||||
// Ideally the backend would save the filters itself, but RN doesn't provide a sync storage solution.
|
||||
// So for now we just fall back to using the default filters...
|
||||
if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
|
||||
bridge.send('overrideComponentFilters', savedComponentFilters);
|
||||
}
|
||||
|
||||
// TODO (npm-packages) Warn if "isBackendStorageAPISupported"
|
||||
const agent = new Agent(bridge);
|
||||
agent.addListener('shutdown', () => {
|
||||
// If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
|
||||
// and that caused the 'shutdown' event on the `agent`, so we don't need to call `bridge.shutdown()` here.
|
||||
hook.emit('shutdown');
|
||||
});
|
||||
|
||||
initBackend(hook, agent, window);
|
||||
|
||||
// Setup React Native style editor if the environment supports it.
|
||||
if (resolveRNStyle != null || hook.resolveRNStyle != null) {
|
||||
setupNativeStyleEditor(
|
||||
bridge,
|
||||
agent,
|
||||
((resolveRNStyle || hook.resolveRNStyle: any): ResolveNativeStyle),
|
||||
nativeStyleEditorValidAttributes ||
|
||||
hook.nativeStyleEditorValidAttributes ||
|
||||
null,
|
||||
);
|
||||
} else {
|
||||
// Otherwise listen to detect if the environment later supports it.
|
||||
// For example, Flipper does not eagerly inject these values.
|
||||
// Instead it relies on the React Native Inspector to lazily inject them.
|
||||
let lazyResolveRNStyle;
|
||||
let lazyNativeStyleEditorValidAttributes;
|
||||
|
||||
const initAfterTick = () => {
|
||||
if (bridge !== null) {
|
||||
setupNativeStyleEditor(
|
||||
bridge,
|
||||
agent,
|
||||
lazyResolveRNStyle,
|
||||
lazyNativeStyleEditorValidAttributes,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (!hook.hasOwnProperty('resolveRNStyle')) {
|
||||
Object.defineProperty(
|
||||
hook,
|
||||
'resolveRNStyle',
|
||||
({
|
||||
enumerable: false,
|
||||
get() {
|
||||
return lazyResolveRNStyle;
|
||||
},
|
||||
set(value) {
|
||||
lazyResolveRNStyle = value;
|
||||
initAfterTick();
|
||||
},
|
||||
}: Object),
|
||||
);
|
||||
}
|
||||
if (!hook.hasOwnProperty('nativeStyleEditorValidAttributes')) {
|
||||
Object.defineProperty(
|
||||
hook,
|
||||
'nativeStyleEditorValidAttributes',
|
||||
({
|
||||
enumerable: false,
|
||||
get() {
|
||||
return lazyNativeStyleEditorValidAttributes;
|
||||
},
|
||||
set(value) {
|
||||
lazyNativeStyleEditorValidAttributes = value;
|
||||
initAfterTick();
|
||||
},
|
||||
}: Object),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function handleClose() {
|
||||
if (__DEBUG__) {
|
||||
debug('WebSocket.onclose');
|
||||
}
|
||||
|
||||
if (bridge !== null) {
|
||||
bridge.emit('shutdown');
|
||||
}
|
||||
|
||||
scheduleRetry();
|
||||
}
|
||||
|
||||
function handleFailed() {
|
||||
if (__DEBUG__) {
|
||||
debug('WebSocket.onerror');
|
||||
}
|
||||
|
||||
scheduleRetry();
|
||||
}
|
||||
|
||||
function handleMessage(event) {
|
||||
let data;
|
||||
try {
|
||||
if (typeof event.data === 'string') {
|
||||
data = JSON.parse(event.data);
|
||||
if (__DEBUG__) {
|
||||
debug('WebSocket.onmessage', data);
|
||||
}
|
||||
} else {
|
||||
throw Error();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'[React DevTools] Failed to parse JSON: ' + (event.data: any),
|
||||
);
|
||||
return;
|
||||
}
|
||||
messageListeners.forEach(fn => {
|
||||
try {
|
||||
fn(data);
|
||||
} catch (error) {
|
||||
// jsc doesn't play so well with tracebacks that go into eval'd code,
|
||||
// so the stack trace here will stop at the `eval()` call. Getting the
|
||||
// message that caused the error is the best we can do for now.
|
||||
console.log('[React DevTools] Error calling listener', data);
|
||||
console.log('error:', error);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
183
packages/react-devtools-core/src/editor.js
vendored
@@ -1,183 +0,0 @@
|
||||
// @flow
|
||||
|
||||
import {existsSync} from 'fs';
|
||||
import {basename, join, isAbsolute} from 'path';
|
||||
import {execSync, spawn} from 'child_process';
|
||||
import {parse} from 'shell-quote';
|
||||
|
||||
function isTerminalEditor(editor: string): boolean {
|
||||
switch (editor) {
|
||||
case 'vim':
|
||||
case 'emacs':
|
||||
case 'nano':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Map from full process name to binary that starts the process
|
||||
// We can't just re-use full process name, because it will spawn a new instance
|
||||
// of the app every time
|
||||
const COMMON_EDITORS = {
|
||||
'/Applications/Atom.app/Contents/MacOS/Atom': 'atom',
|
||||
'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta':
|
||||
'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta',
|
||||
'/Applications/Sublime Text.app/Contents/MacOS/Sublime Text':
|
||||
'/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl',
|
||||
'/Applications/Sublime Text 2.app/Contents/MacOS/Sublime Text 2':
|
||||
'/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl',
|
||||
'/Applications/Visual Studio Code.app/Contents/MacOS/Electron': 'code',
|
||||
};
|
||||
|
||||
function getArgumentsForLineNumber(
|
||||
editor: string,
|
||||
filePath: string,
|
||||
lineNumber: number,
|
||||
): Array<string> {
|
||||
switch (basename(editor)) {
|
||||
case 'vim':
|
||||
case 'mvim':
|
||||
return [filePath, '+' + lineNumber];
|
||||
case 'atom':
|
||||
case 'Atom':
|
||||
case 'Atom Beta':
|
||||
case 'subl':
|
||||
case 'sublime':
|
||||
case 'wstorm':
|
||||
case 'appcode':
|
||||
case 'charm':
|
||||
case 'idea':
|
||||
return [filePath + ':' + lineNumber];
|
||||
case 'joe':
|
||||
case 'emacs':
|
||||
case 'emacsclient':
|
||||
return ['+' + lineNumber, filePath];
|
||||
case 'rmate':
|
||||
case 'mate':
|
||||
case 'mine':
|
||||
return ['--line', lineNumber + '', filePath];
|
||||
case 'code':
|
||||
return ['-g', filePath + ':' + lineNumber];
|
||||
default:
|
||||
// For all others, drop the lineNumber until we have
|
||||
// a mapping above, since providing the lineNumber incorrectly
|
||||
// can result in errors or confusing behavior.
|
||||
return [filePath];
|
||||
}
|
||||
}
|
||||
|
||||
function guessEditor(): Array<string> {
|
||||
// Explicit config always wins
|
||||
if (process.env.REACT_EDITOR) {
|
||||
return parse(process.env.REACT_EDITOR);
|
||||
}
|
||||
|
||||
// Using `ps x` on OSX we can find out which editor is currently running.
|
||||
// Potentially we could use similar technique for Windows and Linux
|
||||
if (process.platform === 'darwin') {
|
||||
try {
|
||||
const output = execSync('ps x').toString();
|
||||
const processNames = Object.keys(COMMON_EDITORS);
|
||||
for (let i = 0; i < processNames.length; i++) {
|
||||
const processName = processNames[i];
|
||||
if (output.indexOf(processName) !== -1) {
|
||||
return [COMMON_EDITORS[processName]];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Ignore...
|
||||
}
|
||||
}
|
||||
|
||||
// Last resort, use old skool env vars
|
||||
if (process.env.VISUAL) {
|
||||
return [process.env.VISUAL];
|
||||
} else if (process.env.EDITOR) {
|
||||
return [process.env.EDITOR];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
let childProcess = null;
|
||||
|
||||
export function getValidFilePath(
|
||||
maybeRelativePath: string,
|
||||
absoluteProjectRoots: Array<string>,
|
||||
): string | null {
|
||||
// We use relative paths at Facebook with deterministic builds.
|
||||
// This is why our internal tooling calls React DevTools with absoluteProjectRoots.
|
||||
// If the filename is absolute then we don't need to care about this.
|
||||
if (isAbsolute(maybeRelativePath)) {
|
||||
if (existsSync(maybeRelativePath)) {
|
||||
return maybeRelativePath;
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < absoluteProjectRoots.length; i++) {
|
||||
const projectRoot = absoluteProjectRoots[i];
|
||||
const joinedPath = join(projectRoot, maybeRelativePath);
|
||||
if (existsSync(joinedPath)) {
|
||||
return joinedPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function doesFilePathExist(
|
||||
maybeRelativePath: string,
|
||||
absoluteProjectRoots: Array<string>,
|
||||
): boolean {
|
||||
return getValidFilePath(maybeRelativePath, absoluteProjectRoots) !== null;
|
||||
}
|
||||
|
||||
export function launchEditor(
|
||||
maybeRelativePath: string,
|
||||
lineNumber: number,
|
||||
absoluteProjectRoots: Array<string>,
|
||||
) {
|
||||
const filePath = getValidFilePath(maybeRelativePath, absoluteProjectRoots);
|
||||
if (filePath === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanitize lineNumber to prevent malicious use on win32
|
||||
// via: https://github.com/nodejs/node/blob/c3bb4b1aa5e907d489619fb43d233c3336bfc03d/lib/child_process.js#L333
|
||||
if (lineNumber && isNaN(lineNumber)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let [editor, ...args] = guessEditor();
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lineNumber) {
|
||||
args = args.concat(getArgumentsForLineNumber(editor, filePath, lineNumber));
|
||||
} else {
|
||||
args.push(filePath);
|
||||
}
|
||||
|
||||
if (childProcess && isTerminalEditor(editor)) {
|
||||
// There's an existing editor process already and it's attached
|
||||
// to the terminal, so go kill it. Otherwise two separate editor
|
||||
// instances attach to the stdin/stdout which gets confusing.
|
||||
childProcess.kill('SIGKILL');
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
// On Windows, launch the editor in a shell because spawn can only
|
||||
// launch .exe files.
|
||||
childProcess = spawn('cmd.exe', ['/C', editor].concat(args), {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
} else {
|
||||
childProcess = spawn(editor, args, {stdio: 'inherit'});
|
||||
}
|
||||
childProcess.on('error', function() {});
|
||||
childProcess.on('exit', function(errorCode) {
|
||||
childProcess = null;
|
||||
});
|
||||
}
|
||||
324
packages/react-devtools-core/src/standalone.js
vendored
@@ -1,324 +0,0 @@
|
||||
// @flow
|
||||
|
||||
import {createElement} from 'react';
|
||||
import {
|
||||
// $FlowFixMe Flow does not yet know about flushSync()
|
||||
flushSync,
|
||||
// $FlowFixMe Flow does not yet know about createRoot()
|
||||
unstable_createRoot as createRoot,
|
||||
} from 'react-dom';
|
||||
import Bridge from 'react-devtools-shared/src/bridge';
|
||||
import Store from 'react-devtools-shared/src/devtools/store';
|
||||
import {
|
||||
getSavedComponentFilters,
|
||||
getAppendComponentStack,
|
||||
} from 'react-devtools-shared/src/utils';
|
||||
import {Server} from 'ws';
|
||||
import {existsSync, readFileSync} from 'fs';
|
||||
import {installHook} from 'react-devtools-shared/src/hook';
|
||||
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
|
||||
import {doesFilePathExist, launchEditor} from './editor';
|
||||
import {__DEBUG__} from 'react-devtools-shared/src/constants';
|
||||
|
||||
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
|
||||
import type {InspectedElement} from 'react-devtools-shared/src/devtools/views/Components/types';
|
||||
|
||||
installHook(window);
|
||||
|
||||
export type StatusListener = (message: string) => void;
|
||||
|
||||
let node: HTMLElement = ((null: any): HTMLElement);
|
||||
let nodeWaitingToConnectHTML: string = '';
|
||||
let projectRoots: Array<string> = [];
|
||||
let statusListener: StatusListener = (message: string) => {};
|
||||
|
||||
// Unlike browser extension users, people using the standalone have actively installed version 4,
|
||||
// So we probably don't need to show them a changelog notice.
|
||||
// We should give embedded users (e.g. Nuclide, Sonar) a way of showing this dialog though.
|
||||
let showWelcomeToTheNewDevToolsDialog: boolean = false;
|
||||
|
||||
function setContentDOMNode(value: HTMLElement) {
|
||||
node = value;
|
||||
|
||||
// Save so we can restore the exact waiting message between sessions.
|
||||
nodeWaitingToConnectHTML = node.innerHTML;
|
||||
|
||||
return DevtoolsUI;
|
||||
}
|
||||
|
||||
function setProjectRoots(value: Array<string>) {
|
||||
projectRoots = value;
|
||||
}
|
||||
|
||||
function setStatusListener(value: StatusListener) {
|
||||
statusListener = value;
|
||||
return DevtoolsUI;
|
||||
}
|
||||
|
||||
function setShowWelcomeToTheNewDevToolsDialog(value: boolean) {
|
||||
showWelcomeToTheNewDevToolsDialog = value;
|
||||
return DevtoolsUI;
|
||||
}
|
||||
|
||||
let bridge: FrontendBridge | null = null;
|
||||
let store: Store | null = null;
|
||||
let root = null;
|
||||
|
||||
const log = (...args) => console.log('[React DevTools]', ...args);
|
||||
log.warn = (...args) => console.warn('[React DevTools]', ...args);
|
||||
log.error = (...args) => console.error('[React DevTools]', ...args);
|
||||
|
||||
function debug(methodName: string, ...args) {
|
||||
if (__DEBUG__) {
|
||||
console.log(
|
||||
`%c[core/standalone] %c${methodName}`,
|
||||
'color: teal; font-weight: bold;',
|
||||
'font-weight: bold;',
|
||||
...args,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function safeUnmount() {
|
||||
flushSync(() => {
|
||||
if (root !== null) {
|
||||
root.unmount();
|
||||
}
|
||||
});
|
||||
root = null;
|
||||
}
|
||||
|
||||
function reload() {
|
||||
safeUnmount();
|
||||
|
||||
node.innerHTML = '';
|
||||
|
||||
setTimeout(() => {
|
||||
root = createRoot(node);
|
||||
root.render(
|
||||
createElement(DevTools, {
|
||||
bridge: ((bridge: any): FrontendBridge),
|
||||
canViewElementSourceFunction,
|
||||
showTabBar: true,
|
||||
showWelcomeToTheNewDevToolsDialog,
|
||||
store: ((store: any): Store),
|
||||
warnIfLegacyBackendDetected: true,
|
||||
viewElementSourceFunction,
|
||||
}),
|
||||
);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function canViewElementSourceFunction(
|
||||
inspectedElement: InspectedElement,
|
||||
): boolean {
|
||||
if (
|
||||
inspectedElement.canViewSource === false ||
|
||||
inspectedElement.source === null
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const {source} = inspectedElement;
|
||||
|
||||
return doesFilePathExist(source.fileName, projectRoots);
|
||||
}
|
||||
|
||||
function viewElementSourceFunction(
|
||||
id: number,
|
||||
inspectedElement: InspectedElement,
|
||||
): void {
|
||||
const {source} = inspectedElement;
|
||||
if (source !== null) {
|
||||
launchEditor(source.fileName, source.lineNumber, projectRoots);
|
||||
} else {
|
||||
log.error('Cannot inspect element', id);
|
||||
}
|
||||
}
|
||||
|
||||
function onDisconnected() {
|
||||
safeUnmount();
|
||||
|
||||
node.innerHTML = nodeWaitingToConnectHTML;
|
||||
}
|
||||
|
||||
function onError({code, message}) {
|
||||
safeUnmount();
|
||||
|
||||
if (code === 'EADDRINUSE') {
|
||||
node.innerHTML = `<div id="waiting"><h2>Another instance of DevTools is running</h2></div>`;
|
||||
} else {
|
||||
node.innerHTML = `<div id="waiting"><h2>Unknown error (${message})</h2></div>`;
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(socket: WebSocket) {
|
||||
const listeners = [];
|
||||
socket.onmessage = event => {
|
||||
let data;
|
||||
try {
|
||||
if (typeof event.data === 'string') {
|
||||
data = JSON.parse(event.data);
|
||||
|
||||
if (__DEBUG__) {
|
||||
debug('WebSocket.onmessage', data);
|
||||
}
|
||||
} else {
|
||||
throw Error();
|
||||
}
|
||||
} catch (e) {
|
||||
log.error('Failed to parse JSON', event.data);
|
||||
return;
|
||||
}
|
||||
listeners.forEach(fn => {
|
||||
try {
|
||||
fn(data);
|
||||
} catch (error) {
|
||||
log.error('Error calling listener', data);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
bridge = new Bridge({
|
||||
listen(fn) {
|
||||
listeners.push(fn);
|
||||
return () => {
|
||||
const index = listeners.indexOf(fn);
|
||||
if (index >= 0) {
|
||||
listeners.splice(index, 1);
|
||||
}
|
||||
};
|
||||
},
|
||||
send(event: string, payload: any, transferable?: Array<any>) {
|
||||
if (socket.readyState === socket.OPEN) {
|
||||
socket.send(JSON.stringify({event, payload}));
|
||||
}
|
||||
},
|
||||
});
|
||||
((bridge: any): FrontendBridge).addListener('shutdown', () => {
|
||||
socket.close();
|
||||
});
|
||||
|
||||
store = new Store(bridge, {supportsNativeInspection: false});
|
||||
|
||||
log('Connected');
|
||||
reload();
|
||||
}
|
||||
|
||||
let startServerTimeoutID: TimeoutID | null = null;
|
||||
|
||||
function connectToSocket(socket: WebSocket) {
|
||||
socket.onerror = err => {
|
||||
onDisconnected();
|
||||
log.error('Error with websocket connection', err);
|
||||
};
|
||||
socket.onclose = () => {
|
||||
onDisconnected();
|
||||
log('Connection to RN closed');
|
||||
};
|
||||
initialize(socket);
|
||||
|
||||
return {
|
||||
close: function() {
|
||||
onDisconnected();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function startServer(port?: number = 8097) {
|
||||
const httpServer = require('http').createServer();
|
||||
const server = new Server({server: httpServer});
|
||||
let connected: WebSocket | null = null;
|
||||
server.on('connection', (socket: WebSocket) => {
|
||||
if (connected !== null) {
|
||||
connected.close();
|
||||
log.warn(
|
||||
'Only one connection allowed at a time.',
|
||||
'Closing the previous connection',
|
||||
);
|
||||
}
|
||||
connected = socket;
|
||||
socket.onerror = error => {
|
||||
connected = null;
|
||||
onDisconnected();
|
||||
log.error('Error with websocket connection', error);
|
||||
};
|
||||
socket.onclose = () => {
|
||||
connected = null;
|
||||
onDisconnected();
|
||||
log('Connection to RN closed');
|
||||
};
|
||||
initialize(socket);
|
||||
});
|
||||
|
||||
server.on('error', event => {
|
||||
onError(event);
|
||||
log.error('Failed to start the DevTools server', event);
|
||||
startServerTimeoutID = setTimeout(() => startServer(port), 1000);
|
||||
});
|
||||
|
||||
httpServer.on('request', (request, response) => {
|
||||
// NPM installs should read from node_modules,
|
||||
// But local dev mode needs to use a relative path.
|
||||
const basePath = existsSync('./node_modules/react-devtools-core')
|
||||
? 'node_modules/react-devtools-core'
|
||||
: '../react-devtools-core';
|
||||
|
||||
// Serve a file that immediately sets up the connection.
|
||||
const backendFile = readFileSync(`${basePath}/dist/backend.js`);
|
||||
|
||||
// The renderer interface doesn't read saved component filters directly,
|
||||
// because they are generally stored in localStorage within the context of the extension.
|
||||
// Because of this it relies on the extension to pass filters, so include them wth the response here.
|
||||
// This will ensure that saved filters are shared across different web pages.
|
||||
const savedPreferencesString = `
|
||||
window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = ${JSON.stringify(
|
||||
getSavedComponentFilters(),
|
||||
)};
|
||||
window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = ${JSON.stringify(
|
||||
getAppendComponentStack(),
|
||||
)};`;
|
||||
|
||||
response.end(
|
||||
savedPreferencesString +
|
||||
'\n;' +
|
||||
backendFile.toString() +
|
||||
'\n;' +
|
||||
'ReactDevToolsBackend.connectToDevTools();',
|
||||
);
|
||||
});
|
||||
|
||||
httpServer.on('error', event => {
|
||||
onError(event);
|
||||
statusListener('Failed to start the server.');
|
||||
startServerTimeoutID = setTimeout(() => startServer(port), 1000);
|
||||
});
|
||||
|
||||
httpServer.listen(port, () => {
|
||||
statusListener('The server is listening on the port ' + port + '.');
|
||||
});
|
||||
|
||||
return {
|
||||
close: function() {
|
||||
connected = null;
|
||||
onDisconnected();
|
||||
if (startServerTimeoutID !== null) {
|
||||
clearTimeout(startServerTimeoutID);
|
||||
}
|
||||
server.close();
|
||||
httpServer.close();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const DevtoolsUI = {
|
||||
connectToSocket,
|
||||
setContentDOMNode,
|
||||
setProjectRoots,
|
||||
setShowWelcomeToTheNewDevToolsDialog,
|
||||
setStatusListener,
|
||||
startServer,
|
||||
};
|
||||
|
||||
export default DevtoolsUI;
|
||||
1
packages/react-devtools-core/standalone.js
vendored
@@ -1 +0,0 @@
|
||||
module.exports = require('./dist/standalone');
|
||||
@@ -1,67 +0,0 @@
|
||||
const {resolve} = require('path');
|
||||
const {DefinePlugin} = require('webpack');
|
||||
const {
|
||||
getGitHubURL,
|
||||
getVersionString,
|
||||
} = require('react-devtools-extensions/utils');
|
||||
|
||||
const NODE_ENV = process.env.NODE_ENV;
|
||||
if (!NODE_ENV) {
|
||||
console.error('NODE_ENV not set');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
|
||||
|
||||
const __DEV__ = NODE_ENV === 'development';
|
||||
|
||||
const GITHUB_URL = getGitHubURL();
|
||||
const DEVTOOLS_VERSION = getVersionString();
|
||||
|
||||
module.exports = {
|
||||
mode: __DEV__ ? 'development' : 'production',
|
||||
devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
|
||||
entry: {
|
||||
backend: './src/backend.js',
|
||||
},
|
||||
output: {
|
||||
path: __dirname + '/dist',
|
||||
filename: '[name].js',
|
||||
|
||||
// This name is important; standalone references it in order to connect.
|
||||
library: 'ReactDevToolsBackend',
|
||||
libraryTarget: 'umd',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
react: resolve(builtModulesDir, 'react'),
|
||||
'react-dom': resolve(builtModulesDir, 'react-dom'),
|
||||
'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
|
||||
'react-is': resolve(builtModulesDir, 'react-is'),
|
||||
scheduler: resolve(builtModulesDir, 'scheduler'),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new DefinePlugin({
|
||||
__DEV__: true,
|
||||
'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
|
||||
'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
|
||||
}),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
configFile: resolve(
|
||||
__dirname,
|
||||
'..',
|
||||
'react-devtools-shared',
|
||||
'babel.config.js',
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
const {resolve} = require('path');
|
||||
const {DefinePlugin} = require('webpack');
|
||||
const {
|
||||
getGitHubURL,
|
||||
getVersionString,
|
||||
} = require('react-devtools-extensions/utils');
|
||||
|
||||
const NODE_ENV = process.env.NODE_ENV;
|
||||
if (!NODE_ENV) {
|
||||
console.error('NODE_ENV not set');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
|
||||
|
||||
const __DEV__ = NODE_ENV === 'development';
|
||||
|
||||
const GITHUB_URL = getGitHubURL();
|
||||
const DEVTOOLS_VERSION = getVersionString();
|
||||
|
||||
module.exports = {
|
||||
mode: __DEV__ ? 'development' : 'production',
|
||||
devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
|
||||
target: 'electron-main',
|
||||
entry: {
|
||||
standalone: './src/standalone.js',
|
||||
},
|
||||
output: {
|
||||
path: __dirname + '/dist',
|
||||
filename: '[name].js',
|
||||
library: '[name]',
|
||||
libraryTarget: 'commonjs2',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
react: resolve(builtModulesDir, 'react'),
|
||||
'react-dom': resolve(builtModulesDir, 'react-dom'),
|
||||
'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
|
||||
'react-is': resolve(builtModulesDir, 'react-is'),
|
||||
scheduler: resolve(builtModulesDir, 'scheduler'),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new DefinePlugin({
|
||||
__DEV__: false,
|
||||
'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
|
||||
'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
|
||||
'process.env.NODE_ENV': `"${NODE_ENV}"`,
|
||||
}),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
configFile: resolve(
|
||||
__dirname,
|
||||
'..',
|
||||
'react-devtools-shared',
|
||||
'babel.config.js',
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader',
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
// WARNING It's important that we disable CSS source maps for production builds.
|
||||
// This causes style-loader to insert styles via a <style> tag rather than URL.createObjectURL,
|
||||
// which in turn avoids a nasty Electron/Chromium bug that breaks DevTools in Nuclide.
|
||||
// (Calls to URL.createObjectURL seem to crash the webview process.)
|
||||
sourceMap: __DEV__,
|
||||
modules: true,
|
||||
localIdentName: '[local]___[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
# Javascript Node CircleCI 2.0 configuration file
|
||||
#
|
||||
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
|
||||
#
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
# specify the version you desire here
|
||||
- image: circleci/node:10.12.0
|
||||
|
||||
# Specify service dependencies here if necessary
|
||||
# CircleCI maintains a library of pre-built images
|
||||
# documented at https://circleci.com/docs/2.0/circleci-images/
|
||||
# - image: circleci/mongo:3.4.4
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
name: Restore node_modules cache
|
||||
keys:
|
||||
- v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
||||
- v1-node-{{ arch }}-{{ .Branch }}-
|
||||
- v1-node-{{ arch }}-
|
||||
|
||||
- run:
|
||||
name: Nodejs Version
|
||||
command: node --version
|
||||
|
||||
- run:
|
||||
name: Install Packages
|
||||
command: yarn install --frozen-lockfile
|
||||
|
||||
- save_cache:
|
||||
name: Save node_modules cache
|
||||
key: v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- node_modules
|
||||
|
||||
- run:
|
||||
name: Check formatting
|
||||
command: yarn prettier:ci
|
||||
|
||||
- run:
|
||||
name: Check lint
|
||||
command: yarn lint:ci
|
||||
|
||||
- run:
|
||||
name: Check Flow
|
||||
command: yarn flow
|
||||
|
||||
- run:
|
||||
name: Test Packages
|
||||
command: yarn test
|
||||
@@ -1,17 +0,0 @@
|
||||
This is the source code for the React DevTools browser extension.
|
||||
|
||||
# Installation
|
||||
|
||||
The easiest way to install this extension is as a browser add-on:
|
||||
* [Chrome web store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en)
|
||||
* [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/)
|
||||
|
||||
# Build
|
||||
|
||||
You can also build and install from source:
|
||||
```sh
|
||||
yarn install
|
||||
|
||||
yarn build:chrome # builds at "packages/react-devtools-extensions/chrome/build"
|
||||
yarn build:firefox # builds at "packages/react-devtools-extensions/firefox/build"
|
||||
```
|
||||
121
packages/react-devtools-extensions/build.js
vendored
@@ -1,121 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const archiver = require('archiver');
|
||||
const {execSync} = require('child_process');
|
||||
const {readFileSync, writeFileSync, createWriteStream} = require('fs');
|
||||
const {copy, ensureDir, move, remove} = require('fs-extra');
|
||||
const {join} = require('path');
|
||||
const {getGitCommit} = require('./utils');
|
||||
|
||||
// These files are copied along with Webpack-bundled files
|
||||
// to produce the final web extension
|
||||
const STATIC_FILES = ['icons', 'popups', 'main.html', 'panel.html'];
|
||||
|
||||
const preProcess = async (destinationPath, tempPath) => {
|
||||
await remove(destinationPath); // Clean up from previously completed builds
|
||||
await remove(tempPath); // Clean up from any previously failed builds
|
||||
await ensureDir(tempPath); // Create temp dir for this new build
|
||||
};
|
||||
|
||||
const build = async (tempPath, manifestPath) => {
|
||||
const binPath = join(tempPath, 'bin');
|
||||
const zipPath = join(tempPath, 'zip');
|
||||
|
||||
const webpackPath = join(
|
||||
__dirname,
|
||||
'..',
|
||||
'..',
|
||||
'node_modules',
|
||||
'.bin',
|
||||
'webpack',
|
||||
);
|
||||
execSync(
|
||||
`${webpackPath} --config webpack.config.js --output-path ${binPath}`,
|
||||
{
|
||||
cwd: __dirname,
|
||||
env: process.env,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
);
|
||||
execSync(
|
||||
`${webpackPath} --config webpack.backend.js --output-path ${binPath}`,
|
||||
{
|
||||
cwd: __dirname,
|
||||
env: process.env,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
);
|
||||
|
||||
// Make temp dir
|
||||
await ensureDir(zipPath);
|
||||
|
||||
const copiedManifestPath = join(zipPath, 'manifest.json');
|
||||
|
||||
// Copy unbuilt source files to zip dir to be packaged:
|
||||
await copy(binPath, join(zipPath, 'build'));
|
||||
await copy(manifestPath, copiedManifestPath);
|
||||
await Promise.all(
|
||||
STATIC_FILES.map(file => copy(join(__dirname, file), join(zipPath, file))),
|
||||
);
|
||||
|
||||
const commit = getGitCommit();
|
||||
const versionDateString = `${commit} (${new Date().toLocaleDateString()})`;
|
||||
|
||||
const manifest = JSON.parse(readFileSync(copiedManifestPath).toString());
|
||||
if (manifest.version_name) {
|
||||
manifest.version_name = versionDateString;
|
||||
} else {
|
||||
manifest.description += `\n\nCreated from revision ${versionDateString}`;
|
||||
}
|
||||
|
||||
writeFileSync(copiedManifestPath, JSON.stringify(manifest, null, 2));
|
||||
|
||||
// Pack the extension
|
||||
const archive = archiver('zip', {zlib: {level: 9}});
|
||||
const zipStream = createWriteStream(join(tempPath, 'ReactDevTools.zip'));
|
||||
await new Promise((resolve, reject) => {
|
||||
archive
|
||||
.directory(zipPath, false)
|
||||
.on('error', err => reject(err))
|
||||
.pipe(zipStream);
|
||||
archive.finalize();
|
||||
zipStream.on('close', () => resolve());
|
||||
});
|
||||
};
|
||||
|
||||
const postProcess = async (tempPath, destinationPath) => {
|
||||
const unpackedSourcePath = join(tempPath, 'zip');
|
||||
const packedSourcePath = join(tempPath, 'ReactDevTools.zip');
|
||||
const packedDestPath = join(destinationPath, 'ReactDevTools.zip');
|
||||
const unpackedDestPath = join(destinationPath, 'unpacked');
|
||||
|
||||
await move(unpackedSourcePath, unpackedDestPath); // Copy built files to destination
|
||||
await move(packedSourcePath, packedDestPath); // Copy built files to destination
|
||||
await remove(tempPath); // Clean up temp directory and files
|
||||
};
|
||||
|
||||
const main = async buildId => {
|
||||
const root = join(__dirname, buildId);
|
||||
const manifestPath = join(root, 'manifest.json');
|
||||
const destinationPath = join(root, 'build');
|
||||
|
||||
try {
|
||||
const tempPath = join(__dirname, 'build', buildId);
|
||||
await preProcess(destinationPath, tempPath);
|
||||
await build(tempPath, manifestPath);
|
||||
|
||||
const builtUnpackedPath = join(destinationPath, 'unpacked');
|
||||
await postProcess(tempPath, destinationPath);
|
||||
|
||||
return builtUnpackedPath;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
module.exports = main;
|
||||
@@ -1,12 +0,0 @@
|
||||
# The Chrome extension
|
||||
|
||||
The source code for this extension has moved to `shells/webextension`.
|
||||
|
||||
Modify the source code there and then rebuild this extension by running `node build` from this directory or `yarn run build:extension:chrome` from the root directory.
|
||||
|
||||
## Testing in Chrome
|
||||
|
||||
You can test a local build of the web extension like so:
|
||||
|
||||
1. Build the extension: `node build`
|
||||
1. Follow the on-screen instructions.
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const chalk = require('chalk');
|
||||
const {execSync} = require('child_process');
|
||||
const {existsSync} = require('fs');
|
||||
const {isAbsolute, join, relative} = require('path');
|
||||
const {argv} = require('yargs');
|
||||
const build = require('../build');
|
||||
|
||||
const main = async () => {
|
||||
const {crx, keyPath} = argv;
|
||||
|
||||
if (crx) {
|
||||
if (!keyPath || !existsSync(keyPath)) {
|
||||
console.error('Must specify a key file (.pem) to build CRX');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
await build('chrome');
|
||||
|
||||
if (crx) {
|
||||
const cwd = join(__dirname, 'build');
|
||||
|
||||
let safeKeyPath = keyPath;
|
||||
if (!isAbsolute(keyPath)) {
|
||||
safeKeyPath = join(relative(cwd, process.cwd()), keyPath);
|
||||
}
|
||||
|
||||
execSync(`crx pack ./unpacked -o ReactDevTools.crx -p ${safeKeyPath}`, {
|
||||
cwd,
|
||||
});
|
||||
}
|
||||
|
||||
console.log(chalk.green('\nThe Chrome extension has been built!'));
|
||||
console.log(chalk.green('You can test this build by running:'));
|
||||
console.log(chalk.gray('\n# From the react-devtools root directory:'));
|
||||
console.log('yarn run test:chrome');
|
||||
};
|
||||
|
||||
main();
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const deploy = require('../deploy');
|
||||
|
||||
const main = async () => await deploy('chrome');
|
||||
|
||||
main();
|
||||
@@ -1,60 +0,0 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "React Developer Tools",
|
||||
"description": "Adds React debugging tools to the Chrome Developer Tools.",
|
||||
"version": "4.0.0",
|
||||
"version_name": "4.0.0",
|
||||
|
||||
"minimum_chrome_version": "49",
|
||||
|
||||
"icons": {
|
||||
"16": "icons/16-production.png",
|
||||
"32": "icons/32-production.png",
|
||||
"48": "icons/48-production.png",
|
||||
"128": "icons/128-production.png"
|
||||
},
|
||||
|
||||
"browser_action": {
|
||||
"default_icon": {
|
||||
"16": "icons/16-disabled.png",
|
||||
"32": "icons/32-disabled.png",
|
||||
"48": "icons/48-disabled.png",
|
||||
"128": "icons/128-disabled.png"
|
||||
},
|
||||
|
||||
"default_popup": "popups/disabled.html"
|
||||
},
|
||||
|
||||
"devtools_page": "main.html",
|
||||
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"web_accessible_resources": [
|
||||
"main.html",
|
||||
"panel.html",
|
||||
"build/backend.js",
|
||||
"build/renderer.js"
|
||||
],
|
||||
|
||||
"background": {
|
||||
"scripts": ["build/background.js"],
|
||||
"persistent": false
|
||||
},
|
||||
|
||||
"permissions": [
|
||||
"<all_urls>",
|
||||
"background",
|
||||
"tabs",
|
||||
"webNavigation",
|
||||
"file:///*",
|
||||
"http://*/*",
|
||||
"https://*/*"
|
||||
],
|
||||
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["build/injectGlobalHook.js"],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "react-devtools-experimental-chrome",
|
||||
"alias": ["react-devtools-experimental-chrome"],
|
||||
"files": ["index.html", "ReactDevTools.zip"]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const chromeLaunch = require('chrome-launch');
|
||||
const {resolve} = require('path');
|
||||
|
||||
const EXTENSION_PATH = resolve('./chrome/build/unpacked');
|
||||
const START_URL = 'https://facebook.github.io/react/';
|
||||
|
||||
chromeLaunch(START_URL, {
|
||||
args: [`--load-extension=${EXTENSION_PATH}`],
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
<ol>
|
||||
<li><a href="ReactDevTools.zip">download extension</a></li>
|
||||
<li>Double-click to extract</li>
|
||||
<li>Navigate to <code>chrome://extensions/</code></li>
|
||||
<li>Enable "Developer mode"</li>
|
||||
<li>Click "LOAD UNPACKED"</li>
|
||||
<li>Select extracted extension folder (<code>ReactDevTools</code>)</li>
|
||||
</ol>
|
||||
@@ -1,7 +0,0 @@
|
||||
<ol>
|
||||
<li><a href="ReactDevTools.zip">download extension</a></li>
|
||||
<li>Extract/unzip</li>
|
||||
<li>Visit <code>about:debugging</code></li>
|
||||
<li>Click "Load Temporary Add-on"</li>
|
||||
<li>Select the <code>manifest.json</code> file inside of the extracted extension folder (<code>ReactDevTools</code>)</li>
|
||||
</ol>
|
||||
@@ -1,46 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>React DevTools pre-release</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
|
||||
sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
React DevTools pre-release
|
||||
</h1>
|
||||
|
||||
<h3>
|
||||
Created on <strong>%date%</strong> from
|
||||
<a href="http://github.com/bvaughn/react-devtools-experimental/commit/%commit%"><code>%commit%</code></a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
This is a preview build of an <a href="https://github.com/facebook/react/tree/master/packages/react-devtools-extensions">unreleased DevTools extension</a>.
|
||||
It has no developer support.
|
||||
</p>
|
||||
|
||||
<h2>Installation instructions</h2>
|
||||
%installation%
|
||||
<p>
|
||||
If you already have the React DevTools extension installed, you will need to temporarily disable or remove it in order to install this prerelease build.
|
||||
</p>
|
||||
|
||||
<h2>Bug reports</h2>
|
||||
<p>
|
||||
Please report bugs as <a href="https://github.com/facebook/react/issues/new?labels=Component:%20Developer%20Tools">GitHub issues</a>.
|
||||
Please include all of the info required to reproduce the bug (e.g. links, code, instructions).
|
||||
</p>
|
||||
|
||||
<h2>Feature requests</h2>
|
||||
<p>
|
||||
Feature requests are not being accepted at this time.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
58
packages/react-devtools-extensions/deploy.js
vendored
@@ -1,58 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const {exec, execSync} = require('child_process');
|
||||
const {readFileSync, writeFileSync} = require('fs');
|
||||
const {join} = require('path');
|
||||
|
||||
const main = async buildId => {
|
||||
const root = join(__dirname, buildId);
|
||||
const buildPath = join(root, 'build');
|
||||
|
||||
execSync(`node ${join(root, './build')}`, {
|
||||
cwd: __dirname,
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
await exec(`cp ${join(root, 'now.json')} ${join(buildPath, 'now.json')}`, {
|
||||
cwd: root,
|
||||
});
|
||||
|
||||
const file = readFileSync(join(root, 'now.json'));
|
||||
const json = JSON.parse(file);
|
||||
const alias = json.alias[0];
|
||||
|
||||
const commit = execSync('git rev-parse HEAD')
|
||||
.toString()
|
||||
.trim()
|
||||
.substr(0, 7);
|
||||
|
||||
let date = new Date();
|
||||
date = `${date.toLocaleDateString()} – ${date.toLocaleTimeString()}`;
|
||||
|
||||
const installationInstructions =
|
||||
buildId === 'chrome'
|
||||
? readFileSync(join(__dirname, 'deploy.chrome.html'))
|
||||
: readFileSync(join(__dirname, 'deploy.firefox.html'));
|
||||
|
||||
let html = readFileSync(join(__dirname, 'deploy.html')).toString();
|
||||
html = html.replace(/%commit%/g, commit);
|
||||
html = html.replace(/%date%/g, date);
|
||||
html = html.replace(/%installation%/, installationInstructions);
|
||||
|
||||
writeFileSync(join(buildPath, 'index.html'), html);
|
||||
|
||||
await exec(`now deploy && now alias ${alias}`, {
|
||||
cwd: buildPath,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
console.log(`Deployed to https://${alias}.now.sh`);
|
||||
};
|
||||
|
||||
module.exports = main;
|
||||
@@ -1,12 +0,0 @@
|
||||
# The Firefox extension
|
||||
|
||||
The source code for this extension has moved to `shells/webextension`.
|
||||
|
||||
Modify the source code there and then rebuild this extension by running `node build` from this directory or `yarn run build:extension:firefox` from the root directory.
|
||||
|
||||
## Testing in Firefox
|
||||
|
||||
1. Build the extension: `node build`
|
||||
1. Follow the on-screen instructions.
|
||||
|
||||
You can test upcoming releases of Firefox by downloading the Beta or Nightly build from the [Firefox releases](https://www.mozilla.org/en-US/firefox/channel/desktop/) page and then following the on-screen instructions after building.
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const chalk = require('chalk');
|
||||
const build = require('../build');
|
||||
|
||||
const main = async () => {
|
||||
await build('firefox');
|
||||
|
||||
console.log(chalk.green('\nThe Firefox extension has been built!'));
|
||||
console.log(chalk.green('You can test this build by running:'));
|
||||
console.log(chalk.gray('\n# From the react-devtools root directory:'));
|
||||
console.log('yarn run test:firefox');
|
||||
console.log(
|
||||
chalk.gray('\n# You can also test against upcoming Firefox releases.')
|
||||
);
|
||||
console.log(
|
||||
chalk.gray(
|
||||
'# First download a release from https://www.mozilla.org/en-US/firefox/channel/desktop/'
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
chalk.gray(
|
||||
'# And then tell web-ext which release to use (eg firefoxdeveloperedition, nightly, beta):'
|
||||
)
|
||||
);
|
||||
console.log('WEB_EXT_FIREFOX=nightly yarn run test:firefox');
|
||||
console.log(chalk.gray('\n# You can test against older versions too:'));
|
||||
console.log(
|
||||
'WEB_EXT_FIREFOX=/Applications/Firefox52.app/Contents/MacOS/firefox-bin yarn run test:firefox'
|
||||
);
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
module.exports = {main};
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const deploy = require('../deploy');
|
||||
|
||||
const main = async () => await deploy('firefox');
|
||||
|
||||
main();
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "React Developer Tools",
|
||||
"description": "Adds React debugging tools to the Firefox Developer Tools.",
|
||||
"version": "4.0.0",
|
||||
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "@react-devtools",
|
||||
"strict_min_version": "54.0"
|
||||
}
|
||||
},
|
||||
|
||||
"icons": {
|
||||
"16": "icons/16-production.png",
|
||||
"32": "icons/32-production.png",
|
||||
"48": "icons/48-production.png",
|
||||
"128": "icons/128-production.png"
|
||||
},
|
||||
|
||||
"browser_action": {
|
||||
"default_icon": {
|
||||
"16": "icons/16-disabled.png",
|
||||
"32": "icons/32-disabled.png",
|
||||
"48": "icons/48-disabled.png",
|
||||
"128": "icons/128-disabled.png"
|
||||
},
|
||||
|
||||
"default_popup": "popups/disabled.html",
|
||||
"browser_style": true
|
||||
},
|
||||
|
||||
"devtools_page": "main.html",
|
||||
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"web_accessible_resources": [
|
||||
"main.html",
|
||||
"panel.html",
|
||||
"build/backend.js",
|
||||
"build/renderer.js"
|
||||
],
|
||||
|
||||
"background": {
|
||||
"scripts": ["build/background.js"]
|
||||
},
|
||||
|
||||
"permissions": [
|
||||
"<all_urls>",
|
||||
"activeTab",
|
||||
"tabs",
|
||||
"webNavigation",
|
||||
"file:///*",
|
||||
"http://*/*",
|
||||
"https://*/*"
|
||||
],
|
||||
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["build/injectGlobalHook.js"],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "react-devtools-experimental-firefox",
|
||||
"alias": ["react-devtools-experimental-firefox"],
|
||||
"files": ["index.html", "ReactDevTools.zip"]
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const {exec} = require('child-process-promise');
|
||||
const {Finder} = require('firefox-profile');
|
||||
const {resolve} = require('path');
|
||||
|
||||
const EXTENSION_PATH = resolve('./firefox/build/unpacked');
|
||||
const START_URL = 'https://facebook.github.io/react/';
|
||||
|
||||
const main = async () => {
|
||||
const finder = new Finder();
|
||||
|
||||
// Use default Firefox profile for testing purposes.
|
||||
// This prevents users from having to re-login-to sites before testing.
|
||||
const findPathPromise = new Promise((resolvePromise, rejectPromise) => {
|
||||
finder.getPath('default', (error, profile) => {
|
||||
if (error) {
|
||||
rejectPromise(error);
|
||||
} else {
|
||||
resolvePromise(profile);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const options = [
|
||||
`--source-dir=${EXTENSION_PATH}`,
|
||||
`--start-url=${START_URL}`,
|
||||
'--browser-console',
|
||||
];
|
||||
|
||||
try {
|
||||
const path = await findPathPromise;
|
||||
const trimmedPath = path.replace(' ', '\\ ');
|
||||
options.push(`--firefox-profile=${trimmedPath}`);
|
||||
} catch (err) {
|
||||
console.warn('Could not find default profile, using temporary profile.');
|
||||
}
|
||||
|
||||
try {
|
||||
await exec(`web-ext run ${options.join(' ')}`);
|
||||
} catch (err) {
|
||||
console.error('`web-ext run` failed', err.stdout, err.stderr);
|
||||
}
|
||||
};
|
||||
|
||||
main();
|
||||
@@ -1,96 +0,0 @@
|
||||
// @flow
|
||||
|
||||
'use strict';
|
||||
|
||||
declare var chrome: {
|
||||
devtools: {
|
||||
network: {
|
||||
onNavigated: {
|
||||
addListener: (cb: (url: string) => void) => void,
|
||||
removeListener: (cb: () => void) => void,
|
||||
},
|
||||
},
|
||||
inspectedWindow: {
|
||||
eval: (code: string, cb?: (res: any, err: ?Object) => any) => void,
|
||||
tabId: number,
|
||||
},
|
||||
panels: {
|
||||
create: (
|
||||
title: string,
|
||||
icon: string,
|
||||
filename: string,
|
||||
cb: (panel: {
|
||||
onHidden: {
|
||||
addListener: (cb: (window: Object) => void) => void,
|
||||
},
|
||||
onShown: {
|
||||
addListener: (cb: (window: Object) => void) => void,
|
||||
},
|
||||
}) => void
|
||||
) => void,
|
||||
themeName: ?string,
|
||||
},
|
||||
},
|
||||
tabs: {
|
||||
create: (options: Object) => void,
|
||||
executeScript: (tabId: number, options: Object, fn: () => void) => void,
|
||||
onUpdated: {
|
||||
addListener: (
|
||||
fn: (tabId: number, changeInfo: Object, tab: Object) => void
|
||||
) => void,
|
||||
},
|
||||
query: (options: Object, fn: (tabArray: Array<Object>) => void) => void,
|
||||
},
|
||||
browserAction: {
|
||||
setIcon: (options: {
|
||||
tabId: number,
|
||||
path: {[key: string]: string},
|
||||
}) => void,
|
||||
setPopup: (options: {
|
||||
tabId: number,
|
||||
popup: string,
|
||||
}) => void,
|
||||
},
|
||||
runtime: {
|
||||
getURL: (path: string) => string,
|
||||
sendMessage: (config: Object) => void,
|
||||
connect: (
|
||||
config: Object
|
||||
) => {
|
||||
disconnect: () => void,
|
||||
onMessage: {
|
||||
addListener: (fn: (message: Object) => void) => void,
|
||||
},
|
||||
onDisconnect: {
|
||||
addListener: (fn: (message: Object) => void) => void,
|
||||
},
|
||||
postMessage: (data: Object) => void,
|
||||
},
|
||||
onConnect: {
|
||||
addListener: (
|
||||
fn: (port: {
|
||||
name: string,
|
||||
sender: {
|
||||
tab: {
|
||||
id: number,
|
||||
url: string,
|
||||
},
|
||||
},
|
||||
}) => void
|
||||
) => void,
|
||||
},
|
||||
onMessage: {
|
||||
addListener: (
|
||||
fn: (
|
||||
req: Object,
|
||||
sender: {
|
||||
url: string,
|
||||
tab: {
|
||||
id: number,
|
||||
},
|
||||
}
|
||||
) => void
|
||||
) => void,
|
||||
},
|
||||
},
|
||||
};
|
||||
1190
packages/react-devtools-extensions/flow-typed/jest.js
vendored
@@ -1,84 +0,0 @@
|
||||
// flow-typed signature: b6bb53397d83d2d821e258cc73818d1b
|
||||
// flow-typed version: 9c71eca8ef/react-test-renderer_v16.x.x/flow_>=v0.47.x
|
||||
|
||||
// Type definitions for react-test-renderer 16.x.x
|
||||
// Ported from: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-test-renderer
|
||||
|
||||
'use strict';
|
||||
|
||||
type ReactComponentInstance = React$Component<any>;
|
||||
|
||||
type ReactTestRendererJSON = {
|
||||
type: string,
|
||||
props: {[propName: string]: any},
|
||||
children: null | ReactTestRendererJSON[],
|
||||
};
|
||||
|
||||
type ReactTestRendererTree = ReactTestRendererJSON & {
|
||||
nodeType: 'component' | 'host',
|
||||
instance: ?ReactComponentInstance,
|
||||
rendered: null | ReactTestRendererTree,
|
||||
};
|
||||
|
||||
type ReactTestInstance = {
|
||||
instance: ?ReactComponentInstance,
|
||||
type: string,
|
||||
props: {[propName: string]: any},
|
||||
parent: null | ReactTestInstance,
|
||||
children: Array<ReactTestInstance | string>,
|
||||
|
||||
find(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance,
|
||||
findByType(type: React$ElementType): ReactTestInstance,
|
||||
findByProps(props: {[propName: string]: any}): ReactTestInstance,
|
||||
|
||||
findAll(
|
||||
predicate: (node: ReactTestInstance) => boolean,
|
||||
options?: {deep: boolean}
|
||||
): ReactTestInstance[],
|
||||
findAllByType(
|
||||
type: React$ElementType,
|
||||
options?: {deep: boolean}
|
||||
): ReactTestInstance[],
|
||||
findAllByProps(
|
||||
props: {[propName: string]: any},
|
||||
options?: {deep: boolean}
|
||||
): ReactTestInstance[],
|
||||
};
|
||||
|
||||
type TestRendererOptions = {
|
||||
createNodeMock(element: React$Element<any>): any,
|
||||
};
|
||||
|
||||
declare module 'react-test-renderer' {
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
declare export type ReactTestRenderer = {
|
||||
toJSON(): null | ReactTestRendererJSON,
|
||||
toTree(): null | ReactTestRendererTree,
|
||||
unmount(nextElement?: React$Element<any>): void,
|
||||
update(nextElement: React$Element<any>): void,
|
||||
getInstance(): ?ReactComponentInstance,
|
||||
root: ReactTestInstance,
|
||||
};
|
||||
|
||||
declare type Thenable = {
|
||||
then(resolve: () => mixed, reject?: () => mixed): mixed,
|
||||
};
|
||||
|
||||
declare function create(
|
||||
nextElement: React$Element<any>,
|
||||
options?: TestRendererOptions
|
||||
): ReactTestRenderer;
|
||||
|
||||
declare function act(callback: () => ?Thenable): Thenable;
|
||||
}
|
||||
|
||||
declare module 'react-test-renderer/shallow' {
|
||||
declare export default class ShallowRenderer {
|
||||
static createRenderer(): ShallowRenderer;
|
||||
getMountedInstance(): ReactTestInstance;
|
||||
getRenderOutput<E: React$Element<any>>(): E;
|
||||
getRenderOutput(): React$Element<any>;
|
||||
render(element: React$Element<any>, context?: any): void;
|
||||
unmount(): void;
|
||||
}
|
||||
}
|
||||
27
packages/react-devtools-extensions/flow.js
vendored
@@ -1,27 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare module 'events' {
|
||||
declare class EventEmitter<Events: Object> {
|
||||
addListener<Event: $Keys<Events>>(
|
||||
event: Event,
|
||||
listener: (...$ElementType<Events, Event>) => any,
|
||||
): void;
|
||||
emit: <Event: $Keys<Events>>(
|
||||
event: Event,
|
||||
...$ElementType<Events, Event>
|
||||
) => void;
|
||||
removeListener(event: $Keys<Events>, listener: Function): void;
|
||||
removeAllListeners(event?: $Keys<Events>): void;
|
||||
}
|
||||
|
||||
declare export default typeof EventEmitter;
|
||||
}
|
||||
|
||||
declare var __DEV__: boolean;
|
||||
|
||||
declare var jasmine: {|
|
||||
getEnv: () => {|
|
||||
afterEach: (callback: Function) => void,
|
||||
beforeEach: (callback: Function) => void,
|
||||
|},
|
||||
|};
|
||||
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 638 B |
|
Before Width: | Height: | Size: 638 B |
|
Before Width: | Height: | Size: 494 B |
|
Before Width: | Height: | Size: 558 B |
|
Before Width: | Height: | Size: 546 B |
|
Before Width: | Height: | Size: 638 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1 +0,0 @@
|
||||
<svg id="Development" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><defs><style>.cls-1{fill:#d94a38;}.cls-2{fill:#fff;}.cls-3{fill:#231f20;}.cls-4{font-size:12px;font-family:MyriadPro-Regular, Myriad Pro;}</style></defs><title>development</title><g id="Background"><rect class="cls-1" width="1024" height="1024" rx="96" ry="96"/></g><g id="Rings"><g id="Ring-2" data-name="Ring"><path class="cls-2" d="M959,509c0-62-74-117-189-150,27-115,17-207-37-238s-139,6-224,88c-86-81-171-118-224-87s-64,123-36,239C135,394,61,449,61,511s74,117,189,150c-27,115-17,207,37,238s139-6,224-88c86,81,171,118,224,87s64-123,36-239C885,626,959,571,959,509ZM713,157c40,23,45,97,21,193a900,900,0,0,0-121-19,900,900,0,0,0-78-94C606,166,673,133,713,157ZM635,583c-14,24-28,47-43,69-27,2-54,3-83,3l-81-3c-15-22-30-46-44-70s-27-48-38-72c12-24,24-49,39-73s28-47,43-69c27-2,54-3,83-3l81,3c15,22,30,46,44,70s27,48,38,72C662,534,649,558,635,583Zm60-27c11,26,21,52,29,77-25,6-52,10-81,14l26-44ZM511,757c-17-19-35-40-52-63H563C546,716,528,738,511,757ZM378,647c-29-3-56-8-81-13,8-25,17-50,28-77l25,45ZM325,464c-11-26-21-52-29-77,25-6,52-10,81-14l-26,44ZM509,263c17,19,35,40,52,63H457C474,304,492,282,509,263ZM670,418l-28-45c29,3,56,8,81,13-8,25-17,50-28,77ZM305,158c40-23,106,9,177,78a900,900,0,0,0-77,95,900,900,0,0,0-120,20C260,255,265,181,305,158ZM102,511c0-46,61-88,156-114a900,900,0,0,0,44,114,900,900,0,0,0-43,114C164,599,102,558,102,511ZM307,863c-40-23-45-97-21-193a900,900,0,0,0,121,19,900,900,0,0,0,78,94C414,854,347,887,307,863Zm408-1c-40,23-106-9-177-78a900,900,0,0,0,77-95,900,900,0,0,0,120-20C760,765,755,839,715,862Zm46-239a900,900,0,0,0-44-114,900,900,0,0,0,43-114c96,26,157,67,157,114S856,597,761,623Z"/></g></g><g id="Ring_Blockers" data-name="Ring Blockers"><circle class="cls-1" cx="417" cy="672" r="45"/><circle class="cls-1" cx="699" cy="513" r="45"/><circle class="cls-1" cx="797" cy="634" r="45"/><circle class="cls-1" cx="479" cy="818" r="45"/><g id="Layer_14" data-name="Layer 14"><rect class="cls-1" x="420" y="621" width="377" height="188"/><rect class="cls-1" x="500" y="530" width="312" height="405"/></g></g><g id="Bug"><g id="Legs"><path class="cls-3" d="M702,496a17,17,0,0,0-21,13l-19,78,34,8,19-78A17,17,0,0,0,702,496Z"/><text class="cls-4" transform="translate(512 512)">780</text><text class="cls-4" transform="translate(512 512)">780</text><path class="cls-3" d="M813,626a17,17,0,0,0-23-9l-73,32,14,32,73-32A17,17,0,0,0,813,626Z"/><path class="cls-3" d="M834,756l-77-20-9,34,77,20a18,18,0,0,0,9-34Z"/><path class="cls-3" d="M425,656a17,17,0,1,0-10,33l76,23,10-33Z"/><path class="cls-3" d="M532,756l-64,48a18,18,0,1,0,21,28l64-48Z"/><path class="cls-3" d="M584,836l-21,77a17,17,0,1,0,34,9l21-77Z"/></g><g id="Body"><path class="cls-3" d="M762,690h0l-51-92h0A125,125,0,0,0,492,721h0l51,92h0A125,125,0,0,0,762,690Z"/></g><g id="Line"><path class="cls-1" d="M613,649h0a17,17,0,0,0-30,18h0L711,887l30-18Z"/></g><g id="Head_Ring" data-name="Head Ring"><circle class="cls-1" cx="511" cy="509" r="113"/></g><g id="Head"><circle class="cls-3" cx="512" cy="512" r="80"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
@@ -1 +0,0 @@
|
||||
<svg id="Development" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><defs><style>.cls-1{fill:#d94a38;}.cls-2{fill:#fff;}.cls-3{fill:#231f20;}.cls-4{font-size:12px;font-family:MyriadPro-Regular, Myriad Pro;}</style></defs><title>development</title><g id="Background"><rect class="cls-1" width="1024" height="1024" rx="96" ry="96"/></g><g id="Rings"><g id="Ring-2" data-name="Ring"><path class="cls-2" d="M959,509c0-62-74-117-189-150,27-115,17-207-37-238s-139,6-224,88c-86-81-171-118-224-87s-64,123-36,239C135,394,61,449,61,511s74,117,189,150c-27,115-17,207,37,238s139-6,224-88c86,81,171,118,224,87s64-123,36-239C885,626,959,571,959,509ZM713,157c40,23,45,97,21,193a900,900,0,0,0-121-19,900,900,0,0,0-78-94C606,166,673,133,713,157ZM635,583c-14,24-28,47-43,69-27,2-54,3-83,3l-81-3c-15-22-30-46-44-70s-27-48-38-72c12-24,24-49,39-73s28-47,43-69c27-2,54-3,83-3l81,3c15,22,30,46,44,70s27,48,38,72C662,534,649,558,635,583Zm60-27c11,26,21,52,29,77-25,6-52,10-81,14l26-44ZM511,757c-17-19-35-40-52-63H563C546,716,528,738,511,757ZM378,647c-29-3-56-8-81-13,8-25,17-50,28-77l25,45ZM325,464c-11-26-21-52-29-77,25-6,52-10,81-14l-26,44ZM509,263c17,19,35,40,52,63H457C474,304,492,282,509,263ZM670,418l-28-45c29,3,56,8,81,13-8,25-17,50-28,77ZM305,158c40-23,106,9,177,78a900,900,0,0,0-77,95,900,900,0,0,0-120,20C260,255,265,181,305,158ZM102,511c0-46,61-88,156-114a900,900,0,0,0,44,114,900,900,0,0,0-43,114C164,599,102,558,102,511ZM307,863c-40-23-45-97-21-193a900,900,0,0,0,121,19,900,900,0,0,0,78,94C414,854,347,887,307,863Zm408-1c-40,23-106-9-177-78a900,900,0,0,0,77-95,900,900,0,0,0,120-20C760,765,755,839,715,862Zm46-239a900,900,0,0,0-44-114,900,900,0,0,0,43-114c96,26,157,67,157,114S856,597,761,623Z"/></g></g><g id="Ring_Blockers" data-name="Ring Blockers"><circle class="cls-1" cx="417" cy="672" r="45"/><circle class="cls-1" cx="699" cy="513" r="45"/><circle class="cls-1" cx="797" cy="634" r="45"/><circle class="cls-1" cx="479" cy="818" r="45"/><g id="Layer_14" data-name="Layer 14"><rect class="cls-1" x="420" y="621" width="377" height="188"/><rect class="cls-1" x="500" y="530" width="312" height="405"/></g></g><g id="Bug"><g id="Legs"><path class="cls-3" d="M702,496a17,17,0,0,0-21,13l-19,78,34,8,19-78A17,17,0,0,0,702,496Z"/><text class="cls-4" transform="translate(512 512)">780</text><text class="cls-4" transform="translate(512 512)">780</text><path class="cls-3" d="M813,626a17,17,0,0,0-23-9l-73,32,14,32,73-32A17,17,0,0,0,813,626Z"/><path class="cls-3" d="M834,756l-77-20-9,34,77,20a18,18,0,0,0,9-34Z"/><path class="cls-3" d="M425,656a17,17,0,1,0-10,33l76,23,10-33Z"/><path class="cls-3" d="M532,756l-64,48a18,18,0,1,0,21,28l64-48Z"/><path class="cls-3" d="M584,836l-21,77a17,17,0,1,0,34,9l21-77Z"/></g><g id="Body"><path class="cls-3" d="M762,690h0l-51-92h0A125,125,0,0,0,492,721h0l51,92h0A125,125,0,0,0,762,690Z"/></g><g id="Line"><path class="cls-1" d="M613,649h0a17,17,0,0,0-30,18h0L711,887l30-18Z"/></g><g id="Head_Ring" data-name="Head Ring"><circle class="cls-1" cx="511" cy="509" r="113"/></g><g id="Head"><circle class="cls-3" cx="512" cy="512" r="80"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
@@ -1 +0,0 @@
|
||||
<svg id="Disabled" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><defs><style>.cls-1{fill:#aaa;}.cls-2{fill:#fff;}</style></defs><title>disabled</title><g id="Background"><rect class="cls-1" width="1024" height="1024" rx="96" ry="96"/></g><g id="Rings"><path class="cls-2" d="M959,509c0-62-74-117-189-150,27-115,17-207-37-238s-139,6-224,88c-86-81-171-118-224-87s-64,123-36,239C135,394,61,449,61,511s74,117,189,150c-27,115-17,207,37,238s139-6,224-88c86,81,171,118,224,87s64-123,36-239C885,626,959,571,959,509ZM713,157c40,23,45,97,21,193a900,900,0,0,0-121-19,900,900,0,0,0-78-94C606,166,673,133,713,157ZM635,583c-14,24-28,47-43,69-27,2-54,3-83,3l-81-3c-15-22-30-46-44-70s-27-48-38-72c12-24,24-49,39-73s28-47,43-69c27-2,54-3,83-3l81,3c15,22,30,46,44,70s27,48,38,72C662,534,649,558,635,583Zm60-27c11,26,21,52,29,77-25,6-52,10-81,14l26-44ZM511,757c-17-19-35-40-52-63H563C546,716,528,738,511,757ZM378,647c-29-3-56-8-81-13,8-25,17-50,28-77l25,45ZM325,464c-11-26-21-52-29-77,25-6,52-10,81-14l-26,44ZM509,263c17,19,35,40,52,63H457C474,304,492,282,509,263ZM670,418l-28-45c29,3,56,8,81,13-8,25-17,50-28,77ZM305,158c40-23,106,9,177,78a900,900,0,0,0-77,95,900,900,0,0,0-120,20C260,255,265,181,305,158ZM102,511c0-46,61-88,156-114a900,900,0,0,0,44,114,900,900,0,0,0-43,114C164,599,102,558,102,511ZM307,863c-40-23-45-97-21-193a900,900,0,0,0,121,19,900,900,0,0,0,78,94C414,854,347,887,307,863Zm408-1c-40,23-106-9-177-78a900,900,0,0,0,77-95,900,900,0,0,0,120-20C760,765,755,839,715,862Zm46-239a900,900,0,0,0-44-114,900,900,0,0,0,43-114c96,26,157,67,157,114S856,597,761,623Z"/></g><g id="Circle"><circle class="cls-2" cx="510" cy="510" r="80"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1 +0,0 @@
|
||||
<svg id="Outdated" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><defs><style>.cls-1{fill:#202020;}.cls-2{fill:#fff;}.cls-3{fill:#f9f453;}</style></defs><title>outdated</title><g id="Background"><rect class="cls-1" width="1024" height="1024" rx="96" ry="96"/></g><g id="Rings"><path class="cls-2" d="M510,325C261,325,60,408,60,510S261,695,510,695s450-83,450-185S759,325,510,325Zm0,330c-225,0-407-65-407-145S285,365,510,365s408,65,408,145S735,655,510,655Z"/><path class="cls-2" d="M670,417C546,202,373,69,285,120s-59,267,65,482S647,951,735,900,794,633,670,417ZM384,583C272,388,237,197,306,157s217,86,329,280,148,385,78,425S497,777,384,583Z"/><g id="BLOCKER"><rect class="cls-1" x="564" y="572" width="315" height="397.12" transform="translate(652 -283) rotate(39)"/><rect class="cls-1" x="685" y="369" width="283" height="360.81" transform="translate(255 -262) rotate(21)"/></g><path class="cls-2" d="M670,603c124-215,153-431,65-482S474,202,350,417,197,849,285,900,546,818,670,603ZM384,437C497,243,644,117,714,157s34,231-78,425S376,903,306,863,272,632,384,437Z"/></g><g id="Circle"><circle class="cls-2" cx="512" cy="512" r="80"/></g><g id="Shield"><path class="cls-3" d="M960,887a24,24,0,0,0-5-15h0L807,605h0v-2h0a25,25,0,0,0-43,3h0L613,876h0a24,24,0,0,0-3,11,25,25,0,0,0,24,25H936A25,25,0,0,0,960,887ZM810,848a15,15,0,0,1-15,15H775a15,15,0,0,1-15-15V828a15,15,0,0,1,15-15h20a15,15,0,0,1,15,15Zm0-74a15,15,0,0,1-15,15H775a15,15,0,0,1-15-15V705a15,15,0,0,1,15-15h20a15,15,0,0,1,15,15Z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1 +0,0 @@
|
||||
<svg id="Production" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><defs><style>.cls-1{fill:#202020;}.cls-2{fill:#59c9f1;}</style></defs><title>production</title><g id="Background"><rect class="cls-1" width="1024" height="1024" rx="96" ry="96"/></g><g id="Rings"><path class="cls-2" d="M959,509c0-62-74-117-189-150,27-115,17-207-37-238s-139,6-224,88c-86-81-171-118-224-87s-64,123-36,239C135,394,61,449,61,511s74,117,189,150c-27,115-17,207,37,238s139-6,224-88c86,81,171,118,224,87s64-123,36-239C885,626,959,571,959,509ZM713,157c40,23,45,97,21,193a900,900,0,0,0-121-19,900,900,0,0,0-78-94C606,166,673,133,713,157ZM635,583c-14,24-28,47-43,69-27,2-54,3-83,3l-81-3c-15-22-30-46-44-70s-27-48-38-72c12-24,24-49,39-73s28-47,43-69c27-2,54-3,83-3l81,3c15,22,30,46,44,70s27,48,38,72C662,534,649,558,635,583Zm60-27c11,26,21,52,29,77-25,6-52,10-81,14l26-44ZM511,757c-17-19-35-40-52-63H563C546,716,528,738,511,757ZM378,647c-29-3-56-8-81-13,8-25,17-50,28-77l25,45ZM325,464c-11-26-21-52-29-77,25-6,52-10,81-14l-26,44ZM509,263c17,19,35,40,52,63H457C474,304,492,282,509,263ZM670,418l-28-45c29,3,56,8,81,13-8,25-17,50-28,77ZM305,158c40-23,106,9,177,78a900,900,0,0,0-77,95,900,900,0,0,0-120,20C260,255,265,181,305,158ZM102,511c0-46,61-88,156-114a900,900,0,0,0,44,114,900,900,0,0,0-43,114C164,599,102,558,102,511ZM307,863c-40-23-45-97-21-193a900,900,0,0,0,121,19,900,900,0,0,0,78,94C414,854,347,887,307,863Zm408-1c-40,23-106-9-177-78a900,900,0,0,0,77-95,900,900,0,0,0,120-20C760,765,755,839,715,862Zm46-239a900,900,0,0,0-44-114,900,900,0,0,0,43-114c96,26,157,67,157,114S856,597,761,623Z"/></g><g id="Circle"><circle class="cls-2" cx="510" cy="510" r="80"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,9 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script src="./build/main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
|
||||
"name": "react-devtools-extensions",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_ENV=production yarn run build:chrome && yarn run build:firefox",
|
||||
"build:dev": "cross-env NODE_ENV=development yarn run build:chrome && yarn run build:firefox",
|
||||
"build:chrome": "cross-env NODE_ENV=production node ./chrome/build",
|
||||
"build:chrome:crx": "cross-env NODE_ENV=production node ./chrome/build --crx",
|
||||
"build:chrome:dev": "cross-env NODE_ENV=development node ./chrome/build",
|
||||
"build:firefox": "cross-env NODE_ENV=production node ./firefox/build",
|
||||
"build:firefox:dev": "cross-env NODE_ENV=development node ./firefox/build",
|
||||
"test:chrome": "node ./chrome/test",
|
||||
"test:firefox": "node ./firefox/test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.1.6",
|
||||
"@babel/plugin-proposal-class-properties": "^7.1.0",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.1.6",
|
||||
"@babel/plugin-transform-react-jsx-source": "^7.2.0",
|
||||
"@babel/preset-env": "^7.1.6",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"archiver": "^3.0.0",
|
||||
"babel-core": "^7.0.0-bridge",
|
||||
"babel-eslint": "^9.0.0",
|
||||
"babel-jest": "^24.7.1",
|
||||
"babel-loader": "^8.0.4",
|
||||
"chrome-launch": "^1.1.4",
|
||||
"child-process-promise": "^2.2.1",
|
||||
"css-loader": "^1.0.1",
|
||||
"firefox-profile": "^1.0.2",
|
||||
"node-libs-browser": "0.5.3",
|
||||
"nullthrows": "^1.0.0",
|
||||
"raw-loader": "^3.1.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"web-ext": "^3.0.0",
|
||||
"webpack": "^4.26.0",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-dev-server": "^3.3.1"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<!doctype html>
|
||||
<html style="display: flex">
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<style>
|
||||
html {
|
||||
display: flex;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
}
|
||||
#container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- main react mount point -->
|
||||
<div id="container">Unable to find React on the page.</div>
|
||||
<script src="./build/panel.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,32 +0,0 @@
|
||||
<script src="shared.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
font-size: 14px;
|
||||
min-width: 460px;
|
||||
min-height: 133px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<p>
|
||||
<b>This page includes an extra development build of React. 🚧</b>
|
||||
</p>
|
||||
<p>
|
||||
The React build on this page includes both development and production versions because dead code elimination has not been applied correctly.
|
||||
<br />
|
||||
<br />
|
||||
This makes its size larger, and causes React to run slower.
|
||||
<br />
|
||||
<br />
|
||||
Make sure to <a href="https://facebook.github.io/react/docs/optimizing-performance.html#use-the-production-build">set up dead code elimination</a> before deployment.
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
Open the developer tools, and the React tab will appear to the right.
|
||||
</p>
|
||||
@@ -1,28 +0,0 @@
|
||||
<script src="shared.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
font-size: 14px;
|
||||
min-width: 460px;
|
||||
min-height: 101px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<p>
|
||||
<b>This page is using the development build of React. 🚧</b>
|
||||
</p>
|
||||
<p>
|
||||
Note that the development build is not suitable for production.
|
||||
<br />
|
||||
Make sure to <a href="https://facebook.github.io/react/docs/optimizing-performance.html#use-the-production-build">use the production build</a> before deployment.
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
Open the developer tools, and the React tab will appear to the right.
|
||||
</p>
|
||||
@@ -1,21 +0,0 @@
|
||||
<script src="shared.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
font-size: 14px;
|
||||
min-width: 410px;
|
||||
min-height: 33px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<p>
|
||||
<b>This page doesn’t appear to be using React.</b>
|
||||
<br />
|
||||
If this seems wrong, follow the <a href="https://github.com/facebook/react-devtools/blob/master/README.md#the-react-tab-doesnt-show-up">troubleshooting instructions</a>.
|
||||
</p>
|
||||
@@ -1,29 +0,0 @@
|
||||
<script src="shared.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
font-size: 14px;
|
||||
min-width: 460px;
|
||||
min-height: 117px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<p>
|
||||
<b>This page is using an outdated version of React. ⌛</b>
|
||||
</p>
|
||||
<p>
|
||||
We recommend updating React to ensure that you receive important bugfixes and performance improvements.
|
||||
<br />
|
||||
<br />
|
||||
You can find the upgrade instructions on the <a href="https://facebook.github.io/react/blog/">React blog</a>.
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
Open the developer tools, and the React tab will appear to the right.
|
||||
</p>
|
||||
@@ -1,21 +0,0 @@
|
||||
<script src="shared.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
font-size: 14px;
|
||||
min-width: 460px;
|
||||
min-height: 39px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<p>
|
||||
<b>This page is using the production build of React. ✅</b>
|
||||
<br />
|
||||
Open the developer tools, and the React tab will appear to the right.
|
||||
</p>
|
||||